LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH V3 1/5] powerpc, perf: Add new BHRB related instructions for POWER8
From: Anshuman Khandual @ 2013-04-22  7:03 UTC (permalink / raw)
  To: Michael Neuling; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <14063.1366599003@ale.ozlabs.ibm.com>

On 04/22/2013 08:20 AM, Michael Neuling wrote:
> Michael Ellerman <michael@ellerman.id.au> wrote:
> 
>> On Mon, Apr 22, 2013 at 11:13:43AM +1000, Michael Neuling wrote:
>>> Michael Ellerman <michael@ellerman.id.au> wrote:
>>>
>>>> On Thu, Apr 18, 2013 at 05:56:12PM +0530, Anshuman Khandual wrote:
>>>>> This patch adds new POWER8 instruction encoding for reading
>>>>> the BHRB buffer entries and also clearing it. Encoding for
>>>>> "clrbhrb" instruction is straight forward.
>>>>
>>>> Which is "clear branch history rolling buffer" ?
>>>>
>>>>> But "mfbhrbe"
>>>>> encoding involves reading a certain index of BHRB buffer
>>>>> into a particular GPR register.
>>>>
>>>> And "Move from branch history rolling buffer entry" ?
>>>>
>>>>> diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
>>>>> index 8752bc8..93ae5a1 100644
>>>>> --- a/arch/powerpc/include/asm/ppc-opcode.h
>>>>> +++ b/arch/powerpc/include/asm/ppc-opcode.h
>>>>> @@ -82,6 +82,7 @@
>>>>>  #define	__REGA0_R31	31
>>>>>  
>>>>>  /* sorted alphabetically */
>>>>> +#define PPC_INST_BHRBE			0x7c00025c
>>>>
>>>> I don't think you really need this, just use the literal value below.
>>>
>>> The rest of the defines in this file do this, so Anshuman's right. 
>>
>> I don't see the point, but sure let's be consistent. Though in that case
>> he should do the same for PPC_CLRBHRB below.
> 
> Agreed.
> 

Sure, would define a new macro (PPC_INST_CLRBHRB) to encode 0x7c00035c
before using it for PPC_CLRBHRB.

> Mikey
> 
>>
>>>>> @@ -297,6 +298,12 @@
>>>>>  #define PPC_NAP			stringify_in_c(.long PPC_INST_NAP)
>>>>>  #define PPC_SLEEP		stringify_in_c(.long PPC_INST_SLEEP)
>>>>>  
>>>>> +/* BHRB instructions */
>>>>> +#define PPC_CLRBHRB		stringify_in_c(.long 0x7c00035c)
>>>>> +#define PPC_MFBHRBE(r, n)	stringify_in_c(.long PPC_INST_BHRBE | \
>>>>> +						__PPC_RS(r) | \
>>>>> +							(((n) & 0x1f) << 11))
>>>>
>>>> Why are you not using ___PPC_RB(n) here ?
>>>
>>> Actually, this is wrong.  The number field should be 10 bits (0x3ff),
>>> not 5 (0x1f)  Anshuman please fix.
>>
>> ACK.

I got it wrong, thought this as 32 instead of 1024. Would fix it.

Regards
Anshuman

^ permalink raw reply

* Re: [PATCH 0/5] of_platform_driver and OF_DEVICE removal
From: Arnd Bergmann @ 2013-04-22  7:03 UTC (permalink / raw)
  To: Rob Herring
  Cc: Roland Dreier, Sean Hefty, Alexander Shishkin, devicetree-discuss,
	linux-usb, linux-kernel, Rob Herring, linux-rdma,
	Christoph Raisch, Hoang-Nam Nguyen, Thadeu Lima de Souza Cascardo,
	Greg Kroah-Hartman, Grant Likely, Paul Mackerras, netdev,
	linuxppc-dev, Hal Rosenstock
In-Reply-To: <1366596798-9457-1-git-send-email-robherring2@gmail.com>

On Monday 22 April 2013, Rob Herring wrote:
> From: Rob Herring <rob.herring@calxeda.com>
> 
> This series is a relatively straight-forward removal of the last remaining
> user of of_platform_driver (ibmebus) and removal of CONFIG_OF_DEVICE which
> is always enabled when CONFIG_OF is enabled.
> 
> Compile tested on powerpc and sparc.
> 

Acked-by: Arnd Bergmann <arnd@arndb.de>

^ permalink raw reply

* Re: [PATCH V3 1/5] powerpc, perf: Add new BHRB related instructions for POWER8
From: Anshuman Khandual @ 2013-04-22  7:03 UTC (permalink / raw)
  To: Michael Neuling; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <14063.1366599003@ale.ozlabs.ibm.com>

On 04/22/2013 08:20 AM, Michael Neuling wrote:
> Michael Ellerman <michael@ellerman.id.au> wrote:
> 
>> On Mon, Apr 22, 2013 at 11:13:43AM +1000, Michael Neuling wrote:
>>> Michael Ellerman <michael@ellerman.id.au> wrote:
>>>
>>>> On Thu, Apr 18, 2013 at 05:56:12PM +0530, Anshuman Khandual wrote:
>>>>> This patch adds new POWER8 instruction encoding for reading
>>>>> the BHRB buffer entries and also clearing it. Encoding for
>>>>> "clrbhrb" instruction is straight forward.
>>>>
>>>> Which is "clear branch history rolling buffer" ?
>>>>
>>>>> But "mfbhrbe"
>>>>> encoding involves reading a certain index of BHRB buffer
>>>>> into a particular GPR register.
>>>>
>>>> And "Move from branch history rolling buffer entry" ?
>>>>
>>>>> diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
>>>>> index 8752bc8..93ae5a1 100644
>>>>> --- a/arch/powerpc/include/asm/ppc-opcode.h
>>>>> +++ b/arch/powerpc/include/asm/ppc-opcode.h
>>>>> @@ -82,6 +82,7 @@
>>>>>  #define	__REGA0_R31	31
>>>>>  
>>>>>  /* sorted alphabetically */
>>>>> +#define PPC_INST_BHRBE			0x7c00025c
>>>>
>>>> I don't think you really need this, just use the literal value below.
>>>
>>> The rest of the defines in this file do this, so Anshuman's right. 
>>
>> I don't see the point, but sure let's be consistent. Though in that case
>> he should do the same for PPC_CLRBHRB below.
> 
> Agreed.
> 

Sure, would define a new macro (PPC_INST_CLRBHRB) to encode 0x7c00035c
before using it for PPC_CLRBHRB.

> Mikey
> 
>>
>>>>> @@ -297,6 +298,12 @@
>>>>>  #define PPC_NAP			stringify_in_c(.long PPC_INST_NAP)
>>>>>  #define PPC_SLEEP		stringify_in_c(.long PPC_INST_SLEEP)
>>>>>  
>>>>> +/* BHRB instructions */
>>>>> +#define PPC_CLRBHRB		stringify_in_c(.long 0x7c00035c)
>>>>> +#define PPC_MFBHRBE(r, n)	stringify_in_c(.long PPC_INST_BHRBE | \
>>>>> +						__PPC_RS(r) | \
>>>>> +							(((n) & 0x1f) << 11))
>>>>
>>>> Why are you not using ___PPC_RB(n) here ?
>>>
>>> Actually, this is wrong.  The number field should be 10 bits (0x3ff),
>>> not 5 (0x1f)  Anshuman please fix.
>>
>> ACK.

I got it wrong, thought this as 32 instead of 1024. Would fix it.

Regards
Anshuman

^ permalink raw reply

* Re: [PATCH V3 1/5] powerpc, perf: Add new BHRB related instructions for POWER8
From: Anshuman Khandual @ 2013-04-22  6:57 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, mikey, linux-kernel
In-Reply-To: <20130421234109.GC22246@concordia>

On 04/22/2013 05:11 AM, Michael Ellerman wrote:
> On Thu, Apr 18, 2013 at 05:56:12PM +0530, Anshuman Khandual wrote:
>> This patch adds new POWER8 instruction encoding for reading
>> the BHRB buffer entries and also clearing it. Encoding for
>> "clrbhrb" instruction is straight forward.
> 
> Which is "clear branch history rolling buffer" ?
> 
>> But "mfbhrbe"
>> encoding involves reading a certain index of BHRB buffer
>> into a particular GPR register.
> 
> And "Move from branch history rolling buffer entry" ?
> 

Sure, would add these descriptions in the change log.

>> diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
>> index 8752bc8..93ae5a1 100644
>> --- a/arch/powerpc/include/asm/ppc-opcode.h
>> +++ b/arch/powerpc/include/asm/ppc-opcode.h
>> @@ -82,6 +82,7 @@
>>  #define	__REGA0_R31	31
>>  
>>  /* sorted alphabetically */
>> +#define PPC_INST_BHRBE			0x7c00025c
> 
> I don't think you really need this, just use the literal value below.
> 
>> @@ -297,6 +298,12 @@
>>  #define PPC_NAP			stringify_in_c(.long PPC_INST_NAP)
>>  #define PPC_SLEEP		stringify_in_c(.long PPC_INST_SLEEP)
>>  
>> +/* BHRB instructions */
>> +#define PPC_CLRBHRB		stringify_in_c(.long 0x7c00035c)
>> +#define PPC_MFBHRBE(r, n)	stringify_in_c(.long PPC_INST_BHRBE | \
>> +						__PPC_RS(r) | \
>> +							(((n) & 0x1f) << 11))
> 
> Why are you not using ___PPC_RB(n) here ?
> 

I would replace __PPC_RS(r) with __PPC_RT(r) which makes more sense from
instruction encoding point of view.

Regards
Anshuman

^ permalink raw reply

* Re: [PATCH] powerpc/fsl-pci: fix setup_pci_atmu() parameter issue
From: Michael Neuling @ 2013-04-22  6:56 UTC (permalink / raw)
  To: Roy Zang; +Cc: linuxppc-dev
In-Reply-To: <1366397734-1416-1-git-send-email-tie-fei.zang@freescale.com>

This was already posted about a week back.  Kumar can you please take
it?

http://patchwork.ozlabs.org/patch/236494/

Mikey

Roy Zang <tie-fei.zang@freescale.com> wrote:

> setup_pci_atmu() only has one parameter and remove the extra one, or
> build will fail due to un-match.
> 
> Signed-off-by: Roy Zang <tie-fei.zang@freescale.com>
> ---
>  arch/powerpc/sysdev/fsl_pci.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
> index 40ffe29..f823304 100644
> --- a/arch/powerpc/sysdev/fsl_pci.c
> +++ b/arch/powerpc/sysdev/fsl_pci.c
> @@ -978,7 +978,7 @@ static int fsl_pci_resume(struct device *dev)
>  		return -ENODEV;
>  	}
>  
> -	setup_pci_atmu(hose, &pci_rsrc);
> +	setup_pci_atmu(hose);
>  
>  	return 0;
>  }
> -- 
> 1.7.9.5
> 
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
> 

^ permalink raw reply

* Re: [PATCH 17/18] cpufreq: powerpc: move cpufreq driver to drivers/cpufreq
From: Viresh Kumar @ 2013-04-22  6:49 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, deepthi
  Cc: robin.randhawa, linux-pm, Viresh Kumar, patches, Liviu.Dudau,
	linux-kernel, cpufreq, rjw, Steve.Bannister, Paul Mackerras,
	Olof Johansson, arvind.chauhan, linuxppc-dev, linaro-kernel,
	charles.garcia-tobin
In-Reply-To: <CAKohpokpiw3zS32oDL+T09ToOQxc28w=2R2up5T3h3c2Agc0wg@mail.gmail.com>

On 9 April 2013 14:05, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> On 5 April 2013 12:16, Viresh Kumar <viresh.kumar@linaro.org> wrote:
>> On 4 April 2013 18:24, Viresh Kumar <viresh.kumar@linaro.org> wrote:
>>> This patch moves cpufreq driver of powerpc platform to drivers/cpufreq.
>>>
>>> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>> Cc: Paul Mackerras <paulus@samba.org>
>>> Cc: Olof Johansson <olof@lixom.net>
>>> Cc: linuxppc-dev@lists.ozlabs.org
>>> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
>>> ---
>>> Compile Tested only.
>>>
>>>  arch/powerpc/platforms/Kconfig                     | 31 ----------------------
>>>  arch/powerpc/platforms/pasemi/Makefile             |  1 -
>>>  arch/powerpc/platforms/powermac/Makefile           |  2 --
>>>  drivers/cpufreq/Kconfig.powerpc                    | 26 ++++++++++++++++++
>>>  drivers/cpufreq/Makefile                           |  3 +++
>>>  .../cpufreq.c => drivers/cpufreq/pasemi-cpufreq.c  |  0
>>>  .../cpufreq/pmac32-cpufreq.c                       |  0
>>>  .../cpufreq/pmac64-cpufreq.c                       |  0
>>>  8 files changed, 29 insertions(+), 34 deletions(-)
>>>  rename arch/powerpc/platforms/pasemi/cpufreq.c => drivers/cpufreq/pasemi-cpufreq.c (100%)
>>>  rename arch/powerpc/platforms/powermac/cpufreq_32.c => drivers/cpufreq/pmac32-cpufreq.c (100%)
>>>  rename arch/powerpc/platforms/powermac/cpufreq_64.c => drivers/cpufreq/pmac64-cpufreq.c (100%)
>>
>> Hi Deepthi,
>>
>> Can you help testing this please?
>
> Ping!!

Ping!!

^ permalink raw reply

* Re: [PATCH RESEND] powerpc/rtas_flash: Free kmem upon module exit
From: Michael Ellerman @ 2013-04-22  6:33 UTC (permalink / raw)
  To: Vasant Hegde; +Cc: linuxppc-dev, paulus
In-Reply-To: <5174CF10.70903@linux.vnet.ibm.com>

On Mon, Apr 22, 2013 at 11:18:00AM +0530, Vasant Hegde wrote:
> Michael,
> 
> On Mon 22 Apr 2013 04:57:57 AM IST, Michael Ellerman wrote:
> >On Fri, Apr 19, 2013 at 05:18:09PM +0530, Vasant Hegde wrote:
> >>Memory allocated to flash_block_list in rtas_flash_write
> >>is not freed during module exit. We hit below call trace
> >>if we unload rtas_flash module after loading new firmware
> >>image and before rebooting the system.
> >
> >Why the resend? Did anything change?
> >
> 
> Nothing is changed. I resent because it was not reviewed for long time.

It's in my test branch, which is in linux-next:

https://github.com/mpe/powerpc-test


cheers

^ permalink raw reply

* Re: [PATCH RESEND] powerpc/rtas_flash: Free kmem upon module exit
From: Vasant Hegde @ 2013-04-22  5:48 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, paulus
In-Reply-To: <20130421232757.GA22246@concordia>

Michael,

On Mon 22 Apr 2013 04:57:57 AM IST, Michael Ellerman wrote:
> On Fri, Apr 19, 2013 at 05:18:09PM +0530, Vasant Hegde wrote:
>> Memory allocated to flash_block_list in rtas_flash_write
>> is not freed during module exit. We hit below call trace
>> if we unload rtas_flash module after loading new firmware
>> image and before rebooting the system.
>
> Why the resend? Did anything change?
>

Nothing is changed. I resent because it was not reviewed for long time.

-Vasant

> cheers
>

^ permalink raw reply

* [PATCH 3/3 v13] iommu/fsl: Freescale PAMU driver and iommu implementation.
From: Varun Sethi @ 2013-04-22  5:31 UTC (permalink / raw)
  To: joro, iommu, linuxppc-dev, linux-kernel, galak, benh,
	stuart.yoder, scottwood
  Cc: Varun Sethi, Timur Tabi
In-Reply-To: <1366608716-1704-1-git-send-email-Varun.Sethi@freescale.com>

Following is a brief description of the PAMU hardware:
PAMU determines what action to take and whether to authorize the action on
the basis of the memory address, a Logical IO Device Number (LIODN), and
PAACT table (logically) indexed by LIODN and address. Hardware devices which
need to access memory must provide an LIODN in addition to the memory address.

Peripheral Access Authorization and Control Tables (PAACTs) are the primary
data structures used by PAMU. A PAACT is a table of peripheral access
authorization and control entries (PAACE).Each PAACE defines the range of
I/O bus address space that is accessible by the LIOD and the associated access
capabilities.

There are two types of PAACTs: primary PAACT (PPAACT) and secondary PAACT
(SPAACT).A given physical I/O device may be able to act as one or more
independent logical I/O devices (LIODs). Each such logical I/O device is
assigned an identifier called logical I/O device number (LIODN). A LIODN is
allocated a contiguous portion of the I/O bus address space called the DSA window
for performing DSA operations. The DSA window may optionally be divided into
multiple sub-windows, each of which may be used to map to a region in system
storage space. The first sub-window is referred to as the primary sub-window
and the remaining are called secondary sub-windows.

This patch provides the PAMU driver (fsl_pamu.c) and the corresponding IOMMU
API implementation (fsl_pamu_domain.c). The PAMU hardware driver (fsl_pamu.c)
has been derived from the work done by Ashish Kalra and Timur Tabi.

Signed-off-by: Timur Tabi <timur@tabi.org>
Signed-off-by: Varun Sethi <Varun.Sethi@freescale.com>
---
changes in v13:
- Use the new header drivers/iommu/pci.h
- fix geometry configured check.
changes in v12:
- Use is_power_of_2 for checking alignement.
- Check for multifucntion PCI device ACS flags for determining device groups.
- Fix get_stash_id function.
- Don't crash in case of access violations, disable the LIODN.
- Don't use list_empty while traversing list using list for each entry.
- Move stash structure and ids to PAMU header files.
- Fix geometry size calculation.
changes in v11:
- changed iova to dma_addr_t in iova_to_phys API.
changes in v10:
- Support for new guts compatibe string for T4 & B4 devices.
- Modified comment about port ID and mentioned the errata number.
- Fixed the issue where data pointer was not freed in case of a an error.
- Pass data pointer while freeing irq.
- Whle initializing the SPAACE entry clear the valid bit.
changes in v9:
- Merged and createad a single function to delete
a device from domain list.
- Refactored the add_device API code.
- Renamed the paace and spaace init fucntions.
- Renamed functions for mapping windows and subwindows.
- Changed the MAX LIODN value to MAX value u-boot can
program.
- Hard coded maximum number of subwindows.
changes in v8:
- implemented the new API for window based IOMMUs.
changes in v7:
- Set max_subwidows in the geometry attribute.
- Add checking for maximum supported LIODN value.
- Use upper_32_bits and lower_32_bits macros while
  intializing PAMU data structures.
changes in v6:
- Simplified complex conditional statements.
- Fixed indentation issues.
- Added comments for IOMMU API implementation.
changes in v5:
- Addressed comments from Timur.
changes in v4:
- Addressed comments from Timur and Scott.
changes in v3:
- Addressed comments by Kumar Gala
- dynamic fspi allocation
- fixed alignment check in map and unmap
 arch/powerpc/sysdev/fsl_pci.h   |    5 +
 drivers/iommu/Kconfig           |   10 +
 drivers/iommu/Makefile          |    1 +
 drivers/iommu/fsl_pamu.c        | 1309 +++++++++++++++++++++++++++++++++++++++
 drivers/iommu/fsl_pamu.h        |  410 ++++++++++++
 drivers/iommu/fsl_pamu_domain.c | 1142 ++++++++++++++++++++++++++++++++++
 drivers/iommu/fsl_pamu_domain.h |   85 +++
 7 files changed, 2962 insertions(+), 0 deletions(-)
 create mode 100644 drivers/iommu/fsl_pamu.c
 create mode 100644 drivers/iommu/fsl_pamu.h
 create mode 100644 drivers/iommu/fsl_pamu_domain.c
 create mode 100644 drivers/iommu/fsl_pamu_domain.h

diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h
index c495c00..feb34f6 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/arch/powerpc/sysdev/fsl_pci.h
@@ -14,6 +14,11 @@
 #ifndef __POWERPC_FSL_PCI_H
 #define __POWERPC_FSL_PCI_H
 
+
+/* FSL PCI controller BRR1 register */
+#define PCI_FSL_BRR1      0xbf8
+#define PCI_FSL_BRR1_VER 0xffff
+
 #define PCIE_LTSSM	0x0404		/* PCIE Link Training and Status */
 #define PCIE_LTSSM_L0	0x16		/* L0 state */
 #define PCIE_IP_REV_2_2		0x02080202 /* PCIE IP block version Rev2.2 */
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index c332fb9..f97db88 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -17,6 +17,16 @@ config OF_IOMMU
        def_bool y
        depends on OF
 
+config FSL_PAMU
+	bool "Freescale IOMMU support"
+	depends on PPC_E500MC
+	select IOMMU_API
+	select GENERIC_ALLOCATOR
+	help
+	  Freescale PAMU support. PAMU is the IOMMU present on Freescale QorIQ platforms.
+	  PAMU can authorize memory access, remap the memory address, and remap I/O
+	  transaction types.
+
 # MSM IOMMU support
 config MSM_IOMMU
 	bool "MSM IOMMU Support"
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index ef0e520..027d1af 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o
 obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
 obj-$(CONFIG_SHMOBILE_IOMMU) += shmobile-iommu.o
 obj-$(CONFIG_SHMOBILE_IPMMU) += shmobile-ipmmu.o
+obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o
diff --git a/drivers/iommu/fsl_pamu.c b/drivers/iommu/fsl_pamu.c
new file mode 100644
index 0000000..d9a27c5
--- /dev/null
+++ b/drivers/iommu/fsl_pamu.c
@@ -0,0 +1,1309 @@
+/*
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ */
+
+#define pr_fmt(fmt)    "fsl-pamu: %s: " fmt, __func__
+
+#include <linux/init.h>
+#include <linux/iommu.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/of_platform.h>
+#include <linux/bootmem.h>
+#include <linux/genalloc.h>
+#include <asm/io.h>
+#include <asm/bitops.h>
+#include <asm/fsl_guts.h>
+
+#include "fsl_pamu.h"
+
+/* define indexes for each operation mapping scenario */
+#define OMI_QMAN        0x00
+#define OMI_FMAN        0x01
+#define OMI_QMAN_PRIV   0x02
+#define OMI_CAAM        0x03
+
+#define make64(high, low) (((u64)(high) << 32) | (low))
+
+struct pamu_isr_data {
+	void __iomem *pamu_reg_base;	/* Base address of PAMU regs*/
+	unsigned int count;		/* The number of PAMUs */
+};
+
+static struct paace *ppaact;
+static struct paace *spaact;
+static struct ome *omt;
+
+/*
+ * Table for matching compatible strings, for device tree
+ * guts node, for QorIQ SOCs.
+ * "fsl,qoriq-device-config-2.0" corresponds to T4 & B4
+ * SOCs. For the older SOCs "fsl,qoriq-device-config-1.0"
+ * string would be used.
+*/
+static const struct of_device_id guts_device_ids[] = {
+	{ .compatible = "fsl,qoriq-device-config-1.0", },
+	{ .compatible = "fsl,qoriq-device-config-2.0", },
+	{}
+};
+
+
+/*
+ * Table for matching compatible strings, for device tree
+ * L3 cache controller node.
+ * "fsl,t4240-l3-cache-controller" corresponds to T4,
+ * "fsl,b4860-l3-cache-controller" corresponds to B4 &
+ * "fsl,p4080-l3-cache-controller" corresponds to other,
+ * SOCs.
+*/
+static const struct of_device_id l3_device_ids[] = {
+	{ .compatible = "fsl,t4240-l3-cache-controller", },
+	{ .compatible = "fsl,b4860-l3-cache-controller", },
+	{ .compatible = "fsl,p4080-l3-cache-controller", },
+	{}
+};
+
+/* maximum subwindows permitted per liodn */
+static u32 max_subwindow_count;
+
+/* Pool for fspi allocation */
+struct gen_pool *spaace_pool;
+
+/**
+ * pamu_get_max_subwin_cnt() - Return the maximum supported
+ * subwindow count per liodn.
+ *
+ */
+u32 pamu_get_max_subwin_cnt()
+{
+	return max_subwindow_count;
+}
+
+/**
+ * pamu_get_ppaace() - Return the primary PACCE
+ * @liodn: liodn PAACT index for desired PAACE
+ *
+ * Returns the ppace pointer upon success else return
+ * null.
+ */
+static struct paace *pamu_get_ppaace(int liodn)
+{
+	if (!ppaact || liodn >= PAACE_NUMBER_ENTRIES) {
+		pr_err("PPAACT doesn't exist\n");
+		return NULL;
+	}
+
+	return &ppaact[liodn];
+}
+
+/**
+ * pamu_enable_liodn() - Set valid bit of PACCE
+ * @liodn: liodn PAACT index for desired PAACE
+ *
+ * Returns 0 upon success else error code < 0 returned
+ */
+int pamu_enable_liodn(int liodn)
+{
+	struct paace *ppaace;
+
+	ppaace = pamu_get_ppaace(liodn);
+	if (!ppaace) {
+		pr_err("Invalid primary paace entry\n");
+		return -ENOENT;
+	}
+
+	if (!get_bf(ppaace->addr_bitfields, PPAACE_AF_WSE)) {
+		pr_err("liodn %d not configured\n", liodn);
+		return -EINVAL;
+	}
+
+	/* Ensure that all other stores to the ppaace complete first */
+	mb();
+
+	set_bf(ppaace->addr_bitfields, PAACE_AF_V, PAACE_V_VALID);
+	mb();
+
+	return 0;
+}
+
+/**
+ * pamu_disable_liodn() - Clears valid bit of PACCE
+ * @liodn: liodn PAACT index for desired PAACE
+ *
+ * Returns 0 upon success else error code < 0 returned
+ */
+int pamu_disable_liodn(int liodn)
+{
+	struct paace *ppaace;
+
+	ppaace = pamu_get_ppaace(liodn);
+	if (!ppaace) {
+		pr_err("Invalid primary paace entry\n");
+		return -ENOENT;
+	}
+
+	set_bf(ppaace->addr_bitfields, PAACE_AF_V, PAACE_V_INVALID);
+	mb();
+
+	return 0;
+}
+
+/* Derive the window size encoding for a particular PAACE entry */
+static unsigned int map_addrspace_size_to_wse(phys_addr_t addrspace_size)
+{
+	/* Bug if not a power of 2 */
+	BUG_ON(!is_power_of_2(addrspace_size));
+
+	/* window size is 2^(WSE+1) bytes */
+	return __ffs(addrspace_size) - 1;
+}
+
+/* Derive the PAACE window count encoding for the subwindow count */
+static unsigned int map_subwindow_cnt_to_wce(u32 subwindow_cnt)
+{
+       /* window count is 2^(WCE+1) bytes */
+       return __ffs(subwindow_cnt) - 1;
+}
+
+/*
+ * Set the PAACE type as primary and set the coherency required domain
+ * attribute
+ */
+static void pamu_init_ppaace(struct paace *ppaace)
+{
+	set_bf(ppaace->addr_bitfields, PAACE_AF_PT, PAACE_PT_PRIMARY);
+
+	set_bf(ppaace->domain_attr.to_host.coherency_required, PAACE_DA_HOST_CR,
+	       PAACE_M_COHERENCE_REQ);
+}
+
+/*
+ * Set the PAACE type as secondary and set the coherency required domain
+ * attribute.
+ */
+static void pamu_init_spaace(struct paace *spaace)
+{
+	set_bf(spaace->addr_bitfields, PAACE_AF_PT, PAACE_PT_SECONDARY);
+	set_bf(spaace->domain_attr.to_host.coherency_required, PAACE_DA_HOST_CR,
+	       PAACE_M_COHERENCE_REQ);
+}
+
+/*
+ * Return the spaace (corresponding to the secondary window index)
+ * for a particular ppaace.
+ */
+static struct paace *pamu_get_spaace(struct paace *paace, u32 wnum)
+{
+	u32 subwin_cnt;
+	struct paace *spaace = NULL;
+
+	subwin_cnt = 1UL << (get_bf(paace->impl_attr, PAACE_IA_WCE) + 1);
+
+	if (wnum < subwin_cnt)
+		spaace = &spaact[paace->fspi + wnum];
+	else
+		pr_err("secondary paace out of bounds\n");
+
+	return spaace;
+}
+
+/**
+ * pamu_get_fspi_and_allocate() - Allocates fspi index and reserves subwindows
+ *                                required for primary PAACE in the secondary
+ *                                PAACE table.
+ * @subwin_cnt: Number of subwindows to be reserved.
+ *
+ * A PPAACE entry may have a number of associated subwindows. A subwindow
+ * corresponds to a SPAACE entry in the SPAACT table. Each PAACE entry stores
+ * the index (fspi) of the first SPAACE entry in the SPAACT table. This
+ * function returns the index of the first SPAACE entry. The remaining
+ * SPAACE entries are reserved contiguously from that index.
+ *
+ * Returns a valid fspi index in the range of 0 - SPAACE_NUMBER_ENTRIES on success.
+ * If no SPAACE entry is available or the allocator can not reserve the required
+ * number of contiguous entries function returns ULONG_MAX indicating a failure.
+ *
+*/
+static unsigned long pamu_get_fspi_and_allocate(u32 subwin_cnt)
+{
+	unsigned long spaace_addr;
+
+	spaace_addr = gen_pool_alloc(spaace_pool, subwin_cnt * sizeof(struct paace));
+	if (!spaace_addr)
+		return ULONG_MAX;
+
+	return (spaace_addr - (unsigned long)spaact) / (sizeof(struct paace));
+}
+
+/* Release the subwindows reserved for a particular LIODN */
+void pamu_free_subwins(int liodn)
+{
+	struct paace *ppaace;
+	u32 subwin_cnt, size;
+
+	ppaace = pamu_get_ppaace(liodn);
+	if (!ppaace) {
+		pr_err("Invalid liodn entry\n");
+		return;
+	}
+
+	if (get_bf(ppaace->addr_bitfields, PPAACE_AF_MW)) {
+		subwin_cnt = 1UL << (get_bf(ppaace->impl_attr, PAACE_IA_WCE) + 1);
+		size = (subwin_cnt - 1) * sizeof(struct paace);
+		gen_pool_free(spaace_pool, (unsigned long)&spaact[ppaace->fspi], size);
+		set_bf(ppaace->addr_bitfields, PPAACE_AF_MW, 0);
+	}
+}
+
+/*
+ * Function used for updating stash destination for the coressponding
+ * LIODN.
+ */
+int  pamu_update_paace_stash(int liodn, u32 subwin, u32 value)
+{
+	struct paace *paace;
+
+	paace = pamu_get_ppaace(liodn);
+	if (!paace) {
+		pr_err("Invalid liodn entry\n");
+		return -ENOENT;
+	}
+	if (subwin) {
+		paace = pamu_get_spaace(paace, subwin - 1);
+		if (!paace) {
+			return -ENOENT;
+		}
+	}
+	set_bf(paace->impl_attr, PAACE_IA_CID, value);
+
+	mb();
+
+	return 0;
+}
+
+/* Disable a subwindow corresponding to the LIODN */
+int pamu_disable_spaace(int liodn, u32 subwin)
+{
+	struct paace *paace;
+
+	paace = pamu_get_ppaace(liodn);
+	if (!paace) {
+		pr_err("Invalid liodn entry\n");
+		return -ENOENT;
+	}
+	if (subwin) {
+		paace = pamu_get_spaace(paace, subwin - 1);
+		if (!paace) {
+			return -ENOENT;
+		}
+		set_bf(paace->addr_bitfields, PAACE_AF_V,
+			 PAACE_V_INVALID);
+	} else {
+		set_bf(paace->addr_bitfields, PAACE_AF_AP,
+			 PAACE_AP_PERMS_DENIED);
+	}
+
+	mb();
+
+	return 0;
+}
+
+
+/**
+ * pamu_config_paace() - Sets up PPAACE entry for specified liodn
+ *
+ * @liodn: Logical IO device number
+ * @win_addr: starting address of DSA window
+ * @win-size: size of DSA window
+ * @omi: Operation mapping index -- if ~omi == 0 then omi not defined
+ * @rpn: real (true physical) page number
+ * @stashid: cache stash id for associated cpu -- if ~stashid == 0 then
+ *	     stashid not defined
+ * @snoopid: snoop id for hardware coherency -- if ~snoopid == 0 then
+ *	     snoopid not defined
+ * @subwin_cnt: number of sub-windows
+ * @prot: window permissions
+ *
+ * Returns 0 upon success else error code < 0 returned
+ */
+int pamu_config_ppaace(int liodn, phys_addr_t win_addr, phys_addr_t win_size,
+		       u32 omi, unsigned long rpn, u32 snoopid, u32 stashid,
+		       u32 subwin_cnt, int prot)
+{
+	struct paace *ppaace;
+	unsigned long fspi;
+
+	if (!is_power_of_2(win_size) || win_size < PAMU_PAGE_SIZE) {
+		pr_err("window size too small or not a power of two %llx\n", win_size);
+		return -EINVAL;
+	}
+
+	if (win_addr & (win_size - 1)) {
+		pr_err("window address is not aligned with window size\n");
+		return -EINVAL;
+	}
+
+	ppaace = pamu_get_ppaace(liodn);
+	if (!ppaace) {
+		return -ENOENT;
+	}
+
+	/* window size is 2^(WSE+1) bytes */
+	set_bf(ppaace->addr_bitfields, PPAACE_AF_WSE,
+		map_addrspace_size_to_wse(win_size));
+
+	pamu_init_ppaace(ppaace);
+
+	ppaace->wbah = win_addr >> (PAMU_PAGE_SHIFT + 20);
+	set_bf(ppaace->addr_bitfields, PPAACE_AF_WBAL,
+	       (win_addr >> PAMU_PAGE_SHIFT));
+
+	/* set up operation mapping if it's configured */
+	if (omi < OME_NUMBER_ENTRIES) {
+		set_bf(ppaace->impl_attr, PAACE_IA_OTM, PAACE_OTM_INDEXED);
+		ppaace->op_encode.index_ot.omi = omi;
+	} else if (~omi != 0) {
+		pr_err("bad operation mapping index: %d\n", omi);
+		return -EINVAL;
+	}
+
+	/* configure stash id */
+	if (~stashid != 0)
+		set_bf(ppaace->impl_attr, PAACE_IA_CID, stashid);
+
+	/* configure snoop id */
+	if (~snoopid != 0)
+		ppaace->domain_attr.to_host.snpid = snoopid;
+
+	if (subwin_cnt) {
+		/* The first entry is in the primary PAACE instead */
+		fspi = pamu_get_fspi_and_allocate(subwin_cnt - 1);
+		if (fspi == ULONG_MAX) {
+			pr_err("spaace indexes exhausted\n");
+			return -EINVAL;
+		}
+
+		/* window count is 2^(WCE+1) bytes */
+		set_bf(ppaace->impl_attr, PAACE_IA_WCE,
+		       map_subwindow_cnt_to_wce(subwin_cnt));
+		set_bf(ppaace->addr_bitfields, PPAACE_AF_MW, 0x1);
+		ppaace->fspi = fspi;
+	} else {
+		set_bf(ppaace->impl_attr, PAACE_IA_ATM, PAACE_ATM_WINDOW_XLATE);
+		ppaace->twbah = rpn >> 20;
+		set_bf(ppaace->win_bitfields, PAACE_WIN_TWBAL, rpn);
+		set_bf(ppaace->addr_bitfields, PAACE_AF_AP, prot);
+		set_bf(ppaace->impl_attr, PAACE_IA_WCE, 0);
+		set_bf(ppaace->addr_bitfields, PPAACE_AF_MW, 0);
+	}
+	mb();
+
+	return 0;
+}
+
+/**
+ * pamu_config_spaace() - Sets up SPAACE entry for specified subwindow
+ *
+ * @liodn:  Logical IO device number
+ * @subwin_cnt:  number of sub-windows associated with dma-window
+ * @subwin: subwindow index
+ * @subwin_size: size of subwindow
+ * @omi: Operation mapping index
+ * @rpn: real (true physical) page number
+ * @snoopid: snoop id for hardware coherency -- if ~snoopid == 0 then
+ *			  snoopid not defined
+ * @stashid: cache stash id for associated cpu
+ * @enable: enable/disable subwindow after reconfiguration
+ * @prot: sub window permissions
+ *
+ * Returns 0 upon success else error code < 0 returned
+ */
+int pamu_config_spaace(int liodn, u32 subwin_cnt, u32 subwin,
+		       phys_addr_t subwin_size, u32 omi, unsigned long rpn,
+		       u32 snoopid, u32 stashid, int enable, int prot)
+{
+	struct paace *paace;
+
+
+	/* setup sub-windows */
+	if (!subwin_cnt) {
+		pr_err("Invalid subwindow count\n");
+		return -EINVAL;
+	}
+
+	paace = pamu_get_ppaace(liodn);
+	if (subwin > 0 && subwin < subwin_cnt && paace) {
+		paace = pamu_get_spaace(paace, subwin - 1);
+
+		if (paace && !(paace->addr_bitfields & PAACE_V_VALID)) {
+			pamu_init_spaace(paace);
+			set_bf(paace->addr_bitfields, SPAACE_AF_LIODN, liodn);
+		}
+	}
+
+	if (!paace) {
+		pr_err("Invalid liodn entry\n");
+		return -ENOENT;
+	}
+
+	if (!is_power_of_2(subwin_size) || subwin_size < PAMU_PAGE_SIZE) {
+		pr_err("subwindow size out of range, or not a power of 2\n");
+		return -EINVAL;
+	}
+
+	if (rpn == ULONG_MAX) {
+		pr_err("real page number out of range\n");
+		return -EINVAL;
+	}
+
+	/* window size is 2^(WSE+1) bytes */
+	set_bf(paace->win_bitfields, PAACE_WIN_SWSE,
+	       map_addrspace_size_to_wse(subwin_size));
+
+	set_bf(paace->impl_attr, PAACE_IA_ATM, PAACE_ATM_WINDOW_XLATE);
+	paace->twbah = rpn >> 20;
+	set_bf(paace->win_bitfields, PAACE_WIN_TWBAL, rpn);
+	set_bf(paace->addr_bitfields, PAACE_AF_AP, prot);
+
+	/* configure snoop id */
+	if (~snoopid != 0)
+		paace->domain_attr.to_host.snpid = snoopid;
+
+	/* set up operation mapping if it's configured */
+	if (omi < OME_NUMBER_ENTRIES) {
+		set_bf(paace->impl_attr, PAACE_IA_OTM, PAACE_OTM_INDEXED);
+		paace->op_encode.index_ot.omi = omi;
+	} else if (~omi != 0) {
+		pr_err("bad operation mapping index: %d\n", omi);
+		return -EINVAL;
+	}
+
+	if (~stashid != 0)
+		set_bf(paace->impl_attr, PAACE_IA_CID, stashid);
+
+	smp_wmb();
+
+	if (enable)
+		set_bf(paace->addr_bitfields, PAACE_AF_V, PAACE_V_VALID);
+
+	mb();
+
+	return 0;
+}
+
+/**
+* get_ome_index() - Returns the index in the operation mapping table
+*                   for device.
+* @*omi_index: pointer for storing the index value
+*
+*/
+void get_ome_index(u32 *omi_index, struct device *dev)
+{
+	if (of_device_is_compatible(dev->of_node, "fsl,qman-portal"))
+		*omi_index = OMI_QMAN;
+	if (of_device_is_compatible(dev->of_node, "fsl,qman"))
+		*omi_index = OMI_QMAN_PRIV;
+}
+
+/**
+ * get_stash_id - Returns stash destination id corresponding to a
+ *                cache type and vcpu.
+ * @stash_dest_hint: L1, L2 or L3
+ * @vcpu: vpcu target for a particular cache type.
+ *
+ * Returs stash on success or ~(u32)0 on failure.
+ *
+ */
+u32 get_stash_id(u32 stash_dest_hint, u32 vcpu)
+{
+	const u32 *prop;
+	struct device_node *node;
+	u32 cache_level;
+	int len, found = 0;
+	int i;
+
+	/* Fastpath, exit early if L3/CPC cache is target for stashing */
+	if (stash_dest_hint == PAMU_ATTR_CACHE_L3) {
+		node = of_find_matching_node(NULL, l3_device_ids);
+		if (node) {
+			prop = of_get_property(node, "cache-stash-id", 0);
+			if (!prop) {
+				pr_err("missing cache-stash-id at %s\n", node->full_name);
+				of_node_put(node);
+				return ~(u32)0;
+			}
+			of_node_put(node);
+			return be32_to_cpup(prop);
+		}
+		return ~(u32)0;
+	}
+
+	for_each_node_by_type(node, "cpu") {
+		prop = of_get_property(node, "reg", &len);
+		for (i = 0; i < len / sizeof(u32); i++) {
+			if (be32_to_cpup(&prop[i]) == vcpu) {
+				found = 1;
+				goto found_cpu_node;
+			}
+		}
+	}
+found_cpu_node:
+
+	/* find the hwnode that represents the cache */
+	for (cache_level = PAMU_ATTR_CACHE_L1; (cache_level < PAMU_ATTR_CACHE_L3) && found; cache_level++) {
+		if (stash_dest_hint == cache_level) {
+			prop = of_get_property(node, "cache-stash-id", 0);
+			if (!prop) {
+				pr_err("missing cache-stash-id at %s\n", node->full_name);
+				of_node_put(node);
+				return ~(u32)0;
+			}
+			of_node_put(node);
+			return be32_to_cpup(prop);
+		}
+
+		prop = of_get_property(node, "next-level-cache", 0);
+		if (!prop) {
+			pr_err("can't find next-level-cache at %s\n",
+				node->full_name);
+			of_node_put(node);
+			return ~(u32)0;  /* can't traverse any further */
+		}
+		of_node_put(node);
+
+		/* advance to next node in cache hierarchy */
+		node = of_find_node_by_phandle(*prop);
+		if (!node) {
+			pr_err("Invalid node for cache hierarchy %s\n",
+				node->full_name);
+			return ~(u32)0;
+		}
+	}
+
+	pr_err("stash dest not found for %d on vcpu %d\n",
+	          stash_dest_hint, vcpu);
+	return ~(u32)0;
+}
+
+/* Identify if the PAACT table entry belongs to QMAN, BMAN or QMAN Portal */
+#define QMAN_PAACE 1
+#define QMAN_PORTAL_PAACE 2
+#define BMAN_PAACE 3
+
+/**
+ * Setup operation mapping and stash destinations for QMAN and QMAN portal.
+ * Memory accesses to QMAN and BMAN private memory need not be coherent, so
+ * clear the PAACE entry coherency attribute for them.
+ */
+static void setup_qbman_paace(struct paace *ppaace, int  paace_type)
+{
+	switch (paace_type) {
+	case QMAN_PAACE:
+		set_bf(ppaace->impl_attr, PAACE_IA_OTM, PAACE_OTM_INDEXED);
+		ppaace->op_encode.index_ot.omi = OMI_QMAN_PRIV;
+		/* setup QMAN Private data stashing for the L3 cache */
+		set_bf(ppaace->impl_attr, PAACE_IA_CID, get_stash_id(PAMU_ATTR_CACHE_L3, 0));
+		set_bf(ppaace->domain_attr.to_host.coherency_required, PAACE_DA_HOST_CR,
+		       0);
+		break;
+	case QMAN_PORTAL_PAACE:
+		set_bf(ppaace->impl_attr, PAACE_IA_OTM, PAACE_OTM_INDEXED);
+		ppaace->op_encode.index_ot.omi = OMI_QMAN;
+		/*Set DQRR and Frame stashing for the L3 cache */
+		set_bf(ppaace->impl_attr, PAACE_IA_CID, get_stash_id(PAMU_ATTR_CACHE_L3, 0));
+		break;
+	case BMAN_PAACE:
+		set_bf(ppaace->domain_attr.to_host.coherency_required, PAACE_DA_HOST_CR,
+		       0);
+		break;
+	}
+}
+
+/**
+ * Setup the operation mapping table for various devices. This is a static
+ * table where each table index corresponds to a particular device. PAMU uses
+ * this table to translate device transaction to appropriate corenet
+ * transaction.
+ */
+static void __init setup_omt(struct ome *omt)
+{
+	struct ome *ome;
+
+	/* Configure OMI_QMAN */
+	ome = &omt[OMI_QMAN];
+
+	ome->moe[IOE_READ_IDX] = EOE_VALID | EOE_READ;
+	ome->moe[IOE_EREAD0_IDX] = EOE_VALID | EOE_RSA;
+	ome->moe[IOE_WRITE_IDX] = EOE_VALID | EOE_WRITE;
+	ome->moe[IOE_EWRITE0_IDX] = EOE_VALID | EOE_WWSAO;
+
+	ome->moe[IOE_DIRECT0_IDX] = EOE_VALID | EOE_LDEC;
+	ome->moe[IOE_DIRECT1_IDX] = EOE_VALID | EOE_LDECPE;
+
+	/* Configure OMI_FMAN */
+	ome = &omt[OMI_FMAN];
+	ome->moe[IOE_READ_IDX]  = EOE_VALID | EOE_READI;
+	ome->moe[IOE_WRITE_IDX] = EOE_VALID | EOE_WRITE;
+
+	/* Configure OMI_QMAN private */
+	ome = &omt[OMI_QMAN_PRIV];
+	ome->moe[IOE_READ_IDX]  = EOE_VALID | EOE_READ;
+	ome->moe[IOE_WRITE_IDX] = EOE_VALID | EOE_WRITE;
+	ome->moe[IOE_EREAD0_IDX] = EOE_VALID | EOE_RSA;
+	ome->moe[IOE_EWRITE0_IDX] = EOE_VALID | EOE_WWSA;
+
+	/* Configure OMI_CAAM */
+	ome = &omt[OMI_CAAM];
+	ome->moe[IOE_READ_IDX]  = EOE_VALID | EOE_READI;
+	ome->moe[IOE_WRITE_IDX] = EOE_VALID | EOE_WRITE;
+}
+
+/*
+ * Get the maximum number of PAACT table entries
+ * and subwindows supported by PAMU
+ */
+static void get_pamu_cap_values(unsigned long pamu_reg_base)
+{
+	u32 pc_val;
+
+	pc_val = in_be32((u32 *)(pamu_reg_base + PAMU_PC3));
+	/* Maximum number of subwindows per liodn */
+	max_subwindow_count = 1 << (1 + PAMU_PC3_MWCE(pc_val));
+}
+
+/* Setup PAMU registers pointing to PAACT, SPAACT and OMT */
+int setup_one_pamu(unsigned long pamu_reg_base, unsigned long pamu_reg_size,
+	           phys_addr_t ppaact_phys, phys_addr_t spaact_phys,
+		   phys_addr_t omt_phys)
+{
+	u32 *pc;
+	struct pamu_mmap_regs *pamu_regs;
+
+	pc = (u32 *) (pamu_reg_base + PAMU_PC);
+	pamu_regs = (struct pamu_mmap_regs *)
+		(pamu_reg_base + PAMU_MMAP_REGS_BASE);
+
+	/* set up pointers to corenet control blocks */
+
+	out_be32(&pamu_regs->ppbah, upper_32_bits(ppaact_phys));
+	out_be32(&pamu_regs->ppbal, lower_32_bits(ppaact_phys));
+	ppaact_phys = ppaact_phys + PAACT_SIZE;
+	out_be32(&pamu_regs->pplah, upper_32_bits(ppaact_phys));
+	out_be32(&pamu_regs->pplal, lower_32_bits(ppaact_phys));
+
+	out_be32(&pamu_regs->spbah, upper_32_bits(spaact_phys));
+	out_be32(&pamu_regs->spbal, lower_32_bits(spaact_phys));
+	spaact_phys = spaact_phys + SPAACT_SIZE;
+	out_be32(&pamu_regs->splah, upper_32_bits(spaact_phys));
+	out_be32(&pamu_regs->splal, lower_32_bits(spaact_phys));
+
+	out_be32(&pamu_regs->obah, upper_32_bits(omt_phys));
+	out_be32(&pamu_regs->obal, lower_32_bits(omt_phys));
+	omt_phys = omt_phys + OMT_SIZE;
+	out_be32(&pamu_regs->olah, upper_32_bits(omt_phys));
+	out_be32(&pamu_regs->olal, lower_32_bits(omt_phys));
+
+	/*
+	 * set PAMU enable bit,
+	 * allow ppaact & omt to be cached
+	 * & enable PAMU access violation interrupts.
+	 */
+
+	out_be32((u32 *)(pamu_reg_base + PAMU_PICS),
+			PAMU_ACCESS_VIOLATION_ENABLE);
+	out_be32(pc, PAMU_PC_PE | PAMU_PC_OCE | PAMU_PC_SPCC | PAMU_PC_PPCC);
+	return 0;
+}
+
+/* Enable all device LIODNS */
+static void __init setup_liodns(void)
+{
+	int i, len;
+	struct paace *ppaace;
+	struct device_node *node = NULL;
+	const u32 *prop;
+
+	for_each_node_with_property(node, "fsl,liodn") {
+		prop = of_get_property(node, "fsl,liodn", &len);
+		for (i = 0; i < len / sizeof(u32); i++) {
+			int liodn;
+
+			liodn = be32_to_cpup(&prop[i]);
+			if (liodn >= PAACE_NUMBER_ENTRIES) {
+				pr_err("Invalid LIODN value %d\n", liodn);
+				continue;
+			}
+			ppaace = pamu_get_ppaace(liodn);
+			pamu_init_ppaace(ppaace);
+			/* window size is 2^(WSE+1) bytes */
+			set_bf(ppaace->addr_bitfields, PPAACE_AF_WSE, 35);
+			ppaace->wbah = 0;
+			set_bf(ppaace->addr_bitfields, PPAACE_AF_WBAL, 0);
+			set_bf(ppaace->impl_attr, PAACE_IA_ATM,
+				PAACE_ATM_NO_XLATE);
+			set_bf(ppaace->addr_bitfields, PAACE_AF_AP,
+				PAACE_AP_PERMS_ALL);
+			if (of_device_is_compatible(node, "fsl,qman-portal"))
+				setup_qbman_paace(ppaace, QMAN_PORTAL_PAACE);
+			if (of_device_is_compatible(node, "fsl,qman"))
+				setup_qbman_paace(ppaace, QMAN_PAACE);
+			if (of_device_is_compatible(node, "fsl,bman"))
+				setup_qbman_paace(ppaace, BMAN_PAACE);
+			mb();
+			pamu_enable_liodn(liodn);
+		}
+	}
+}
+
+irqreturn_t pamu_av_isr(int irq, void *arg)
+{
+	struct pamu_isr_data *data = arg;
+	phys_addr_t phys;
+	unsigned int i, j, ret;
+
+	pr_emerg("fsl-pamu: access violation interrupt\n");
+
+	for (i = 0; i < data->count; i++) {
+		void __iomem *p = data->pamu_reg_base + i * PAMU_OFFSET;
+		u32 pics = in_be32(p + PAMU_PICS);
+
+		if (pics & PAMU_ACCESS_VIOLATION_STAT) {
+			u32 avs1 = in_be32(p + PAMU_AVS1);
+			struct paace *paace;
+
+			pr_emerg("POES1=%08x\n", in_be32(p + PAMU_POES1));
+			pr_emerg("POES2=%08x\n", in_be32(p + PAMU_POES2));
+			pr_emerg("AVS1=%08x\n", avs1);
+			pr_emerg("AVS2=%08x\n", in_be32(p + PAMU_AVS2));
+			pr_emerg("AVA=%016llx\n", make64(in_be32(p + PAMU_AVAH),
+				in_be32(p + PAMU_AVAL)));
+			pr_emerg("UDAD=%08x\n", in_be32(p + PAMU_UDAD));
+			pr_emerg("POEA=%016llx\n", make64(in_be32(p + PAMU_POEAH),
+				in_be32(p + PAMU_POEAL)));
+
+			phys = make64(in_be32(p + PAMU_POEAH),
+				in_be32(p + PAMU_POEAL));
+
+			/* Assume that POEA points to a PAACE */
+			if (phys) {
+				u32 *paace = phys_to_virt(phys);
+
+				/* Only the first four words are relevant */
+				for (j = 0; j < 4; j++)
+					pr_emerg("PAACE[%u]=%08x\n", j, in_be32(paace + j));
+			}
+
+			/* clear access violation condition */
+			out_be32((p + PAMU_AVS1), avs1 & PAMU_AV_MASK);
+			paace = pamu_get_ppaace(avs1 >> PAMU_AVS1_LIODN_SHIFT);
+			BUG_ON(!paace);
+			/* check if we got a violation for a disabled LIODN */
+			if (!get_bf(paace->addr_bitfields, PAACE_AF_V)) {
+				/*
+				 * As per hardware erratum A-003638, access
+				 * violation can be reported for a disabled
+				 * LIODN. If we hit that condition, disable
+				 * access violation reporting.
+				 */
+				pics &= ~PAMU_ACCESS_VIOLATION_ENABLE;
+			} else {
+				/* Disable the LIODN */
+				ret = pamu_disable_liodn(avs1 >> PAMU_AVS1_LIODN_SHIFT);
+				BUG_ON(ret);
+				pr_emerg("Disabling liodn %x\n", avs1 >> PAMU_AVS1_LIODN_SHIFT);
+			}
+			out_be32((p + PAMU_PICS), pics);
+		}
+	}
+
+
+	return IRQ_HANDLED;
+}
+
+#define LAWAR_EN		0x80000000
+#define LAWAR_TARGET_MASK	0x0FF00000
+#define LAWAR_TARGET_SHIFT	20
+#define LAWAR_SIZE_MASK		0x0000003F
+#define LAWAR_CSDID_MASK	0x000FF000
+#define LAWAR_CSDID_SHIFT	12
+
+#define LAW_SIZE_4K		0xb
+
+struct ccsr_law {
+	u32	lawbarh;	/* LAWn base address high */
+	u32	lawbarl;	/* LAWn base address low */
+	u32	lawar;		/* LAWn attributes */
+	u32	reserved;
+};
+
+/*
+ * Create a coherence subdomain for a given memory block.
+ */
+static int __init create_csd(phys_addr_t phys, size_t size, u32 csd_port_id)
+{
+	struct device_node *np;
+	const __be32 *iprop;
+	void __iomem *lac = NULL;	/* Local Access Control registers */
+	struct ccsr_law __iomem *law;
+	void __iomem *ccm = NULL;
+	u32 __iomem *csdids;
+	unsigned int i, num_laws, num_csds;
+	u32 law_target = 0;
+	u32 csd_id = 0;
+	int ret = 0;
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,corenet-law");
+	if (!np)
+		return -ENODEV;
+
+	iprop = of_get_property(np, "fsl,num-laws", NULL);
+	if (!iprop) {
+		ret = -ENODEV;
+		goto error;
+	}
+
+	num_laws = be32_to_cpup(iprop);
+	if (!num_laws) {
+		ret = -ENODEV;
+		goto error;
+	}
+
+	lac = of_iomap(np, 0);
+	if (!lac) {
+		ret = -ENODEV;
+		goto error;
+	}
+
+	/* LAW registers are at offset 0xC00 */
+	law = lac + 0xC00;
+
+	of_node_put(np);
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,corenet-cf");
+	if (!np) {
+		ret = -ENODEV;
+		goto error;
+	}
+
+	iprop = of_get_property(np, "fsl,ccf-num-csdids", NULL);
+	if (!iprop) {
+		ret = -ENODEV;
+		goto error;
+	}
+
+	num_csds = be32_to_cpup(iprop);
+	if (!num_csds) {
+		ret = -ENODEV;
+		goto error;
+	}
+
+	ccm = of_iomap(np, 0);
+	if (!ccm) {
+		ret = -ENOMEM;
+		goto error;
+	}
+
+	/* The undocumented CSDID registers are at offset 0x600 */
+	csdids = ccm + 0x600;
+
+	of_node_put(np);
+	np = NULL;
+
+	/* Find an unused coherence subdomain ID */
+	for (csd_id = 0; csd_id < num_csds; csd_id++) {
+		if (!csdids[csd_id])
+			break;
+	}
+
+	/* Store the Port ID in the (undocumented) proper CIDMRxx register */
+	csdids[csd_id] = csd_port_id;
+
+	/* Find the DDR LAW that maps to our buffer. */
+	for (i = 0; i < num_laws; i++) {
+		if (law[i].lawar & LAWAR_EN) {
+			phys_addr_t law_start, law_end;
+
+			law_start = make64(law[i].lawbarh, law[i].lawbarl);
+			law_end = law_start +
+				(2ULL << (law[i].lawar & LAWAR_SIZE_MASK));
+
+			if (law_start <= phys && phys < law_end) {
+				law_target = law[i].lawar & LAWAR_TARGET_MASK;
+				break;
+			}
+		}
+	}
+
+	if (i == 0 || i == num_laws) {
+		/* This should never happen*/
+		ret = -ENOENT;
+		goto error;
+	}
+
+	/* Find a free LAW entry */
+	while (law[--i].lawar & LAWAR_EN) {
+		if (i == 0) {
+			/* No higher priority LAW slots available */
+			ret = -ENOENT;
+			goto error;
+		}
+	}
+
+	law[i].lawbarh = upper_32_bits(phys);
+	law[i].lawbarl = lower_32_bits(phys);
+	wmb();
+	law[i].lawar = LAWAR_EN | law_target | (csd_id << LAWAR_CSDID_SHIFT) |
+		(LAW_SIZE_4K + get_order(size));
+	wmb();
+
+error:
+	if (ccm)
+		iounmap(ccm);
+
+	if (lac)
+		iounmap(lac);
+
+	if (np)
+		of_node_put(np);
+
+	return ret;
+}
+
+/*
+ * Table of SVRs and the corresponding PORT_ID values. Port ID corresponds to a
+ * bit map of snoopers for a given range of memory mapped by a LAW.
+ *
+ * All future CoreNet-enabled SOCs will have this erratum(A-004510) fixed, so this
+ * table should never need to be updated.  SVRs are guaranteed to be unique, so
+ * there is no worry that a future SOC will inadvertently have one of these
+ * values.
+ */
+static const struct {
+	u32 svr;
+	u32 port_id;
+} port_id_map[] = {
+	{0x82100010, 0xFF000000},	/* P2040 1.0 */
+	{0x82100011, 0xFF000000},	/* P2040 1.1 */
+	{0x82100110, 0xFF000000},	/* P2041 1.0 */
+	{0x82100111, 0xFF000000},	/* P2041 1.1 */
+	{0x82110310, 0xFF000000},	/* P3041 1.0 */
+	{0x82110311, 0xFF000000},	/* P3041 1.1 */
+	{0x82010020, 0xFFF80000},	/* P4040 2.0 */
+	{0x82000020, 0xFFF80000},	/* P4080 2.0 */
+	{0x82210010, 0xFC000000},       /* P5010 1.0 */
+	{0x82210020, 0xFC000000},       /* P5010 2.0 */
+	{0x82200010, 0xFC000000},	/* P5020 1.0 */
+	{0x82050010, 0xFF800000},	/* P5021 1.0 */
+	{0x82040010, 0xFF800000},	/* P5040 1.0 */
+};
+
+#define SVR_SECURITY	0x80000	/* The Security (E) bit */
+
+static int __init fsl_pamu_probe(struct platform_device *pdev)
+{
+	void __iomem *pamu_regs = NULL;
+	struct ccsr_guts __iomem *guts_regs = NULL;
+	u32 pamubypenr, pamu_counter;
+	unsigned long pamu_reg_off;
+	unsigned long pamu_reg_base;
+	struct pamu_isr_data *data = NULL;
+	struct device_node *guts_node;
+	u64 size;
+	struct page *p;
+	int ret = 0;
+	int irq;
+	phys_addr_t ppaact_phys;
+	phys_addr_t spaact_phys;
+	phys_addr_t omt_phys;
+	size_t mem_size = 0;
+	unsigned int order = 0;
+	u32 csd_port_id = 0;
+	unsigned i;
+	/*
+	 * enumerate all PAMUs and allocate and setup PAMU tables
+	 * for each of them,
+	 * NOTE : All PAMUs share the same LIODN tables.
+	 */
+
+	pamu_regs = of_iomap(pdev->dev.of_node, 0);
+	if (!pamu_regs) {
+		dev_err(&pdev->dev, "ioremap of PAMU node failed\n");
+		return -ENOMEM;
+	}
+	of_get_address(pdev->dev.of_node, 0, &size, NULL);
+
+	irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+	if (irq == NO_IRQ) {
+		dev_warn(&pdev->dev, "no interrupts listed in PAMU node\n");
+		goto error;
+	}
+
+	data = kzalloc(sizeof(struct pamu_isr_data), GFP_KERNEL);
+	if (!data) {
+		dev_err(&pdev->dev, "PAMU isr data memory allocation failed\n");
+		ret = -ENOMEM;
+		goto error;
+	}
+	data->pamu_reg_base = pamu_regs;
+	data->count = size / PAMU_OFFSET;
+
+	/* The ISR needs access to the regs, so we won't iounmap them */
+	ret = request_irq(irq, pamu_av_isr, 0, "pamu", data);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "error %i installing ISR for irq %i\n",
+			ret, irq);
+		goto error;
+	}
+
+	guts_node = of_find_matching_node(NULL, guts_device_ids);
+	if (!guts_node) {
+		dev_err(&pdev->dev, "could not find GUTS node %s\n",
+			pdev->dev.of_node->full_name);
+		ret = -ENODEV;
+		goto error;
+	}
+
+	guts_regs = of_iomap(guts_node, 0);
+	of_node_put(guts_node);
+	if (!guts_regs) {
+		dev_err(&pdev->dev, "ioremap of GUTS node failed\n");
+		ret = -ENODEV;
+		goto error;
+	}
+
+	/* read in the PAMU capability registers */
+	get_pamu_cap_values((unsigned long)pamu_regs);
+	/*
+	 * To simplify the allocation of a coherency domain, we allocate the
+	 * PAACT and the OMT in the same memory buffer.  Unfortunately, this
+	 * wastes more memory compared to allocating the buffers separately.
+	 */
+	/* Determine how much memory we need */
+	mem_size = (PAGE_SIZE << get_order(PAACT_SIZE)) +
+		(PAGE_SIZE << get_order(SPAACT_SIZE)) +
+		(PAGE_SIZE << get_order(OMT_SIZE));
+	order = get_order(mem_size);
+
+	p = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
+	if (!p) {
+		dev_err(&pdev->dev, "unable to allocate PAACT/SPAACT/OMT block\n");
+		ret = -ENOMEM;
+		goto error;
+	}
+
+	ppaact = page_address(p);
+	ppaact_phys = page_to_phys(p);
+
+	/* Make sure the memory is naturally aligned */
+	if (ppaact_phys & ((PAGE_SIZE << order) - 1)) {
+		dev_err(&pdev->dev, "PAACT/OMT block is unaligned\n");
+		ret = -ENOMEM;
+		goto error;
+	}
+
+	spaact = (void *)ppaact + (PAGE_SIZE << get_order(PAACT_SIZE));
+	omt = (void *)spaact + (PAGE_SIZE << get_order(SPAACT_SIZE));
+
+	dev_dbg(&pdev->dev, "ppaact virt=%p phys=0x%llx\n", ppaact,
+		(unsigned long long) ppaact_phys);
+
+	/* Check to see if we need to implement the work-around on this SOC */
+
+	/* Determine the Port ID for our coherence subdomain */
+	for (i = 0; i < ARRAY_SIZE(port_id_map); i++) {
+		if (port_id_map[i].svr == (mfspr(SPRN_SVR) & ~SVR_SECURITY)) {
+			csd_port_id = port_id_map[i].port_id;
+			dev_dbg(&pdev->dev, "found matching SVR %08x\n",
+				port_id_map[i].svr);
+			break;
+		}
+	}
+
+	if (csd_port_id) {
+		dev_dbg(&pdev->dev, "creating coherency subdomain at address "
+			"0x%llx, size %zu, port id 0x%08x", ppaact_phys,
+			mem_size, csd_port_id);
+
+		ret = create_csd(ppaact_phys, mem_size, csd_port_id);
+		if (ret) {
+			dev_err(&pdev->dev, "could not create coherence "
+				"subdomain\n");
+			return ret;
+		}
+	}
+
+	spaact_phys = virt_to_phys(spaact);
+	omt_phys = virt_to_phys(omt);
+
+	spaace_pool = gen_pool_create(ilog2(sizeof(struct paace)), -1);
+	if (!spaace_pool) {
+		ret = -ENOMEM;
+		dev_err(&pdev->dev, "PAMU : failed to allocate spaace gen pool\n");
+		goto error;
+	}
+
+	ret = gen_pool_add(spaace_pool, (unsigned long)spaact, SPAACT_SIZE, -1);
+	if (ret)
+		goto error_genpool;
+
+	pamubypenr = in_be32(&guts_regs->pamubypenr);
+
+	for (pamu_reg_off = 0, pamu_counter = 0x80000000; pamu_reg_off < size;
+	     pamu_reg_off += PAMU_OFFSET, pamu_counter >>= 1) {
+
+		pamu_reg_base = (unsigned long) pamu_regs + pamu_reg_off;
+		setup_one_pamu(pamu_reg_base, pamu_reg_off, ppaact_phys,
+				 spaact_phys, omt_phys);
+		/* Disable PAMU bypass for this PAMU */
+		pamubypenr &= ~pamu_counter;
+	}
+
+	setup_omt(omt);
+
+	/* Enable all relevant PAMU(s) */
+	out_be32(&guts_regs->pamubypenr, pamubypenr);
+
+	iounmap(guts_regs);
+
+	/* Enable DMA for the LIODNs in the device tree*/
+
+	setup_liodns();
+
+	return 0;
+
+error_genpool:
+	gen_pool_destroy(spaace_pool);
+
+error:
+	if (irq != NO_IRQ)
+		free_irq(irq, data);
+
+	if (data) {
+		memset(data, 0, sizeof(struct pamu_isr_data));
+		kfree(data);
+	}
+
+	if (pamu_regs)
+		iounmap(pamu_regs);
+
+	if (guts_regs)
+		iounmap(guts_regs);
+
+	if (ppaact)
+		free_pages((unsigned long)ppaact, order);
+
+	ppaact = NULL;
+
+	return ret;
+}
+
+static const struct of_device_id fsl_of_pamu_ids[] = {
+	{
+		.compatible = "fsl,p4080-pamu",
+	},
+	{
+		.compatible = "fsl,pamu",
+	},
+	{},
+};
+
+static struct platform_driver fsl_of_pamu_driver = {
+	.driver = {
+		.name = "fsl-of-pamu",
+		.owner = THIS_MODULE,
+	},
+	.probe = fsl_pamu_probe,
+};
+
+static __init int fsl_pamu_init(void)
+{
+	struct platform_device *pdev = NULL;
+	struct device_node *np;
+	int ret;
+
+	/*
+	 * The normal OF process calls the probe function at some
+	 * indeterminate later time, after most drivers have loaded.  This is
+	 * too late for us, because PAMU clients (like the Qman driver)
+	 * depend on PAMU being initialized early.
+	 *
+	 * So instead, we "manually" call our probe function by creating the
+	 * platform devices ourselves.
+	 */
+
+	/*
+	 * We assume that there is only one PAMU node in the device tree.  A
+	 * single PAMU node represents all of the PAMU devices in the SOC
+	 * already.   Everything else already makes that assumption, and the
+	 * binding for the PAMU nodes doesn't allow for any parent-child
+	 * relationships anyway.  In other words, support for more than one
+	 * PAMU node would require significant changes to a lot of code.
+	 */
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,pamu");
+	if (!np) {
+		pr_err("fsl-pamu: could not find a PAMU node\n");
+		return -ENODEV;
+	}
+
+	ret = platform_driver_register(&fsl_of_pamu_driver);
+	if (ret) {
+		pr_err("fsl-pamu: could not register driver (err=%i)\n", ret);
+		goto error_driver_register;
+	}
+
+	pdev = platform_device_alloc("fsl-of-pamu", 0);
+	if (!pdev) {
+		pr_err("fsl-pamu: could not allocate device %s\n",
+		       np->full_name);
+		ret = -ENOMEM;
+		goto error_device_alloc;
+	}
+	pdev->dev.of_node = of_node_get(np);
+
+	ret = pamu_domain_init();
+	if (ret)
+		goto error_device_add;
+
+	ret = platform_device_add(pdev);
+	if (ret) {
+		pr_err("fsl-pamu: could not add device %s (err=%i)\n",
+		       np->full_name, ret);
+		goto error_device_add;
+	}
+
+	return 0;
+
+error_device_add:
+	of_node_put(pdev->dev.of_node);
+	pdev->dev.of_node = NULL;
+
+	platform_device_put(pdev);
+
+error_device_alloc:
+	platform_driver_unregister(&fsl_of_pamu_driver);
+
+error_driver_register:
+	of_node_put(np);
+
+	return ret;
+}
+arch_initcall(fsl_pamu_init);
diff --git a/drivers/iommu/fsl_pamu.h b/drivers/iommu/fsl_pamu.h
new file mode 100644
index 0000000..3c730ab
--- /dev/null
+++ b/drivers/iommu/fsl_pamu.h
@@ -0,0 +1,410 @@
+/*
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ */
+
+#ifndef __FSL_PAMU_H
+#define __FSL_PAMU_H
+
+#include <linux/fsl_pamu_stash.h>
+
+/* Bit Field macros
+ *	v = bit field variable; m = mask, m##_SHIFT = shift, x = value to load
+ */
+#define set_bf(v, m, x)		(v = ((v) & ~(m)) | (((x) << (m##_SHIFT)) & (m)))
+#define get_bf(v, m)		(((v) & (m)) >> (m##_SHIFT))
+
+/* PAMU CCSR space */
+#define PAMU_PGC 0x00000000     /* Allows all peripheral accesses */
+#define PAMU_PE 0x40000000      /* enable PAMU                    */
+
+/* PAMU_OFFSET to the next pamu space in ccsr */
+#define PAMU_OFFSET 0x1000
+
+#define PAMU_MMAP_REGS_BASE 0
+
+struct pamu_mmap_regs {
+	u32 ppbah;
+	u32 ppbal;
+	u32 pplah;
+	u32 pplal;
+	u32 spbah;
+	u32 spbal;
+	u32 splah;
+	u32 splal;
+	u32 obah;
+	u32 obal;
+	u32 olah;
+	u32 olal;
+};
+
+/* PAMU Error Registers */
+#define PAMU_POES1 0x0040
+#define PAMU_POES2 0x0044
+#define PAMU_POEAH 0x0048
+#define PAMU_POEAL 0x004C
+#define PAMU_AVS1  0x0050
+#define PAMU_AVS1_AV    0x1
+#define PAMU_AVS1_OTV   0x6
+#define PAMU_AVS1_APV   0x78
+#define PAMU_AVS1_WAV   0x380
+#define PAMU_AVS1_LAV   0x1c00
+#define PAMU_AVS1_GCV   0x2000
+#define PAMU_AVS1_PDV   0x4000
+#define PAMU_AV_MASK    (PAMU_AVS1_AV | PAMU_AVS1_OTV | PAMU_AVS1_APV | PAMU_AVS1_WAV \
+			| PAMU_AVS1_LAV | PAMU_AVS1_GCV | PAMU_AVS1_PDV)
+#define PAMU_AVS1_LIODN_SHIFT 16
+#define PAMU_LAV_LIODN_NOT_IN_PPAACT 0x400
+
+#define PAMU_AVS2  0x0054
+#define PAMU_AVAH  0x0058
+#define PAMU_AVAL  0x005C
+#define PAMU_EECTL 0x0060
+#define PAMU_EEDIS 0x0064
+#define PAMU_EEINTEN 0x0068
+#define PAMU_EEDET 0x006C
+#define PAMU_EEATTR 0x0070
+#define PAMU_EEAHI 0x0074
+#define PAMU_EEALO 0x0078
+#define PAMU_EEDHI 0X007C
+#define PAMU_EEDLO 0x0080
+#define PAMU_EECC  0x0084
+#define PAMU_UDAD  0x0090
+
+/* PAMU Revision Registers */
+#define PAMU_PR1 0x0BF8
+#define PAMU_PR2 0x0BFC
+
+/* PAMU version mask */
+#define PAMU_PR1_MASK 0xffff
+
+/* PAMU Capabilities Registers */
+#define PAMU_PC1 0x0C00
+#define PAMU_PC2 0x0C04
+#define PAMU_PC3 0x0C08
+#define PAMU_PC4 0x0C0C
+
+/* PAMU Control Register */
+#define PAMU_PC 0x0C10
+
+/* PAMU control defs */
+#define PAMU_CONTROL 0x0C10
+#define PAMU_PC_PGC 0x80000000  /* PAMU gate closed bit */
+#define PAMU_PC_PE   0x40000000 /* PAMU enable bit */
+#define PAMU_PC_SPCC 0x00000010 /* sPAACE cache enable */
+#define PAMU_PC_PPCC 0x00000001 /* pPAACE cache enable */
+#define PAMU_PC_OCE  0x00001000 /* OMT cache enable */
+
+#define PAMU_PFA1 0x0C14
+#define PAMU_PFA2 0x0C18
+
+#define PAMU_PC2_MLIODN(X) ((X) >> 16)
+#define PAMU_PC3_MWCE(X) (((X) >> 21) & 0xf)
+
+/* PAMU Interrupt control and Status Register */
+#define PAMU_PICS 0x0C1C
+#define PAMU_ACCESS_VIOLATION_STAT   0x8
+#define PAMU_ACCESS_VIOLATION_ENABLE 0x4
+
+/* PAMU Debug Registers */
+#define PAMU_PD1 0x0F00
+#define PAMU_PD2 0x0F04
+#define PAMU_PD3 0x0F08
+#define PAMU_PD4 0x0F0C
+
+#define PAACE_AP_PERMS_DENIED  0x0
+#define PAACE_AP_PERMS_QUERY   0x1
+#define PAACE_AP_PERMS_UPDATE  0x2
+#define PAACE_AP_PERMS_ALL     0x3
+
+#define PAACE_DD_TO_HOST       0x0
+#define PAACE_DD_TO_IO         0x1
+#define PAACE_PT_PRIMARY       0x0
+#define PAACE_PT_SECONDARY     0x1
+#define PAACE_V_INVALID        0x0
+#define PAACE_V_VALID          0x1
+#define PAACE_MW_SUBWINDOWS    0x1
+
+#define PAACE_WSE_4K           0xB
+#define PAACE_WSE_8K           0xC
+#define PAACE_WSE_16K          0xD
+#define PAACE_WSE_32K          0xE
+#define PAACE_WSE_64K          0xF
+#define PAACE_WSE_128K         0x10
+#define PAACE_WSE_256K         0x11
+#define PAACE_WSE_512K         0x12
+#define PAACE_WSE_1M           0x13
+#define PAACE_WSE_2M           0x14
+#define PAACE_WSE_4M           0x15
+#define PAACE_WSE_8M           0x16
+#define PAACE_WSE_16M          0x17
+#define PAACE_WSE_32M          0x18
+#define PAACE_WSE_64M          0x19
+#define PAACE_WSE_128M         0x1A
+#define PAACE_WSE_256M         0x1B
+#define PAACE_WSE_512M         0x1C
+#define PAACE_WSE_1G           0x1D
+#define PAACE_WSE_2G           0x1E
+#define PAACE_WSE_4G           0x1F
+
+#define PAACE_DID_PCI_EXPRESS_1 0x00
+#define PAACE_DID_PCI_EXPRESS_2 0x01
+#define PAACE_DID_PCI_EXPRESS_3 0x02
+#define PAACE_DID_PCI_EXPRESS_4 0x03
+#define PAACE_DID_LOCAL_BUS     0x04
+#define PAACE_DID_SRIO          0x0C
+#define PAACE_DID_MEM_1         0x10
+#define PAACE_DID_MEM_2         0x11
+#define PAACE_DID_MEM_3         0x12
+#define PAACE_DID_MEM_4         0x13
+#define PAACE_DID_MEM_1_2       0x14
+#define PAACE_DID_MEM_3_4       0x15
+#define PAACE_DID_MEM_1_4       0x16
+#define PAACE_DID_BM_SW_PORTAL  0x18
+#define PAACE_DID_PAMU          0x1C
+#define PAACE_DID_CAAM          0x21
+#define PAACE_DID_QM_SW_PORTAL  0x3C
+#define PAACE_DID_CORE0_INST    0x80
+#define PAACE_DID_CORE0_DATA    0x81
+#define PAACE_DID_CORE1_INST    0x82
+#define PAACE_DID_CORE1_DATA    0x83
+#define PAACE_DID_CORE2_INST    0x84
+#define PAACE_DID_CORE2_DATA    0x85
+#define PAACE_DID_CORE3_INST    0x86
+#define PAACE_DID_CORE3_DATA    0x87
+#define PAACE_DID_CORE4_INST    0x88
+#define PAACE_DID_CORE4_DATA    0x89
+#define PAACE_DID_CORE5_INST    0x8A
+#define PAACE_DID_CORE5_DATA    0x8B
+#define PAACE_DID_CORE6_INST    0x8C
+#define PAACE_DID_CORE6_DATA    0x8D
+#define PAACE_DID_CORE7_INST    0x8E
+#define PAACE_DID_CORE7_DATA    0x8F
+#define PAACE_DID_BROADCAST     0xFF
+
+#define PAACE_ATM_NO_XLATE      0x00
+#define PAACE_ATM_WINDOW_XLATE  0x01
+#define PAACE_ATM_PAGE_XLATE    0x02
+#define PAACE_ATM_WIN_PG_XLATE  \
+                (PAACE_ATM_WINDOW_XLATE | PAACE_ATM_PAGE_XLATE)
+#define PAACE_OTM_NO_XLATE      0x00
+#define PAACE_OTM_IMMEDIATE     0x01
+#define PAACE_OTM_INDEXED       0x02
+#define PAACE_OTM_RESERVED      0x03
+
+#define PAACE_M_COHERENCE_REQ   0x01
+
+#define PAACE_PID_0             0x0
+#define PAACE_PID_1             0x1
+#define PAACE_PID_2             0x2
+#define PAACE_PID_3             0x3
+#define PAACE_PID_4             0x4
+#define PAACE_PID_5             0x5
+#define PAACE_PID_6             0x6
+#define PAACE_PID_7             0x7
+
+#define PAACE_TCEF_FORMAT0_8B   0x00
+#define PAACE_TCEF_FORMAT1_RSVD 0x01
+/*
+ * Hard coded value for the PAACT size to accomodate
+ * maximum LIODN value generated by u-boot.
+ */
+#define PAACE_NUMBER_ENTRIES    0x500
+/* Hard coded value for the SPAACT size */
+#define SPAACE_NUMBER_ENTRIES	0x800
+
+#define	OME_NUMBER_ENTRIES      16
+
+/* PAACE Bit Field Defines */
+#define PPAACE_AF_WBAL			0xfffff000
+#define PPAACE_AF_WBAL_SHIFT		12
+#define PPAACE_AF_WSE			0x00000fc0
+#define PPAACE_AF_WSE_SHIFT		6
+#define PPAACE_AF_MW			0x00000020
+#define PPAACE_AF_MW_SHIFT		5
+
+#define SPAACE_AF_LIODN			0xffff0000
+#define SPAACE_AF_LIODN_SHIFT		16
+
+#define PAACE_AF_AP			0x00000018
+#define PAACE_AF_AP_SHIFT		3
+#define PAACE_AF_DD			0x00000004
+#define PAACE_AF_DD_SHIFT		2
+#define PAACE_AF_PT			0x00000002
+#define PAACE_AF_PT_SHIFT		1
+#define PAACE_AF_V			0x00000001
+#define PAACE_AF_V_SHIFT		0
+
+#define PAACE_DA_HOST_CR		0x80
+#define PAACE_DA_HOST_CR_SHIFT		7
+
+#define PAACE_IA_CID			0x00FF0000
+#define PAACE_IA_CID_SHIFT		16
+#define PAACE_IA_WCE			0x000000F0
+#define PAACE_IA_WCE_SHIFT		4
+#define PAACE_IA_ATM			0x0000000C
+#define PAACE_IA_ATM_SHIFT		2
+#define PAACE_IA_OTM			0x00000003
+#define PAACE_IA_OTM_SHIFT		0
+
+#define PAACE_WIN_TWBAL			0xfffff000
+#define PAACE_WIN_TWBAL_SHIFT		12
+#define PAACE_WIN_SWSE			0x00000fc0
+#define PAACE_WIN_SWSE_SHIFT		6
+
+/* PAMU Data Structures */
+/* primary / secondary paact structure */
+struct paace {
+	/* PAACE Offset 0x00 */
+	u32 wbah;				/* only valid for Primary PAACE */
+	u32 addr_bitfields;		/* See P/S PAACE_AF_* */
+
+	/* PAACE Offset 0x08 */
+	/* Interpretation of first 32 bits dependent on DD above */
+	union {
+		struct {
+			/* Destination ID, see PAACE_DID_* defines */
+			u8 did;
+			/* Partition ID */
+			u8 pid;
+			/* Snoop ID */
+			u8 snpid;
+			/* coherency_required : 1 reserved : 7 */
+			u8 coherency_required; /* See PAACE_DA_* */
+		} to_host;
+		struct {
+			/* Destination ID, see PAACE_DID_* defines */
+			u8  did;
+			u8  reserved1;
+			u16 reserved2;
+		} to_io;
+	} domain_attr;
+
+	/* Implementation attributes + window count + address & operation translation modes */
+	u32 impl_attr;			/* See PAACE_IA_* */
+
+	/* PAACE Offset 0x10 */
+	/* Translated window base address */
+	u32 twbah;
+	u32 win_bitfields;			/* See PAACE_WIN_* */
+
+	/* PAACE Offset 0x18 */
+	/* first secondary paace entry */
+	u32 fspi;				/* only valid for Primary PAACE */
+	union {
+		struct {
+			u8 ioea;
+			u8 moea;
+			u8 ioeb;
+			u8 moeb;
+		} immed_ot;
+		struct {
+			u16 reserved;
+			u16 omi;
+		} index_ot;
+	} op_encode;
+
+	/* PAACE Offsets 0x20-0x38 */
+	u32 reserved[8];			/* not currently implemented */
+};
+
+/* OME : Operation mapping entry
+ * MOE : Mapped Operation Encodings
+ * The operation mapping table is table containing operation mapping entries (OME).
+ * The index of a particular OME is programmed in the PAACE entry for translation
+ * in bound I/O operations corresponding to an LIODN. The OMT is used for translation
+ * specifically in case of the indexed translation mode. Each OME contains a 128
+ * byte mapped operation encoding (MOE), where each byte represents an MOE.
+ */
+#define NUM_MOE 128
+struct ome {
+	u8 moe[NUM_MOE];
+} __attribute__((packed));
+
+#define PAACT_SIZE              (sizeof(struct paace) * PAACE_NUMBER_ENTRIES)
+#define SPAACT_SIZE              (sizeof(struct paace) * SPAACE_NUMBER_ENTRIES)
+#define OMT_SIZE                (sizeof(struct ome) * OME_NUMBER_ENTRIES)
+
+#define PAMU_PAGE_SHIFT 12
+#define PAMU_PAGE_SIZE  4096ULL
+
+#define IOE_READ        0x00
+#define IOE_READ_IDX    0x00
+#define IOE_WRITE       0x81
+#define IOE_WRITE_IDX   0x01
+#define IOE_EREAD0      0x82    /* Enhanced read type 0 */
+#define IOE_EREAD0_IDX  0x02    /* Enhanced read type 0 */
+#define IOE_EWRITE0     0x83    /* Enhanced write type 0 */
+#define IOE_EWRITE0_IDX 0x03    /* Enhanced write type 0 */
+#define IOE_DIRECT0     0x84    /* Directive type 0 */
+#define IOE_DIRECT0_IDX 0x04    /* Directive type 0 */
+#define IOE_EREAD1      0x85    /* Enhanced read type 1 */
+#define IOE_EREAD1_IDX  0x05    /* Enhanced read type 1 */
+#define IOE_EWRITE1     0x86    /* Enhanced write type 1 */
+#define IOE_EWRITE1_IDX 0x06    /* Enhanced write type 1 */
+#define IOE_DIRECT1     0x87    /* Directive type 1 */
+#define IOE_DIRECT1_IDX 0x07    /* Directive type 1 */
+#define IOE_RAC         0x8c    /* Read with Atomic clear */
+#define IOE_RAC_IDX     0x0c    /* Read with Atomic clear */
+#define IOE_RAS         0x8d    /* Read with Atomic set */
+#define IOE_RAS_IDX     0x0d    /* Read with Atomic set */
+#define IOE_RAD         0x8e    /* Read with Atomic decrement */
+#define IOE_RAD_IDX     0x0e    /* Read with Atomic decrement */
+#define IOE_RAI         0x8f    /* Read with Atomic increment */
+#define IOE_RAI_IDX     0x0f    /* Read with Atomic increment */
+
+#define EOE_READ        0x00
+#define EOE_WRITE       0x01
+#define EOE_RAC         0x0c    /* Read with Atomic clear */
+#define EOE_RAS         0x0d    /* Read with Atomic set */
+#define EOE_RAD         0x0e    /* Read with Atomic decrement */
+#define EOE_RAI         0x0f    /* Read with Atomic increment */
+#define EOE_LDEC        0x10    /* Load external cache */
+#define EOE_LDECL       0x11    /* Load external cache with stash lock */
+#define EOE_LDECPE      0x12    /* Load external cache with preferred exclusive */
+#define EOE_LDECPEL     0x13    /* Load external cache with preferred exclusive and lock */
+#define EOE_LDECFE      0x14    /* Load external cache with forced exclusive */
+#define EOE_LDECFEL     0x15    /* Load external cache with forced exclusive and lock */
+#define EOE_RSA         0x16    /* Read with stash allocate */
+#define EOE_RSAU        0x17    /* Read with stash allocate and unlock */
+#define EOE_READI       0x18    /* Read with invalidate */
+#define EOE_RWNITC      0x19    /* Read with no intention to cache */
+#define EOE_WCI         0x1a    /* Write cache inhibited */
+#define EOE_WWSA        0x1b    /* Write with stash allocate */
+#define EOE_WWSAL       0x1c    /* Write with stash allocate and lock */
+#define EOE_WWSAO       0x1d    /* Write with stash allocate only */
+#define EOE_WWSAOL      0x1e    /* Write with stash allocate only and lock */
+#define EOE_VALID       0x80
+
+/* Function prototypes */
+int pamu_domain_init(void);
+int pamu_enable_liodn(int liodn);
+int pamu_disable_liodn(int liodn);
+void pamu_free_subwins(int liodn);
+int pamu_config_ppaace(int liodn, phys_addr_t win_addr, phys_addr_t win_size,
+		       u32 omi, unsigned long rpn, u32 snoopid, uint32_t stashid,
+		       u32 subwin_cnt, int prot);
+int pamu_config_spaace(int liodn, u32 subwin_cnt, u32 subwin_addr,
+		       phys_addr_t subwin_size, u32 omi, unsigned long rpn,
+		       uint32_t snoopid, u32 stashid, int enable, int prot);
+
+u32 get_stash_id(u32 stash_dest_hint, u32 vcpu);
+void get_ome_index(u32 *omi_index, struct device *dev);
+int  pamu_update_paace_stash(int liodn, u32 subwin, u32 value);
+int pamu_disable_spaace(int liodn, u32 subwin);
+u32 pamu_get_max_subwin_cnt(void);
+
+#endif  /* __FSL_PAMU_H */
diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c
new file mode 100644
index 0000000..bf2452c
--- /dev/null
+++ b/drivers/iommu/fsl_pamu_domain.c
@@ -0,0 +1,1142 @@
+/*
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ * Author: Varun Sethi <varun.sethi@freescale.com>
+ *
+ */
+
+#define pr_fmt(fmt)    "fsl-pamu-domain: %s: " fmt, __func__
+
+#include <linux/init.h>
+#include <linux/iommu.h>
+#include <linux/notifier.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/of_platform.h>
+#include <linux/bootmem.h>
+#include <linux/err.h>
+#include <asm/io.h>
+#include <asm/bitops.h>
+
+#include <asm/pci-bridge.h>
+#include <sysdev/fsl_pci.h>
+
+#include "fsl_pamu_domain.h"
+#include "pci.h"
+
+/*
+ * Global spinlock that needs to be held while
+ * configuring PAMU.
+ */
+static DEFINE_SPINLOCK(iommu_lock);
+
+static struct kmem_cache *fsl_pamu_domain_cache;
+static struct kmem_cache *iommu_devinfo_cache;
+static DEFINE_SPINLOCK(device_domain_lock);
+
+static int __init iommu_init_mempool(void)
+{
+
+	fsl_pamu_domain_cache = kmem_cache_create("fsl_pamu_domain",
+					 sizeof(struct fsl_dma_domain),
+					 0,
+					 SLAB_HWCACHE_ALIGN,
+
+					 NULL);
+	if (!fsl_pamu_domain_cache) {
+		pr_err("Couldn't create fsl iommu_domain cache\n");
+		return -ENOMEM;
+	}
+
+	iommu_devinfo_cache = kmem_cache_create("iommu_devinfo",
+					 sizeof(struct device_domain_info),
+					 0,
+					 SLAB_HWCACHE_ALIGN,
+					 NULL);
+	if (!iommu_devinfo_cache) {
+		pr_err("Couldn't create devinfo cache\n");
+		kmem_cache_destroy(fsl_pamu_domain_cache);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static phys_addr_t get_phys_addr(struct fsl_dma_domain *dma_domain, dma_addr_t iova)
+{
+	u32 win_cnt = dma_domain->win_cnt;
+	struct dma_window *win_ptr =
+				&dma_domain->win_arr[0];
+	struct iommu_domain_geometry *geom;
+
+	geom = &dma_domain->iommu_domain->geometry;
+
+	if (!win_cnt || !dma_domain->geom_size) {
+		pr_err("Number of windows/geometry not configured for the domain\n");
+		return 0;
+	}
+
+	if (win_cnt > 1) {
+		u64 subwin_size;
+		dma_addr_t subwin_iova;
+		u32 wnd;
+
+		subwin_size = dma_domain->geom_size >> ilog2(win_cnt);
+		subwin_iova = iova & ~(subwin_size - 1);
+		wnd = (subwin_iova - geom->aperture_start) >> ilog2(subwin_size);
+		win_ptr = &dma_domain->win_arr[wnd];
+	}
+
+	if (win_ptr->valid)
+		return (win_ptr->paddr + (iova & (win_ptr->size - 1)));
+
+	return 0;
+}
+
+static int map_subwins(int liodn, struct fsl_dma_domain *dma_domain)
+{
+	struct dma_window *sub_win_ptr =
+				&dma_domain->win_arr[0];
+	int i, ret;
+	unsigned long rpn, flags;
+
+	for (i = 0; i < dma_domain->win_cnt; i++) {
+		if (sub_win_ptr[i].valid) {
+			rpn = sub_win_ptr[i].paddr >>
+				 PAMU_PAGE_SHIFT;
+			spin_lock_irqsave(&iommu_lock, flags);
+			ret = pamu_config_spaace(liodn, dma_domain->win_cnt, i,
+						 sub_win_ptr[i].size,
+						 ~(u32)0,
+						 rpn,
+						 dma_domain->snoop_id,
+						 dma_domain->stash_id,
+						 (i > 0) ? 1 : 0,
+						 sub_win_ptr[i].prot);
+			spin_unlock_irqrestore(&iommu_lock, flags);
+			if (ret) {
+				pr_err("PAMU SPAACE configuration failed for liodn %d\n",
+					 liodn);
+				return ret;
+			}
+		}
+	}
+
+	return ret;
+}
+
+static int map_win(int liodn, struct fsl_dma_domain *dma_domain)
+{
+	int ret;
+	struct dma_window *wnd = &dma_domain->win_arr[0];
+	phys_addr_t wnd_addr = dma_domain->iommu_domain->geometry.aperture_start;
+	unsigned long flags;
+
+	spin_lock_irqsave(&iommu_lock, flags);
+	ret = pamu_config_ppaace(liodn, wnd_addr,
+				 wnd->size,
+				 ~(u32)0,
+				 wnd->paddr >> PAMU_PAGE_SHIFT,
+				 dma_domain->snoop_id, dma_domain->stash_id,
+				 0, wnd->prot);
+	spin_unlock_irqrestore(&iommu_lock, flags);
+	if (ret)
+		pr_err("PAMU PAACE configuration failed for liodn %d\n",
+			liodn);
+
+	return ret;
+}
+
+/* Map the DMA window corresponding to the LIODN */
+static int map_liodn(int liodn, struct fsl_dma_domain *dma_domain)
+{
+	if (dma_domain->win_cnt > 1)
+		return map_subwins(liodn, dma_domain);
+	else
+		return map_win(liodn, dma_domain);
+
+}
+
+/* Update window/subwindow mapping for the LIODN */
+static int update_liodn(int liodn, struct fsl_dma_domain *dma_domain, u32 wnd_nr)
+{
+	int ret;
+	struct dma_window *wnd = &dma_domain->win_arr[wnd_nr];
+	unsigned long flags;
+
+	spin_lock_irqsave(&iommu_lock, flags);
+	if (dma_domain->win_cnt > 1) {
+		ret = pamu_config_spaace(liodn, dma_domain->win_cnt, wnd_nr,
+					 wnd->size,
+					 ~(u32)0,
+					 wnd->paddr >> PAMU_PAGE_SHIFT,
+					 dma_domain->snoop_id,
+					 dma_domain->stash_id,
+					 (wnd_nr > 0) ? 1 : 0,
+					 wnd->prot);
+		if (ret)
+			pr_err("Subwindow reconfiguration failed for liodn %d\n", liodn);
+	} else {
+		phys_addr_t wnd_addr;
+
+		wnd_addr = dma_domain->iommu_domain->geometry.aperture_start;
+
+		ret = pamu_config_ppaace(liodn, wnd_addr,
+					 wnd->size,
+					 ~(u32)0,
+					 wnd->paddr >> PAMU_PAGE_SHIFT,
+					dma_domain->snoop_id, dma_domain->stash_id,
+					0, wnd->prot);
+		if (ret)
+			pr_err("Window reconfiguration failed for liodn %d\n", liodn);
+	}
+
+	spin_unlock_irqrestore(&iommu_lock, flags);
+
+	return ret;
+}
+
+static int update_liodn_stash(int liodn, struct fsl_dma_domain *dma_domain,
+				 u32 val)
+{
+	int ret = 0, i;
+	unsigned long flags;
+
+	spin_lock_irqsave(&iommu_lock, flags);
+	if (!dma_domain->win_arr) {
+		pr_err("Windows not configured, stash destination update failed for liodn %d\n", liodn);
+		spin_unlock_irqrestore(&iommu_lock, flags);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < dma_domain->win_cnt; i++) {
+		ret = pamu_update_paace_stash(liodn, i, val);
+		if (ret) {
+			pr_err("Failed to update SPAACE %d field for liodn %d\n ", i, liodn);
+			spin_unlock_irqrestore(&iommu_lock, flags);
+			return ret;
+		}
+	}
+
+	spin_unlock_irqrestore(&iommu_lock, flags);
+
+	return ret;
+}
+
+/* Set the geometry parameters for a LIODN */
+static int pamu_set_liodn(int liodn, struct device *dev,
+			   struct fsl_dma_domain *dma_domain,
+			   struct iommu_domain_geometry *geom_attr,
+			   u32 win_cnt)
+{
+	phys_addr_t window_addr, window_size;
+	phys_addr_t subwin_size;
+	int ret = 0, i;
+	u32 omi_index = ~(u32)0;
+	unsigned long flags;
+
+	/*
+	 * Configure the omi_index at the geometry setup time.
+	 * This is a static value which depends on the type of
+	 * device and would not change thereafter.
+	 */
+	get_ome_index(&omi_index, dev);
+
+	window_addr = geom_attr->aperture_start;
+	window_size = dma_domain->geom_size;
+
+	spin_lock_irqsave(&iommu_lock, flags);
+	ret = pamu_disable_liodn(liodn);
+	if (!ret)
+		ret = pamu_config_ppaace(liodn, window_addr, window_size, omi_index,
+					 0, dma_domain->snoop_id,
+					 dma_domain->stash_id, win_cnt, 0);
+	spin_unlock_irqrestore(&iommu_lock, flags);
+	if (ret) {
+		pr_err("PAMU PAACE configuration failed for liodn %d, win_cnt =%d\n", liodn, win_cnt);
+		return ret;
+	}
+
+	if (win_cnt > 1) {
+		subwin_size = window_size >> ilog2(win_cnt);
+		for (i = 0; i < win_cnt; i++) {
+			spin_lock_irqsave(&iommu_lock, flags);
+			ret = pamu_disable_spaace(liodn, i);
+			if (!ret)
+				ret = pamu_config_spaace(liodn, win_cnt, i,
+							 subwin_size, omi_index,
+							 0, dma_domain->snoop_id,
+							 dma_domain->stash_id,
+							 0, 0);
+			spin_unlock_irqrestore(&iommu_lock, flags);
+			if (ret) {
+				pr_err("PAMU SPAACE configuration failed for liodn %d\n", liodn);
+				return ret;
+			}
+		}
+	}
+
+	return ret;
+}
+
+static int check_size(u64 size, dma_addr_t iova)
+{
+	/*
+	 * Size must be a power of two and at least be equal
+	 * to PAMU page size.
+	 */
+	if (!is_power_of_2(size) || size < PAMU_PAGE_SIZE) {
+		pr_err("%s: size too small or not a power of two\n", __func__);
+		return -EINVAL;
+	}
+
+	/* iova must be page size aligned*/
+	if (iova & (size - 1)) {
+		pr_err("%s: address is not aligned with window size\n", __func__);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct fsl_dma_domain *iommu_alloc_dma_domain(void)
+{
+	struct fsl_dma_domain *domain;
+
+	domain = kmem_cache_zalloc(fsl_pamu_domain_cache, GFP_KERNEL);
+	if (!domain)
+		return NULL;
+
+	domain->stash_id = ~(u32)0;
+	domain->snoop_id = ~(u32)0;
+	domain->win_cnt = pamu_get_max_subwin_cnt();
+	domain->geom_size = 0;
+
+	INIT_LIST_HEAD(&domain->devices);
+
+	spin_lock_init(&domain->domain_lock);
+
+	return domain;
+}
+
+static inline struct device_domain_info *find_domain(struct device *dev)
+{
+	return dev->archdata.iommu_domain;
+}
+
+static void remove_device_ref(struct device_domain_info *info, u32 win_cnt)
+{
+	unsigned long flags;
+
+	list_del(&info->link);
+	spin_lock_irqsave(&iommu_lock, flags);
+	if (win_cnt > 1)
+		pamu_free_subwins(info->liodn);
+	pamu_disable_liodn(info->liodn);
+	spin_unlock_irqrestore(&iommu_lock, flags);
+	spin_lock_irqsave(&device_domain_lock, flags);
+	info->dev->archdata.iommu_domain = NULL;
+	kmem_cache_free(iommu_devinfo_cache, info);
+	spin_unlock_irqrestore(&device_domain_lock, flags);
+}
+
+static void detach_device(struct device *dev, struct fsl_dma_domain *dma_domain)
+{
+	struct device_domain_info *info, *tmp;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dma_domain->domain_lock, flags);
+	/* Remove the device from the domain device list */
+	list_for_each_entry_safe(info, tmp, &dma_domain->devices, link) {
+		if (!dev || (info->dev == dev))
+			remove_device_ref(info, dma_domain->win_cnt);
+	}
+	spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+}
+
+static void attach_device(struct fsl_dma_domain *dma_domain, int liodn, struct device *dev)
+{
+	struct device_domain_info *info, *old_domain_info;
+	unsigned long flags;
+
+	spin_lock_irqsave(&device_domain_lock, flags);
+	/*
+	 * Check here if the device is already attached to domain or not.
+	 * If the device is already attached to a domain detach it.
+	 */
+	old_domain_info = find_domain(dev);
+	if (old_domain_info && old_domain_info->domain != dma_domain) {
+		spin_unlock_irqrestore(&device_domain_lock, flags);
+		detach_device(dev, old_domain_info->domain);
+		spin_lock_irqsave(&device_domain_lock, flags);
+	}
+
+	info = kmem_cache_zalloc(iommu_devinfo_cache, GFP_KERNEL);
+
+	info->dev = dev;
+	info->liodn = liodn;
+	info->domain = dma_domain;
+
+	list_add(&info->link, &dma_domain->devices);
+	/*
+	 * In case of devices with multiple LIODNs just store
+	 * the info for the first LIODN as all
+	 * LIODNs share the same domain
+	 */
+	if (!old_domain_info)
+		dev->archdata.iommu_domain = info;
+	spin_unlock_irqrestore(&device_domain_lock, flags);
+
+}
+
+static phys_addr_t fsl_pamu_iova_to_phys(struct iommu_domain *domain,
+					    dma_addr_t iova)
+{
+	struct fsl_dma_domain *dma_domain = domain->priv;
+
+	if ((iova < domain->geometry.aperture_start) ||
+		iova > (domain->geometry.aperture_end))
+		return 0;
+
+	return get_phys_addr(dma_domain, iova);
+}
+
+static int fsl_pamu_domain_has_cap(struct iommu_domain *domain,
+				      unsigned long cap)
+{
+	return cap == IOMMU_CAP_CACHE_COHERENCY;
+}
+
+static void fsl_pamu_domain_destroy(struct iommu_domain *domain)
+{
+	struct fsl_dma_domain *dma_domain = domain->priv;
+
+	domain->priv = NULL;
+
+	/* remove all the devices from the device list */
+	detach_device(NULL, dma_domain);
+
+	dma_domain->enabled = 0;
+	dma_domain->mapped = 0;
+
+	kmem_cache_free(fsl_pamu_domain_cache, dma_domain);
+}
+
+static int fsl_pamu_domain_init(struct iommu_domain *domain)
+{
+	struct fsl_dma_domain *dma_domain;
+
+	dma_domain = iommu_alloc_dma_domain();
+	if (!dma_domain) {
+		pr_err("dma_domain allocation failed\n");
+		return -ENOMEM;
+	}
+	domain->priv = dma_domain;
+	dma_domain->iommu_domain = domain;
+	/* defaul geometry 64 GB i.e. maximum system address */
+	domain->geometry.aperture_start = 0;
+	domain->geometry.aperture_end = (1ULL << 36) - 1;
+	domain->geometry.force_aperture = true;
+
+	return 0;
+}
+
+/* Configure geometry settings for all LIODNs associated with domain */
+static int pamu_set_domain_geometry(struct fsl_dma_domain *dma_domain,
+				    struct iommu_domain_geometry *geom_attr,
+				    u32 win_cnt)
+{
+	struct device_domain_info *info;
+	int ret = 0;
+
+	list_for_each_entry(info, &dma_domain->devices, link) {
+		ret = pamu_set_liodn(info->liodn, info->dev, dma_domain,
+				      geom_attr, win_cnt);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+/* Update stash destination for all LIODNs associated with the domain */
+static int update_domain_stash(struct fsl_dma_domain *dma_domain, u32 val)
+{
+	struct device_domain_info *info;
+	int ret = 0;
+
+	list_for_each_entry(info, &dma_domain->devices, link) {
+		ret = update_liodn_stash(info->liodn, dma_domain, val);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+/* Update domain mappings for all LIODNs associated with the domain */
+static int update_domain_mapping(struct fsl_dma_domain *dma_domain, u32 wnd_nr)
+{
+	struct device_domain_info *info;
+	int ret = 0;
+
+	list_for_each_entry(info, &dma_domain->devices, link) {
+		ret = update_liodn(info->liodn, dma_domain, wnd_nr);
+		if (ret)
+			break;
+	}
+	return ret;
+}
+
+static int disable_domain_win(struct fsl_dma_domain *dma_domain, u32 wnd_nr)
+{
+	struct device_domain_info *info;
+	int ret = 0;
+
+	list_for_each_entry(info, &dma_domain->devices, link) {
+		if (dma_domain->win_cnt == 1 && dma_domain->enabled) {
+			ret = pamu_disable_liodn(info->liodn);
+			if (!ret)
+				dma_domain->enabled = 0;
+		} else {
+			ret = pamu_disable_spaace(info->liodn, wnd_nr);
+		}
+	}
+
+	return ret;
+}
+
+static void fsl_pamu_window_disable(struct iommu_domain *domain, u32 wnd_nr)
+{
+	struct fsl_dma_domain *dma_domain = domain->priv;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&dma_domain->domain_lock, flags);
+	if (!dma_domain->win_arr) {
+		pr_err("Number of windows not configured\n");
+		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+		return;
+	}
+
+	if (wnd_nr >= dma_domain->win_cnt) {
+		pr_err("Invalid window index\n");
+		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+		return;
+	}
+
+	if (dma_domain->win_arr[wnd_nr].valid) {
+		ret = disable_domain_win(dma_domain, wnd_nr);
+		if (!ret) {
+			dma_domain->win_arr[wnd_nr].valid = 0;
+			dma_domain->mapped--;
+		}
+	}
+
+	spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+
+}
+
+static int fsl_pamu_window_enable(struct iommu_domain *domain, u32 wnd_nr,
+				  phys_addr_t paddr, u64 size, int prot)
+{
+	struct fsl_dma_domain *dma_domain = domain->priv;
+	struct dma_window *wnd;
+	int pamu_prot = 0;
+	int ret;
+	unsigned long flags;
+	u64 win_size;
+
+	if (prot & IOMMU_READ)
+		pamu_prot |= PAACE_AP_PERMS_QUERY;
+	if (prot & IOMMU_WRITE)
+		pamu_prot |= PAACE_AP_PERMS_UPDATE;
+
+	spin_lock_irqsave(&dma_domain->domain_lock, flags);
+	if (!dma_domain->win_arr) {
+		pr_err("Number of windows not configured\n");
+		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+		return -ENODEV;
+	}
+
+	if (wnd_nr >= dma_domain->win_cnt) {
+		pr_err("Invalid window index\n");
+		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+		return -EINVAL;
+	}
+
+	win_size = dma_domain->geom_size >> ilog2(dma_domain->win_cnt);
+	if (size > win_size) {
+		pr_err("Invalid window size \n");
+		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+		return -EINVAL;
+	}
+
+	if (dma_domain->win_cnt == 1) {
+		if (dma_domain->enabled) {
+			pr_err("Disable the window before updating the mapping\n");
+			spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+			return -EBUSY;
+		}
+
+		ret = check_size(size, domain->geometry.aperture_start);
+		if (ret) {
+			pr_err("Aperture start not aligned to the size\n");
+			spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+			return -EINVAL;
+		}
+	}
+
+	wnd = &dma_domain->win_arr[wnd_nr];
+	if (!wnd->valid) {
+		wnd->paddr = paddr;
+		wnd->size = size;
+		wnd->prot = pamu_prot;
+
+		ret = update_domain_mapping(dma_domain, wnd_nr);
+		if (!ret) {
+			wnd->valid = 1;
+			dma_domain->mapped++;
+		}
+	} else {
+		pr_err("Disable the window before updating the mapping\n");
+		ret = -EBUSY;
+	}
+
+	spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+
+	return ret;
+}
+
+/*
+ * Attach the LIODN to the DMA domain and configure the geometry
+ * and window mappings.
+ */
+static int handle_attach_device(struct fsl_dma_domain *dma_domain,
+				 struct device *dev, const u32 *liodn,
+				 int num)
+{
+	unsigned long flags;
+	struct iommu_domain *domain = dma_domain->iommu_domain;
+	int ret = 0;
+	int i;
+
+	spin_lock_irqsave(&dma_domain->domain_lock, flags);
+	for (i = 0; i < num; i++) {
+
+		/* Ensure that LIODN value is valid */
+		if (liodn[i] >= PAACE_NUMBER_ENTRIES) {
+			pr_err("Invalid liodn %d, attach device failed for %s\n",
+				liodn[i], dev->of_node->full_name);
+			ret = -EINVAL;
+			break;
+		}
+
+		attach_device(dma_domain, liodn[i], dev);
+		/*
+		 * Check if geometry has already been configured
+		 * for the domain. If yes, set the geometry for
+		 * the LIODN.
+		 */
+		if (dma_domain->win_arr) {
+			u32 win_cnt = dma_domain->win_cnt > 1 ? dma_domain->win_cnt : 0;
+			ret = pamu_set_liodn(liodn[i], dev, dma_domain,
+					      &domain->geometry,
+					      win_cnt);
+			if (ret)
+				break;
+			if (dma_domain->mapped) {
+				/*
+				 * Create window/subwindow mapping for
+				 * the LIODN.
+				 */
+				ret = map_liodn(liodn[i], dma_domain);
+				if (ret)
+					break;
+			}
+		}
+	}
+	spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+
+	return ret;
+}
+
+static int fsl_pamu_attach_device(struct iommu_domain *domain,
+				  struct device *dev)
+{
+	struct fsl_dma_domain *dma_domain = domain->priv;
+	const u32 *liodn;
+	u32 liodn_cnt;
+	int len, ret = 0;
+	struct pci_dev *pdev = NULL;
+	struct pci_controller *pci_ctl;
+
+	/*
+	 * Use LIODN of the PCI controller while attaching a
+	 * PCI device.
+	 */
+	if (dev->bus == &pci_bus_type) {
+		pdev = to_pci_dev(dev);
+		pci_ctl = pci_bus_to_host(pdev->bus);
+		/*
+		 * make dev point to pci controller device
+		 * so we can get the LIODN programmed by
+		 * u-boot.
+		 */
+		dev = pci_ctl->parent;
+	}
+
+	liodn = of_get_property(dev->of_node, "fsl,liodn", &len);
+	if (liodn) {
+		liodn_cnt = len / sizeof(u32);
+		ret = handle_attach_device(dma_domain, dev,
+					 liodn, liodn_cnt);
+	} else {
+		pr_err("missing fsl,liodn property at %s\n",
+		          dev->of_node->full_name);
+			ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static void fsl_pamu_detach_device(struct iommu_domain *domain,
+				      struct device *dev)
+{
+	struct fsl_dma_domain *dma_domain = domain->priv;
+	const u32 *prop;
+	int len;
+	struct pci_dev *pdev = NULL;
+	struct pci_controller *pci_ctl;
+
+	/*
+	 * Use LIODN of the PCI controller while detaching a
+	 * PCI device.
+	 */
+	if (dev->bus == &pci_bus_type) {
+		pdev = to_pci_dev(dev);
+		pci_ctl = pci_bus_to_host(pdev->bus);
+		/*
+		 * make dev point to pci controller device
+		 * so we can get the LIODN programmed by
+		 * u-boot.
+		 */
+		dev = pci_ctl->parent;
+	}
+
+	prop = of_get_property(dev->of_node, "fsl,liodn", &len);
+	if (prop)
+		detach_device(dev, dma_domain);
+	else
+		pr_err("missing fsl,liodn property at %s\n",
+		          dev->of_node->full_name);
+}
+
+static  int configure_domain_geometry(struct iommu_domain *domain, void *data)
+{
+	struct iommu_domain_geometry *geom_attr = data;
+	struct fsl_dma_domain *dma_domain = domain->priv;
+	dma_addr_t geom_size;
+	unsigned long flags;
+
+	geom_size = geom_attr->aperture_end - geom_attr->aperture_start + 1;
+	/*
+	 * Sanity check the geometry size. Also, we do not support
+	 * DMA outside of the geometry.
+	 */
+	if (check_size(geom_size, geom_attr->aperture_start) ||
+		!geom_attr->force_aperture) {
+			pr_err("Invalid PAMU geometry attributes\n");
+			return -EINVAL;
+		}
+
+	spin_lock_irqsave(&dma_domain->domain_lock, flags);
+	if (dma_domain->enabled) {
+		pr_err("Can't set geometry attributes as domain is active\n");
+		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+		return  -EBUSY;
+	}
+
+	/* Copy the domain geometry information */
+	memcpy(&domain->geometry, geom_attr,
+	       sizeof(struct iommu_domain_geometry));
+	dma_domain->geom_size = geom_size;
+
+	spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+
+	return 0;
+}
+
+/* Set the domain stash attribute */
+static int configure_domain_stash(struct fsl_dma_domain *dma_domain, void *data)
+{
+	struct pamu_stash_attribute *stash_attr = data;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&dma_domain->domain_lock, flags);
+
+	memcpy(&dma_domain->dma_stash, stash_attr,
+		 sizeof(struct pamu_stash_attribute));
+
+	dma_domain->stash_id = get_stash_id(stash_attr->cache,
+					    stash_attr->cpu);
+	if (dma_domain->stash_id == ~(u32)0) {
+		pr_err("Invalid stash attributes\n");
+		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+		return -EINVAL;
+	}
+
+	ret = update_domain_stash(dma_domain, dma_domain->stash_id);
+
+	spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+
+	return ret;
+}
+
+/* Configure domain dma state i.e. enable/disable DMA*/
+static int configure_domain_dma_state(struct fsl_dma_domain *dma_domain, bool enable)
+{
+	struct device_domain_info *info;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&dma_domain->domain_lock, flags);
+
+	if (enable && !dma_domain->mapped) {
+		pr_err("Can't enable DMA domain without valid mapping\n");
+		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+		return -ENODEV;
+	}
+
+	dma_domain->enabled = enable;
+	list_for_each_entry(info, &dma_domain->devices,
+				 link) {
+		ret = (enable) ? pamu_enable_liodn(info->liodn) :
+			pamu_disable_liodn(info->liodn);
+		if (ret)
+			pr_err("Unable to set dma state for liodn %d",
+				 info->liodn);
+	}
+	spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+
+	return 0;
+}
+
+static int fsl_pamu_set_domain_attr(struct iommu_domain *domain,
+				 enum iommu_attr attr_type, void *data)
+{
+	struct fsl_dma_domain *dma_domain = domain->priv;
+	int ret = 0;
+
+
+	switch (attr_type) {
+	case DOMAIN_ATTR_GEOMETRY:
+		ret = configure_domain_geometry(domain, data);
+		break;
+	case DOMAIN_ATTR_PAMU_STASH:
+		ret = configure_domain_stash(dma_domain, data);
+		break;
+	case DOMAIN_ATTR_PAMU_ENABLE:
+		ret = configure_domain_dma_state(dma_domain, *(int *)data);
+		break;
+	default:
+		pr_err("Unsupported attribute type\n");
+		ret = -EINVAL;
+		break;
+	};
+
+	return ret;
+}
+
+static int fsl_pamu_get_domain_attr(struct iommu_domain *domain,
+				 enum iommu_attr attr_type, void *data)
+{
+	struct fsl_dma_domain *dma_domain = domain->priv;
+	int ret = 0;
+
+
+	switch (attr_type) {
+	case DOMAIN_ATTR_PAMU_STASH:
+		memcpy((struct pamu_stash_attribute *) data, &dma_domain->dma_stash,
+				 sizeof(struct pamu_stash_attribute));
+		break;
+	case DOMAIN_ATTR_PAMU_ENABLE:
+		*(int *)data = dma_domain->enabled;
+		break;
+	case DOMAIN_ATTR_FSL_PAMUV1:
+		*(int *)data = DOMAIN_ATTR_FSL_PAMUV1;
+		break;
+	default:
+		pr_err("Unsupported attribute type\n");
+		ret = -EINVAL;
+		break;
+	};
+
+	return ret;
+}
+
+#define REQ_ACS_FLAGS	(PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF)
+
+static struct iommu_group *get_device_iommu_group(struct device *dev)
+{
+	struct iommu_group *group;
+
+	group = iommu_group_get(dev);
+	if (!group)
+		group = iommu_group_alloc();
+
+	return group;
+}
+
+static  bool check_pci_ctl_endpt_part(struct pci_controller *pci_ctl)
+{
+	u32 version;
+
+	/* Check the PCI controller version number by readding BRR1 register */
+	version = in_be32(pci_ctl->cfg_addr + (PCI_FSL_BRR1 >> 2));
+	version &= PCI_FSL_BRR1_VER;
+	/* If PCI controller version is >= 0x204 we can partition endpoints*/
+	if (version >= 0x204)
+		return 1;
+
+	return 0;
+}
+
+static struct iommu_group *get_peer_pci_device_group(struct pci_dev *pdev)
+{
+	struct iommu_group *group = NULL;
+
+	/* check if this is the first device on the bus*/
+	if (pdev->bus_list.next == pdev->bus_list.prev) {
+		struct pci_bus *bus = pdev->bus->parent;
+		/* Traverese the parent bus list to get
+		 * pdev & dev for the sibling device.
+		 */
+		while (bus) {
+			if (!list_empty(&bus->devices)) {
+				pdev = container_of(bus->devices.next,
+					            struct pci_dev, bus_list);
+				group = iommu_group_get(&pdev->dev);
+				break;
+			} else
+				bus = bus->parent;
+		}
+	} else {
+		/*
+		 * Get the pdev & dev for the sibling device
+		 */
+		pdev = container_of(pdev->bus_list.prev,
+				    struct pci_dev, bus_list);
+		group = iommu_group_get(&pdev->dev);
+	}
+
+	return group;
+}
+
+static struct iommu_group *get_pci_device_group(struct pci_dev *pdev)
+{
+	struct iommu_group *group = NULL;
+	struct pci_dev *bridge, *dma_pdev = NULL;
+	struct pci_controller *pci_ctl;
+	bool pci_endpt_partioning;
+
+	pci_ctl = pci_bus_to_host(pdev->bus);
+	pci_endpt_partioning = check_pci_ctl_endpt_part(pci_ctl);
+	/* We can partition PCIe devices so assign device group to the device */
+	if (pci_endpt_partioning) {
+		bridge = pci_find_upstream_pcie_bridge(pdev);
+		if (bridge) {
+			if (pci_is_pcie(bridge))
+				dma_pdev = pci_get_domain_bus_and_slot(
+						pci_domain_nr(pdev->bus),
+						bridge->subordinate->number, 0);
+			if (!dma_pdev)
+				dma_pdev = pci_dev_get(bridge);
+		} else
+			dma_pdev = pci_dev_get(pdev);
+
+		/* Account for quirked devices */
+		swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev));
+
+		/*
+		 * If it's a multifunction device that does not support our
+		 * required ACS flags, add to the same group as function 0.
+		 */
+		if (dma_pdev->multifunction &&
+		    !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS))
+			swap_pci_ref(&dma_pdev,
+				     pci_get_slot(dma_pdev->bus,
+						  PCI_DEVFN(PCI_SLOT(dma_pdev->devfn),
+						  0)));
+
+		group = get_device_iommu_group(&pdev->dev);
+		pci_dev_put(pdev);
+		/*
+		 * PCIe controller is not a paritionable entity
+		 * free the controller device iommu_group.
+		 */
+		if (pci_ctl->parent->iommu_group)
+			iommu_group_remove_device(pci_ctl->parent);
+	} else {
+		/*
+		 * All devices connected to the controller will share the
+		 * PCI controllers device group. If this is the first
+		 * device to be probed for the pci controller, copy the
+		 * device group information from the PCI controller device
+		 * node and remove the PCI controller iommu group.
+		 * For subsequent devices, the iommu group information can
+		 * be obtained from sibling devices (i.e. from the bus_devices
+		 * link list).
+		 */
+		if (pci_ctl->parent->iommu_group) {
+			group = get_device_iommu_group(pci_ctl->parent);
+			iommu_group_remove_device(pci_ctl->parent);
+		} else
+			group = get_peer_pci_device_group(pdev);
+	}
+
+	return group;
+}
+
+static int fsl_pamu_add_device(struct device *dev)
+{
+	struct iommu_group *group = NULL;
+	struct pci_dev *pdev;
+	const u32 *prop;
+	int ret, len;
+
+	/*
+	 * For platform devices we allocate a separate group for
+	 * each of the devices.
+	 */
+	if (dev->bus == &pci_bus_type) {
+		pdev = to_pci_dev(dev);
+		/* Don't create device groups for virtual PCI bridges */
+		if (pdev->subordinate)
+			return 0;
+
+		group = get_pci_device_group(pdev);
+
+	} else {
+		prop = of_get_property(dev->of_node, "fsl,liodn", &len);
+		if (prop)
+			group = get_device_iommu_group(dev);
+	}
+
+	if (!group || IS_ERR(group))
+		return PTR_ERR(group);
+
+	ret = iommu_group_add_device(group, dev);
+
+	iommu_group_put(group);
+	return ret;
+}
+
+static void fsl_pamu_remove_device(struct device *dev)
+{
+	iommu_group_remove_device(dev);
+}
+
+static int fsl_pamu_set_windows(struct iommu_domain *domain, u32 w_count)
+{
+	struct fsl_dma_domain *dma_domain = domain->priv;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&dma_domain->domain_lock, flags);
+	/* Ensure domain is inactive i.e. DMA should be disabled for the domain */
+	if (dma_domain->enabled) {
+		pr_err("Can't set geometry attributes as domain is active\n");
+		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+		return  -EBUSY;
+	}
+
+	/* Ensure that the geometry has been set for the domain */
+	if (!dma_domain->geom_size) {
+		pr_err("Please configure geometry before setting the number of windows\n");
+		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+		return -EINVAL;
+	}
+
+	/*
+	 * Ensure we have valid window count i.e. it should be less than
+	 * maximum permissible limit and should be a power of two.
+	 */
+	if (w_count > pamu_get_max_subwin_cnt() || !is_power_of_2(w_count)) {
+		pr_err("Invalid window count\n");
+		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+		return -EINVAL;
+	}
+
+	ret = pamu_set_domain_geometry(dma_domain, &domain->geometry,
+				((w_count > 1) ? w_count : 0));
+	if (!ret) {
+		if (dma_domain->win_arr)
+			kfree(dma_domain->win_arr);
+		dma_domain->win_arr = kzalloc(sizeof(struct dma_window) *
+							  w_count, GFP_KERNEL);
+		if (!dma_domain->win_arr) {
+			spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+			return -ENOMEM;
+		}
+		dma_domain->win_cnt = w_count;
+	}
+	spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+
+	return ret;
+}
+
+static u32 fsl_pamu_get_windows(struct iommu_domain *domain)
+{
+	struct fsl_dma_domain *dma_domain = domain->priv;
+
+	return dma_domain->win_cnt;
+}
+
+static struct iommu_ops fsl_pamu_ops = {
+	.domain_init	= fsl_pamu_domain_init,
+	.domain_destroy = fsl_pamu_domain_destroy,
+	.attach_dev	= fsl_pamu_attach_device,
+	.detach_dev	= fsl_pamu_detach_device,
+	.domain_window_enable = fsl_pamu_window_enable,
+	.domain_window_disable = fsl_pamu_window_disable,
+	.domain_get_windows = fsl_pamu_get_windows,
+	.domain_set_windows = fsl_pamu_set_windows,
+	.iova_to_phys	= fsl_pamu_iova_to_phys,
+	.domain_has_cap = fsl_pamu_domain_has_cap,
+	.domain_set_attr = fsl_pamu_set_domain_attr,
+	.domain_get_attr = fsl_pamu_get_domain_attr,
+	.add_device	= fsl_pamu_add_device,
+	.remove_device	= fsl_pamu_remove_device,
+};
+
+int pamu_domain_init()
+{
+	int ret = 0;
+
+	ret = iommu_init_mempool();
+	if (ret)
+		return ret;
+
+	bus_set_iommu(&platform_bus_type, &fsl_pamu_ops);
+	bus_set_iommu(&pci_bus_type, &fsl_pamu_ops);
+
+	return ret;
+}
diff --git a/drivers/iommu/fsl_pamu_domain.h b/drivers/iommu/fsl_pamu_domain.h
new file mode 100644
index 0000000..c90293f
--- /dev/null
+++ b/drivers/iommu/fsl_pamu_domain.h
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ */
+
+#ifndef __FSL_PAMU_DOMAIN_H
+#define __FSL_PAMU_DOMAIN_H
+
+#include "fsl_pamu.h"
+
+struct dma_window {
+	phys_addr_t paddr;
+	u64 size;
+	int valid;
+	int prot;
+};
+
+struct fsl_dma_domain {
+	/*
+	 * Indicates the geometry size for the domain.
+	 * This would be set when the geometry is
+	 * configured for the domain.
+	 */
+	dma_addr_t			geom_size;
+	/*
+	 * Number of windows assocaited with this domain.
+	 * During domain initialization, it is set to the
+	 * the maximum number of subwindows allowed for a LIODN.
+	 * Minimum value for this is 1 indicating a single PAMU
+	 * window, without any sub windows. Value can be set/
+	 * queried by set_attr/get_attr API for DOMAIN_ATTR_WINDOWS.
+	 * Value can only be set once the geometry has been configured.
+	 */
+	u32				win_cnt;
+	/*
+	 * win_arr contains information of the configured
+	 * windows for a domain. This is allocated only
+	 * when the number of windows for the domain are
+	 * set.
+	 */
+	struct dma_window		*win_arr;
+	/* list of devices associated with the domain */
+	struct list_head		devices;
+	/* dma_domain states:
+	 * mapped - A particular mapping has been created
+	 * within the configured geometry.
+	 * enabled - DMA has been enabled for the given
+	 * domain. This translates to setting of the
+	 * valid bit for the primary PAACE in the PAMU
+	 * PAACT table. Domain geometry should be set and
+	 * it must have a valid mapping before DMA can be
+	 * enabled for it.
+	 *
+	 */
+	int				mapped;
+	int				enabled;
+	/* stash_id obtained from the stash attribute details */
+	u32				stash_id;
+	struct pamu_stash_attribute	dma_stash;
+	u32				snoop_id;
+	struct iommu_domain		*iommu_domain;
+	spinlock_t			domain_lock;
+};
+
+/* domain-device relationship */
+struct device_domain_info {
+	struct list_head link;	/* link to domain siblings */
+	struct device *dev;
+	u32 liodn;
+	struct fsl_dma_domain *domain; /* pointer to domain */
+};
+#endif  /* __FSL_PAMU_DOMAIN_H */
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH 2/3 v13] iommu/fsl: Add additional iommu attributes required by the PAMU driver.
From: Varun Sethi @ 2013-04-22  5:31 UTC (permalink / raw)
  To: joro, iommu, linuxppc-dev, linux-kernel, galak, benh,
	stuart.yoder, scottwood
  Cc: Varun Sethi
In-Reply-To: <1366608716-1704-1-git-send-email-Varun.Sethi@freescale.com>

Added the following domain attributes for the FSL PAMU driver:
1. Added new iommu stash attribute, which allows setting of the
   LIODN specific stash id parameter through IOMMU API.
2. Added an attribute for enabling/disabling DMA to a particular
   memory window.
3. Added domain attribute to check for PAMUV1 specific constraints.

Signed-off-by: Varun Sethi <Varun.Sethi@freescale.com>
---
v13 changes:
- created a new file include/linux/fsl_pamu_stash.h for stash
attributes.
v12 changes:
- Moved PAMU specifc stash ids and structures to PAMU header file.
- no change in v11.
- no change in v10.
 include/linux/fsl_pamu_stash.h |   39 +++++++++++++++++++++++++++++++++++++++
 include/linux/iommu.h          |   16 ++++++++++++++++
 2 files changed, 55 insertions(+), 0 deletions(-)
 create mode 100644 include/linux/fsl_pamu_stash.h

diff --git a/include/linux/fsl_pamu_stash.h b/include/linux/fsl_pamu_stash.h
new file mode 100644
index 0000000..caa1b21
--- /dev/null
+++ b/include/linux/fsl_pamu_stash.h
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ */
+
+#ifndef __FSL_PAMU_STASH_H
+#define __FSL_PAMU_STASH_H
+
+/* cache stash targets */
+enum pamu_stash_target {
+	PAMU_ATTR_CACHE_L1 = 1,
+	PAMU_ATTR_CACHE_L2,
+	PAMU_ATTR_CACHE_L3,
+};
+
+/*
+ * This attribute allows configuring stashig specific parameters
+ * in the PAMU hardware.
+ */
+
+struct pamu_stash_attribute {
+	u32 	cpu;	/* cpu number */
+	u32 	cache;	/* cache to stash to: L1,L2,L3 */
+};
+
+#endif  /* __FSL_PAMU_STASH_H */
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 2727810..c5dc2b9 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -57,10 +57,26 @@ struct iommu_domain {
 #define IOMMU_CAP_CACHE_COHERENCY	0x1
 #define IOMMU_CAP_INTR_REMAP		0x2	/* isolates device intrs */
 
+/*
+ * Following constraints are specifc to PAMUV1:
+ *  -aperture must be power of 2, and naturally aligned
+ *  -number of windows must be power of 2, and address space size
+ *   of each window is determined by aperture size / # of windows
+ *  -the actual size of the mapped region of a window must be power
+ *   of 2 starting with 4KB and physical address must be naturally
+ *   aligned.
+ * DOMAIN_ATTR_FSL_PAMUV1 corresponds to the above mentioned contraints.
+ * The caller can invoke iommu_domain_get_attr to check if the underlying
+ * iommu implementation supports these constraints.
+ */
+
 enum iommu_attr {
 	DOMAIN_ATTR_GEOMETRY,
 	DOMAIN_ATTR_PAGING,
 	DOMAIN_ATTR_WINDOWS,
+	DOMAIN_ATTR_PAMU_STASH,
+	DOMAIN_ATTR_PAMU_ENABLE,
+	DOMAIN_ATTR_FSL_PAMUV1,
 	DOMAIN_ATTR_MAX,
 };
 
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH 1/3 v2] iommu: Move swap_pci_ref function to pci.h.
From: Varun Sethi @ 2013-04-22  5:31 UTC (permalink / raw)
  To: joro, iommu, linuxppc-dev, linux-kernel, galak, benh,
	stuart.yoder, scottwood
  Cc: Varun Sethi

swap_pci_ref function is used by the IOMMU API code for swapping pci device
pointers, while determining the iommu group for the device.
Currently this function was being implemented for different IOMMU drivers.
This patch moves the function to a new file, drivers/iommu/pci.h so that the
implementation can be shared across various IOMMU drivers.

Signed-off-by: Varun Sethi <Varun.Sethi@freescale.com>
---
v2 changes:
- created a new file drivers/iommu/pci.h.

 drivers/iommu/amd_iommu.c   |    7 +------
 drivers/iommu/intel-iommu.c |    7 +------
 drivers/iommu/pci.h         |   29 +++++++++++++++++++++++++++++
 3 files changed, 31 insertions(+), 12 deletions(-)
 create mode 100644 drivers/iommu/pci.h

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index a7f6b04..2463464 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -46,6 +46,7 @@
 #include "amd_iommu_proto.h"
 #include "amd_iommu_types.h"
 #include "irq_remapping.h"
+#include "pci.h"
 
 #define CMD_SET_TYPE(cmd, t) ((cmd)->data[1] |= ((t) << 28))
 
@@ -263,12 +264,6 @@ static bool check_device(struct device *dev)
 	return true;
 }
 
-static void swap_pci_ref(struct pci_dev **from, struct pci_dev *to)
-{
-	pci_dev_put(*from);
-	*from = to;
-}
-
 static struct pci_bus *find_hosted_bus(struct pci_bus *bus)
 {
 	while (!bus->self) {
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 6e0b9ff..81ad7b8 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -47,6 +47,7 @@
 #include <asm/iommu.h>
 
 #include "irq_remapping.h"
+#include "pci.h"
 
 #define ROOT_SIZE		VTD_PAGE_SIZE
 #define CONTEXT_SIZE		VTD_PAGE_SIZE
@@ -4137,12 +4138,6 @@ static int intel_iommu_domain_has_cap(struct iommu_domain *domain,
 	return 0;
 }
 
-static void swap_pci_ref(struct pci_dev **from, struct pci_dev *to)
-{
-	pci_dev_put(*from);
-	*from = to;
-}
-
 #define REQ_ACS_FLAGS	(PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF)
 
 static int intel_iommu_add_device(struct device *dev)
diff --git a/drivers/iommu/pci.h b/drivers/iommu/pci.h
new file mode 100644
index 0000000..d460646
--- /dev/null
+++ b/drivers/iommu/pci.h
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright (C) 2013 Red Hat, Inc.
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ */
+#ifndef __PCI_H
+#define __PCI_H
+
+/* Helper function for swapping pci device reference */
+static inline void swap_pci_ref(struct pci_dev **from, struct pci_dev *to)
+{
+	pci_dev_put(*from);
+	*from = to;
+}
+
+#endif  /* __PCI_H */
-- 
1.7.4.1

^ permalink raw reply related

* Re: [PATCH v2 06/15] powerpc/85xx: add support to JOG feature using cpufreq interface
From: Viresh Kumar @ 2013-04-22  3:25 UTC (permalink / raw)
  To: Zhao Chenhui; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1366368468-29143-6-git-send-email-chenhui.zhao@freescale.com>

On Fri, Apr 19, 2013 at 4:17 PM, Zhao Chenhui
<chenhui.zhao@freescale.com> wrote:
> diff --git a/drivers/cpufreq/mpc85xx-cpufreq.c b/drivers/cpufreq/mpc85xx-cpufreq.c

> +#include <linux/module.h>
> +#include <linux/cpufreq.h>
> +#include <linux/of_platform.h>
> +#include <linux/suspend.h>
> +#include <linux/cpu.h>
> +#include <linux/time.h>
> +#include <linux/io.h>
> +#include <linux/smp.h>

Would be better to keep them in alphabetical order, so that we don't add
anything twice.

> +static int mpc85xx_cpufreq_cpu_init(struct cpufreq_policy *policy)
> +{
> +       unsigned int i, cur_pll;
> +       int hw_cpu = get_hard_smp_processor_id(policy->cpu);
> +
> +       if (!cpu_present(policy->cpu))

This can't happen and so no need to check it.

> +               return -ENODEV;
> +
> +       /* the latency of a transition, the unit is ns */
> +       policy->cpuinfo.transition_latency = 2000;
> +
> +       cur_pll = get_pll(hw_cpu);
> +
> +       /* initialize frequency table */
> +       pr_debug("core%d frequency table:\n", hw_cpu);
> +       for (i = 0; mpc85xx_freqs[i].frequency != CPUFREQ_TABLE_END; i++) {
> +               if (mpc85xx_freqs[i].index <= max_pll[hw_cpu]) {
> +                       /* The frequency unit is kHz. */
> +                       mpc85xx_freqs[i].frequency =
> +                               (sysfreq * mpc85xx_freqs[i].index / 2) / 1000;
> +               } else {
> +                       mpc85xx_freqs[i].frequency = CPUFREQ_ENTRY_INVALID;
> +               }
> +
> +               pr_debug("%d: %dkHz\n", i, mpc85xx_freqs[i].frequency);
> +
> +               if (mpc85xx_freqs[i].index == cur_pll)
> +                       policy->cur = mpc85xx_freqs[i].frequency;
> +       }
> +       pr_debug("current pll is at %d, and core freq is%d\n",
> +                       cur_pll, policy->cur);
> +
> +       cpufreq_frequency_table_get_attr(mpc85xx_freqs, policy->cpu);
> +
> +       /*
> +        * This ensures that policy->cpuinfo_min
> +        * and policy->cpuinfo_max are set correctly.
> +        */
> +       return cpufreq_frequency_table_cpuinfo(policy, mpc85xx_freqs);

Call cpufreq_frequency_table_get_attr() at the end after above call is
successful.

> +}

> +static int mpc85xx_cpufreq_target(struct cpufreq_policy *policy,
> +                             unsigned int target_freq,
> +                             unsigned int relation)

merge above two lines.

> +{
> +       struct cpufreq_freqs freqs;
> +       unsigned int new;
> +       int ret = 0;
> +
> +       if (!set_pll)
> +               return -ENODEV;
> +
> +       cpufreq_frequency_table_target(policy,
> +                                      mpc85xx_freqs,
> +                                      target_freq,
> +                                      relation,
> +                                      &new);

same.. merge all above to put it in a single line.

> +       freqs.old = policy->cur;
> +       freqs.new = mpc85xx_freqs[new].frequency;
> +       freqs.cpu = policy->cpu;

not required now.

> +       mutex_lock(&mpc85xx_switch_mutex);
> +       cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);

ditto. Rebase over latest code from linux-next. This call has changed.

> +       ret = set_pll(policy->cpu, mpc85xx_freqs[new].index);
> +       if (!ret) {
> +               pr_info("cpufreq: Setting core%d frequency to %d kHz and PLL ratio to %d:2\n",
> +                        policy->cpu, mpc85xx_freqs[new].frequency,
> +                        mpc85xx_freqs[new].index);
> +
> +               ppc_proc_freq = freqs.new * 1000ul;
> +       }
> +       cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
> +       mutex_unlock(&mpc85xx_switch_mutex);
> +
> +       return ret;
> +}

> +static int __init mpc85xx_jog_init(void)
> +{
> +       struct device_node *np;
> +       unsigned int svr;
> +
> +       np = of_find_matching_node(NULL, mpc85xx_jog_ids);
> +       if (!np)
> +               return -ENODEV;
> +
> +       guts = of_iomap(np, 0);
> +       if (!guts) {
> +               of_node_put(np);
> +               return -ENODEV;
> +       }
> +
> +       sysfreq = fsl_get_sys_freq();
> +
> +       if (of_device_is_compatible(np, "fsl,mpc8536-guts")) {
> +               svr = mfspr(SPRN_SVR);
> +               if ((svr & 0x7fff) == 0x10) {
> +                       pr_err("MPC8536 Rev 1.0 does not support cpufreq(JOG).\n");
> +                       of_node_put(np);

unmap too??

> +                       return -ENODEV;
> +               }
> +               mpc85xx_freqs = mpc8536_freqs_table;
> +               set_pll = mpc8536_set_pll;
> +               max_pll[0] = get_pll(0);
> +
> +       } else if (of_device_is_compatible(np, "fsl,p1022-guts")) {
> +               mpc85xx_freqs = p1022_freqs_table;
> +               set_pll = p1022_set_pll;
> +               max_pll[0] = get_pll(0);
> +               max_pll[1] = get_pll(1);
> +       }
> +
> +       pr_info("Freescale MPC85xx cpufreq(JOG) driver\n");
> +
> +       of_node_put(np);
> +       return cpufreq_register_driver(&mpc85xx_cpufreq_driver);
> +}
> +
> +device_initcall(mpc85xx_jog_init);

^ permalink raw reply

* Re: [PATCH 3/3] powerpc/powernv: Patch MSI EOI handler on P8
From: Michael Ellerman @ 2013-04-22  2:56 UTC (permalink / raw)
  To: Gavin Shan; +Cc: linuxppc-dev
In-Reply-To: <20130422014533.GA7902@shangw.(null)>

On Mon, Apr 22, 2013 at 09:45:33AM +0800, Gavin Shan wrote:
> On Mon, Apr 22, 2013 at 09:34:36AM +1000, Michael Ellerman wrote:
> >On Fri, Apr 19, 2013 at 05:32:45PM +0800, Gavin Shan wrote:
> >> The EOI handler of MSI/MSI-X interrupts for P8 (PHB3) need additional
> >> steps to handle the P/Q bits in IVE before EOIing the corresponding
> >> interrupt. The patch changes the EOI handler to cover that.
> 
> Thanks for your time to review it, Michael. By the way, I think I need
> rebase the patch since the patch fb1b55d654a7038ca6337fbf55839a308c9bc1a7
> ("Using bitmap to manage MSI") has been merged to linux-next.
> 
> >> diff --git a/arch/powerpc/sysdev/xics/icp-native.c b/arch/powerpc/sysdev/xics/icp-native.c
> >> index 48861d3..289355e 100644
> >> --- a/arch/powerpc/sysdev/xics/icp-native.c
> >> +++ b/arch/powerpc/sysdev/xics/icp-native.c
> >> @@ -27,6 +27,10 @@
> >>  #include <asm/xics.h>
> >>  #include <asm/kvm_ppc.h>
> >>  
> >> +#if defined(CONFIG_PPC_POWERNV) && defined(CONFIG_PCI_MSI)
> >> +extern int pnv_pci_msi_eoi(unsigned int hw_irq);
> >> +#endif
> >
> >You don't need to #ifdef the extern. But it should be in a header, not
> >here.
> >
> 
> Ok. I'll put it into asm/xics.h, but I want to confirm we needn't
> #ifdef when moving it to asm/xics.h?

No you don't need it #ifdef'd. It's just extra noise in the file, and
doesn't really add anything IMHO.

cheers

^ permalink raw reply

* Re: [PATCH V3 1/5] powerpc, perf: Add new BHRB related instructions for POWER8
From: Michael Neuling @ 2013-04-22  2:50 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, linux-kernel, Anshuman Khandual
In-Reply-To: <20130422024546.GA24739@concordia>

Michael Ellerman <michael@ellerman.id.au> wrote:

> On Mon, Apr 22, 2013 at 11:13:43AM +1000, Michael Neuling wrote:
> > Michael Ellerman <michael@ellerman.id.au> wrote:
> > 
> > > On Thu, Apr 18, 2013 at 05:56:12PM +0530, Anshuman Khandual wrote:
> > > > This patch adds new POWER8 instruction encoding for reading
> > > > the BHRB buffer entries and also clearing it. Encoding for
> > > > "clrbhrb" instruction is straight forward.
> > > 
> > > Which is "clear branch history rolling buffer" ?
> > > 
> > > > But "mfbhrbe"
> > > > encoding involves reading a certain index of BHRB buffer
> > > > into a particular GPR register.
> > > 
> > > And "Move from branch history rolling buffer entry" ?
> > > 
> > > > diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
> > > > index 8752bc8..93ae5a1 100644
> > > > --- a/arch/powerpc/include/asm/ppc-opcode.h
> > > > +++ b/arch/powerpc/include/asm/ppc-opcode.h
> > > > @@ -82,6 +82,7 @@
> > > >  #define	__REGA0_R31	31
> > > >  
> > > >  /* sorted alphabetically */
> > > > +#define PPC_INST_BHRBE			0x7c00025c
> > > 
> > > I don't think you really need this, just use the literal value below.
> > 
> > The rest of the defines in this file do this, so Anshuman's right. 
> 
> I don't see the point, but sure let's be consistent. Though in that case
> he should do the same for PPC_CLRBHRB below.

Agreed.

Mikey

> 
> > > > @@ -297,6 +298,12 @@
> > > >  #define PPC_NAP			stringify_in_c(.long PPC_INST_NAP)
> > > >  #define PPC_SLEEP		stringify_in_c(.long PPC_INST_SLEEP)
> > > >  
> > > > +/* BHRB instructions */
> > > > +#define PPC_CLRBHRB		stringify_in_c(.long 0x7c00035c)
> > > > +#define PPC_MFBHRBE(r, n)	stringify_in_c(.long PPC_INST_BHRBE | \
> > > > +						__PPC_RS(r) | \
> > > > +							(((n) & 0x1f) << 11))
> > > 
> > > Why are you not using ___PPC_RB(n) here ?
> > 
> > Actually, this is wrong.  The number field should be 10 bits (0x3ff),
> > not 5 (0x1f)  Anshuman please fix.
> 
> ACK.
> 
> cheers
> 

^ permalink raw reply

* Re: [PATCH V3 1/5] powerpc, perf: Add new BHRB related instructions for POWER8
From: Michael Ellerman @ 2013-04-22  2:45 UTC (permalink / raw)
  To: Michael Neuling; +Cc: linuxppc-dev, linux-kernel, Anshuman Khandual
In-Reply-To: <14010.1366593223@ale.ozlabs.ibm.com>

On Mon, Apr 22, 2013 at 11:13:43AM +1000, Michael Neuling wrote:
> Michael Ellerman <michael@ellerman.id.au> wrote:
> 
> > On Thu, Apr 18, 2013 at 05:56:12PM +0530, Anshuman Khandual wrote:
> > > This patch adds new POWER8 instruction encoding for reading
> > > the BHRB buffer entries and also clearing it. Encoding for
> > > "clrbhrb" instruction is straight forward.
> > 
> > Which is "clear branch history rolling buffer" ?
> > 
> > > But "mfbhrbe"
> > > encoding involves reading a certain index of BHRB buffer
> > > into a particular GPR register.
> > 
> > And "Move from branch history rolling buffer entry" ?
> > 
> > > diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
> > > index 8752bc8..93ae5a1 100644
> > > --- a/arch/powerpc/include/asm/ppc-opcode.h
> > > +++ b/arch/powerpc/include/asm/ppc-opcode.h
> > > @@ -82,6 +82,7 @@
> > >  #define	__REGA0_R31	31
> > >  
> > >  /* sorted alphabetically */
> > > +#define PPC_INST_BHRBE			0x7c00025c
> > 
> > I don't think you really need this, just use the literal value below.
> 
> The rest of the defines in this file do this, so Anshuman's right. 

I don't see the point, but sure let's be consistent. Though in that case
he should do the same for PPC_CLRBHRB below.

> > > @@ -297,6 +298,12 @@
> > >  #define PPC_NAP			stringify_in_c(.long PPC_INST_NAP)
> > >  #define PPC_SLEEP		stringify_in_c(.long PPC_INST_SLEEP)
> > >  
> > > +/* BHRB instructions */
> > > +#define PPC_CLRBHRB		stringify_in_c(.long 0x7c00035c)
> > > +#define PPC_MFBHRBE(r, n)	stringify_in_c(.long PPC_INST_BHRBE | \
> > > +						__PPC_RS(r) | \
> > > +							(((n) & 0x1f) << 11))
> > 
> > Why are you not using ___PPC_RB(n) here ?
> 
> Actually, this is wrong.  The number field should be 10 bits (0x3ff),
> not 5 (0x1f)  Anshuman please fix.

ACK.

cheers

^ permalink raw reply

* [PATCH 1/5] ibmebus: convert of_platform_driver to platform_driver
From: Rob Herring @ 2013-04-22  2:13 UTC (permalink / raw)
  To: linux-kernel, devicetree-discuss
  Cc: Roland Dreier, Arnd Bergmann, linux-rdma, Rob Herring,
	Christoph Raisch, Hoang-Nam Nguyen, Thadeu Lima de Souza Cascardo,
	netdev, Grant Likely, Paul Mackerras, Sean Hefty, linuxppc-dev,
	Hal Rosenstock
In-Reply-To: <1366596798-9457-1-git-send-email-robherring2@gmail.com>

From: Rob Herring <rob.herring@calxeda.com>

ibmebus is the last remaining user of of_platform_driver and the
conversion to a regular platform driver is trivial.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Hoang-Nam Nguyen <hnguyen@de.ibm.com>
Cc: Christoph Raisch <raisch@de.ibm.com>
Cc: Roland Dreier <roland@kernel.org>
Cc: Sean Hefty <sean.hefty@intel.com>
Cc: Hal Rosenstock <hal.rosenstock@gmail.com>
Cc: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
Cc: Grant Likely <grant.likely@linaro.org>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-rdma@vger.kernel.org
Cc: netdev@vger.kernel.org
---
 arch/powerpc/include/asm/ibmebus.h        |    4 ++--
 arch/powerpc/kernel/ibmebus.c             |   22 ++++++++++------------
 drivers/infiniband/hw/ehca/ehca_main.c    |    5 ++---
 drivers/net/ethernet/ibm/ehea/ehea_main.c |    8 +++-----
 4 files changed, 17 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/include/asm/ibmebus.h b/arch/powerpc/include/asm/ibmebus.h
index 1a9d9ae..088f95b 100644
--- a/arch/powerpc/include/asm/ibmebus.h
+++ b/arch/powerpc/include/asm/ibmebus.h
@@ -48,8 +48,8 @@
 
 extern struct bus_type ibmebus_bus_type;
 
-int ibmebus_register_driver(struct of_platform_driver *drv);
-void ibmebus_unregister_driver(struct of_platform_driver *drv);
+int ibmebus_register_driver(struct platform_driver *drv);
+void ibmebus_unregister_driver(struct platform_driver *drv);
 
 int ibmebus_request_irq(u32 ist, irq_handler_t handler,
 			unsigned long irq_flags, const char *devname,
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index 8220baa..16a7c23 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -205,7 +205,7 @@ static int ibmebus_create_devices(const struct of_device_id *matches)
 	return ret;
 }
 
-int ibmebus_register_driver(struct of_platform_driver *drv)
+int ibmebus_register_driver(struct platform_driver *drv)
 {
 	/* If the driver uses devices that ibmebus doesn't know, add them */
 	ibmebus_create_devices(drv->driver.of_match_table);
@@ -215,7 +215,7 @@ int ibmebus_register_driver(struct of_platform_driver *drv)
 }
 EXPORT_SYMBOL(ibmebus_register_driver);
 
-void ibmebus_unregister_driver(struct of_platform_driver *drv)
+void ibmebus_unregister_driver(struct platform_driver *drv)
 {
 	driver_unregister(&drv->driver);
 }
@@ -338,11 +338,10 @@ static int ibmebus_bus_bus_match(struct device *dev, struct device_driver *drv)
 static int ibmebus_bus_device_probe(struct device *dev)
 {
 	int error = -ENODEV;
-	struct of_platform_driver *drv;
+	struct platform_driver *drv;
 	struct platform_device *of_dev;
-	const struct of_device_id *match;
 
-	drv = to_of_platform_driver(dev->driver);
+	drv = to_platform_driver(dev->driver);
 	of_dev = to_platform_device(dev);
 
 	if (!drv->probe)
@@ -350,9 +349,8 @@ static int ibmebus_bus_device_probe(struct device *dev)
 
 	of_dev_get(of_dev);
 
-	match = of_match_device(drv->driver.of_match_table, dev);
-	if (match)
-		error = drv->probe(of_dev, match);
+	if (of_driver_match_device(dev, dev->driver))
+		error = drv->probe(of_dev);
 	if (error)
 		of_dev_put(of_dev);
 
@@ -362,7 +360,7 @@ static int ibmebus_bus_device_probe(struct device *dev)
 static int ibmebus_bus_device_remove(struct device *dev)
 {
 	struct platform_device *of_dev = to_platform_device(dev);
-	struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
+	struct platform_driver *drv = to_platform_driver(dev->driver);
 
 	if (dev->driver && drv->remove)
 		drv->remove(of_dev);
@@ -372,7 +370,7 @@ static int ibmebus_bus_device_remove(struct device *dev)
 static void ibmebus_bus_device_shutdown(struct device *dev)
 {
 	struct platform_device *of_dev = to_platform_device(dev);
-	struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
+	struct platform_driver *drv = to_platform_driver(dev->driver);
 
 	if (dev->driver && drv->shutdown)
 		drv->shutdown(of_dev);
@@ -419,7 +417,7 @@ struct device_attribute ibmebus_bus_device_attrs[] = {
 static int ibmebus_bus_legacy_suspend(struct device *dev, pm_message_t mesg)
 {
 	struct platform_device *of_dev = to_platform_device(dev);
-	struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
+	struct platform_driver *drv = to_platform_driver(dev->driver);
 	int ret = 0;
 
 	if (dev->driver && drv->suspend)
@@ -430,7 +428,7 @@ static int ibmebus_bus_legacy_suspend(struct device *dev, pm_message_t mesg)
 static int ibmebus_bus_legacy_resume(struct device *dev)
 {
 	struct platform_device *of_dev = to_platform_device(dev);
-	struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
+	struct platform_driver *drv = to_platform_driver(dev->driver);
 	int ret = 0;
 
 	if (dev->driver && drv->resume)
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index f8a6291..982e3ef 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -713,8 +713,7 @@ static struct attribute_group ehca_dev_attr_grp = {
 	.attrs = ehca_dev_attrs
 };
 
-static int ehca_probe(struct platform_device *dev,
-		      const struct of_device_id *id)
+static int ehca_probe(struct platform_device *dev)
 {
 	struct ehca_shca *shca;
 	const u64 *handle;
@@ -937,7 +936,7 @@ static struct of_device_id ehca_device_table[] =
 };
 MODULE_DEVICE_TABLE(of, ehca_device_table);
 
-static struct of_platform_driver ehca_driver = {
+static struct platform_driver ehca_driver = {
 	.probe       = ehca_probe,
 	.remove      = ehca_remove,
 	.driver = {
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c
index 328f47c..c6ecf70 100644
--- a/drivers/net/ethernet/ibm/ehea/ehea_main.c
+++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c
@@ -98,8 +98,7 @@ static struct ehea_fw_handle_array ehea_fw_handles;
 static struct ehea_bcmc_reg_array ehea_bcmc_regs;
 
 
-static int ehea_probe_adapter(struct platform_device *dev,
-			      const struct of_device_id *id);
+static int ehea_probe_adapter(struct platform_device *dev);
 
 static int ehea_remove(struct platform_device *dev);
 
@@ -112,7 +111,7 @@ static struct of_device_id ehea_device_table[] = {
 };
 MODULE_DEVICE_TABLE(of, ehea_device_table);
 
-static struct of_platform_driver ehea_driver = {
+static struct platform_driver ehea_driver = {
 	.driver = {
 		.name = "ehea",
 		.owner = THIS_MODULE,
@@ -3255,8 +3254,7 @@ static void ehea_remove_device_sysfs(struct platform_device *dev)
 	device_remove_file(&dev->dev, &dev_attr_remove_port);
 }
 
-static int ehea_probe_adapter(struct platform_device *dev,
-			      const struct of_device_id *id)
+static int ehea_probe_adapter(struct platform_device *dev)
 {
 	struct ehea_adapter *adapter;
 	const u64 *adapter_handle;
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 0/5] of_platform_driver and OF_DEVICE removal
From: Rob Herring @ 2013-04-22  2:13 UTC (permalink / raw)
  To: linux-kernel, devicetree-discuss
  Cc: Roland Dreier, Sean Hefty, Arnd Bergmann, Alexander Shishkin,
	linux-usb, Rob Herring, linux-rdma, Christoph Raisch,
	Hoang-Nam Nguyen, Thadeu Lima de Souza Cascardo,
	Greg Kroah-Hartman, Grant Likely, Paul Mackerras, netdev,
	linuxppc-dev, Hal Rosenstock

From: Rob Herring <rob.herring@calxeda.com>

This series is a relatively straight-forward removal of the last remaining
user of of_platform_driver (ibmebus) and removal of CONFIG_OF_DEVICE which
is always enabled when CONFIG_OF is enabled.

Compile tested on powerpc and sparc.

Rob

Rob Herring (5):
  ibmebus: convert of_platform_driver to platform_driver
  driver core: move to_platform_driver to platform_device.h
  of: remove of_platform_driver
  usb: chipidea: depend on CONFIG_OF instead of CONFIG_OF_DEVICE
  of: remove CONFIG_OF_DEVICE

 arch/powerpc/include/asm/ibmebus.h        |    4 ++--
 arch/powerpc/kernel/ibmebus.c             |   22 ++++++++++-----------
 drivers/base/platform.c                   |    3 ---
 drivers/infiniband/hw/ehca/ehca_main.c    |    5 ++---
 drivers/net/ethernet/ibm/ehea/ehea_main.c |    8 +++-----
 drivers/of/Kconfig                        |    3 ---
 drivers/of/Makefile                       |    3 +--
 drivers/usb/chipidea/Makefile             |    2 +-
 include/linux/of_device.h                 |    6 +++---
 include/linux/of_platform.h               |   30 +----------------------------
 include/linux/platform_device.h           |    3 +++
 11 files changed, 26 insertions(+), 63 deletions(-)

-- 
1.7.10.4

^ permalink raw reply

* Re: [PATCH 3/3] powerpc/powernv: Patch MSI EOI handler on P8
From: Gavin Shan @ 2013-04-22  1:45 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, Gavin Shan
In-Reply-To: <20130421233436.GB22246@concordia>

On Mon, Apr 22, 2013 at 09:34:36AM +1000, Michael Ellerman wrote:
>On Fri, Apr 19, 2013 at 05:32:45PM +0800, Gavin Shan wrote:
>> The EOI handler of MSI/MSI-X interrupts for P8 (PHB3) need additional
>> steps to handle the P/Q bits in IVE before EOIing the corresponding
>> interrupt. The patch changes the EOI handler to cover that.

Thanks for your time to review it, Michael. By the way, I think I need
rebase the patch since the patch fb1b55d654a7038ca6337fbf55839a308c9bc1a7
("Using bitmap to manage MSI") has been merged to linux-next.

>> diff --git a/arch/powerpc/sysdev/xics/icp-native.c b/arch/powerpc/sysdev/xics/icp-native.c
>> index 48861d3..289355e 100644
>> --- a/arch/powerpc/sysdev/xics/icp-native.c
>> +++ b/arch/powerpc/sysdev/xics/icp-native.c
>> @@ -27,6 +27,10 @@
>>  #include <asm/xics.h>
>>  #include <asm/kvm_ppc.h>
>>  
>> +#if defined(CONFIG_PPC_POWERNV) && defined(CONFIG_PCI_MSI)
>> +extern int pnv_pci_msi_eoi(unsigned int hw_irq);
>> +#endif
>
>You don't need to #ifdef the extern. But it should be in a header, not
>here.
>

Ok. I'll put it into asm/xics.h, but I want to confirm we needn't
#ifdef when moving it to asm/xics.h?

>> @@ -89,6 +93,24 @@ static void icp_native_eoi(struct irq_data *d)
>>  	icp_native_set_xirr((xics_pop_cppr() << 24) | hw_irq);
>>  }
>>  
>> +static void icp_p8_native_eoi(struct irq_data *d)
>> +{
>> +	unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
>> +	int ret;
>> +
>> +	/* Let firmware handle P/Q bits */
>> +#if defined(CONFIG_PPC_POWERNV) && defined(CONFIG_PCI_MSI)
>> +	if (hw_irq != XICS_IPI) {
>> +		ret = pnv_pci_msi_eoi(hw_irq);
>> +		WARN_ON_ONCE(ret);
>> +	}
>> +#endif
>
>Why the ifdef in here? You only ever hook this function up if those are
>true, so why do you need to check them again?
>

Right. I will remove #ifdef here in next version.

>> @@ -296,6 +318,15 @@ int __init icp_native_init(void)
>>  	if (found == 0)
>>  		return -ENODEV;
>>  
>> +	/* Change the EOI handler for P8 */
>> +#if defined(CONFIG_PPC_POWERNV) && defined(CONFIG_PCI_MSI)
>
>This would be neater if you created CONFIG_POWERNV_MSI, like we have
>CONFIG_PSERIES_MSI.
>

Sure. I'll introduce CONFIG_PSERIES_MSI in next version.

Thanks,
Gavin

^ permalink raw reply

* Re: [PATCH V3 1/5] powerpc, perf: Add new BHRB related instructions for POWER8
From: Michael Neuling @ 2013-04-22  1:13 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, linux-kernel, Anshuman Khandual
In-Reply-To: <20130421234109.GC22246@concordia>

Michael Ellerman <michael@ellerman.id.au> wrote:

> On Thu, Apr 18, 2013 at 05:56:12PM +0530, Anshuman Khandual wrote:
> > This patch adds new POWER8 instruction encoding for reading
> > the BHRB buffer entries and also clearing it. Encoding for
> > "clrbhrb" instruction is straight forward.
> 
> Which is "clear branch history rolling buffer" ?
> 
> > But "mfbhrbe"
> > encoding involves reading a certain index of BHRB buffer
> > into a particular GPR register.
> 
> And "Move from branch history rolling buffer entry" ?
> 
> > diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
> > index 8752bc8..93ae5a1 100644
> > --- a/arch/powerpc/include/asm/ppc-opcode.h
> > +++ b/arch/powerpc/include/asm/ppc-opcode.h
> > @@ -82,6 +82,7 @@
> >  #define	__REGA0_R31	31
> >  
> >  /* sorted alphabetically */
> > +#define PPC_INST_BHRBE			0x7c00025c
> 
> I don't think you really need this, just use the literal value below.

The rest of the defines in this file do this, so Anshuman's right. 

> > @@ -297,6 +298,12 @@
> >  #define PPC_NAP			stringify_in_c(.long PPC_INST_NAP)
> >  #define PPC_SLEEP		stringify_in_c(.long PPC_INST_SLEEP)
> >  
> > +/* BHRB instructions */
> > +#define PPC_CLRBHRB		stringify_in_c(.long 0x7c00035c)
> > +#define PPC_MFBHRBE(r, n)	stringify_in_c(.long PPC_INST_BHRBE | \
> > +						__PPC_RS(r) | \
> > +							(((n) & 0x1f) << 11))
> 
> Why are you not using ___PPC_RB(n) here ?

Actually, this is wrong.  The number field should be 10 bits (0x3ff),
not 5 (0x1f)  Anshuman please fix.  

Mikey

^ permalink raw reply

* Re: [PATCH V3 1/5] powerpc, perf: Add new BHRB related instructions for POWER8
From: Michael Ellerman @ 2013-04-21 23:41 UTC (permalink / raw)
  To: Anshuman Khandual; +Cc: linuxppc-dev, mikey, linux-kernel
In-Reply-To: <1366287976-3900-2-git-send-email-khandual@linux.vnet.ibm.com>

On Thu, Apr 18, 2013 at 05:56:12PM +0530, Anshuman Khandual wrote:
> This patch adds new POWER8 instruction encoding for reading
> the BHRB buffer entries and also clearing it. Encoding for
> "clrbhrb" instruction is straight forward.

Which is "clear branch history rolling buffer" ?

> But "mfbhrbe"
> encoding involves reading a certain index of BHRB buffer
> into a particular GPR register.

And "Move from branch history rolling buffer entry" ?

> diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
> index 8752bc8..93ae5a1 100644
> --- a/arch/powerpc/include/asm/ppc-opcode.h
> +++ b/arch/powerpc/include/asm/ppc-opcode.h
> @@ -82,6 +82,7 @@
>  #define	__REGA0_R31	31
>  
>  /* sorted alphabetically */
> +#define PPC_INST_BHRBE			0x7c00025c

I don't think you really need this, just use the literal value below.

> @@ -297,6 +298,12 @@
>  #define PPC_NAP			stringify_in_c(.long PPC_INST_NAP)
>  #define PPC_SLEEP		stringify_in_c(.long PPC_INST_SLEEP)
>  
> +/* BHRB instructions */
> +#define PPC_CLRBHRB		stringify_in_c(.long 0x7c00035c)
> +#define PPC_MFBHRBE(r, n)	stringify_in_c(.long PPC_INST_BHRBE | \
> +						__PPC_RS(r) | \
> +							(((n) & 0x1f) << 11))

Why are you not using ___PPC_RB(n) here ?

cheers

^ permalink raw reply

* Re: [PATCH v2 06/15] powerpc/85xx: add support to JOG feature using cpufreq interface
From: Rafael J. Wysocki @ 2013-04-21 23:43 UTC (permalink / raw)
  To: Zhao Chenhui; +Cc: linuxppc-dev, cpufreq, linux-pm
In-Reply-To: <20130419110057.GC29421@localhost.localdomain>

On Friday, April 19, 2013 07:00:57 PM Zhao Chenhui wrote:
> ----- Forwarded message from Zhao Chenhui <chenhui.zhao@freescale.com> -----
> 
> Date: Fri, 19 Apr 2013 18:47:39 +0800
> From: Zhao Chenhui <chenhui.zhao@freescale.com>
> To: linuxppc-dev@lists.ozlabs.org
> CC: linux-kernel@vger.kernel.org
> Subject: [linuxppc-release] [PATCH v2 06/15] powerpc/85xx: add support to JOG feature using cpufreq interface
> X-Mailer: git-send-email 1.7.3
> 
> From: chenhui zhao <chenhui.zhao@freescale.com>
> 
> Some 85xx silicons like MPC8536 and P1022 have a JOG feature, which provides
> a dynamic mechanism to lower or raise the CPU core clock at runtime.
> 
> This patch adds the support to change CPU frequency using the standard
> cpufreq interface. The ratio CORE to CCB can be 1:1(except MPC8536), 3:2,
> 2:1, 5:2, 3:1, 7:2 and 4:1.
> 
> Two CPU cores on P1022 must not in the low power state during the frequency
> transition. The driver uses a atomic counter to meet the requirement.
> 
> The jog mode frequency transition process on the MPC8536 is similar to
> the deep sleep process. The driver need save the CPU state and restore
> it after CPU warm reset.
> 
> Note:
>  * The I/O peripherals such as PCIe and eTSEC may lose packets during
>    the jog mode frequency transition.
>  * The driver doesn't support MPC8536 Rev 1.0 due to a JOG erratum.
>    Subsequent revisions of MPC8536 have corrected the erratum.
> 
> Signed-off-by: Dave Liu <daveliu@freescale.com>
> Signed-off-by: Li Yang <leoli@freescale.com>
> Signed-off-by: Jerry Huang <Chang-Ming.Huang@freescale.com>
> Signed-off-by: Zhao Chenhui <chenhui.zhao@freescale.com>
> CC: Scott Wood <scottwood@freescale.com>

Well, I'd like someone from the PowerPC camp to comment on this before I take it.

Thanks,
Rafael


> ---
>  arch/powerpc/platforms/85xx/Makefile |    1 +
>  drivers/cpufreq/Kconfig.powerpc      |   10 +
>  drivers/cpufreq/Makefile             |    1 +
>  drivers/cpufreq/mpc85xx-cpufreq.c    |  390 ++++++++++++++++++++++++++++++++++
>  4 files changed, 402 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/cpufreq/mpc85xx-cpufreq.c
> 
> diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
> index a35bab7..da53bde 100644
> --- a/arch/powerpc/platforms/85xx/Makefile
> +++ b/arch/powerpc/platforms/85xx/Makefile
> @@ -3,6 +3,7 @@
>  #
>  obj-$(CONFIG_SMP) += smp.o
>  obj-$(CONFIG_FSL_PMC)	+= sleep.o
> +obj-$(CONFIG_CPU_FREQ_MPC85xx)	+= sleep.o
>  
>  obj-y += common.o
>  
> diff --git a/drivers/cpufreq/Kconfig.powerpc b/drivers/cpufreq/Kconfig.powerpc
> index e76992f..ba06a00 100644
> --- a/drivers/cpufreq/Kconfig.powerpc
> +++ b/drivers/cpufreq/Kconfig.powerpc
> @@ -5,3 +5,13 @@ config CPU_FREQ_MAPLE
>  	help
>  	  This adds support for frequency switching on Maple 970FX
>  	  Evaluation Board and compatible boards (IBM JS2x blades).
> +
> +config CPU_FREQ_MPC85xx
> +	bool "Support for Freescale MPC85xx CPU freq"
> +	depends on PPC_85xx && PPC32 && !PPC_E500MC
> +	select CPU_FREQ_TABLE
> +	help
> +	  This adds support for dynamic frequency switching on
> +	  Freescale MPC85xx by cpufreq interface. MPC8536 and P1022
> +	  have a JOG feature, which provides a dynamic mechanism
> +	  to lower or raise the CPU core clock at runtime.
> diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
> index 863fd18..e7aecc5 100644
> --- a/drivers/cpufreq/Makefile
> +++ b/drivers/cpufreq/Makefile
> @@ -61,3 +61,4 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)		+= imx6q-cpufreq.o
>  ##################################################################################
>  # PowerPC platform drivers
>  obj-$(CONFIG_CPU_FREQ_MAPLE)		+= maple-cpufreq.o
> +obj-$(CONFIG_CPU_FREQ_MPC85xx)		+= mpc85xx-cpufreq.o
> diff --git a/drivers/cpufreq/mpc85xx-cpufreq.c b/drivers/cpufreq/mpc85xx-cpufreq.c
> new file mode 100644
> index 0000000..f56c826
> --- /dev/null
> +++ b/drivers/cpufreq/mpc85xx-cpufreq.c
> @@ -0,0 +1,390 @@
> +/*
> + * Copyright (C) 2008-2012 Freescale Semiconductor, Inc.
> + * Author: Dave Liu <daveliu@freescale.com>
> + * Modifier: Chenhui Zhao <chenhui.zhao@freescale.com>
> + *
> + * The cpufreq driver is for Freescale 85xx processor,
> + * based on arch/powerpc/platforms/cell/cbe_cpufreq.c
> + * (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007
> + *	Christian Krafft <krafft@de.ibm.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2, or (at your option)
> + * any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/cpufreq.h>
> +#include <linux/of_platform.h>
> +#include <linux/suspend.h>
> +#include <linux/cpu.h>
> +#include <linux/time.h>
> +#include <linux/io.h>
> +#include <linux/smp.h>
> +
> +#include <asm/prom.h>
> +#include <asm/reg.h>
> +#include <asm/machdep.h>
> +
> +#include <sysdev/fsl_soc.h>
> +
> +static DEFINE_MUTEX(mpc85xx_switch_mutex);
> +static void __iomem *guts;
> +
> +static u32 sysfreq;
> +static unsigned int max_pll[2];
> +static atomic_t in_jog_process;
> +static struct cpufreq_frequency_table *mpc85xx_freqs;
> +static int (*set_pll)(unsigned int cpu, unsigned int pll);
> +
> +static struct cpufreq_frequency_table mpc8536_freqs_table[] = {
> +	{3,	0},
> +	{4,	0},
> +	{5,	0},
> +	{6,	0},
> +	{7,	0},
> +	{8,	0},
> +	{0,	CPUFREQ_TABLE_END},
> +};
> +
> +static struct cpufreq_frequency_table p1022_freqs_table[] = {
> +	{2,	0},
> +	{3,	0},
> +	{4,	0},
> +	{5,	0},
> +	{6,	0},
> +	{7,	0},
> +	{8,	0},
> +	{0,	CPUFREQ_TABLE_END},
> +};
> +
> +#define FREQ_500MHz	500000000
> +#define FREQ_800MHz	800000000
> +
> +#define CORE_RATIO_STRIDE	8
> +#define CORE_RATIO_MASK		0x3f
> +#define CORE_RATIO_SHIFT	16
> +
> +#define PORPLLSR	0x0	/* Power-On Reset PLL ratio status register */
> +
> +#define PMJCR		0x7c	/* Power Management Jog Control Register */
> +#define PMJCR_CORE0_SPD	0x00001000
> +#define PMJCR_CORE_SPD	0x00002000
> +
> +#define POWMGTCSR	0x80 /* Power management control and status register */
> +#define POWMGTCSR_JOG		0x00200000
> +#define POWMGTCSR_INT_MASK	0x00000f00
> +
> +static void spin_while_jogging(void *dummy)
> +{
> +	unsigned long flags;
> +
> +	local_irq_save(flags);
> +
> +	atomic_inc(&in_jog_process);
> +
> +	while (atomic_read(&in_jog_process) != 0)
> +		barrier();
> +
> +	local_irq_restore(flags);
> +}
> +
> +static int get_pll(int hw_cpu)
> +{
> +	int shift;
> +	u32 val = in_be32(guts + PORPLLSR);
> +
> +	shift = hw_cpu * CORE_RATIO_STRIDE + CORE_RATIO_SHIFT;
> +
> +	return (val >> shift) & CORE_RATIO_MASK;
> +}
> +
> +static int mpc8536_set_pll(unsigned int cpu, unsigned int pll)
> +{
> +	u32 corefreq, val, mask;
> +	unsigned int cur_pll = get_pll(0);
> +	unsigned long flags;
> +
> +	if (pll == cur_pll)
> +		return 0;
> +
> +	val = (pll & CORE_RATIO_MASK) << CORE_RATIO_SHIFT;
> +
> +	corefreq = sysfreq * pll / 2;
> +	/*
> +	 * Set the COREx_SPD bit if the requested core frequency
> +	 * is larger than the threshold frequency.
> +	 */
> +	if (corefreq > FREQ_800MHz)
> +			val |= PMJCR_CORE_SPD;
> +
> +	mask = (CORE_RATIO_MASK << CORE_RATIO_SHIFT) | PMJCR_CORE_SPD;
> +	clrsetbits_be32(guts + PMJCR, mask, val);
> +
> +	/* readback to sync write */
> +	in_be32(guts + PMJCR);
> +
> +	local_irq_save(flags);
> +	mpc85xx_enter_deep_sleep(get_immrbase(), POWMGTCSR_JOG);
> +	local_irq_restore(flags);
> +
> +	/* verify */
> +	cur_pll =  get_pll(0);
> +	if (cur_pll != pll) {
> +		pr_err("%s: error. The current PLL is %d instead of %d.\n",
> +				__func__, cur_pll, pll);
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +static int p1022_set_pll(unsigned int cpu, unsigned int pll)
> +{
> +	int index, hw_cpu = get_hard_smp_processor_id(cpu);
> +	int shift;
> +	u32 corefreq, val, mask = 0;
> +	unsigned int cur_pll = get_pll(hw_cpu);
> +	unsigned long flags;
> +	int ret = 0;
> +
> +	if (pll == cur_pll)
> +		return 0;
> +
> +	shift = hw_cpu * CORE_RATIO_STRIDE + CORE_RATIO_SHIFT;
> +	val = (pll & CORE_RATIO_MASK) << shift;
> +
> +	corefreq = sysfreq * pll / 2;
> +	/*
> +	 * Set the COREx_SPD bit if the requested core frequency
> +	 * is larger than the threshold frequency.
> +	 */
> +	if (corefreq > FREQ_500MHz)
> +		val |= PMJCR_CORE0_SPD << hw_cpu;
> +
> +	mask = (CORE_RATIO_MASK << shift) | (PMJCR_CORE0_SPD << hw_cpu);
> +	clrsetbits_be32(guts + PMJCR, mask, val);
> +
> +	/* readback to sync write */
> +	in_be32(guts + PMJCR);
> +
> +	get_online_cpus();
> +	/*
> +	 * A Jog request can not be asserted when any core is in a low
> +	 * power state on P1022. Before executing a jog request, any
> +	 * core which is in a low power state must be waked by a
> +	 * interrupt, and keep waking up until the sequence is
> +	 * finished.
> +	 */
> +	for_each_present_cpu(index) {
> +		if (!cpu_online(index)) {
> +			put_online_cpus();
> +			pr_err("%s: error, core%d is down.\n", __func__, index);
> +			return -1;
> +		}
> +	}
> +
> +	atomic_set(&in_jog_process, 0);
> +	smp_call_function(spin_while_jogging, NULL, 0);
> +
> +	local_irq_save(flags);
> +
> +	/* Wait for the other core to wake. */
> +	if (!spin_event_timeout(atomic_read(&in_jog_process) == 1, 1000, 100)) {
> +		pr_err("%s: timeout, the other core is not at running state.\n",
> +					__func__);
> +		ret = -1;
> +		goto err;
> +	}
> +
> +	out_be32(guts + POWMGTCSR, POWMGTCSR_JOG | POWMGTCSR_INT_MASK);
> +
> +	if (!spin_event_timeout(
> +		(in_be32(guts + POWMGTCSR) & POWMGTCSR_JOG) == 0, 1000, 100)) {
> +		pr_err("%s: timeout, fail to switch the core frequency.\n",
> +				__func__);
> +		ret = -1;
> +		goto err;
> +	}
> +
> +	clrbits32(guts + POWMGTCSR, POWMGTCSR_INT_MASK);
> +	in_be32(guts + POWMGTCSR);
> +
> +	atomic_set(&in_jog_process, 0);
> +err:
> +	local_irq_restore(flags);
> +	put_online_cpus();
> +
> +	/* verify */
> +	cur_pll =  get_pll(hw_cpu);
> +	if (cur_pll != pll) {
> +		pr_err("%s: error, the current PLL of core %d is %d instead of %d.\n",
> +				__func__, hw_cpu, cur_pll, pll);
> +		return -1;
> +	}
> +
> +	return ret;
> +}
> +
> +/*
> + * cpufreq functions
> + */
> +static int mpc85xx_cpufreq_cpu_init(struct cpufreq_policy *policy)
> +{
> +	unsigned int i, cur_pll;
> +	int hw_cpu = get_hard_smp_processor_id(policy->cpu);
> +
> +	if (!cpu_present(policy->cpu))
> +		return -ENODEV;
> +
> +	/* the latency of a transition, the unit is ns */
> +	policy->cpuinfo.transition_latency = 2000;
> +
> +	cur_pll = get_pll(hw_cpu);
> +
> +	/* initialize frequency table */
> +	pr_debug("core%d frequency table:\n", hw_cpu);
> +	for (i = 0; mpc85xx_freqs[i].frequency != CPUFREQ_TABLE_END; i++) {
> +		if (mpc85xx_freqs[i].index <= max_pll[hw_cpu]) {
> +			/* The frequency unit is kHz. */
> +			mpc85xx_freqs[i].frequency =
> +				(sysfreq * mpc85xx_freqs[i].index / 2) / 1000;
> +		} else {
> +			mpc85xx_freqs[i].frequency = CPUFREQ_ENTRY_INVALID;
> +		}
> +
> +		pr_debug("%d: %dkHz\n", i, mpc85xx_freqs[i].frequency);
> +
> +		if (mpc85xx_freqs[i].index == cur_pll)
> +			policy->cur = mpc85xx_freqs[i].frequency;
> +	}
> +	pr_debug("current pll is at %d, and core freq is%d\n",
> +			cur_pll, policy->cur);
> +
> +	cpufreq_frequency_table_get_attr(mpc85xx_freqs, policy->cpu);
> +
> +	/*
> +	 * This ensures that policy->cpuinfo_min
> +	 * and policy->cpuinfo_max are set correctly.
> +	 */
> +	return cpufreq_frequency_table_cpuinfo(policy, mpc85xx_freqs);
> +}
> +
> +static int mpc85xx_cpufreq_cpu_exit(struct cpufreq_policy *policy)
> +{
> +	cpufreq_frequency_table_put_attr(policy->cpu);
> +
> +	return 0;
> +}
> +
> +static int mpc85xx_cpufreq_verify(struct cpufreq_policy *policy)
> +{
> +	return cpufreq_frequency_table_verify(policy, mpc85xx_freqs);
> +}
> +
> +static int mpc85xx_cpufreq_target(struct cpufreq_policy *policy,
> +			      unsigned int target_freq,
> +			      unsigned int relation)
> +{
> +	struct cpufreq_freqs freqs;
> +	unsigned int new;
> +	int ret = 0;
> +
> +	if (!set_pll)
> +		return -ENODEV;
> +
> +	cpufreq_frequency_table_target(policy,
> +				       mpc85xx_freqs,
> +				       target_freq,
> +				       relation,
> +				       &new);
> +
> +	freqs.old = policy->cur;
> +	freqs.new = mpc85xx_freqs[new].frequency;
> +	freqs.cpu = policy->cpu;
> +
> +	mutex_lock(&mpc85xx_switch_mutex);
> +	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
> +
> +	ret = set_pll(policy->cpu, mpc85xx_freqs[new].index);
> +	if (!ret) {
> +		pr_info("cpufreq: Setting core%d frequency to %d kHz and PLL ratio to %d:2\n",
> +			 policy->cpu, mpc85xx_freqs[new].frequency,
> +			 mpc85xx_freqs[new].index);
> +
> +		ppc_proc_freq = freqs.new * 1000ul;
> +	}
> +	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
> +	mutex_unlock(&mpc85xx_switch_mutex);
> +
> +	return ret;
> +}
> +
> +static struct cpufreq_driver mpc85xx_cpufreq_driver = {
> +	.verify		= mpc85xx_cpufreq_verify,
> +	.target		= mpc85xx_cpufreq_target,
> +	.init		= mpc85xx_cpufreq_cpu_init,
> +	.exit		= mpc85xx_cpufreq_cpu_exit,
> +	.name		= "mpc85xx-JOG",
> +	.owner		= THIS_MODULE,
> +	.flags		= CPUFREQ_CONST_LOOPS,
> +};
> +
> +static struct of_device_id mpc85xx_jog_ids[] = {
> +	{ .compatible = "fsl,mpc8536-guts", },
> +	{ .compatible = "fsl,p1022-guts", },
> +	{}
> +};
> +
> +static int __init mpc85xx_jog_init(void)
> +{
> +	struct device_node *np;
> +	unsigned int svr;
> +
> +	np = of_find_matching_node(NULL, mpc85xx_jog_ids);
> +	if (!np)
> +		return -ENODEV;
> +
> +	guts = of_iomap(np, 0);
> +	if (!guts) {
> +		of_node_put(np);
> +		return -ENODEV;
> +	}
> +
> +	sysfreq = fsl_get_sys_freq();
> +
> +	if (of_device_is_compatible(np, "fsl,mpc8536-guts")) {
> +		svr = mfspr(SPRN_SVR);
> +		if ((svr & 0x7fff) == 0x10) {
> +			pr_err("MPC8536 Rev 1.0 does not support cpufreq(JOG).\n");
> +			of_node_put(np);
> +			return -ENODEV;
> +		}
> +		mpc85xx_freqs = mpc8536_freqs_table;
> +		set_pll = mpc8536_set_pll;
> +		max_pll[0] = get_pll(0);
> +
> +	} else if (of_device_is_compatible(np, "fsl,p1022-guts")) {
> +		mpc85xx_freqs = p1022_freqs_table;
> +		set_pll = p1022_set_pll;
> +		max_pll[0] = get_pll(0);
> +		max_pll[1] = get_pll(1);
> +	}
> +
> +	pr_info("Freescale MPC85xx cpufreq(JOG) driver\n");
> +
> +	of_node_put(np);
> +	return cpufreq_register_driver(&mpc85xx_cpufreq_driver);
> +}
> +
> +device_initcall(mpc85xx_jog_init);
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply

* Re: [PATCH 3/3] powerpc/powernv: Patch MSI EOI handler on P8
From: Michael Ellerman @ 2013-04-21 23:34 UTC (permalink / raw)
  To: Gavin Shan; +Cc: linuxppc-dev
In-Reply-To: <1366363965-23281-3-git-send-email-shangw@linux.vnet.ibm.com>

On Fri, Apr 19, 2013 at 05:32:45PM +0800, Gavin Shan wrote:
> The EOI handler of MSI/MSI-X interrupts for P8 (PHB3) need additional
> steps to handle the P/Q bits in IVE before EOIing the corresponding
> interrupt. The patch changes the EOI handler to cover that.

> diff --git a/arch/powerpc/sysdev/xics/icp-native.c b/arch/powerpc/sysdev/xics/icp-native.c
> index 48861d3..289355e 100644
> --- a/arch/powerpc/sysdev/xics/icp-native.c
> +++ b/arch/powerpc/sysdev/xics/icp-native.c
> @@ -27,6 +27,10 @@
>  #include <asm/xics.h>
>  #include <asm/kvm_ppc.h>
>  
> +#if defined(CONFIG_PPC_POWERNV) && defined(CONFIG_PCI_MSI)
> +extern int pnv_pci_msi_eoi(unsigned int hw_irq);
> +#endif

You don't need to #ifdef the extern. But it should be in a header, not
here.

> @@ -89,6 +93,24 @@ static void icp_native_eoi(struct irq_data *d)
>  	icp_native_set_xirr((xics_pop_cppr() << 24) | hw_irq);
>  }
>  
> +static void icp_p8_native_eoi(struct irq_data *d)
> +{
> +	unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
> +	int ret;
> +
> +	/* Let firmware handle P/Q bits */
> +#if defined(CONFIG_PPC_POWERNV) && defined(CONFIG_PCI_MSI)
> +	if (hw_irq != XICS_IPI) {
> +		ret = pnv_pci_msi_eoi(hw_irq);
> +		WARN_ON_ONCE(ret);
> +	}
> +#endif

Why the ifdef in here? You only ever hook this function up if those are
true, so why do you need to check them again?

> @@ -296,6 +318,15 @@ int __init icp_native_init(void)
>  	if (found == 0)
>  		return -ENODEV;
>  
> +	/* Change the EOI handler for P8 */
> +#if defined(CONFIG_PPC_POWERNV) && defined(CONFIG_PCI_MSI)

This would be neater if you created CONFIG_POWERNV_MSI, like we have
CONFIG_PSERIES_MSI.

cheers

^ permalink raw reply

* Re: [PATCH RESEND] powerpc/rtas_flash: Free kmem upon module exit
From: Michael Ellerman @ 2013-04-21 23:27 UTC (permalink / raw)
  To: Vasant Hegde; +Cc: linuxppc-dev, paulus
In-Reply-To: <20130419114737.20439.54937.stgit@hegdevasant>

On Fri, Apr 19, 2013 at 05:18:09PM +0530, Vasant Hegde wrote:
> Memory allocated to flash_block_list in rtas_flash_write
> is not freed during module exit. We hit below call trace
> if we unload rtas_flash module after loading new firmware
> image and before rebooting the system.

Why the resend? Did anything change?

cheers

^ permalink raw reply

* [PATCH] ptrace/powerpc: dont flush_ptrace_hw_breakpoint() on fork()
From: Oleg Nesterov @ 2013-04-21 16:47 UTC (permalink / raw)
  To: Michael Neuling, Benjamin Herrenschmidt, Paul Mackerras
  Cc: linuxppc-dev, linux-kernel

arch_dup_task_struct() does flush_ptrace_hw_breakpoint(src), this
destroys the parent's breakpoints for no reason. We should clear
child->thread.ptrace_bps[] copied by dup_task_struct() instead.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Michael Neuling <mikey@neuling.org>

--- x/arch/powerpc/kernel/process.c
+++ x/arch/powerpc/kernel/process.c
@@ -910,10 +910,6 @@ int arch_dup_task_struct(struct task_str
 	flush_altivec_to_thread(src);
 	flush_vsx_to_thread(src);
 	flush_spe_to_thread(src);
-#ifdef CONFIG_HAVE_HW_BREAKPOINT
-	flush_ptrace_hw_breakpoint(src);
-#endif /* CONFIG_HAVE_HW_BREAKPOINT */
-
 	*dst = *src;
 	return 0;
 }
@@ -984,6 +980,10 @@ int copy_thread(unsigned long clone_flag
 	p->thread.ksp_limit = (unsigned long)task_stack_page(p) +
 				_ALIGN_UP(sizeof(struct thread_info), 16);
 
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+	p->thread.ptrace_bps[0] = NULL;
+#endif
+
 #ifdef CONFIG_PPC_STD_MMU_64
 	if (mmu_has_feature(MMU_FTR_SLB)) {
 		unsigned long sp_vsid;

^ permalink raw reply

* Re: PROBLEM: Linux 3.6.2 fails to boot on IBM Cell
From: Dennis Schridde @ 2013-04-21 12:31 UTC (permalink / raw)
  To: Grant Likely; +Cc: Thomas Gleixner, linuxppc-dev
In-Reply-To: <20121115175835.652C43E197F@localhost>


[-- Attachment #1.1: Type: text/plain, Size: 836 bytes --]

Hello all of you!

Am Donnerstag, 15. November 2012, 17:58:35 schrieb Grant Likely:
> Umm, no. Some suggestions were made so I assumed you'd try those.
> 
> Anyway, here is a real patch. Try this:
> 
> -	for_each_node(node) {
> +	for_each_online_node(node) {

I am running my 3.8.6 kernel with your patch now (will this be merged anytime 
soon?), but I still get a bunch of irq mapping failed messages.

Examples:
[    0.490734] irq: irq-93==>hwirq-0x5d mapping failed: -22
[   22.016469] irq: no irq domain found for /axon@10000000000/plb5/pciex-
utl@a00000a000004000 !

Please see attached log.

In addition I see a weird issue: All programs run on CPU 0 (cores 0+1) only, 
while CPU 1 (cores 2+3) is always idle. Could this have anything to do with 
the IRQ issue, or shall I start a new thread/report for that?

Best regards,
Dennis

[-- Attachment #1.2: blade00-dmesg.log --]
[-- Type: text/x-log, Size: 60051 bytes --]

[    0.000000] Allocated 20480 bytes for 32 pacas at c00000000fffb000
[    0.000000] Using Cell machine description
[    0.000000] Page orders: linear mapping = 24, virtual = 12, io = 12, vmemmap = 24
[    0.000000] Found initrd at 0xc000000004265000:0xc000000004c22964
[    0.000000] Found legacy serial port 0 for /axon@10000000000/plb5/plb4/opb/serial@40000200
[    0.000000]   mem=14540000200, taddr=14540000200, irq=0, clk=14745600, speed=19200
[    0.000000] Found legacy serial port 1 for /axon@10000000000/plb5/plb4/opb/serial@40000300
[    0.000000]   mem=14540000300, taddr=14540000300, irq=0, clk=14745600, speed=115200
[    0.000000] Found legacy serial port 2 for /axon@30000000000/plb5/plb4/opb/serial@40000200
[    0.000000]   mem=34540000200, taddr=34540000200, irq=0, clk=14745600, speed=-1
[    0.000000] Found legacy serial port 3 for /axon@30000000000/plb5/plb4/opb/serial@40000300
[    0.000000]   mem=34540000300, taddr=34540000300, irq=0, clk=14745600, speed=-1
[    0.000000] bootconsole [udbg0] enabled
[    0.000000] CPU maps initialized for 2 threads per core
[    0.000000]  (thread shift is 1)
[    0.000000] Freed 16384 bytes for unused pacas
[    0.000000] Starting Linux PPC64 #1 SMP Tue Apr 16 10:08:12 CEST 2013
[    0.000000] -----------------------------------------------------
[    0.000000] ppc64_pft_size                = 0x0
[    0.000000] physicalMemorySize            = 0x200000000
[    0.000000] htab_address                  = 0xc000000078000000
[    0.000000] htab_hash_mask                = 0xfffff
[    0.000000] -----------------------------------------------------
[    0.000000] Linux version 3.8.6-aufs (root@blade00) (gcc version 4.7.2 (Gentoo 4.7.2-r1 p1.5, pie-0.5.5) ) #1 SMP Tue Apr 16 10:08:12 CEST 2013
[    0.000000] *** 0000 : CF000012

[    0.000000] *** 0000 : Setup Arch
[    0.000000] [boot]0012 Setup Arch
[    0.000000] Node 0 Memory: 0x0-0x100000000
[    0.000000] Node 1 Memory: 0x100000000-0x200000000
[    0.000000] mmio NVRAM, 1020k at 0x14502000000 mapped to d000080080008000
[    0.000000] Zone ranges:
[    0.000000]   DMA      [mem 0x00000000-0x1ffffffff]
[    0.000000]   Normal   empty
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x00000000-0xffffffff]
[    0.000000]   node   1: [mem 0x100000000-0x1ffffffff]
[    0.000000] On node 0 totalpages: 1048576
[    0.000000]   DMA zone: 14336 pages used for memmap
[    0.000000]   DMA zone: 0 pages reserved
[    0.000000]   DMA zone: 1034240 pages, LIFO batch:31
[    0.000000] On node 1 totalpages: 1048576
[    0.000000]   DMA zone: 14336 pages used for memmap
[    0.000000]   DMA zone: 0 pages reserved
[    0.000000]   DMA zone: 1034240 pages, LIFO batch:31
[    0.000000] *** 0000 : CF000015

[    0.000000] *** 0000 : Setup Done
[    0.000000] [boot]0015 Setup Done
[    0.000000] PERCPU: Embedded 11 pages/cpu @c000000000800000 s14848 r0 d30208 u262144
[    0.000000] pcpu-alloc: s14848 r0 d30208 u262144 alloc=1*1048576
[    0.000000] pcpu-alloc: [0] 0 1 2 3 
[    0.000000] Built 2 zonelists in Node order, mobility grouping on.  Total pages: 2068480
[    0.000000] Policy zone: DMA
[    0.000000] Kernel command line:  ksdevice=bootif lang=  ip=eth0:dhcp root=nfs:192.168.100.1:/export/gentoo/root-ppc64 text  
[    0.000000] PID hash table entries: 4096 (order: 3, 32768 bytes)
[    0.000000] freeing bootmem node 0
[    0.000000] freeing bootmem node 1
[    0.000000] Memory: 8058732k/8388608k available (6164k kernel code, 329876k reserved, 676k data, 398k bss, 2072k init)
[    0.000000] SLUB: Genslabs=15, HWalign=128, Order=0-3, MinObjects=0, CPUs=4, Nodes=256
[    0.000000] Hierarchical RCU implementation.
[    0.000000] 	RCU restricting CPUs from NR_CPUS=32 to nr_cpu_ids=4.
[    0.000000] NR_IRQS:512 nr_irqs:512 16
[    0.000000] IIC for CPU 0 target id 0xe : /be@20000000000/interrupt-controller@508400
[    0.000000] IIC for CPU 1 target id 0xf : /be@20000000000/interrupt-controller@508400
[    0.000000] IIC for CPU 2 target id 0x1e : /be@20100000000/interrupt-controller@508400
[    0.000000] IIC for CPU 3 target id 0x1f : /be@20100000000/interrupt-controller@508400
[    0.000000] mpic: Setting up MPIC " MPIC     " version 1.2 at 0, max 4 CPUs
[    0.000000] mpic: ISU size: 128, shift: 7, mask: 7f
[    0.000000] mpic: Initializing for 128 sources
[    0.000000] /axon@10000000000/interrupt-controller: hooking up to IRQ 43
[    0.000000] mpic: Setting up MPIC " MPIC     " version 1.2 at 0, max 4 CPUs
[    0.000000] mpic: ISU size: 128, shift: 7, mask: 7f
[    0.000000] mpic: Initializing for 128 sources
[    0.000000] /axon@30000000000/interrupt-controller: hooking up to IRQ 299
[    0.000000] time_init: decrementer frequency = 26.664333 MHz
[    0.000000] time_init: processor frequency   = 3200.000000 MHz
[    0.000000] clocksource: timebase mult[2580d717] shift[24] registered
[    0.000000] clockevent: decrementer mult[6d37946] shift[32] cpu[0]
[    0.000000] Console: colour dummy device 80x25
[    0.065086] pid_max: default: 32768 minimum: 301
[    0.095333] Dentry cache hash table entries: 1048576 (order: 11, 8388608 bytes)
[    0.151126] Inode-cache hash table entries: 524288 (order: 10, 4194304 bytes)
[    0.198839] Mount-cache hash table entries: 256
[    0.227727] Brought up 4 CPUs
[    0.245016] Node 0 CPUs: 0-1
[    0.245025] Node 1 CPUs: 2-3
[    0.245668] devtmpfs: initialized
[    0.316341] NET: Registered protocol family 16
[    0.342793] iommu: node 0, dynamic window 0x0-0x80000000 fixed window 0x80000000-0x280000000
[    0.344192] IOMMU: Using strong ordering for fixed mapping
[    0.378559] IOMMU table initialized, virtual merging enabled
[    0.412058] iommu: node 1, dynamic window 0x0-0x80000000 fixed window 0x80000000-0x280000000
[    0.414287] IOMMU: Using strong ordering for fixed mapping
[    0.468866] PCI: Probing PCI hardware
[    0.490341] PCI: Probing PCI hardware done
[    0.490734] irq: irq-93==>hwirq-0x5d mapping failed: -22
[    0.522130] ------------[ cut here ]------------
[    0.549706] WARNING: at /usr/src/linux-3.8.6-aufs/kernel/irq/irqdomain.c:467
[    0.591895] Modules linked in:
[    0.610126] NIP: c0000000000bdeac LR: c0000000000bdea8 CTR: c000000000025670
[    0.652317] REGS: c0000000fe667190 TRAP: 0700   Not tainted  (3.8.6-aufs)
[    0.692940] MSR: 9000000000029032 <SF,HV,EE,ME,IR,DR,RI>  CR: 44000024  XER: 00000000
[    0.739817] SOFTE: 1
[    0.752840] TASK = c0000000fe668000[1] 'swapper/0' THREAD: c0000000fe664000 CPU: 0
GPR00: c0000000000bdea8 c0000000fe667410 c000000000699cb0 000000000000002c 
GPR04: 0000000000000000 0000000078e26d37 0000000000000008 0000000000000000 
GPR08: 0000000078eef1c4 0000000000000000 0000000000000000 0000000000000000 
GPR12: d000070000000000 c00000000fffb000 c00000000000a460 0000000000000000 
GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 
GPR20: 0000000000000000 0000000000000000 c0000000fe006078 000000000000005e 
GPR24: 0000000000000174 000000000000005d 000000000000005d c0000000fe65fc00 
GPR28: c0000000fe006060 000000000000005d c000000000643be0 000000000000005d 
[    1.119009] NIP [c0000000000bdeac] .irq_domain_associate_many+0x264/0x290
[    1.159628] LR [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290
[    1.199731] Call Trace:
[    1.214318] [c0000000fe667410] [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290 (unreliable)
[    1.269528] [c0000000fe6674e0] [c0000000000be928] .irq_create_mapping+0xc8/0x1d0
[    1.313801] [c0000000fe667580] [c0000000000bead8] .irq_create_of_mapping+0xa8/0x170
[    1.359639] [c0000000fe667630] [c000000000290c30] .irq_of_parse_and_map+0x40/0x58
[    1.404429] [c0000000fe6676c0] [c000000000290df0] .of_irq_count+0x30/0x58
[    1.445057] [c0000000fe667750] [c00000000029182c] .of_device_alloc+0x1ec/0x288
[    1.488287] [c0000000fe667850] [c00000000029191c] .of_platform_device_create_pdata+0x54/0xf8
[    1.538810] [c0000000fe6678f0] [c000000000291b04] .of_platform_bus_create+0x144/0x1e0
[    1.585687] [c0000000fe6679e0] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[    1.632564] [c0000000fe667ad0] [c000000000291d50] .of_platform_bus_probe+0xd0/0x140
[    1.678404] [c0000000fe667b70] [c0000000004109e4] .__machine_initcall_cell_cell_publish_devices+0x54/0x1b0
[    1.736219] [c0000000fe667c40] [c000000000009e70] .do_one_initcall+0x168/0x1d0
[    1.779445] [c0000000fe667d00] [c0000000003ffb6c] .kernel_init_freeable+0x14c/0x21c
[    1.825281] [c0000000fe667db0] [c00000000000a47c] .kernel_init+0x1c/0x108
[    1.865907] [c0000000fe667e30] [c000000000008cd8] .ret_from_kernel_thread+0x64/0x8c
[    1.911738] Instruction dump:
[    1.929448] 7fa4eb78 7ca507b4 4828c965 60000000 0fe00000 3860ffea 4bffff80 e87e8020 
[    1.975803] 7fa4eb78 7fe5fb78 4828c945 60000000 <0fe00000> 39200000 7f83e378 7f44d378 
[    2.023213] ---[ end trace 093b23e74665976f ]---
[    2.051302] irq: irq-59==>hwirq-0x3b mapping failed: -22
[    2.082642] ------------[ cut here ]------------
[    2.110236] WARNING: at /usr/src/linux-3.8.6-aufs/kernel/irq/irqdomain.c:467
[    2.152425] Modules linked in:
[    2.170657] NIP: c0000000000bdeac LR: c0000000000bdea8 CTR: c000000000025670
[    2.212846] REGS: c0000000fe666fb0 TRAP: 0700   Tainted: G        W     (3.8.6-aufs)
[    2.259200] MSR: 9000000000029032 <SF,HV,EE,ME,IR,DR,RI>  CR: 44000024  XER: 00000000
[    2.306076] SOFTE: 1
[    2.319100] TASK = c0000000fe668000[1] 'swapper/0' THREAD: c0000000fe664000 CPU: 0
GPR00: c0000000000bdea8 c0000000fe667230 c000000000699cb0 000000000000002c 
GPR04: 0000000000000000 000000007b5d549f 0000000000000008 0000000000000000 
GPR08: 000000007b69dec9 0000000000000000 0000000000000000 0000000000000000 
GPR12: d000070000000000 c00000000fffb000 c00000000000a460 0000000000000000 
GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 
GPR20: 0000000000000000 0000000000000000 c0000000fe006078 000000000000003c 
GPR24: 00000000000000ec 000000000000003b 000000000000003b c0000000fe803100 
GPR28: c0000000fe006060 000000000000003b c000000000643be0 000000000000003b 
[    2.685263] NIP [c0000000000bdeac] .irq_domain_associate_many+0x264/0x290
[    2.725888] LR [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290
[    2.765991] Call Trace:
[    2.780579] [c0000000fe667230] [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290 (unreliable)
[    2.835789] [c0000000fe667300] [c0000000000be928] .irq_create_mapping+0xc8/0x1d0
[    2.880062] [c0000000fe6673a0] [c0000000000bead8] .irq_create_of_mapping+0xa8/0x170
[    2.925896] [c0000000fe667450] [c000000000290c30] .irq_of_parse_and_map+0x40/0x58
[    2.970690] [c0000000fe6674e0] [c000000000290df0] .of_irq_count+0x30/0x58
[    3.011315] [c0000000fe667570] [c00000000029182c] .of_device_alloc+0x1ec/0x288
[    3.054548] [c0000000fe667670] [c00000000029191c] .of_platform_device_create_pdata+0x54/0xf8
[    3.105070] [c0000000fe667710] [c000000000291b04] .of_platform_bus_create+0x144/0x1e0
[    3.151946] [c0000000fe667800] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[    3.198824] [c0000000fe6678f0] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[    3.245701] [c0000000fe6679e0] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[    3.292577] [c0000000fe667ad0] [c000000000291d50] .of_platform_bus_probe+0xd0/0x140
[    3.338414] [c0000000fe667b70] [c0000000004109e4] .__machine_initcall_cell_cell_publish_devices+0x54/0x1b0
[    3.396228] [c0000000fe667c40] [c000000000009e70] .do_one_initcall+0x168/0x1d0
[    3.439457] [c0000000fe667d00] [c0000000003ffb6c] .kernel_init_freeable+0x14c/0x21c
[    3.485294] [c0000000fe667db0] [c00000000000a47c] .kernel_init+0x1c/0x108
[    3.525921] [c0000000fe667e30] [c000000000008cd8] .ret_from_kernel_thread+0x64/0x8c
[    3.571752] Instruction dump:
[    3.589461] 7fa4eb78 7ca507b4 4828c965 60000000 0fe00000 3860ffea 4bffff80 e87e8020 
[    3.635817] 7fa4eb78 7fe5fb78 4828c945 60000000 <0fe00000> 39200000 7f83e378 7f44d378 
[    3.683216] ---[ end trace 093b23e746659770 ]---
[    3.711776] irq: irq-18==>hwirq-0x2 mapping failed: -22
[    3.742608] ------------[ cut here ]------------
[    3.770199] WARNING: at /usr/src/linux-3.8.6-aufs/kernel/irq/irqdomain.c:467
[    3.812387] Modules linked in:
[    3.830618] NIP: c0000000000bdeac LR: c0000000000bdea8 CTR: c000000000025670
[    3.872808] REGS: c0000000fe666ec0 TRAP: 0700   Tainted: G        W     (3.8.6-aufs)
[    3.919162] MSR: 9000000000029032 <SF,HV,EE,ME,IR,DR,RI>  CR: 44000024  XER: 00000000
[    3.966038] SOFTE: 1
[    3.979061] TASK = c0000000fe668000[1] 'swapper/0' THREAD: c0000000fe664000 CPU: 0
GPR00: c0000000000bdea8 c0000000fe667140 c000000000699cb0 000000000000002b 
GPR04: 0000000000000000 000000007e00bb99 0000000000000008 0000000000000000 
GPR08: 000000007e0d404e 0000000000000000 0000000000000000 0000000000000000 
GPR12: d000070000000000 c00000000fffb000 c00000000000a460 0000000000000000 
GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 
GPR20: 0000000000000000 0000000000000000 c0000000fe006078 0000000000000013 
GPR24: 0000000000000008 0000000000000002 0000000000000012 c0000000fe803500 
GPR28: c0000000fe006060 0000000000000012 c000000000643be0 0000000000000002 
[    4.345224] NIP [c0000000000bdeac] .irq_domain_associate_many+0x264/0x290
[    4.385850] LR [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290
[    4.425953] Call Trace:
[    4.440540] [c0000000fe667140] [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290 (unreliable)
[    4.495750] [c0000000fe667210] [c0000000000be928] .irq_create_mapping+0xc8/0x1d0
[    4.540023] [c0000000fe6672b0] [c0000000000bead8] .irq_create_of_mapping+0xa8/0x170
[    4.585858] [c0000000fe667360] [c000000000290c30] .irq_of_parse_and_map+0x40/0x58
[    4.630651] [c0000000fe6673f0] [c000000000290df0] .of_irq_count+0x30/0x58
[    4.671277] [c0000000fe667480] [c00000000029182c] .of_device_alloc+0x1ec/0x288
[    4.714509] [c0000000fe667580] [c00000000029191c] .of_platform_device_create_pdata+0x54/0xf8
[    4.765032] [c0000000fe667620] [c000000000291b04] .of_platform_bus_create+0x144/0x1e0
[    4.811908] [c0000000fe667710] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[    4.858786] [c0000000fe667800] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[    4.905662] [c0000000fe6678f0] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[    4.952539] [c0000000fe6679e0] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[    4.999415] [c0000000fe667ad0] [c000000000291d50] .of_platform_bus_probe+0xd0/0x140
[    5.045253] [c0000000fe667b70] [c0000000004109e4] .__machine_initcall_cell_cell_publish_devices+0x54/0x1b0
[    5.103067] [c0000000fe667c40] [c000000000009e70] .do_one_initcall+0x168/0x1d0
[    5.146297] [c0000000fe667d00] [c0000000003ffb6c] .kernel_init_freeable+0x14c/0x21c
[    5.192132] [c0000000fe667db0] [c00000000000a47c] .kernel_init+0x1c/0x108
[    5.232760] [c0000000fe667e30] [c000000000008cd8] .ret_from_kernel_thread+0x64/0x8c
[    5.278590] Instruction dump:
[    5.296299] 7fa4eb78 7ca507b4 4828c965 60000000 0fe00000 3860ffea 4bffff80 e87e8020 
[    5.342655] 7fa4eb78 7fe5fb78 4828c945 60000000 <0fe00000> 39200000 7f83e378 7f44d378 
[    5.390054] ---[ end trace 093b23e746659771 ]---
[    5.419401] irq: irq-102==>hwirq-0x66 mapping failed: -22
[    5.451267] ------------[ cut here ]------------
[    5.478859] WARNING: at /usr/src/linux-3.8.6-aufs/kernel/irq/irqdomain.c:467
[    5.521048] Modules linked in:
[    5.539279] NIP: c0000000000bdeac LR: c0000000000bdea8 CTR: c000000000025670
[    5.581470] REGS: c0000000fe6670a0 TRAP: 0700   Tainted: G        W     (3.8.6-aufs)
[    5.627823] MSR: 9000000000029032 <SF,HV,EE,ME,IR,DR,RI>  CR: 84000024  XER: 00000000
[    5.674700] SOFTE: 1
[    5.687723] TASK = c0000000fe668000[1] 'swapper/0' THREAD: c0000000fe664000 CPU: 0
GPR00: c0000000000bdea8 c0000000fe667320 c000000000699cb0 000000000000002d 
GPR04: 0000000000000000 0000000080b79860 0000000000000008 0000000000000000 
GPR08: 0000000080c47261 0000000000000000 0000000000000000 0000000000000000 
GPR12: d000070000000000 c00000000fffb000 c00000000000a460 0000000000000000 
GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 
GPR20: 0000000000000000 0000000000000000 c0000000fe006078 0000000000000067 
GPR24: 0000000000000198 0000000000000066 0000000000000066 c0000000fe806f00 
GPR28: c0000000fe006060 0000000000000066 c000000000643be0 0000000000000066 
[    6.053885] NIP [c0000000000bdeac] .irq_domain_associate_many+0x264/0x290
[    6.094512] LR [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290
[    6.134614] Call Trace:
[    6.149201] [c0000000fe667320] [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290 (unreliable)
[    6.204412] [c0000000fe6673f0] [c0000000000be928] .irq_create_mapping+0xc8/0x1d0
[    6.248684] [c0000000fe667490] [c0000000000bead8] .irq_create_of_mapping+0xa8/0x170
[    6.294520] [c0000000fe667540] [c000000000290c30] .irq_of_parse_and_map+0x40/0x58
[    6.339313] [c0000000fe6675d0] [c000000000290df0] .of_irq_count+0x30/0x58
[    6.379940] [c0000000fe667660] [c00000000029182c] .of_device_alloc+0x1ec/0x288
[    6.423171] [c0000000fe667760] [c00000000029191c] .of_platform_device_create_pdata+0x54/0xf8
[    6.473693] [c0000000fe667800] [c000000000291b04] .of_platform_bus_create+0x144/0x1e0
[    6.520570] [c0000000fe6678f0] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[    6.567447] [c0000000fe6679e0] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[    6.614324] [c0000000fe667ad0] [c000000000291d50] .of_platform_bus_probe+0xd0/0x140
[    6.660160] [c0000000fe667b70] [c0000000004109e4] .__machine_initcall_cell_cell_publish_devices+0x54/0x1b0
[    6.717975] [c0000000fe667c40] [c000000000009e70] .do_one_initcall+0x168/0x1d0
[    6.761204] [c0000000fe667d00] [c0000000003ffb6c] .kernel_init_freeable+0x14c/0x21c
[    6.807039] [c0000000fe667db0] [c00000000000a47c] .kernel_init+0x1c/0x108
[    6.847667] [c0000000fe667e30] [c000000000008cd8] .ret_from_kernel_thread+0x64/0x8c
[    6.893498] Instruction dump:
[    6.911208] 7fa4eb78 7ca507b4 4828c965 60000000 0fe00000 3860ffea 4bffff80 e87e8020 
[    6.957563] 7fa4eb78 7fe5fb78 4828c945 60000000 <0fe00000> 39200000 7f83e378 7f44d378 
[    7.004962] ---[ end trace 093b23e746659772 ]---
[    7.032744] irq: irq-110==>hwirq-0x6e mapping failed: -22
[    7.064870] ------------[ cut here ]------------
[    7.092465] WARNING: at /usr/src/linux-3.8.6-aufs/kernel/irq/irqdomain.c:467
[    7.134654] Modules linked in:
[    7.152885] NIP: c0000000000bdeac LR: c0000000000bdea8 CTR: c000000000025670
[    7.195074] REGS: c0000000fe6670a0 TRAP: 0700   Tainted: G        W     (3.8.6-aufs)
[    7.241429] MSR: 9000000000029032 <SF,HV,EE,ME,IR,DR,RI>  CR: 84000024  XER: 00000000
[    7.288306] SOFTE: 1
[    7.301328] TASK = c0000000fe668000[1] 'swapper/0' THREAD: c0000000fe664000 CPU: 0
GPR00: c0000000000bdea8 c0000000fe667320 c000000000699cb0 000000000000002d 
GPR04: 0000000000000000 0000000083483c8a 0000000000000008 0000000000000000 
GPR08: 000000008354f799 0000000000000000 0000000000000000 0000000000000000 
GPR12: d000070000000000 c00000000fffb000 c00000000000a460 0000000000000000 
GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 
GPR20: 0000000000000000 0000000000000000 c0000000fe006078 000000000000006f 
GPR24: 00000000000001b8 000000000000006e 000000000000006e c0000000fe806f00 
GPR28: c0000000fe006060 000000000000006e c000000000643be0 000000000000006e 
[    7.667491] NIP [c0000000000bdeac] .irq_domain_associate_many+0x264/0x290
[    7.708117] LR [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290
[    7.748219] Call Trace:
[    7.762807] [c0000000fe667320] [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290 (unreliable)
[    7.818018] [c0000000fe6673f0] [c0000000000be928] .irq_create_mapping+0xc8/0x1d0
[    7.862290] [c0000000fe667490] [c0000000000bead8] .irq_create_of_mapping+0xa8/0x170
[    7.908125] [c0000000fe667540] [c000000000290c30] .irq_of_parse_and_map+0x40/0x58
[    7.952918] [c0000000fe6675d0] [c000000000290df0] .of_irq_count+0x30/0x58
[    7.993545] [c0000000fe667660] [c00000000029182c] .of_device_alloc+0x1ec/0x288
[    8.036776] [c0000000fe667760] [c00000000029191c] .of_platform_device_create_pdata+0x54/0xf8
[    8.087299] [c0000000fe667800] [c000000000291b04] .of_platform_bus_create+0x144/0x1e0
[    8.134175] [c0000000fe6678f0] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[    8.181053] [c0000000fe6679e0] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[    8.227929] [c0000000fe667ad0] [c000000000291d50] .of_platform_bus_probe+0xd0/0x140
[    8.273765] [c0000000fe667b70] [c0000000004109e4] .__machine_initcall_cell_cell_publish_devices+0x54/0x1b0
[    8.331580] [c0000000fe667c40] [c000000000009e70] .do_one_initcall+0x168/0x1d0
[    8.374810] [c0000000fe667d00] [c0000000003ffb6c] .kernel_init_freeable+0x14c/0x21c
[    8.420646] [c0000000fe667db0] [c00000000000a47c] .kernel_init+0x1c/0x108
[    8.461272] [c0000000fe667e30] [c000000000008cd8] .ret_from_kernel_thread+0x64/0x8c
[    8.507103] Instruction dump:
[    8.524813] 7fa4eb78 7ca507b4 4828c965 60000000 0fe00000 3860ffea 4bffff80 e87e8020 
[    8.571169] 7fa4eb78 7fe5fb78 4828c945 60000000 <0fe00000> 39200000 7f83e378 7f44d378 
[    8.618568] ---[ end trace 093b23e746659773 ]---
[    8.646369] irq: irq-39==>hwirq-0x27 mapping failed: -22
[    8.677955] ------------[ cut here ]------------
[    8.705551] WARNING: at /usr/src/linux-3.8.6-aufs/kernel/irq/irqdomain.c:467
[    8.747738] Modules linked in:
[    8.765970] NIP: c0000000000bdeac LR: c0000000000bdea8 CTR: c000000000025670
[    8.808160] REGS: c0000000fe6670a0 TRAP: 0700   Tainted: G        W     (3.8.6-aufs)
[    8.854513] MSR: 9000000000029032 <SF,HV,EE,ME,IR,DR,RI>  CR: 84000024  XER: 00000000
[    8.901390] SOFTE: 1
[    8.914413] TASK = c0000000fe668000[1] 'swapper/0' THREAD: c0000000fe664000 CPU: 0
GPR00: c0000000000bdea8 c0000000fe667320 c000000000699cb0 000000000000002c 
GPR04: 0000000000000000 0000000085d8c1ca 0000000000000008 0000000000000000 
GPR08: 0000000085e54682 0000000000000000 0000000000000000 0000000000000000 
GPR12: d000070000000000 c00000000fffb000 c00000000000a460 0000000000000000 
GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 
GPR20: 0000000000000000 0000000000000000 c0000000fe006078 0000000000000028 
GPR24: 000000000000009c 0000000000000027 0000000000000027 c0000000fe807000 
GPR28: c0000000fe006060 0000000000000027 c000000000643be0 0000000000000027 
[    9.280577] NIP [c0000000000bdeac] .irq_domain_associate_many+0x264/0x290
[    9.321202] LR [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290
[    9.361304] Call Trace:
[    9.375891] [c0000000fe667320] [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290 (unreliable)
[    9.431102] [c0000000fe6673f0] [c0000000000be928] .irq_create_mapping+0xc8/0x1d0
[    9.475374] [c0000000fe667490] [c0000000000bead8] .irq_create_of_mapping+0xa8/0x170
[    9.521210] [c0000000fe667540] [c000000000290c30] .irq_of_parse_and_map+0x40/0x58
[    9.566002] [c0000000fe6675d0] [c000000000290df0] .of_irq_count+0x30/0x58
[    9.606630] [c0000000fe667660] [c00000000029182c] .of_device_alloc+0x1ec/0x288
[    9.649861] [c0000000fe667760] [c00000000029191c] .of_platform_device_create_pdata+0x54/0xf8
[    9.700383] [c0000000fe667800] [c000000000291b04] .of_platform_bus_create+0x144/0x1e0
[    9.747260] [c0000000fe6678f0] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[    9.794137] [c0000000fe6679e0] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[    9.841014] [c0000000fe667ad0] [c000000000291d50] .of_platform_bus_probe+0xd0/0x140
[    9.886851] [c0000000fe667b70] [c0000000004109e4] .__machine_initcall_cell_cell_publish_devices+0x54/0x1b0
[    9.944665] [c0000000fe667c40] [c000000000009e70] .do_one_initcall+0x168/0x1d0
[    9.987895] [c0000000fe667d00] [c0000000003ffb6c] .kernel_init_freeable+0x14c/0x21c
[   10.033731] [c0000000fe667db0] [c00000000000a47c] .kernel_init+0x1c/0x108
[   10.074357] [c0000000fe667e30] [c000000000008cd8] .ret_from_kernel_thread+0x64/0x8c
[   10.120188] Instruction dump:
[   10.137898] 7fa4eb78 7ca507b4 4828c965 60000000 0fe00000 3860ffea 4bffff80 e87e8020 
[   10.184254] 7fa4eb78 7fe5fb78 4828c945 60000000 <0fe00000> 39200000 7f83e378 7f44d378 
[   10.231652] ---[ end trace 093b23e746659774 ]---
[   10.259697] irq: irq-93==>hwirq-0x5d mapping failed: -22
[   10.291040] ------------[ cut here ]------------
[   10.318635] WARNING: at /usr/src/linux-3.8.6-aufs/kernel/irq/irqdomain.c:467
[   10.360823] Modules linked in:
[   10.379055] NIP: c0000000000bdeac LR: c0000000000bdea8 CTR: c000000000025670
[   10.421245] REGS: c0000000fe667190 TRAP: 0700   Tainted: G        W     (3.8.6-aufs)
[   10.467599] MSR: 9000000000029032 <SF,HV,EE,ME,IR,DR,RI>  CR: 84000024  XER: 00000000
[   10.514475] SOFTE: 1
[   10.527498] TASK = c0000000fe668000[1] 'swapper/0' THREAD: c0000000fe664000 CPU: 0
GPR00: c0000000000bdea8 c0000000fe667410 c000000000699cb0 000000000000002c 
GPR04: 0000000000000000 00000000886910b7 0000000000000008 0000000000000000 
GPR08: 0000000088759576 0000000000000000 0000000000000000 0000000000000000 
GPR12: d000070000000000 c00000000fffb000 c00000000000a460 0000000000000000 
GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 
GPR20: 0000000000000000 0000000000000000 c0000001fe001018 000000000000005e 
GPR24: 0000000000000174 000000000000005d 000000000000005d c0000001fe743100 
GPR28: c0000001fe001000 000000000000005d c000000000643be0 000000000000005d 
[   10.893662] NIP [c0000000000bdeac] .irq_domain_associate_many+0x264/0x290
[   10.934287] LR [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290
[   10.974389] Call Trace:
[   10.988976] [c0000000fe667410] [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290 (unreliable)
[   11.044187] [c0000000fe6674e0] [c0000000000be928] .irq_create_mapping+0xc8/0x1d0
[   11.088460] [c0000000fe667580] [c0000000000bead8] .irq_create_of_mapping+0xa8/0x170
[   11.134294] [c0000000fe667630] [c000000000290c30] .irq_of_parse_and_map+0x40/0x58
[   11.179088] [c0000000fe6676c0] [c000000000290df0] .of_irq_count+0x30/0x58
[   11.219715] [c0000000fe667750] [c00000000029182c] .of_device_alloc+0x1ec/0x288
[   11.262946] [c0000000fe667850] [c00000000029191c] .of_platform_device_create_pdata+0x54/0xf8
[   11.313468] [c0000000fe6678f0] [c000000000291b04] .of_platform_bus_create+0x144/0x1e0
[   11.360346] [c0000000fe6679e0] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[   11.407222] [c0000000fe667ad0] [c000000000291d50] .of_platform_bus_probe+0xd0/0x140
[   11.453058] [c0000000fe667b70] [c0000000004109e4] .__machine_initcall_cell_cell_publish_devices+0x54/0x1b0
[   11.510873] [c0000000fe667c40] [c000000000009e70] .do_one_initcall+0x168/0x1d0
[   11.554103] [c0000000fe667d00] [c0000000003ffb6c] .kernel_init_freeable+0x14c/0x21c
[   11.599938] [c0000000fe667db0] [c00000000000a47c] .kernel_init+0x1c/0x108
[   11.640565] [c0000000fe667e30] [c000000000008cd8] .ret_from_kernel_thread+0x64/0x8c
[   11.686396] Instruction dump:
[   11.704106] 7fa4eb78 7ca507b4 4828c965 60000000 0fe00000 3860ffea 4bffff80 e87e8020 
[   11.750461] 7fa4eb78 7fe5fb78 4828c945 60000000 <0fe00000> 39200000 7f83e378 7f44d378 
[   11.797861] ---[ end trace 093b23e746659775 ]---
[   11.825985] irq: irq-59==>hwirq-0x3b mapping failed: -22
[   11.857353] ------------[ cut here ]------------
[   11.884947] WARNING: at /usr/src/linux-3.8.6-aufs/kernel/irq/irqdomain.c:467
[   11.927135] Modules linked in:
[   11.945367] NIP: c0000000000bdeac LR: c0000000000bdea8 CTR: c000000000025670
[   11.987557] REGS: c0000000fe666fb0 TRAP: 0700   Tainted: G        W     (3.8.6-aufs)
[   12.033911] MSR: 9000000000029032 <SF,HV,EE,ME,IR,DR,RI>  CR: 84000024  XER: 00000000
[   12.080787] SOFTE: 1
[   12.093810] TASK = c0000000fe668000[1] 'swapper/0' THREAD: c0000000fe664000 CPU: 0
GPR00: c0000000000bdea8 c0000000fe667230 c000000000699cb0 000000000000002c 
GPR04: 0000000000000000 000000008ae64d23 0000000000000008 0000000000000000 
GPR08: 000000008af2dcbb 0000000000000000 0000000000000000 0000000000000000 
GPR12: d000070000000000 c00000000fffb000 c00000000000a460 0000000000000000 
GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 
GPR20: 0000000000000000 0000000000000000 c0000001fe001018 000000000000003c 
GPR24: 00000000000000ec 000000000000003b 000000000000003b c0000001fe743600 
GPR28: c0000001fe001000 000000000000003b c000000000643be0 000000000000003b 
[   12.459974] NIP [c0000000000bdeac] .irq_domain_associate_many+0x264/0x290
[   12.500599] LR [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290
[   12.540701] Call Trace:
[   12.555288] [c0000000fe667230] [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290 (unreliable)
[   12.610499] [c0000000fe667300] [c0000000000be928] .irq_create_mapping+0xc8/0x1d0
[   12.654772] [c0000000fe6673a0] [c0000000000bead8] .irq_create_of_mapping+0xa8/0x170
[   12.700607] [c0000000fe667450] [c000000000290c30] .irq_of_parse_and_map+0x40/0x58
[   12.745400] [c0000000fe6674e0] [c000000000290df0] .of_irq_count+0x30/0x58
[   12.786027] [c0000000fe667570] [c00000000029182c] .of_device_alloc+0x1ec/0x288
[   12.829258] [c0000000fe667670] [c00000000029191c] .of_platform_device_create_pdata+0x54/0xf8
[   12.879780] [c0000000fe667710] [c000000000291b04] .of_platform_bus_create+0x144/0x1e0
[   12.926658] [c0000000fe667800] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[   12.973534] [c0000000fe6678f0] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[   13.020411] [c0000000fe6679e0] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[   13.067288] [c0000000fe667ad0] [c000000000291d50] .of_platform_bus_probe+0xd0/0x140
[   13.113125] [c0000000fe667b70] [c0000000004109e4] .__machine_initcall_cell_cell_publish_devices+0x54/0x1b0
[   13.170939] [c0000000fe667c40] [c000000000009e70] .do_one_initcall+0x168/0x1d0
[   13.214169] [c0000000fe667d00] [c0000000003ffb6c] .kernel_init_freeable+0x14c/0x21c
[   13.260005] [c0000000fe667db0] [c00000000000a47c] .kernel_init+0x1c/0x108
[   13.300631] [c0000000fe667e30] [c000000000008cd8] .ret_from_kernel_thread+0x64/0x8c
[   13.346462] Instruction dump:
[   13.364172] 7fa4eb78 7ca507b4 4828c965 60000000 0fe00000 3860ffea 4bffff80 e87e8020 
[   13.410527] 7fa4eb78 7fe5fb78 4828c945 60000000 <0fe00000> 39200000 7f83e378 7f44d378 
[   13.457926] ---[ end trace 093b23e746659776 ]---
[   13.486091] irq: irq-20==>hwirq-0x2 mapping failed: -22
[   13.516898] ------------[ cut here ]------------
[   13.544492] WARNING: at /usr/src/linux-3.8.6-aufs/kernel/irq/irqdomain.c:467
[   13.586680] Modules linked in:
[   13.604912] NIP: c0000000000bdeac LR: c0000000000bdea8 CTR: c000000000025670
[   13.647101] REGS: c0000000fe666ec0 TRAP: 0700   Tainted: G        W     (3.8.6-aufs)
[   13.693456] MSR: 9000000000029032 <SF,HV,EE,ME,IR,DR,RI>  CR: 84000024  XER: 00000000
[   13.740333] SOFTE: 1
[   13.753356] TASK = c0000000fe668000[1] 'swapper/0' THREAD: c0000000fe664000 CPU: 0
GPR00: c0000000000bdea8 c0000000fe667140 c000000000699cb0 000000000000002b 
GPR04: 0000000000000000 000000008d89b97c 0000000000000008 0000000000000000 
GPR08: 000000008d9612d7 0000000000000000 0000000000000000 0000000000000000 
GPR12: d000070000000000 c00000000fffb000 c00000000000a460 0000000000000000 
GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 
GPR20: 0000000000000000 0000000000000000 c0000001fe001018 0000000000000015 
GPR24: 0000000000000008 0000000000000002 0000000000000014 c0000001fe743900 
GPR28: c0000001fe001000 0000000000000014 c000000000643be0 0000000000000002 
[   14.119519] NIP [c0000000000bdeac] .irq_domain_associate_many+0x264/0x290
[   14.160144] LR [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290
[   14.200246] Call Trace:
[   14.214833] [c0000000fe667140] [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290 (unreliable)
[   14.270044] [c0000000fe667210] [c0000000000be928] .irq_create_mapping+0xc8/0x1d0
[   14.314317] [c0000000fe6672b0] [c0000000000bead8] .irq_create_of_mapping+0xa8/0x170
[   14.360152] [c0000000fe667360] [c000000000290c30] .irq_of_parse_and_map+0x40/0x58
[   14.404945] [c0000000fe6673f0] [c000000000290df0] .of_irq_count+0x30/0x58
[   14.445571] [c0000000fe667480] [c00000000029182c] .of_device_alloc+0x1ec/0x288
[   14.488802] [c0000000fe667580] [c00000000029191c] .of_platform_device_create_pdata+0x54/0xf8
[   14.539325] [c0000000fe667620] [c000000000291b04] .of_platform_bus_create+0x144/0x1e0
[   14.586202] [c0000000fe667710] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[   14.633079] [c0000000fe667800] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[   14.679956] [c0000000fe6678f0] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[   14.726833] [c0000000fe6679e0] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[   14.773710] [c0000000fe667ad0] [c000000000291d50] .of_platform_bus_probe+0xd0/0x140
[   14.819546] [c0000000fe667b70] [c0000000004109e4] .__machine_initcall_cell_cell_publish_devices+0x54/0x1b0
[   14.877361] [c0000000fe667c40] [c000000000009e70] .do_one_initcall+0x168/0x1d0
[   14.920591] [c0000000fe667d00] [c0000000003ffb6c] .kernel_init_freeable+0x14c/0x21c
[   14.966426] [c0000000fe667db0] [c00000000000a47c] .kernel_init+0x1c/0x108
[   15.007053] [c0000000fe667e30] [c000000000008cd8] .ret_from_kernel_thread+0x64/0x8c
[   15.052885] Instruction dump:
[   15.070594] 7fa4eb78 7ca507b4 4828c965 60000000 0fe00000 3860ffea 4bffff80 e87e8020 
[   15.116950] 7fa4eb78 7fe5fb78 4828c945 60000000 <0fe00000> 39200000 7f83e378 7f44d378 
[   15.164348] ---[ end trace 093b23e746659777 ]---
[   15.193877] irq: irq-108==>hwirq-0x66 mapping failed: -22
[   15.225769] ------------[ cut here ]------------
[   15.253363] WARNING: at /usr/src/linux-3.8.6-aufs/kernel/irq/irqdomain.c:467
[   15.295550] Modules linked in:
[   15.313782] NIP: c0000000000bdeac LR: c0000000000bdea8 CTR: c000000000025670
[   15.355972] REGS: c0000000fe6670a0 TRAP: 0700   Tainted: G        W     (3.8.6-aufs)
[   15.402326] MSR: 9000000000029032 <SF,HV,EE,ME,IR,DR,RI>  CR: 84000024  XER: 00000000
[   15.449202] SOFTE: 1
[   15.462226] TASK = c0000000fe668000[1] 'swapper/0' THREAD: c0000000fe664000 CPU: 0
GPR00: c0000000000bdea8 c0000000fe667320 c000000000699cb0 000000000000002d 
GPR04: 0000000000000000 0000000090406ac4 0000000000000008 0000000000000000 
GPR08: 00000000904d5a9f 0000000000000000 0000000000000000 0000000000000000 
GPR12: d000070000000000 c00000000fffb000 c00000000000a460 0000000000000000 
GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 
GPR20: 0000000000000000 0000000000000000 c0000001fe001018 000000000000006d 
GPR24: 0000000000000198 0000000000000066 000000000000006c c0000001fe74c400 
GPR28: c0000001fe001000 000000000000006c c000000000643be0 0000000000000066 
[   15.828389] NIP [c0000000000bdeac] .irq_domain_associate_many+0x264/0x290
[   15.869013] LR [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290
[   15.909117] Call Trace:
[   15.923704] [c0000000fe667320] [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290 (unreliable)
[   15.978914] [c0000000fe6673f0] [c0000000000be928] .irq_create_mapping+0xc8/0x1d0
[   16.023187] [c0000000fe667490] [c0000000000bead8] .irq_create_of_mapping+0xa8/0x170
[   16.069022] [c0000000fe667540] [c000000000290c30] .irq_of_parse_and_map+0x40/0x58
[   16.113814] [c0000000fe6675d0] [c000000000290df0] .of_irq_count+0x30/0x58
[   16.154441] [c0000000fe667660] [c00000000029182c] .of_device_alloc+0x1ec/0x288
[   16.197673] [c0000000fe667760] [c00000000029191c] .of_platform_device_create_pdata+0x54/0xf8
[   16.248196] [c0000000fe667800] [c000000000291b04] .of_platform_bus_create+0x144/0x1e0
[   16.295072] [c0000000fe6678f0] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[   16.341949] [c0000000fe6679e0] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[   16.388826] [c0000000fe667ad0] [c000000000291d50] .of_platform_bus_probe+0xd0/0x140
[   16.434662] [c0000000fe667b70] [c0000000004109e4] .__machine_initcall_cell_cell_publish_devices+0x54/0x1b0
[   16.492476] [c0000000fe667c40] [c000000000009e70] .do_one_initcall+0x168/0x1d0
[   16.535707] [c0000000fe667d00] [c0000000003ffb6c] .kernel_init_freeable+0x14c/0x21c
[   16.581542] [c0000000fe667db0] [c00000000000a47c] .kernel_init+0x1c/0x108
[   16.622168] [c0000000fe667e30] [c000000000008cd8] .ret_from_kernel_thread+0x64/0x8c
[   16.668000] Instruction dump:
[   16.685710] 7fa4eb78 7ca507b4 4828c965 60000000 0fe00000 3860ffea 4bffff80 e87e8020 
[   16.732066] 7fa4eb78 7fe5fb78 4828c945 60000000 <0fe00000> 39200000 7f83e378 7f44d378 
[   16.779464] ---[ end trace 093b23e746659778 ]---
[   16.807242] irq: irq-110==>hwirq-0x6e mapping failed: -22
[   16.839373] ------------[ cut here ]------------
[   16.866968] WARNING: at /usr/src/linux-3.8.6-aufs/kernel/irq/irqdomain.c:467
[   16.909155] Modules linked in:
[   16.927387] NIP: c0000000000bdeac LR: c0000000000bdea8 CTR: c000000000025670
[   16.969576] REGS: c0000000fe6670a0 TRAP: 0700   Tainted: G        W     (3.8.6-aufs)
[   17.015931] MSR: 9000000000029032 <SF,HV,EE,ME,IR,DR,RI>  CR: 84000024  XER: 00000000
[   17.062808] SOFTE: 1
[   17.075831] TASK = c0000000fe668000[1] 'swapper/0' THREAD: c0000000fe664000 CPU: 0
GPR00: c0000000000bdea8 c0000000fe667320 c000000000699cb0 000000000000002d 
GPR04: 0000000000000000 0000000092d124ca 0000000000000008 0000000000000000 
GPR08: 0000000092dddfc6 0000000000000000 0000000000000000 0000000000000000 
GPR12: d000070000000000 c00000000fffb000 c00000000000a460 0000000000000000 
GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 
GPR20: 0000000000000000 0000000000000000 c0000001fe001018 000000000000006f 
GPR24: 00000000000001b8 000000000000006e 000000000000006e c0000001fe74c400 
GPR28: c0000001fe001000 000000000000006e c000000000643be0 000000000000006e 
[   17.441994] NIP [c0000000000bdeac] .irq_domain_associate_many+0x264/0x290
[   17.482619] LR [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290
[   17.522722] Call Trace:
[   17.537310] [c0000000fe667320] [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290 (unreliable)
[   17.592520] [c0000000fe6673f0] [c0000000000be928] .irq_create_mapping+0xc8/0x1d0
[   17.636792] [c0000000fe667490] [c0000000000bead8] .irq_create_of_mapping+0xa8/0x170
[   17.682627] [c0000000fe667540] [c000000000290c30] .irq_of_parse_and_map+0x40/0x58
[   17.727421] [c0000000fe6675d0] [c000000000290df0] .of_irq_count+0x30/0x58
[   17.768047] [c0000000fe667660] [c00000000029182c] .of_device_alloc+0x1ec/0x288
[   17.811278] [c0000000fe667760] [c00000000029191c] .of_platform_device_create_pdata+0x54/0xf8
[   17.861801] [c0000000fe667800] [c000000000291b04] .of_platform_bus_create+0x144/0x1e0
[   17.908678] [c0000000fe6678f0] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[   17.955555] [c0000000fe6679e0] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[   18.002431] [c0000000fe667ad0] [c000000000291d50] .of_platform_bus_probe+0xd0/0x140
[   18.048268] [c0000000fe667b70] [c0000000004109e4] .__machine_initcall_cell_cell_publish_devices+0x54/0x1b0
[   18.106082] [c0000000fe667c40] [c000000000009e70] .do_one_initcall+0x168/0x1d0
[   18.149312] [c0000000fe667d00] [c0000000003ffb6c] .kernel_init_freeable+0x14c/0x21c
[   18.195148] [c0000000fe667db0] [c00000000000a47c] .kernel_init+0x1c/0x108
[   18.235775] [c0000000fe667e30] [c000000000008cd8] .ret_from_kernel_thread+0x64/0x8c
[   18.281606] Instruction dump:
[   18.299315] 7fa4eb78 7ca507b4 4828c965 60000000 0fe00000 3860ffea 4bffff80 e87e8020 
[   18.345671] 7fa4eb78 7fe5fb78 4828c945 60000000 <0fe00000> 39200000 7f83e378 7f44d378 
[   18.393070] ---[ end trace 093b23e746659779 ]---
[   18.420872] irq: irq-42==>hwirq-0x27 mapping failed: -22
[   18.452457] ------------[ cut here ]------------
[   18.480052] WARNING: at /usr/src/linux-3.8.6-aufs/kernel/irq/irqdomain.c:467
[   18.522241] Modules linked in:
[   18.540472] NIP: c0000000000bdeac LR: c0000000000bdea8 CTR: c000000000025670
[   18.582662] REGS: c0000000fe6670a0 TRAP: 0700   Tainted: G        W     (3.8.6-aufs)
[   18.629016] MSR: 9000000000029032 <SF,HV,EE,ME,IR,DR,RI>  CR: 84000024  XER: 00000000
[   18.675893] SOFTE: 1
[   18.688916] TASK = c0000000fe668000[1] 'swapper/0' THREAD: c0000000fe664000 CPU: 0
GPR00: c0000000000bdea8 c0000000fe667320 c000000000699cb0 000000000000002c 
GPR04: 0000000000000000 000000009561a9f3 0000000000000008 0000000000000000 
GPR08: 00000000956e2ec4 0000000000000000 0000000000000000 0000000000000000 
GPR12: d000070000000000 c00000000fffb000 c00000000000a460 0000000000000000 
GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 
GPR20: 0000000000000000 0000000000000000 c0000001fe001018 000000000000002b 
GPR24: 000000000000009c 0000000000000027 000000000000002a c0000001fe74c500 
GPR28: c0000001fe001000 000000000000002a c000000000643be0 0000000000000027 
[   19.055078] NIP [c0000000000bdeac] .irq_domain_associate_many+0x264/0x290
[   19.095704] LR [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290
[   19.135807] Call Trace:
[   19.150394] [c0000000fe667320] [c0000000000bdea8] .irq_domain_associate_many+0x260/0x290 (unreliable)
[   19.205604] [c0000000fe6673f0] [c0000000000be928] .irq_create_mapping+0xc8/0x1d0
[   19.249876] [c0000000fe667490] [c0000000000bead8] .irq_create_of_mapping+0xa8/0x170
[   19.295712] [c0000000fe667540] [c000000000290c30] .irq_of_parse_and_map+0x40/0x58
[   19.340505] [c0000000fe6675d0] [c000000000290df0] .of_irq_count+0x30/0x58
[   19.381131] [c0000000fe667660] [c00000000029182c] .of_device_alloc+0x1ec/0x288
[   19.424363] [c0000000fe667760] [c00000000029191c] .of_platform_device_create_pdata+0x54/0xf8
[   19.474886] [c0000000fe667800] [c000000000291b04] .of_platform_bus_create+0x144/0x1e0
[   19.521763] [c0000000fe6678f0] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[   19.568640] [c0000000fe6679e0] [c000000000291b60] .of_platform_bus_create+0x1a0/0x1e0
[   19.615516] [c0000000fe667ad0] [c000000000291d50] .of_platform_bus_probe+0xd0/0x140
[   19.661353] [c0000000fe667b70] [c0000000004109e4] .__machine_initcall_cell_cell_publish_devices+0x54/0x1b0
[   19.719167] [c0000000fe667c40] [c000000000009e70] .do_one_initcall+0x168/0x1d0
[   19.762397] [c0000000fe667d00] [c0000000003ffb6c] .kernel_init_freeable+0x14c/0x21c
[   19.808233] [c0000000fe667db0] [c00000000000a47c] .kernel_init+0x1c/0x108
[   19.848859] [c0000000fe667e30] [c000000000008cd8] .ret_from_kernel_thread+0x64/0x8c
[   19.894691] Instruction dump:
[   19.912401] 7fa4eb78 7ca507b4 4828c965 60000000 0fe00000 3860ffea 4bffff80 e87e8020 
[   19.958756] 7fa4eb78 7fe5fb78 4828c945 60000000 <0fe00000> 39200000 7f83e378 7f44d378 
[   20.006154] ---[ end trace 093b23e74665977a ]---
[   20.033998] iommu: missing iommu for <no-node> (node -1)
[   20.065580] iommu: missing iommu for <no-node> (node -1)
[   20.097448] axon_msi: setup MSIC on /axon@10000000000/plb5/msic@4000004400003000
[   20.097647] axon_msi: setup MSIC on /axon@30000000000/plb5/msic@4000004400003000
[   20.098925] bio: create slab <bio-0> at 0
[   20.122808] vgaarb: loaded
[   20.138920] Switching to clocksource timebase
[   20.171194] NET: Registered protocol family 2
[   20.197448] TCP established hash table entries: 65536 (order: 8, 1048576 bytes)
[   20.242041] TCP bind hash table entries: 65536 (order: 8, 1048576 bytes)
[   20.284006] TCP: Hash tables configured (established 65536 bind 65536)
[   20.322737] TCP: reno registered
[   20.341968] UDP hash table entries: 4096 (order: 5, 131072 bytes)
[   20.378547] UDP-Lite hash table entries: 4096 (order: 5, 131072 bytes)
[   20.417767] PCI: CLS 0 bytes, default 128
[   20.417908] Unpacking initramfs...
[   20.998378] Freeing initrd memory: 9976k freed
[   21.026844] iommu: missing iommu for <no-node> (node -1)
[   21.058400] Setting up PCI bus /axon@10000000000/plb5/plb4/pcix@4000004600000000
[   21.102499] PCI host bridge /axon@10000000000/plb5/plb4/pcix@4000004600000000  ranges:
[   21.149865]   IO 0x0000014608000000..0x000001460800ffff -> 0x0000000000000000
[   21.192573]  MEM 0x0000014780000000..0x00000147bfffffff -> 0x0000000080000000 
[   21.235804]  MEM 0x00000147c0000000..0x00000147ffffffff -> 0x00000000c0000000 Prefetch
[   21.283303] of-pci 14600000000.pcix: PCI host bridge to bus 0000:00
[   21.320704] pci_bus 0000:00: root bus resource [io  0x10000-0x1ffff] (bus address [0x0000-0xffff])
[   21.374351] pci_bus 0000:00: root bus resource [mem 0x14780000000-0x147bfffffff] (bus address [0x80000000-0xbfffffff])
[   21.438415] pci_bus 0000:00: root bus resource [mem 0x147c0000000-0x147ffffffff pref] (bus address [0xc0000000-0xffffffff])
[   21.505081] pci_bus 0000:00: root bus resource [bus 00-ff]
[   21.537895] pci_bus 0000:00: busn_res: [bus 00-ff] end is updated to ff
[   21.537995] pci 0000:00:01.0: [14e4:16a8] type 00 class 0x020000
[   21.538100] pci 0000:00:01.0: reg 10: [mem 0x14780000000-0x1478000ffff 64bit]
[   21.538535] pci 0000:00:01.0: PME# supported from D3hot D3cold
[   21.538676] pci 0000:00:01.1: [14e4:16a8] type 00 class 0x020000
[   21.538785] pci 0000:00:01.1: reg 10: [mem 0x14780010000-0x1478001ffff 64bit]
[   21.539213] pci 0000:00:01.1: PME# supported from D3hot D3cold
[   21.539379] pci_bus 0000:00: busn_res: [bus 00-ff] end is updated to 00
[   21.539606] Setting up PCI bus /axon@10000000000/plb5/pciex@a00000a000000000
[   21.581406] PCI host bridge /axon@10000000000/plb5/pciex@a00000a000000000  ranges:
[   21.626704]   IO 0x000001a100000000..0x000001a10000ffff -> 0x0000000000000000
[   21.669416]  MEM 0x000001c080000000..0x000001c0bfffffff -> 0x0000000080000000 
[   21.712642]  MEM 0x000001c0c0000000..0x000001c0ffffffff -> 0x00000000c0000000 Prefetch
[   21.760128] of-pci D18000002400.pciex: PCI host bridge to bus 0001:00
[   21.798585] pci_bus 0001:00: root bus resource [io  0x21000-0x30fff] (bus address [0x0000-0xffff])
[   21.852232] pci_bus 0001:00: root bus resource [mem 0x1c080000000-0x1c0bfffffff] (bus address [0x80000000-0xbfffffff])
[   21.916296] pci_bus 0001:00: root bus resource [mem 0x1c0c0000000-0x1c0ffffffff pref] (bus address [0xc0000000-0xffffffff])
[   21.982968] pci_bus 0001:00: root bus resource [bus 00-ff]
[   22.015778] pci_bus 0001:00: busn_res: [bus 00-ff] end is updated to ff
[   22.015874] pci 0001:00:00.0: [1014:032c] type 01 class 0x060400
[   22.015969] pci 0001:00:00.0: reg 10: [mem 0x00000000-0x7fffffff 64bit pref]
[   22.016023] pci 0001:00:00.0: reg 38: [mem 0x1c0ffff8000-0x1c0ffffffff pref]
[   22.016091] PCI: Hiding resources on Axon PCIE RC 0001:00:00.0
[   22.016322] pci 0001:00:00.0: supports D1 D2
[   22.016329] pci 0001:00:00.0: PME# supported from D0 D1 D2 D3hot D3cold
[   22.016469] irq: no irq domain found for /axon@10000000000/plb5/pciex-utl@a00000a000004000 !
[   22.066811] pci 0001:00:00.0: PCI bridge to [bus 01]
[   22.096348] pci_bus 0001:00: busn_res: [bus 00-ff] end is updated to 01
[   22.096492] Setting up PCI bus /axon@10000000000/plb5/pciex@a00000a200000000
[   22.138454] PCI host bridge /axon@10000000000/plb5/pciex@a00000a200000000  ranges:
[   22.183757]   IO 0x000001a300000000..0x000001a30000ffff -> 0x0000000000000000
[   22.226467]  MEM 0x000001d080000000..0x000001d0bfffffff -> 0x0000000080000000 
[   22.269700]  MEM 0x000001d0c0000000..0x000001d0ffffffff -> 0x00000000c0000000 Prefetch
[   22.317183] of-pci D18000002800.pciex: PCI host bridge to bus 0002:00
[   22.355637] pci_bus 0002:00: root bus resource [io  0x32000-0x41fff] (bus address [0x0000-0xffff])
[   22.409286] pci_bus 0002:00: root bus resource [mem 0x1d080000000-0x1d0bfffffff] (bus address [0x80000000-0xbfffffff])
[   22.473351] pci_bus 0002:00: root bus resource [mem 0x1d0c0000000-0x1d0ffffffff pref] (bus address [0xc0000000-0xffffffff])
[   22.540019] pci_bus 0002:00: root bus resource [bus 00-ff]
[   22.572831] pci_bus 0002:00: busn_res: [bus 00-ff] end is updated to ff
[   22.572925] pci 0002:00:00.0: [1014:032c] type 01 class 0x060400
[   22.573019] pci 0002:00:00.0: reg 10: [mem 0x00000000-0x7fffffff 64bit pref]
[   22.573072] pci 0002:00:00.0: reg 38: [mem 0x1d0ffff8000-0x1d0ffffffff pref]
[   22.573139] PCI: Hiding resources on Axon PCIE RC 0002:00:00.0
[   22.573370] pci 0002:00:00.0: supports D1 D2
[   22.573377] pci 0002:00:00.0: PME# supported from D0 D1 D2 D3hot D3cold
[   22.573513] irq: no irq domain found for /axon@10000000000/plb5/pciex-utl@a00000a200004000 !
[   22.623873] pci 0002:00:00.0: PCI bridge to [bus 01]
[   22.653403] pci_bus 0002:00: busn_res: [bus 00-ff] end is updated to 01
[   22.653571] Setting up PCI bus /axon@30000000000/plb5/plb4/pcix@4000004600000000
[   22.697598] PCI host bridge /axon@30000000000/plb5/plb4/pcix@4000004600000000  ranges:
[   22.744978]   IO 0x0000034608000000..0x000003460800ffff -> 0x0000000000000000
[   22.787688]  MEM 0x0000034780000000..0x00000347bfffffff -> 0x0000000080000000 
[   22.830920]  MEM 0x00000347c0000000..0x00000347ffffffff -> 0x00000000c0000000 Prefetch
[   22.878412] of-pci 34600000000.pcix: PCI host bridge to bus 0003:00
[   22.915816] pci_bus 0003:00: root bus resource [io  0x43000-0x52fff] (bus address [0x0000-0xffff])
[   22.969462] pci_bus 0003:00: root bus resource [mem 0x34780000000-0x347bfffffff] (bus address [0x80000000-0xbfffffff])
[   23.033529] pci_bus 0003:00: root bus resource [mem 0x347c0000000-0x347ffffffff pref] (bus address [0xc0000000-0xffffffff])
[   23.100200] pci_bus 0003:00: root bus resource [bus 00-ff]
[   23.133010] pci_bus 0003:00: busn_res: [bus 00-ff] end is updated to ff
[   23.133069] pci 0003:00:01.0: [1033:0035] type 00 class 0x0c0310
[   23.133151] pci 0003:00:01.0: reg 10: [mem 0x34780000000-0x34780000fff]
[   23.133512] pci 0003:00:01.0: supports D1 D2
[   23.133520] pci 0003:00:01.0: PME# supported from D0 D1 D2 D3hot
[   23.133611] pci 0003:00:01.1: [1033:0035] type 00 class 0x0c0310
[   23.133691] pci 0003:00:01.1: reg 10: [mem 0x34780001000-0x34780001fff]
[   23.134068] pci 0003:00:01.1: supports D1 D2
[   23.134076] pci 0003:00:01.1: PME# supported from D0 D1 D2 D3hot
[   23.134167] pci 0003:00:01.2: [1033:00e0] type 00 class 0x0c0320
[   23.134247] pci 0003:00:01.2: reg 10: [mem 0x34780002000-0x347800020ff]
[   23.134605] pci 0003:00:01.2: supports D1 D2
[   23.134612] pci 0003:00:01.2: PME# supported from D0 D1 D2 D3hot
[   23.134776] pci_bus 0003:00: busn_res: [bus 00-ff] end is updated to 00
[   23.236836] pci 0003:00:01.2: enabling device (0140 -> 0142)
[   23.270411] Setting up PCI bus /axon@30000000000/plb5/pciex@a00000a000000000
[   23.312464] PCI host bridge /axon@30000000000/plb5/pciex@a00000a000000000  ranges:
[   23.357765]   IO 0x000003a100000000..0x000003a10000ffff -> 0x0000000000000000
[   23.400470]  MEM 0x000003c080000000..0x000003c0bfffffff -> 0x0000000080000000 
[   23.443702]  MEM 0x000003c0c0000000..0x000003c0ffffffff -> 0x00000000c0000000 Prefetch
[   23.491188] of-pci D38000002400.pciex: PCI host bridge to bus 0004:00
[   23.529643] pci_bus 0004:00: root bus resource [io  0x54000-0x63fff] (bus address [0x0000-0xffff])
[   23.583289] pci_bus 0004:00: root bus resource [mem 0x3c080000000-0x3c0bfffffff] (bus address [0x80000000-0xbfffffff])
[   23.647356] pci_bus 0004:00: root bus resource [mem 0x3c0c0000000-0x3c0ffffffff pref] (bus address [0xc0000000-0xffffffff])
[   23.714024] pci_bus 0004:00: root bus resource [bus 00-ff]
[   23.746836] pci_bus 0004:00: busn_res: [bus 00-ff] end is updated to ff
[   23.746935] pci 0004:00:00.0: [1014:032c] type 01 class 0x060400
[   23.747035] pci 0004:00:00.0: reg 10: [mem 0x00000000-0x7fffffff 64bit pref]
[   23.747093] pci 0004:00:00.0: reg 38: [mem 0x3c0ffff8000-0x3c0ffffffff pref]
[   23.747163] PCI: Hiding resources on Axon PCIE RC 0004:00:00.0
[   23.747409] pci 0004:00:00.0: supports D1 D2
[   23.747416] pci 0004:00:00.0: PME# supported from D0 D1 D2 D3hot D3cold
[   23.747563] irq: no irq domain found for /axon@30000000000/plb5/pciex-utl@a00000a000004000 !
[   23.797937] pci 0004:00:00.0: PCI bridge to [bus 01]
[   23.827465] pci_bus 0004:00: busn_res: [bus 00-ff] end is updated to 01
[   23.827605] Setting up PCI bus /axon@30000000000/plb5/pciex@a00000a200000000
[   23.869564] PCI host bridge /axon@30000000000/plb5/pciex@a00000a200000000  ranges:
[   23.914870]   IO 0x000003a300000000..0x000003a30000ffff -> 0x0000000000000000
[   23.957576]  MEM 0x000003d080000000..0x000003d0bfffffff -> 0x0000000080000000 
[   24.000807]  MEM 0x000003d0c0000000..0x000003d0ffffffff -> 0x00000000c0000000 Prefetch
[   24.048303] of-pci D38000002800.pciex: PCI host bridge to bus 0005:00
[   24.086747] pci_bus 0005:00: root bus resource [io  0x65000-0x74fff] (bus address [0x0000-0xffff])
[   24.140395] pci_bus 0005:00: root bus resource [mem 0x3d080000000-0x3d0bfffffff] (bus address [0x80000000-0xbfffffff])
[   24.204462] pci_bus 0005:00: root bus resource [mem 0x3d0c0000000-0x3d0ffffffff pref] (bus address [0xc0000000-0xffffffff])
[   24.271129] pci_bus 0005:00: root bus resource [bus 00-ff]
[   24.303941] pci_bus 0005:00: busn_res: [bus 00-ff] end is updated to ff
[   24.304047] pci 0005:00:00.0: [1014:032c] type 01 class 0x060400
[   24.304146] pci 0005:00:00.0: reg 10: [mem 0x00000000-0x7fffffff 64bit pref]
[   24.304203] pci 0005:00:00.0: reg 38: [mem 0x3d0ffff8000-0x3d0ffffffff pref]
[   24.304272] PCI: Hiding resources on Axon PCIE RC 0005:00:00.0
[   24.304517] pci 0005:00:00.0: supports D1 D2
[   24.304524] pci 0005:00:00.0: PME# supported from D0 D1 D2 D3hot D3cold
[   24.304664] irq: no irq domain found for /axon@30000000000/plb5/pciex-utl@a00000a200004000 !
[   24.355200] pci 0005:01:00.0: [15b3:634a] type 00 class 0x0c0600
[   24.355378] pci 0005:01:00.0: reg 10: [mem 0x3d080000000-0x3d0800fffff 64bit]
[   24.355524] pci 0005:01:00.0: reg 18: [mem 0x3d0c0000000-0x3d0c1ffffff 64bit pref]
[   24.356526] pci 0005:00:00.0: PCI bridge to [bus 01]
[   24.385809] pci 0005:00:00.0:   bridge window [mem 0x3d080000000-0x3d0800fffff]
[   24.385844] pci 0005:00:00.0:   bridge window [mem 0x3d0c0000000-0x3d0c1ffffff 64bit pref]
[   24.385934] pci_bus 0005:00: busn_res: [bus 00-ff] end is updated to 01
[   24.386274] iommu: missing iommu for <no-node> (node -1)
[   24.423030] iommu: missing iommu for <no-node> (node -1)
[   24.463050] msgmni has been set to 15888
[   24.500072] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253)
[   24.543980] io scheduler noop registered
[   24.567417] io scheduler deadline registered
[   24.593225] io scheduler cfq registered (default)
[   24.664957] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[   24.702646] iommu: missing iommu for <no-node> (node -1)
[   24.756219] serial8250.0: ttyS0 at MMIO 0x14540000200 (irq = 16) is a U6_16550A
[   24.799650] console [ttyS0] enabled, bootconsole disabled
[   24.885615] serial8250.0: ttyS1 at MMIO 0x14540000300 (irq = 17) is a U6_16550A
[   24.950843] serial8250.0: ttyS2 at MMIO 0x34540000200 (irq = 18) is a U6_16550A
[   25.016425] serial8250.0: ttyS3 at MMIO 0x34540000300 (irq = 19) is a U6_16550A
[   25.061120] mousedev: PS/2 mouse device common for all mice
[   25.094572] cpuidle: using governor ladder
[   25.119166] cpuidle: using governor menu
[   25.143019] TCP: cubic registered
[   25.162962] Key type dns_resolver registered
[   25.191007] /usr/src/linux-3.8.6-aufs/drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
[   25.246286] Freeing unused kernel memory: 2072k freed
[   25.598515] dracut: dracut-027-ebfd8cd
[   25.870831] RPC: Registered named UNIX socket transport module.
[   25.906410] RPC: Registered udp transport module.
[   25.934647] RPC: Registered tcp transport module.
[   25.962878] RPC: Registered tcp NFSv4.1 backchannel transport module.
[   26.060180] NET: Registered protocol family 1
[   26.128272] NET: Registered protocol family 10
[   26.288658] systemd-udevd[143]: starting version 200
[   26.565854] pps_core: LinuxPPS API ver. 1 registered
[   26.595737] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[   26.657618] PTP clock support registered
[   26.720952] tg3.c:v3.128 (December 03, 2012)
[   26.746875] tg3 0000:00:01.0: enabling device (0140 -> 0142)
[   26.812886] tg3 0000:00:01.0 eth0: Tigon3 [partno(none) rev 2100] (PCIX:100MHz:64-bit) MAC address 00:1a:64:b8:08:18
[   26.876142] tg3 0000:00:01.0 eth0: attached PHY is serdes (1000Base-SX Ethernet) (WireSpeed[0], EEE[0])
[   26.932674] tg3 0000:00:01.0 eth0: RXcsums[1] LinkChgREG[0] MIirq[0] ASF[1] TSOcap[0]
[   26.942744] usbcore: registered new interface driver usbfs
[   26.942899] usbcore: registered new interface driver hub
[   27.044642] tg3 0000:00:01.0 eth0: dma_rwctrl[769f4000] dma_mask[64-bit]
[   27.085684] usbcore: registered new device driver usb
[   27.101276] tg3 0000:00:01.1: enabling device (0140 -> 0142)
[   27.110440] tg3 0000:00:01.1 eth1: Tigon3 [partno(none) rev 2100] (PCIX:100MHz:64-bit) MAC address 00:1a:64:b8:08:19
[   27.110454] tg3 0000:00:01.1 eth1: attached PHY is serdes (1000Base-SX Ethernet) (WireSpeed[0], EEE[0])
[   27.110467] tg3 0000:00:01.1 eth1: RXcsums[1] LinkChgREG[0] MIirq[0] ASF[0] TSOcap[1]
[   27.110479] tg3 0000:00:01.1 eth1: dma_rwctrl[769f4000] dma_mask[64-bit]
[   27.371083] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[   27.413388] ehci-pci: EHCI PCI platform driver
[   27.444298] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[   27.483890] ehci-pci 0003:00:01.2: EHCI Host Controller
[   27.515594] ehci-pci 0003:00:01.2: new USB bus registered, assigned bus number 1
[   27.561329] ehci-pci 0003:00:01.2: irq 21, io mem 0x34780002000
[   27.602979] ehci-pci 0003:00:01.2: USB 2.0 started, EHCI 1.00
[   27.639547] hub 1-0:1.0: USB hub found
[   27.662086] hub 1-0:1.0: 5 ports detected
[   27.687335] ohci_hcd 0003:00:01.0: OHCI Host Controller
[   27.718695] ohci_hcd 0003:00:01.0: new USB bus registered, assigned bus number 2
[   27.763128] ohci_hcd 0003:00:01.0: irq 21, io mem 0x34780000000
[   27.879080] hub 2-0:1.0: USB hub found
[   27.901608] hub 2-0:1.0: 3 ports detected
[   27.926261] ohci_hcd 0003:00:01.1: OHCI Host Controller
[   27.957619] ohci_hcd 0003:00:01.1: new USB bus registered, assigned bus number 3
[   27.957668] ohci_hcd 0003:00:01.1: irq 21, io mem 0x34780001000
[   28.037674] hub 3-0:1.0: USB hub found
[   28.037699] hub 3-0:1.0: 2 ports detected
[   28.932303] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
[   28.995421] NET: Registered protocol family 17
[   29.935487] tg3 0000:00:01.0 eth0: Link is up at 1000 Mbps, full duplex
[   29.975345] tg3 0000:00:01.0 eth0: Flow control is on for TX and on for RX
[   30.017138] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[   33.536157] FS-Cache: Loaded
[   33.579120] FS-Cache: Netfs 'nfs' registered for caching
[   33.644356] NFS: Registering the id_resolver key type
[   33.674914] Key type id_resolver registered
[   33.700043] Key type id_legacy registered
[   34.603362] dracut: Mounted root filesystem 192.168.100.1:/export/gentoo/root-ppc64
[   35.043969] dracut: Switching root
[   36.916516] systemd-udevd[375]: starting version 200
[   37.676340] systemd-udevd[387]: renamed network interface eth1 to enp0s1f1
[   37.906905] rtc-generic rtc-generic: rtc core: registered rtc-generic as rtc0
[   37.980118] mlx4_core: Mellanox ConnectX core driver v1.1 (Dec, 2011)
[   37.980232] mlx4_core: Initializing 0005:01:00.0
[   37.980484] mlx4_core 0005:01:00.0: enabling device (0140 -> 0142)
[   43.360940] mlx4_core 0005:01:00.0: command 0xc failed: fw status = 0x40
[   43.361874] mlx4_core 0005:01:00.0: command 0xc failed: fw status = 0x40
[   45.330025] <mlx4_ib> mlx4_ib_add: mlx4_ib: Mellanox ConnectX InfiniBand driver v1.0 (April 4, 2008)
[   54.036776] mlx4_core 0005:01:00.0: command 0x5a failed: fw status = 0x2

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply


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