All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] powerpc: Add iommu domain pointer to device archdata
@ 2013-07-15  4:50 ` Varun Sethi
  0 siblings, 0 replies; 20+ messages in thread
From: Varun Sethi @ 2013-07-15  4:50 UTC (permalink / raw)
  To: joro, iommu, linuxppc-dev, linux-kernel, benh, galak,
	alex.williamson, stuart.yoder, scottwood
  Cc: Varun Sethi

Add an iommu domain pointer to device (powerpc) archdata.  Devices
are attached to iommu domains and this pointer provides a mechanism
to correlate between a device and the associated iommu domain.  This
field is set when a device is attached to a domain.

Signed-off-by: Varun Sethi <Varun.Sethi@freescale.com>
Acked-by: Kumar Gala <galak@kernel.crashing.org>
---
- rebased patch to 3.11-rc1
 arch/powerpc/include/asm/device.h |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h
index 77e97dd..38faede 100644
--- a/arch/powerpc/include/asm/device.h
+++ b/arch/powerpc/include/asm/device.h
@@ -28,6 +28,9 @@ struct dev_archdata {
 		void		*iommu_table_base;
 	} dma_data;
 
+#ifdef CONFIG_IOMMU_API
+	void			*iommu_domain;
+#endif
 #ifdef CONFIG_SWIOTLB
 	dma_addr_t		max_direct_dma_addr;
 #endif
-- 
1.7.4.1



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 1/3] powerpc: Add iommu domain pointer to device archdata
@ 2013-07-15  4:50 ` Varun Sethi
  0 siblings, 0 replies; 20+ messages in thread
From: Varun Sethi @ 2013-07-15  4:50 UTC (permalink / raw)
  To: joro-zLv9SwRftAIdnm+yROfE0A,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r,
	galak-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r,
	alex.williamson-H+wXaHxf7aLQT0dZR+AlfA,
	stuart.yoder-KZfg59tc24xl57MIdRCFDg,
	scottwood-KZfg59tc24xl57MIdRCFDg
  Cc: Varun Sethi

Add an iommu domain pointer to device (powerpc) archdata.  Devices
are attached to iommu domains and this pointer provides a mechanism
to correlate between a device and the associated iommu domain.  This
field is set when a device is attached to a domain.

Signed-off-by: Varun Sethi <Varun.Sethi-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
Acked-by: Kumar Gala <galak-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r@public.gmane.org>
---
- rebased patch to 3.11-rc1
 arch/powerpc/include/asm/device.h |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h
index 77e97dd..38faede 100644
--- a/arch/powerpc/include/asm/device.h
+++ b/arch/powerpc/include/asm/device.h
@@ -28,6 +28,9 @@ struct dev_archdata {
 		void		*iommu_table_base;
 	} dma_data;
 
+#ifdef CONFIG_IOMMU_API
+	void			*iommu_domain;
+#endif
 #ifdef CONFIG_SWIOTLB
 	dma_addr_t		max_direct_dma_addr;
 #endif
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 2/3 v19] iommu/fsl: Add additional iommu attributes required by the PAMU driver.
  2013-07-15  4:50 ` Varun Sethi
@ 2013-07-15  4:50   ` Varun Sethi
  -1 siblings, 0 replies; 20+ messages in thread
From: Varun Sethi @ 2013-07-15  4:50 UTC (permalink / raw)
  To: joro, iommu, linuxppc-dev, linux-kernel, benh, galak,
	alex.williamson, stuart.yoder, scottwood
  Cc: Varun Sethi

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>
---
v19:
- rebased to 3.11-rc1
- no changes since v16
v16 changes:
- rebased to 3.10-rc6
v15 changes:
- Moved fsl_pamu_stash.h under arch/powerpc/include/asm.
v14 changes:
- Add FSL prefix to PAMU attributes.
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.
 arch/powerpc/include/asm/fsl_pamu_stash.h |   39 +++++++++++++++++++++++++++++
 include/linux/iommu.h                     |   16 ++++++++++++
 2 files changed, 55 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/include/asm/fsl_pamu_stash.h

diff --git a/arch/powerpc/include/asm/fsl_pamu_stash.h b/arch/powerpc/include/asm/fsl_pamu_stash.h
new file mode 100644
index 0000000..caa1b21
--- /dev/null
+++ b/arch/powerpc/include/asm/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 3aeb730..7ea319e 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -58,10 +58,26 @@ struct iommu_domain {
 #define IOMMU_CAP_CACHE_COHERENCY	0x1
 #define IOMMU_CAP_INTR_REMAP		0x2	/* isolates device intrs */
 
+/*
+ * Following constraints are specifc to FSL_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_FSL_PAMU_STASH,
+	DOMAIN_ATTR_FSL_PAMU_ENABLE,
+	DOMAIN_ATTR_FSL_PAMUV1,
 	DOMAIN_ATTR_MAX,
 };
 
-- 
1.7.4.1



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 2/3 v19] iommu/fsl: Add additional iommu attributes required by the PAMU driver.
@ 2013-07-15  4:50   ` Varun Sethi
  0 siblings, 0 replies; 20+ messages in thread
From: Varun Sethi @ 2013-07-15  4:50 UTC (permalink / raw)
  To: joro, iommu, linuxppc-dev, linux-kernel, benh, galak,
	alex.williamson, stuart.yoder, scottwood
  Cc: Varun Sethi

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>
---
v19:
- rebased to 3.11-rc1
- no changes since v16
v16 changes:
- rebased to 3.10-rc6
v15 changes:
- Moved fsl_pamu_stash.h under arch/powerpc/include/asm.
v14 changes:
- Add FSL prefix to PAMU attributes.
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.
 arch/powerpc/include/asm/fsl_pamu_stash.h |   39 +++++++++++++++++++++++++++++
 include/linux/iommu.h                     |   16 ++++++++++++
 2 files changed, 55 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/include/asm/fsl_pamu_stash.h

diff --git a/arch/powerpc/include/asm/fsl_pamu_stash.h b/arch/powerpc/include/asm/fsl_pamu_stash.h
new file mode 100644
index 0000000..caa1b21
--- /dev/null
+++ b/arch/powerpc/include/asm/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 3aeb730..7ea319e 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -58,10 +58,26 @@ struct iommu_domain {
 #define IOMMU_CAP_CACHE_COHERENCY	0x1
 #define IOMMU_CAP_INTR_REMAP		0x2	/* isolates device intrs */
 
+/*
+ * Following constraints are specifc to FSL_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_FSL_PAMU_STASH,
+	DOMAIN_ATTR_FSL_PAMU_ENABLE,
+	DOMAIN_ATTR_FSL_PAMUV1,
 	DOMAIN_ATTR_MAX,
 };
 
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 3/3 v18] iommu/fsl: Freescale PAMU driver and iommu implementation.
@ 2013-07-15  4:50   ` Varun Sethi
  0 siblings, 0 replies; 20+ messages in thread
From: Varun Sethi @ 2013-07-15  4:50 UTC (permalink / raw)
  To: joro, iommu, linuxppc-dev, linux-kernel, benh, galak,
	alex.williamson, stuart.yoder, scottwood
  Cc: Varun Sethi, Timur Tabi

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.

[For iommu group support]
Acked-by: Alex Williamson <alex.williamson@redhat.com>

Signed-off-by: Timur Tabi <timur@tabi.org>
Signed-off-by: Varun Sethi <Varun.Sethi@freescale.com>

---
changes in v19:
- rebased to 3.11-rc1
changes in v18:
- Merged the two loops for searching shared iommu_group
in to a single loop.
- Renamed function used for searching shared iommu groups.
changes in v17
- Fixed iommu group check for peer/parent bus devices.
- Check for ACS till root node while allocating device
groups.
- Fix the reference to pdev instead of dma_dev.
changes in v16
- rebased to kernel 3.10-rc6
changes in v15:
- Updated path for fsl_pamu_stash.h.
changes in v14:
- Use updated PAMU specific attributes.
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 | 1172 +++++++++++++++++++++++++++++++++++
 drivers/iommu/fsl_pamu_domain.h |   85 +++
 7 files changed, 2992 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 72b5625..1e01291 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/arch/powerpc/sysdev/fsl_pci.h
@@ -16,6 +16,11 @@
 
 struct platform_device;
 
+
+/* 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 820d85c..fe302e3 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 bbe7041..14c1f47 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -16,3 +16,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..a831fee
--- /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_debug("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_debug("Invalid primary paace entry\n");
+		return -ENOENT;
+	}
+
+	if (!get_bf(ppaace->addr_bitfields, PPAACE_AF_WSE)) {
+		pr_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("window size too small or not a power of two %llx\n", win_size);
+		return -EINVAL;
+	}
+
+	if (win_addr & (win_size - 1)) {
+		pr_debug("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_debug("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_debug("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_debug("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_debug("Invalid liodn entry\n");
+		return -ENOENT;
+	}
+
+	if (!is_power_of_2(subwin_size) || subwin_size < PAMU_PAGE_SIZE) {
+		pr_debug("subwindow size out of range, or not a power of 2\n");
+		return -EINVAL;
+	}
+
+	if (rpn == ULONG_MAX) {
+		pr_debug("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_debug("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_debug("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_debug("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_debug("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_debug("Invalid node for cache hierarchy %s\n",
+				node->full_name);
+			return ~(u32)0;
+		}
+	}
+
+	pr_debug("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_debug("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..8fc1a12
--- /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 <asm/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..14d803a
--- /dev/null
+++ b/drivers/iommu/fsl_pamu_domain.c
@@ -0,0 +1,1172 @@
+/*
+ * 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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("%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_debug("%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_ATOMIC);
+
+	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_debug("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_debug("Number of windows not configured\n");
+		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+		return;
+	}
+
+	if (wnd_nr >= dma_domain->win_cnt) {
+		pr_debug("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_debug("Number of windows not configured\n");
+		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+		return -ENODEV;
+	}
+
+	if (wnd_nr >= dma_domain->win_cnt) {
+		pr_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("Invalid PAMU geometry attributes\n");
+			return -EINVAL;
+		}
+
+	spin_lock_irqsave(&dma_domain->domain_lock, flags);
+	if (dma_domain->enabled) {
+		pr_debug("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_debug("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_debug("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_debug("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_FSL_PAMU_STASH:
+		ret = configure_domain_stash(dma_domain, data);
+		break;
+	case DOMAIN_ATTR_FSL_PAMU_ENABLE:
+		ret = configure_domain_dma_state(dma_domain, *(int *)data);
+		break;
+	default:
+		pr_debug("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_FSL_PAMU_STASH:
+		memcpy((struct pamu_stash_attribute *) data, &dma_domain->dma_stash,
+				 sizeof(struct pamu_stash_attribute));
+		break;
+	case DOMAIN_ATTR_FSL_PAMU_ENABLE:
+		*(int *)data = dma_domain->enabled;
+		break;
+	case DOMAIN_ATTR_FSL_PAMUV1:
+		*(int *)data = DOMAIN_ATTR_FSL_PAMUV1;
+		break;
+	default:
+		pr_debug("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;
+}
+
+/* Get iommu group information from peer devices or devices on the parent bus */
+static struct iommu_group *get_shared_pci_device_group(struct pci_dev *pdev)
+{
+	struct pci_dev *tmp;
+	struct iommu_group *group;
+	struct pci_bus *bus = pdev->bus;
+
+	/* 
+	 * Traverese the pci bus device list to get
+	 * the shared iommu group.
+	 */
+	while (bus) {
+		list_for_each_entry(tmp, &bus->devices, bus_list) {
+			if (tmp == pdev)
+				continue;
+			group = iommu_group_get(&tmp->dev);
+			if (group)
+				return group;
+		}
+
+		bus = bus->parent;
+	}
+
+	return NULL;
+}
+
+static struct iommu_group *get_pci_device_group(struct pci_dev *pdev)
+{
+	struct pci_controller *pci_ctl;
+	bool pci_endpt_partioning;
+	struct iommu_group *group = NULL;
+	struct pci_dev *bridge, *dma_pdev = NULL;
+
+	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 lowest numbered
+		 * function that also does not suport the required ACS flags.
+		 */
+		if (dma_pdev->multifunction &&
+		    !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) {
+			u8 i, slot = PCI_SLOT(dma_pdev->devfn);
+
+			for (i = 0; i < 8; i++) {
+				struct pci_dev *tmp;
+
+				tmp = pci_get_slot(dma_pdev->bus, PCI_DEVFN(slot, i));
+				if (!tmp)
+					continue;
+
+				if (!pci_acs_enabled(tmp, REQ_ACS_FLAGS)) {
+					swap_pci_ref(&dma_pdev, tmp);
+					break;
+				}
+				pci_dev_put(tmp);
+			}
+		}
+
+		/*
+		 * Devices on the root bus go through the iommu.  If that's not us,
+	 	 * find the next upstream device and test ACS up to the root bus.
+		 * Finding the next device may require skipping virtual buses.
+		 */
+		while (!pci_is_root_bus(dma_pdev->bus)) {
+			struct pci_bus *bus = dma_pdev->bus;
+
+			while (!bus->self) {
+				if (!pci_is_root_bus(bus))
+					bus = bus->parent;
+				else
+					goto root_bus;
+			}
+
+			if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS))
+				break;
+
+			swap_pci_ref(&dma_pdev, pci_dev_get(bus->self));
+		}
+
+root_bus:
+		group = get_device_iommu_group(&dma_pdev->dev);
+		pci_dev_put(dma_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_shared_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_debug("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_debug("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_debug("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_ATOMIC);
+		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	[flat|nested] 20+ messages in thread

* [PATCH 3/3 v18] iommu/fsl: Freescale PAMU driver and iommu implementation.
@ 2013-07-15  4:50   ` Varun Sethi
  0 siblings, 0 replies; 20+ messages in thread
From: Varun Sethi @ 2013-07-15  4:50 UTC (permalink / raw)
  To: joro-zLv9SwRftAIdnm+yROfE0A,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r,
	galak-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r,
	alex.williamson-H+wXaHxf7aLQT0dZR+AlfA,
	stuart.yoder-KZfg59tc24xl57MIdRCFDg,
	scottwood-KZfg59tc24xl57MIdRCFDg
  Cc: Varun Sethi, Timur Tabi

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.

[For iommu group support]
Acked-by: Alex Williamson <alex.williamson-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

Signed-off-by: Timur Tabi <timur-N01EOCouUvQ@public.gmane.org>
Signed-off-by: Varun Sethi <Varun.Sethi-KZfg59tc24xl57MIdRCFDg@public.gmane.org>

---
changes in v19:
- rebased to 3.11-rc1
changes in v18:
- Merged the two loops for searching shared iommu_group
in to a single loop.
- Renamed function used for searching shared iommu groups.
changes in v17
- Fixed iommu group check for peer/parent bus devices.
- Check for ACS till root node while allocating device
groups.
- Fix the reference to pdev instead of dma_dev.
changes in v16
- rebased to kernel 3.10-rc6
changes in v15:
- Updated path for fsl_pamu_stash.h.
changes in v14:
- Use updated PAMU specific attributes.
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 | 1172 +++++++++++++++++++++++++++++++++++
 drivers/iommu/fsl_pamu_domain.h |   85 +++
 7 files changed, 2992 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 72b5625..1e01291 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/arch/powerpc/sysdev/fsl_pci.h
@@ -16,6 +16,11 @@
 
 struct platform_device;
 
+
+/* 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 820d85c..fe302e3 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 bbe7041..14c1f47 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -16,3 +16,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..a831fee
--- /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_debug("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_debug("Invalid primary paace entry\n");
+		return -ENOENT;
+	}
+
+	if (!get_bf(ppaace->addr_bitfields, PPAACE_AF_WSE)) {
+		pr_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("window size too small or not a power of two %llx\n", win_size);
+		return -EINVAL;
+	}
+
+	if (win_addr & (win_size - 1)) {
+		pr_debug("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_debug("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_debug("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_debug("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_debug("Invalid liodn entry\n");
+		return -ENOENT;
+	}
+
+	if (!is_power_of_2(subwin_size) || subwin_size < PAMU_PAGE_SIZE) {
+		pr_debug("subwindow size out of range, or not a power of 2\n");
+		return -EINVAL;
+	}
+
+	if (rpn == ULONG_MAX) {
+		pr_debug("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_debug("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_debug("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_debug("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_debug("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_debug("Invalid node for cache hierarchy %s\n",
+				node->full_name);
+			return ~(u32)0;
+		}
+	}
+
+	pr_debug("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_debug("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..8fc1a12
--- /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 <asm/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..14d803a
--- /dev/null
+++ b/drivers/iommu/fsl_pamu_domain.c
@@ -0,0 +1,1172 @@
+/*
+ * 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-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
+ *
+ */
+
+#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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("%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_debug("%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_ATOMIC);
+
+	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_debug("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_debug("Number of windows not configured\n");
+		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+		return;
+	}
+
+	if (wnd_nr >= dma_domain->win_cnt) {
+		pr_debug("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_debug("Number of windows not configured\n");
+		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+		return -ENODEV;
+	}
+
+	if (wnd_nr >= dma_domain->win_cnt) {
+		pr_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("Invalid PAMU geometry attributes\n");
+			return -EINVAL;
+		}
+
+	spin_lock_irqsave(&dma_domain->domain_lock, flags);
+	if (dma_domain->enabled) {
+		pr_debug("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_debug("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_debug("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_debug("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_FSL_PAMU_STASH:
+		ret = configure_domain_stash(dma_domain, data);
+		break;
+	case DOMAIN_ATTR_FSL_PAMU_ENABLE:
+		ret = configure_domain_dma_state(dma_domain, *(int *)data);
+		break;
+	default:
+		pr_debug("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_FSL_PAMU_STASH:
+		memcpy((struct pamu_stash_attribute *) data, &dma_domain->dma_stash,
+				 sizeof(struct pamu_stash_attribute));
+		break;
+	case DOMAIN_ATTR_FSL_PAMU_ENABLE:
+		*(int *)data = dma_domain->enabled;
+		break;
+	case DOMAIN_ATTR_FSL_PAMUV1:
+		*(int *)data = DOMAIN_ATTR_FSL_PAMUV1;
+		break;
+	default:
+		pr_debug("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;
+}
+
+/* Get iommu group information from peer devices or devices on the parent bus */
+static struct iommu_group *get_shared_pci_device_group(struct pci_dev *pdev)
+{
+	struct pci_dev *tmp;
+	struct iommu_group *group;
+	struct pci_bus *bus = pdev->bus;
+
+	/* 
+	 * Traverese the pci bus device list to get
+	 * the shared iommu group.
+	 */
+	while (bus) {
+		list_for_each_entry(tmp, &bus->devices, bus_list) {
+			if (tmp == pdev)
+				continue;
+			group = iommu_group_get(&tmp->dev);
+			if (group)
+				return group;
+		}
+
+		bus = bus->parent;
+	}
+
+	return NULL;
+}
+
+static struct iommu_group *get_pci_device_group(struct pci_dev *pdev)
+{
+	struct pci_controller *pci_ctl;
+	bool pci_endpt_partioning;
+	struct iommu_group *group = NULL;
+	struct pci_dev *bridge, *dma_pdev = NULL;
+
+	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 lowest numbered
+		 * function that also does not suport the required ACS flags.
+		 */
+		if (dma_pdev->multifunction &&
+		    !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) {
+			u8 i, slot = PCI_SLOT(dma_pdev->devfn);
+
+			for (i = 0; i < 8; i++) {
+				struct pci_dev *tmp;
+
+				tmp = pci_get_slot(dma_pdev->bus, PCI_DEVFN(slot, i));
+				if (!tmp)
+					continue;
+
+				if (!pci_acs_enabled(tmp, REQ_ACS_FLAGS)) {
+					swap_pci_ref(&dma_pdev, tmp);
+					break;
+				}
+				pci_dev_put(tmp);
+			}
+		}
+
+		/*
+		 * Devices on the root bus go through the iommu.  If that's not us,
+	 	 * find the next upstream device and test ACS up to the root bus.
+		 * Finding the next device may require skipping virtual buses.
+		 */
+		while (!pci_is_root_bus(dma_pdev->bus)) {
+			struct pci_bus *bus = dma_pdev->bus;
+
+			while (!bus->self) {
+				if (!pci_is_root_bus(bus))
+					bus = bus->parent;
+				else
+					goto root_bus;
+			}
+
+			if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS))
+				break;
+
+			swap_pci_ref(&dma_pdev, pci_dev_get(bus->self));
+		}
+
+root_bus:
+		group = get_device_iommu_group(&dma_pdev->dev);
+		pci_dev_put(dma_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_shared_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_debug("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_debug("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_debug("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_ATOMIC);
+		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	[flat|nested] 20+ messages in thread

* RE: [PATCH 3/3 v18] iommu/fsl: Freescale PAMU driver and iommu implementation.
  2013-07-15  4:50   ` Varun Sethi
  (?)
@ 2013-07-29 12:14     ` Sethi Varun-B16395
  -1 siblings, 0 replies; 20+ messages in thread
From: Sethi Varun-B16395 @ 2013-07-29 12:14 UTC (permalink / raw)
  To: Sethi Varun-B16395, joro, iommu, linuxppc-dev, linux-kernel,
	benh, galak, alex.williamson, Yoder Stuart-B08248,
	Wood Scott-B07421
  Cc: Timur Tabi

Hi Joerg,
Do you have any further comments on this patch set?

Regards
Varun

> -----Original Message-----
> From: Sethi Varun-B16395
> Sent: Monday, July 15, 2013 10:21 AM
> To: joro@8bytes.org; iommu@lists.linux-foundation.org; linuxppc-
> dev@lists.ozlabs.org; linux-kernel@vger.kernel.org;
> benh@kernel.crashing.org; galak@kernel.crashing.org;
> alex.williamson@redhat.com; Yoder Stuart-B08248; Wood Scott-B07421
> Cc: Sethi Varun-B16395; Timur Tabi
> Subject: [PATCH 3/3 v18] iommu/fsl: Freescale PAMU driver and iommu
> implementation.
> 
> 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.
> 
> [For iommu group support]
> Acked-by: Alex Williamson <alex.williamson@redhat.com>
> 
> Signed-off-by: Timur Tabi <timur@tabi.org>
> Signed-off-by: Varun Sethi <Varun.Sethi@freescale.com>
> 
> ---
> changes in v19:
> - rebased to 3.11-rc1
> changes in v18:
> - Merged the two loops for searching shared iommu_group
> in to a single loop.
> - Renamed function used for searching shared iommu groups.
> changes in v17
> - Fixed iommu group check for peer/parent bus devices.
> - Check for ACS till root node while allocating device
> groups.
> - Fix the reference to pdev instead of dma_dev.
> changes in v16
> - rebased to kernel 3.10-rc6
> changes in v15:
> - Updated path for fsl_pamu_stash.h.
> changes in v14:
> - Use updated PAMU specific attributes.
> 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 | 1172
> +++++++++++++++++++++++++++++++++++
>  drivers/iommu/fsl_pamu_domain.h |   85 +++
>  7 files changed, 2992 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 72b5625..1e01291 100644
> --- a/arch/powerpc/sysdev/fsl_pci.h
> +++ b/arch/powerpc/sysdev/fsl_pci.h
> @@ -16,6 +16,11 @@
> 
>  struct platform_device;
> 
> +
> +/* 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 820d85c..fe302e3 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 bbe7041..14c1f47 100644
> --- a/drivers/iommu/Makefile
> +++ b/drivers/iommu/Makefile
> @@ -16,3 +16,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..a831fee
> --- /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_debug("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_debug("Invalid primary paace entry\n");
> +		return -ENOENT;
> +	}
> +
> +	if (!get_bf(ppaace->addr_bitfields, PPAACE_AF_WSE)) {
> +		pr_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("window size too small or not a power of two
> %llx\n", win_size);
> +		return -EINVAL;
> +	}
> +
> +	if (win_addr & (win_size - 1)) {
> +		pr_debug("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_debug("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_debug("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_debug("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_debug("Invalid liodn entry\n");
> +		return -ENOENT;
> +	}
> +
> +	if (!is_power_of_2(subwin_size) || subwin_size < PAMU_PAGE_SIZE) {
> +		pr_debug("subwindow size out of range, or not a power of
> 2\n");
> +		return -EINVAL;
> +	}
> +
> +	if (rpn == ULONG_MAX) {
> +		pr_debug("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_debug("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_debug("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_debug("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_debug("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_debug("Invalid node for cache hierarchy %s\n",
> +				node->full_name);
> +			return ~(u32)0;
> +		}
> +	}
> +
> +	pr_debug("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_debug("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..8fc1a12
> --- /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 <asm/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..14d803a
> --- /dev/null
> +++ b/drivers/iommu/fsl_pamu_domain.c
> @@ -0,0 +1,1172 @@
> +/*
> + * 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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("%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_debug("%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_ATOMIC);
> +
> +	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_debug("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_debug("Number of windows not configured\n");
> +		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
> +		return;
> +	}
> +
> +	if (wnd_nr >= dma_domain->win_cnt) {
> +		pr_debug("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_debug("Number of windows not configured\n");
> +		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
> +		return -ENODEV;
> +	}
> +
> +	if (wnd_nr >= dma_domain->win_cnt) {
> +		pr_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("Invalid PAMU geometry attributes\n");
> +			return -EINVAL;
> +		}
> +
> +	spin_lock_irqsave(&dma_domain->domain_lock, flags);
> +	if (dma_domain->enabled) {
> +		pr_debug("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_debug("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_debug("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_debug("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_FSL_PAMU_STASH:
> +		ret = configure_domain_stash(dma_domain, data);
> +		break;
> +	case DOMAIN_ATTR_FSL_PAMU_ENABLE:
> +		ret = configure_domain_dma_state(dma_domain, *(int *)data);
> +		break;
> +	default:
> +		pr_debug("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_FSL_PAMU_STASH:
> +		memcpy((struct pamu_stash_attribute *) data, &dma_domain-
> >dma_stash,
> +				 sizeof(struct pamu_stash_attribute));
> +		break;
> +	case DOMAIN_ATTR_FSL_PAMU_ENABLE:
> +		*(int *)data = dma_domain->enabled;
> +		break;
> +	case DOMAIN_ATTR_FSL_PAMUV1:
> +		*(int *)data = DOMAIN_ATTR_FSL_PAMUV1;
> +		break;
> +	default:
> +		pr_debug("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;
> +}
> +
> +/* Get iommu group information from peer devices or devices on the
> parent bus */
> +static struct iommu_group *get_shared_pci_device_group(struct pci_dev
> *pdev)
> +{
> +	struct pci_dev *tmp;
> +	struct iommu_group *group;
> +	struct pci_bus *bus = pdev->bus;
> +
> +	/*
> +	 * Traverese the pci bus device list to get
> +	 * the shared iommu group.
> +	 */
> +	while (bus) {
> +		list_for_each_entry(tmp, &bus->devices, bus_list) {
> +			if (tmp == pdev)
> +				continue;
> +			group = iommu_group_get(&tmp->dev);
> +			if (group)
> +				return group;
> +		}
> +
> +		bus = bus->parent;
> +	}
> +
> +	return NULL;
> +}
> +
> +static struct iommu_group *get_pci_device_group(struct pci_dev *pdev)
> +{
> +	struct pci_controller *pci_ctl;
> +	bool pci_endpt_partioning;
> +	struct iommu_group *group = NULL;
> +	struct pci_dev *bridge, *dma_pdev = NULL;
> +
> +	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 lowest
> numbered
> +		 * function that also does not suport the required ACS flags.
> +		 */
> +		if (dma_pdev->multifunction &&
> +		    !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) {
> +			u8 i, slot = PCI_SLOT(dma_pdev->devfn);
> +
> +			for (i = 0; i < 8; i++) {
> +				struct pci_dev *tmp;
> +
> +				tmp = pci_get_slot(dma_pdev->bus, PCI_DEVFN(slot,
> i));
> +				if (!tmp)
> +					continue;
> +
> +				if (!pci_acs_enabled(tmp, REQ_ACS_FLAGS)) {
> +					swap_pci_ref(&dma_pdev, tmp);
> +					break;
> +				}
> +				pci_dev_put(tmp);
> +			}
> +		}
> +
> +		/*
> +		 * Devices on the root bus go through the iommu.  If that's
> not us,
> +	 	 * find the next upstream device and test ACS up to the root
> bus.
> +		 * Finding the next device may require skipping virtual
> buses.
> +		 */
> +		while (!pci_is_root_bus(dma_pdev->bus)) {
> +			struct pci_bus *bus = dma_pdev->bus;
> +
> +			while (!bus->self) {
> +				if (!pci_is_root_bus(bus))
> +					bus = bus->parent;
> +				else
> +					goto root_bus;
> +			}
> +
> +			if (pci_acs_path_enabled(bus->self, NULL,
> REQ_ACS_FLAGS))
> +				break;
> +
> +			swap_pci_ref(&dma_pdev, pci_dev_get(bus->self));
> +		}
> +
> +root_bus:
> +		group = get_device_iommu_group(&dma_pdev->dev);
> +		pci_dev_put(dma_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_shared_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_debug("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_debug("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_debug("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_ATOMIC);
> +		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	[flat|nested] 20+ messages in thread

* RE: [PATCH 3/3 v18] iommu/fsl: Freescale PAMU driver and iommu implementation.
@ 2013-07-29 12:14     ` Sethi Varun-B16395
  0 siblings, 0 replies; 20+ messages in thread
From: Sethi Varun-B16395 @ 2013-07-29 12:14 UTC (permalink / raw)
  To: Sethi Varun-B16395, joro, iommu, linuxppc-dev, linux-kernel,
	benh, galak, alex.williamson, Yoder Stuart-B08248,
	Wood Scott-B07421
  Cc: Timur Tabi

Hi Joerg,
Do you have any further comments on this patch set?

Regards
Varun

> -----Original Message-----
> From: Sethi Varun-B16395
> Sent: Monday, July 15, 2013 10:21 AM
> To: joro@8bytes.org; iommu@lists.linux-foundation.org; linuxppc-
> dev@lists.ozlabs.org; linux-kernel@vger.kernel.org;
> benh@kernel.crashing.org; galak@kernel.crashing.org;
> alex.williamson@redhat.com; Yoder Stuart-B08248; Wood Scott-B07421
> Cc: Sethi Varun-B16395; Timur Tabi
> Subject: [PATCH 3/3 v18] iommu/fsl: Freescale PAMU driver and iommu
> implementation.
>=20
> 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.
>=20
> 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.
>=20
> 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.
>=20
> 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.
>=20
> [For iommu group support]
> Acked-by: Alex Williamson <alex.williamson@redhat.com>
>=20
> Signed-off-by: Timur Tabi <timur@tabi.org>
> Signed-off-by: Varun Sethi <Varun.Sethi@freescale.com>
>=20
> ---
> changes in v19:
> - rebased to 3.11-rc1
> changes in v18:
> - Merged the two loops for searching shared iommu_group
> in to a single loop.
> - Renamed function used for searching shared iommu groups.
> changes in v17
> - Fixed iommu group check for peer/parent bus devices.
> - Check for ACS till root node while allocating device
> groups.
> - Fix the reference to pdev instead of dma_dev.
> changes in v16
> - rebased to kernel 3.10-rc6
> changes in v15:
> - Updated path for fsl_pamu_stash.h.
> changes in v14:
> - Use updated PAMU specific attributes.
> 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 | 1172
> +++++++++++++++++++++++++++++++++++
>  drivers/iommu/fsl_pamu_domain.h |   85 +++
>  7 files changed, 2992 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
>=20
> diff --git a/arch/powerpc/sysdev/fsl_pci.h
> b/arch/powerpc/sysdev/fsl_pci.h
> index 72b5625..1e01291 100644
> --- a/arch/powerpc/sysdev/fsl_pci.h
> +++ b/arch/powerpc/sysdev/fsl_pci.h
> @@ -16,6 +16,11 @@
>=20
>  struct platform_device;
>=20
> +
> +/* 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 820d85c..fe302e3 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -17,6 +17,16 @@ config OF_IOMMU
>         def_bool y
>         depends on OF
>=20
> +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 bbe7041..14c1f47 100644
> --- a/drivers/iommu/Makefile
> +++ b/drivers/iommu/Makefile
> @@ -16,3 +16,4 @@ obj-$(CONFIG_TEGRA_IOMMU_SMMU) +=3D tegra-smmu.o
>  obj-$(CONFIG_EXYNOS_IOMMU) +=3D exynos-iommu.o
>  obj-$(CONFIG_SHMOBILE_IOMMU) +=3D shmobile-iommu.o
>  obj-$(CONFIG_SHMOBILE_IPMMU) +=3D shmobile-ipmmu.o
> +obj-$(CONFIG_FSL_PAMU) +=3D 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..a831fee
> --- /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[] =3D {
> +	{ .compatible =3D "fsl,qoriq-device-config-1.0", },
> +	{ .compatible =3D "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[] =3D {
> +	{ .compatible =3D "fsl,t4240-l3-cache-controller", },
> +	{ .compatible =3D "fsl,b4860-l3-cache-controller", },
> +	{ .compatible =3D "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 >=3D PAACE_NUMBER_ENTRIES) {
> +		pr_debug("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 =3D pamu_get_ppaace(liodn);
> +	if (!ppaace) {
> +		pr_debug("Invalid primary paace entry\n");
> +		return -ENOENT;
> +	}
> +
> +	if (!get_bf(ppaace->addr_bitfields, PPAACE_AF_WSE)) {
> +		pr_debug("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 =3D pamu_get_ppaace(liodn);
> +	if (!ppaace) {
> +		pr_debug("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 =3D NULL;
> +
> +	subwin_cnt =3D 1UL << (get_bf(paace->impl_attr, PAACE_IA_WCE) + 1);
> +
> +	if (wnum < subwin_cnt)
> +		spaace =3D &spaact[paace->fspi + wnum];
> +	else
> +		pr_debug("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 =3D 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 =3D pamu_get_ppaace(liodn);
> +	if (!ppaace) {
> +		pr_debug("Invalid liodn entry\n");
> +		return;
> +	}
> +
> +	if (get_bf(ppaace->addr_bitfields, PPAACE_AF_MW)) {
> +		subwin_cnt =3D 1UL << (get_bf(ppaace->impl_attr, PAACE_IA_WCE)
> + 1);
> +		size =3D (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 =3D pamu_get_ppaace(liodn);
> +	if (!paace) {
> +		pr_debug("Invalid liodn entry\n");
> +		return -ENOENT;
> +	}
> +	if (subwin) {
> +		paace =3D 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 =3D pamu_get_ppaace(liodn);
> +	if (!paace) {
> +		pr_debug("Invalid liodn entry\n");
> +		return -ENOENT;
> +	}
> +	if (subwin) {
> +		paace =3D 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 =3D=3D 0 then omi not define=
d
> + * @rpn: real (true physical) page number
> + * @stashid: cache stash id for associated cpu -- if ~stashid =3D=3D 0 t=
hen
> + *	     stashid not defined
> + * @snoopid: snoop id for hardware coherency -- if ~snoopid =3D=3D 0 the=
n
> + *	     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_debug("window size too small or not a power of two
> %llx\n", win_size);
> +		return -EINVAL;
> +	}
> +
> +	if (win_addr & (win_size - 1)) {
> +		pr_debug("window address is not aligned with window size\n");
> +		return -EINVAL;
> +	}
> +
> +	ppaace =3D 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 =3D 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 =3D omi;
> +	} else if (~omi !=3D 0) {
> +		pr_debug("bad operation mapping index: %d\n", omi);
> +		return -EINVAL;
> +	}
> +
> +	/* configure stash id */
> +	if (~stashid !=3D 0)
> +		set_bf(ppaace->impl_attr, PAACE_IA_CID, stashid);
> +
> +	/* configure snoop id */
> +	if (~snoopid !=3D 0)
> +		ppaace->domain_attr.to_host.snpid =3D snoopid;
> +
> +	if (subwin_cnt) {
> +		/* The first entry is in the primary PAACE instead */
> +		fspi =3D pamu_get_fspi_and_allocate(subwin_cnt - 1);
> +		if (fspi =3D=3D ULONG_MAX) {
> +			pr_debug("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 =3D fspi;
> +	} else {
> +		set_bf(ppaace->impl_attr, PAACE_IA_ATM,
> PAACE_ATM_WINDOW_XLATE);
> +		ppaace->twbah =3D 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 =3D=3D 0 the=
n
> + *			  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_debug("Invalid subwindow count\n");
> +		return -EINVAL;
> +	}
> +
> +	paace =3D pamu_get_ppaace(liodn);
> +	if (subwin > 0 && subwin < subwin_cnt && paace) {
> +		paace =3D 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_debug("Invalid liodn entry\n");
> +		return -ENOENT;
> +	}
> +
> +	if (!is_power_of_2(subwin_size) || subwin_size < PAMU_PAGE_SIZE) {
> +		pr_debug("subwindow size out of range, or not a power of
> 2\n");
> +		return -EINVAL;
> +	}
> +
> +	if (rpn =3D=3D ULONG_MAX) {
> +		pr_debug("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 =3D 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 !=3D 0)
> +		paace->domain_attr.to_host.snpid =3D 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 =3D omi;
> +	} else if (~omi !=3D 0) {
> +		pr_debug("bad operation mapping index: %d\n", omi);
> +		return -EINVAL;
> +	}
> +
> +	if (~stashid !=3D 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 =3D OMI_QMAN;
> +	if (of_device_is_compatible(dev->of_node, "fsl,qman"))
> +		*omi_index =3D 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 =3D 0;
> +	int i;
> +
> +	/* Fastpath, exit early if L3/CPC cache is target for stashing */
> +	if (stash_dest_hint =3D=3D PAMU_ATTR_CACHE_L3) {
> +		node =3D of_find_matching_node(NULL, l3_device_ids);
> +		if (node) {
> +			prop =3D of_get_property(node, "cache-stash-id", 0);
> +			if (!prop) {
> +				pr_debug("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 =3D of_get_property(node, "reg", &len);
> +		for (i =3D 0; i < len / sizeof(u32); i++) {
> +			if (be32_to_cpup(&prop[i]) =3D=3D vcpu) {
> +				found =3D 1;
> +				goto found_cpu_node;
> +			}
> +		}
> +	}
> +found_cpu_node:
> +
> +	/* find the hwnode that represents the cache */
> +	for (cache_level =3D PAMU_ATTR_CACHE_L1; (cache_level <
> PAMU_ATTR_CACHE_L3) && found; cache_level++) {
> +		if (stash_dest_hint =3D=3D cache_level) {
> +			prop =3D of_get_property(node, "cache-stash-id", 0);
> +			if (!prop) {
> +				pr_debug("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 =3D of_get_property(node, "next-level-cache", 0);
> +		if (!prop) {
> +			pr_debug("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 =3D of_find_node_by_phandle(*prop);
> +		if (!node) {
> +			pr_debug("Invalid node for cache hierarchy %s\n",
> +				node->full_name);
> +			return ~(u32)0;
> +		}
> +	}
> +
> +	pr_debug("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 =3D 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 =3D 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 =3D &omt[OMI_QMAN];
> +
> +	ome->moe[IOE_READ_IDX] =3D EOE_VALID | EOE_READ;
> +	ome->moe[IOE_EREAD0_IDX] =3D EOE_VALID | EOE_RSA;
> +	ome->moe[IOE_WRITE_IDX] =3D EOE_VALID | EOE_WRITE;
> +	ome->moe[IOE_EWRITE0_IDX] =3D EOE_VALID | EOE_WWSAO;
> +
> +	ome->moe[IOE_DIRECT0_IDX] =3D EOE_VALID | EOE_LDEC;
> +	ome->moe[IOE_DIRECT1_IDX] =3D EOE_VALID | EOE_LDECPE;
> +
> +	/* Configure OMI_FMAN */
> +	ome =3D &omt[OMI_FMAN];
> +	ome->moe[IOE_READ_IDX]  =3D EOE_VALID | EOE_READI;
> +	ome->moe[IOE_WRITE_IDX] =3D EOE_VALID | EOE_WRITE;
> +
> +	/* Configure OMI_QMAN private */
> +	ome =3D &omt[OMI_QMAN_PRIV];
> +	ome->moe[IOE_READ_IDX]  =3D EOE_VALID | EOE_READ;
> +	ome->moe[IOE_WRITE_IDX] =3D EOE_VALID | EOE_WRITE;
> +	ome->moe[IOE_EREAD0_IDX] =3D EOE_VALID | EOE_RSA;
> +	ome->moe[IOE_EWRITE0_IDX] =3D EOE_VALID | EOE_WWSA;
> +
> +	/* Configure OMI_CAAM */
> +	ome =3D &omt[OMI_CAAM];
> +	ome->moe[IOE_READ_IDX]  =3D EOE_VALID | EOE_READI;
> +	ome->moe[IOE_WRITE_IDX] =3D 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 =3D in_be32((u32 *)(pamu_reg_base + PAMU_PC3));
> +	/* Maximum number of subwindows per liodn */
> +	max_subwindow_count =3D 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 =3D (u32 *) (pamu_reg_base + PAMU_PC);
> +	pamu_regs =3D (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 =3D 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 =3D 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 =3D 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 =3D NULL;
> +	const u32 *prop;
> +
> +	for_each_node_with_property(node, "fsl,liodn") {
> +		prop =3D of_get_property(node, "fsl,liodn", &len);
> +		for (i =3D 0; i < len / sizeof(u32); i++) {
> +			int liodn;
> +
> +			liodn =3D be32_to_cpup(&prop[i]);
> +			if (liodn >=3D PAACE_NUMBER_ENTRIES) {
> +				pr_debug("Invalid LIODN value %d\n", liodn);
> +				continue;
> +			}
> +			ppaace =3D 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 =3D 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 =3D arg;
> +	phys_addr_t phys;
> +	unsigned int i, j, ret;
> +
> +	pr_emerg("fsl-pamu: access violation interrupt\n");
> +
> +	for (i =3D 0; i < data->count; i++) {
> +		void __iomem *p =3D data->pamu_reg_base + i * PAMU_OFFSET;
> +		u32 pics =3D in_be32(p + PAMU_PICS);
> +
> +		if (pics & PAMU_ACCESS_VIOLATION_STAT) {
> +			u32 avs1 =3D in_be32(p + PAMU_AVS1);
> +			struct paace *paace;
> +
> +			pr_emerg("POES1=3D%08x\n", in_be32(p + PAMU_POES1));
> +			pr_emerg("POES2=3D%08x\n", in_be32(p + PAMU_POES2));
> +			pr_emerg("AVS1=3D%08x\n", avs1);
> +			pr_emerg("AVS2=3D%08x\n", in_be32(p + PAMU_AVS2));
> +			pr_emerg("AVA=3D%016llx\n", make64(in_be32(p +
> PAMU_AVAH),
> +				in_be32(p + PAMU_AVAL)));
> +			pr_emerg("UDAD=3D%08x\n", in_be32(p + PAMU_UDAD));
> +			pr_emerg("POEA=3D%016llx\n", make64(in_be32(p +
> PAMU_POEAH),
> +				in_be32(p + PAMU_POEAL)));
> +
> +			phys =3D make64(in_be32(p + PAMU_POEAH),
> +				in_be32(p + PAMU_POEAL));
> +
> +			/* Assume that POEA points to a PAACE */
> +			if (phys) {
> +				u32 *paace =3D phys_to_virt(phys);
> +
> +				/* Only the first four words are relevant */
> +				for (j =3D 0; j < 4; j++)
> +					pr_emerg("PAACE[%u]=3D%08x\n", j,
> in_be32(paace + j));
> +			}
> +
> +			/* clear access violation condition */
> +			out_be32((p + PAMU_AVS1), avs1 & PAMU_AV_MASK);
> +			paace =3D 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 &=3D ~PAMU_ACCESS_VIOLATION_ENABLE;
> +			} else {
> +				/* Disable the LIODN */
> +				ret =3D 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 =3D NULL;	/* Local Access Control registers */
> +	struct ccsr_law __iomem *law;
> +	void __iomem *ccm =3D NULL;
> +	u32 __iomem *csdids;
> +	unsigned int i, num_laws, num_csds;
> +	u32 law_target =3D 0;
> +	u32 csd_id =3D 0;
> +	int ret =3D 0;
> +
> +	np =3D of_find_compatible_node(NULL, NULL, "fsl,corenet-law");
> +	if (!np)
> +		return -ENODEV;
> +
> +	iprop =3D of_get_property(np, "fsl,num-laws", NULL);
> +	if (!iprop) {
> +		ret =3D -ENODEV;
> +		goto error;
> +	}
> +
> +	num_laws =3D be32_to_cpup(iprop);
> +	if (!num_laws) {
> +		ret =3D -ENODEV;
> +		goto error;
> +	}
> +
> +	lac =3D of_iomap(np, 0);
> +	if (!lac) {
> +		ret =3D -ENODEV;
> +		goto error;
> +	}
> +
> +	/* LAW registers are at offset 0xC00 */
> +	law =3D lac + 0xC00;
> +
> +	of_node_put(np);
> +
> +	np =3D of_find_compatible_node(NULL, NULL, "fsl,corenet-cf");
> +	if (!np) {
> +		ret =3D -ENODEV;
> +		goto error;
> +	}
> +
> +	iprop =3D of_get_property(np, "fsl,ccf-num-csdids", NULL);
> +	if (!iprop) {
> +		ret =3D -ENODEV;
> +		goto error;
> +	}
> +
> +	num_csds =3D be32_to_cpup(iprop);
> +	if (!num_csds) {
> +		ret =3D -ENODEV;
> +		goto error;
> +	}
> +
> +	ccm =3D of_iomap(np, 0);
> +	if (!ccm) {
> +		ret =3D -ENOMEM;
> +		goto error;
> +	}
> +
> +	/* The undocumented CSDID registers are at offset 0x600 */
> +	csdids =3D ccm + 0x600;
> +
> +	of_node_put(np);
> +	np =3D NULL;
> +
> +	/* Find an unused coherence subdomain ID */
> +	for (csd_id =3D 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] =3D csd_port_id;
> +
> +	/* Find the DDR LAW that maps to our buffer. */
> +	for (i =3D 0; i < num_laws; i++) {
> +		if (law[i].lawar & LAWAR_EN) {
> +			phys_addr_t law_start, law_end;
> +
> +			law_start =3D make64(law[i].lawbarh, law[i].lawbarl);
> +			law_end =3D law_start +
> +				(2ULL << (law[i].lawar & LAWAR_SIZE_MASK));
> +
> +			if (law_start <=3D phys && phys < law_end) {
> +				law_target =3D law[i].lawar & LAWAR_TARGET_MASK;
> +				break;
> +			}
> +		}
> +	}
> +
> +	if (i =3D=3D 0 || i =3D=3D num_laws) {
> +		/* This should never happen*/
> +		ret =3D -ENOENT;
> +		goto error;
> +	}
> +
> +	/* Find a free LAW entry */
> +	while (law[--i].lawar & LAWAR_EN) {
> +		if (i =3D=3D 0) {
> +			/* No higher priority LAW slots available */
> +			ret =3D -ENOENT;
> +			goto error;
> +		}
> +	}
> +
> +	law[i].lawbarh =3D upper_32_bits(phys);
> +	law[i].lawbarl =3D lower_32_bits(phys);
> +	wmb();
> +	law[i].lawar =3D 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[] =3D {
> +	{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 =3D NULL;
> +	struct ccsr_guts __iomem *guts_regs =3D NULL;
> +	u32 pamubypenr, pamu_counter;
> +	unsigned long pamu_reg_off;
> +	unsigned long pamu_reg_base;
> +	struct pamu_isr_data *data =3D NULL;
> +	struct device_node *guts_node;
> +	u64 size;
> +	struct page *p;
> +	int ret =3D 0;
> +	int irq;
> +	phys_addr_t ppaact_phys;
> +	phys_addr_t spaact_phys;
> +	phys_addr_t omt_phys;
> +	size_t mem_size =3D 0;
> +	unsigned int order =3D 0;
> +	u32 csd_port_id =3D 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 =3D 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 =3D irq_of_parse_and_map(pdev->dev.of_node, 0);
> +	if (irq =3D=3D NO_IRQ) {
> +		dev_warn(&pdev->dev, "no interrupts listed in PAMU node\n");
> +		goto error;
> +	}
> +
> +	data =3D kzalloc(sizeof(struct pamu_isr_data), GFP_KERNEL);
> +	if (!data) {
> +		dev_err(&pdev->dev, "PAMU isr data memory allocation
> failed\n");
> +		ret =3D -ENOMEM;
> +		goto error;
> +	}
> +	data->pamu_reg_base =3D pamu_regs;
> +	data->count =3D size / PAMU_OFFSET;
> +
> +	/* The ISR needs access to the regs, so we won't iounmap them */
> +	ret =3D 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 =3D 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 =3D -ENODEV;
> +		goto error;
> +	}
> +
> +	guts_regs =3D of_iomap(guts_node, 0);
> +	of_node_put(guts_node);
> +	if (!guts_regs) {
> +		dev_err(&pdev->dev, "ioremap of GUTS node failed\n");
> +		ret =3D -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 =3D (PAGE_SIZE << get_order(PAACT_SIZE)) +
> +		(PAGE_SIZE << get_order(SPAACT_SIZE)) +
> +		(PAGE_SIZE << get_order(OMT_SIZE));
> +	order =3D get_order(mem_size);
> +
> +	p =3D alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
> +	if (!p) {
> +		dev_err(&pdev->dev, "unable to allocate PAACT/SPAACT/OMT
> block\n");
> +		ret =3D -ENOMEM;
> +		goto error;
> +	}
> +
> +	ppaact =3D page_address(p);
> +	ppaact_phys =3D 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 =3D -ENOMEM;
> +		goto error;
> +	}
> +
> +	spaact =3D (void *)ppaact + (PAGE_SIZE << get_order(PAACT_SIZE));
> +	omt =3D (void *)spaact + (PAGE_SIZE << get_order(SPAACT_SIZE));
> +
> +	dev_dbg(&pdev->dev, "ppaact virt=3D%p phys=3D0x%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 =3D 0; i < ARRAY_SIZE(port_id_map); i++) {
> +		if (port_id_map[i].svr =3D=3D (mfspr(SPRN_SVR) & ~SVR_SECURITY))
> {
> +			csd_port_id =3D 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 =3D 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 =3D virt_to_phys(spaact);
> +	omt_phys =3D virt_to_phys(omt);
> +
> +	spaace_pool =3D gen_pool_create(ilog2(sizeof(struct paace)), -1);
> +	if (!spaace_pool) {
> +		ret =3D -ENOMEM;
> +		dev_err(&pdev->dev, "PAMU : failed to allocate spaace gen
> pool\n");
> +		goto error;
> +	}
> +
> +	ret =3D gen_pool_add(spaace_pool, (unsigned long)spaact, SPAACT_SIZE,
> -1);
> +	if (ret)
> +		goto error_genpool;
> +
> +	pamubypenr =3D in_be32(&guts_regs->pamubypenr);
> +
> +	for (pamu_reg_off =3D 0, pamu_counter =3D 0x80000000; pamu_reg_off <
> size;
> +	     pamu_reg_off +=3D PAMU_OFFSET, pamu_counter >>=3D 1) {
> +
> +		pamu_reg_base =3D (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 &=3D ~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 !=3D 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 =3D NULL;
> +
> +	return ret;
> +}
> +
> +static const struct of_device_id fsl_of_pamu_ids[] =3D {
> +	{
> +		.compatible =3D "fsl,p4080-pamu",
> +	},
> +	{
> +		.compatible =3D "fsl,pamu",
> +	},
> +	{},
> +};
> +
> +static struct platform_driver fsl_of_pamu_driver =3D {
> +	.driver =3D {
> +		.name =3D "fsl-of-pamu",
> +		.owner =3D THIS_MODULE,
> +	},
> +	.probe =3D fsl_pamu_probe,
> +};
> +
> +static __init int fsl_pamu_init(void)
> +{
> +	struct platform_device *pdev =3D 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 =3D of_find_compatible_node(NULL, NULL, "fsl,pamu");
> +	if (!np) {
> +		pr_err("fsl-pamu: could not find a PAMU node\n");
> +		return -ENODEV;
> +	}
> +
> +	ret =3D platform_driver_register(&fsl_of_pamu_driver);
> +	if (ret) {
> +		pr_err("fsl-pamu: could not register driver (err=3D%i)\n",
> ret);
> +		goto error_driver_register;
> +	}
> +
> +	pdev =3D platform_device_alloc("fsl-of-pamu", 0);
> +	if (!pdev) {
> +		pr_err("fsl-pamu: could not allocate device %s\n",
> +		       np->full_name);
> +		ret =3D -ENOMEM;
> +		goto error_device_alloc;
> +	}
> +	pdev->dev.of_node =3D of_node_get(np);
> +
> +	ret =3D pamu_domain_init();
> +	if (ret)
> +		goto error_device_add;
> +
> +	ret =3D platform_device_add(pdev);
> +	if (ret) {
> +		pr_err("fsl-pamu: could not add device %s (err=3D%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 =3D 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..8fc1a12
> --- /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 <asm/fsl_pamu_stash.h>
> +
> +/* Bit Field macros
> + *	v =3D bit field variable; m =3D mask, m##_SHIFT =3D shift, x =3D valu=
e to
> load
> + */
> +#define set_bf(v, m, x)		(v =3D ((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..14d803a
> --- /dev/null
> +++ b/drivers/iommu/fsl_pamu_domain.c
> @@ -0,0 +1,1172 @@
> +/*
> + * 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 =3D kmem_cache_create("fsl_pamu_domain",
> +					 sizeof(struct fsl_dma_domain),
> +					 0,
> +					 SLAB_HWCACHE_ALIGN,
> +
> +					 NULL);
> +	if (!fsl_pamu_domain_cache) {
> +		pr_debug("Couldn't create fsl iommu_domain cache\n");
> +		return -ENOMEM;
> +	}
> +
> +	iommu_devinfo_cache =3D kmem_cache_create("iommu_devinfo",
> +					 sizeof(struct device_domain_info),
> +					 0,
> +					 SLAB_HWCACHE_ALIGN,
> +					 NULL);
> +	if (!iommu_devinfo_cache) {
> +		pr_debug("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 =3D dma_domain->win_cnt;
> +	struct dma_window *win_ptr =3D
> +				&dma_domain->win_arr[0];
> +	struct iommu_domain_geometry *geom;
> +
> +	geom =3D &dma_domain->iommu_domain->geometry;
> +
> +	if (!win_cnt || !dma_domain->geom_size) {
> +		pr_debug("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 =3D dma_domain->geom_size >> ilog2(win_cnt);
> +		subwin_iova =3D iova & ~(subwin_size - 1);
> +		wnd =3D (subwin_iova - geom->aperture_start) >>
> ilog2(subwin_size);
> +		win_ptr =3D &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 =3D
> +				&dma_domain->win_arr[0];
> +	int i, ret;
> +	unsigned long rpn, flags;
> +
> +	for (i =3D 0; i < dma_domain->win_cnt; i++) {
> +		if (sub_win_ptr[i].valid) {
> +			rpn =3D sub_win_ptr[i].paddr >>
> +				 PAMU_PAGE_SHIFT;
> +			spin_lock_irqsave(&iommu_lock, flags);
> +			ret =3D 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_debug("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 =3D &dma_domain->win_arr[0];
> +	phys_addr_t wnd_addr =3D dma_domain->iommu_domain-
> >geometry.aperture_start;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&iommu_lock, flags);
> +	ret =3D 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_debug("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 =3D &dma_domain->win_arr[wnd_nr];
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&iommu_lock, flags);
> +	if (dma_domain->win_cnt > 1) {
> +		ret =3D 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_debug("Subwindow reconfiguration failed for liodn
> %d\n", liodn);
> +	} else {
> +		phys_addr_t wnd_addr;
> +
> +		wnd_addr =3D dma_domain->iommu_domain->geometry.aperture_start;
> +
> +		ret =3D 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_debug("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 =3D 0, i;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&iommu_lock, flags);
> +	if (!dma_domain->win_arr) {
> +		pr_debug("Windows not configured, stash destination update
> failed for liodn %d\n", liodn);
> +		spin_unlock_irqrestore(&iommu_lock, flags);
> +		return -EINVAL;
> +	}
> +
> +	for (i =3D 0; i < dma_domain->win_cnt; i++) {
> +		ret =3D pamu_update_paace_stash(liodn, i, val);
> +		if (ret) {
> +			pr_debug("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 =3D 0, i;
> +	u32 omi_index =3D ~(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 =3D geom_attr->aperture_start;
> +	window_size =3D dma_domain->geom_size;
> +
> +	spin_lock_irqsave(&iommu_lock, flags);
> +	ret =3D pamu_disable_liodn(liodn);
> +	if (!ret)
> +		ret =3D 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_debug("PAMU PAACE configuration failed for liodn %d,
> win_cnt =3D%d\n", liodn, win_cnt);
> +		return ret;
> +	}
> +
> +	if (win_cnt > 1) {
> +		subwin_size =3D window_size >> ilog2(win_cnt);
> +		for (i =3D 0; i < win_cnt; i++) {
> +			spin_lock_irqsave(&iommu_lock, flags);
> +			ret =3D pamu_disable_spaace(liodn, i);
> +			if (!ret)
> +				ret =3D 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_debug("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_debug("%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_debug("%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 =3D kmem_cache_zalloc(fsl_pamu_domain_cache, GFP_KERNEL);
> +	if (!domain)
> +		return NULL;
> +
> +	domain->stash_id =3D ~(u32)0;
> +	domain->snoop_id =3D ~(u32)0;
> +	domain->win_cnt =3D pamu_get_max_subwin_cnt();
> +	domain->geom_size =3D 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 =3D 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 =3D=3D 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 =3D find_domain(dev);
> +	if (old_domain_info && old_domain_info->domain !=3D dma_domain) {
> +		spin_unlock_irqrestore(&device_domain_lock, flags);
> +		detach_device(dev, old_domain_info->domain);
> +		spin_lock_irqsave(&device_domain_lock, flags);
> +	}
> +
> +	info =3D kmem_cache_zalloc(iommu_devinfo_cache, GFP_ATOMIC);
> +
> +	info->dev =3D dev;
> +	info->liodn =3D liodn;
> +	info->domain =3D 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 =3D 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 =3D 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 =3D=3D IOMMU_CAP_CACHE_COHERENCY;
> +}
> +
> +static void fsl_pamu_domain_destroy(struct iommu_domain *domain)
> +{
> +	struct fsl_dma_domain *dma_domain =3D domain->priv;
> +
> +	domain->priv =3D NULL;
> +
> +	/* remove all the devices from the device list */
> +	detach_device(NULL, dma_domain);
> +
> +	dma_domain->enabled =3D 0;
> +	dma_domain->mapped =3D 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 =3D iommu_alloc_dma_domain();
> +	if (!dma_domain) {
> +		pr_debug("dma_domain allocation failed\n");
> +		return -ENOMEM;
> +	}
> +	domain->priv =3D dma_domain;
> +	dma_domain->iommu_domain =3D domain;
> +	/* defaul geometry 64 GB i.e. maximum system address */
> +	domain->geometry.aperture_start =3D 0;
> +	domain->geometry.aperture_end =3D (1ULL << 36) - 1;
> +	domain->geometry.force_aperture =3D 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 =3D 0;
> +
> +	list_for_each_entry(info, &dma_domain->devices, link) {
> +		ret =3D 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 =3D 0;
> +
> +	list_for_each_entry(info, &dma_domain->devices, link) {
> +		ret =3D 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 =3D 0;
> +
> +	list_for_each_entry(info, &dma_domain->devices, link) {
> +		ret =3D 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 =3D 0;
> +
> +	list_for_each_entry(info, &dma_domain->devices, link) {
> +		if (dma_domain->win_cnt =3D=3D 1 && dma_domain->enabled) {
> +			ret =3D pamu_disable_liodn(info->liodn);
> +			if (!ret)
> +				dma_domain->enabled =3D 0;
> +		} else {
> +			ret =3D 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 =3D domain->priv;
> +	unsigned long flags;
> +	int ret;
> +
> +	spin_lock_irqsave(&dma_domain->domain_lock, flags);
> +	if (!dma_domain->win_arr) {
> +		pr_debug("Number of windows not configured\n");
> +		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
> +		return;
> +	}
> +
> +	if (wnd_nr >=3D dma_domain->win_cnt) {
> +		pr_debug("Invalid window index\n");
> +		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
> +		return;
> +	}
> +
> +	if (dma_domain->win_arr[wnd_nr].valid) {
> +		ret =3D disable_domain_win(dma_domain, wnd_nr);
> +		if (!ret) {
> +			dma_domain->win_arr[wnd_nr].valid =3D 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 =3D domain->priv;
> +	struct dma_window *wnd;
> +	int pamu_prot =3D 0;
> +	int ret;
> +	unsigned long flags;
> +	u64 win_size;
> +
> +	if (prot & IOMMU_READ)
> +		pamu_prot |=3D PAACE_AP_PERMS_QUERY;
> +	if (prot & IOMMU_WRITE)
> +		pamu_prot |=3D PAACE_AP_PERMS_UPDATE;
> +
> +	spin_lock_irqsave(&dma_domain->domain_lock, flags);
> +	if (!dma_domain->win_arr) {
> +		pr_debug("Number of windows not configured\n");
> +		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
> +		return -ENODEV;
> +	}
> +
> +	if (wnd_nr >=3D dma_domain->win_cnt) {
> +		pr_debug("Invalid window index\n");
> +		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
> +		return -EINVAL;
> +	}
> +
> +	win_size =3D dma_domain->geom_size >> ilog2(dma_domain->win_cnt);
> +	if (size > win_size) {
> +		pr_debug("Invalid window size \n");
> +		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
> +		return -EINVAL;
> +	}
> +
> +	if (dma_domain->win_cnt =3D=3D 1) {
> +		if (dma_domain->enabled) {
> +			pr_debug("Disable the window before updating the
> mapping\n");
> +			spin_unlock_irqrestore(&dma_domain->domain_lock,
> flags);
> +			return -EBUSY;
> +		}
> +
> +		ret =3D check_size(size, domain->geometry.aperture_start);
> +		if (ret) {
> +			pr_debug("Aperture start not aligned to the size\n");
> +			spin_unlock_irqrestore(&dma_domain->domain_lock,
> flags);
> +			return -EINVAL;
> +		}
> +	}
> +
> +	wnd =3D &dma_domain->win_arr[wnd_nr];
> +	if (!wnd->valid) {
> +		wnd->paddr =3D paddr;
> +		wnd->size =3D size;
> +		wnd->prot =3D pamu_prot;
> +
> +		ret =3D update_domain_mapping(dma_domain, wnd_nr);
> +		if (!ret) {
> +			wnd->valid =3D 1;
> +			dma_domain->mapped++;
> +		}
> +	} else {
> +		pr_debug("Disable the window before updating the mapping\n");
> +		ret =3D -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 =3D dma_domain->iommu_domain;
> +	int ret =3D 0;
> +	int i;
> +
> +	spin_lock_irqsave(&dma_domain->domain_lock, flags);
> +	for (i =3D 0; i < num; i++) {
> +
> +		/* Ensure that LIODN value is valid */
> +		if (liodn[i] >=3D PAACE_NUMBER_ENTRIES) {
> +			pr_debug("Invalid liodn %d, attach device failed for
> %s\n",
> +				liodn[i], dev->of_node->full_name);
> +			ret =3D -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 =3D dma_domain->win_cnt > 1 ? dma_domain-
> >win_cnt : 0;
> +			ret =3D 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 =3D 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 =3D domain->priv;
> +	const u32 *liodn;
> +	u32 liodn_cnt;
> +	int len, ret =3D 0;
> +	struct pci_dev *pdev =3D NULL;
> +	struct pci_controller *pci_ctl;
> +
> +	/*
> +	 * Use LIODN of the PCI controller while attaching a
> +	 * PCI device.
> +	 */
> +	if (dev->bus =3D=3D &pci_bus_type) {
> +		pdev =3D to_pci_dev(dev);
> +		pci_ctl =3D pci_bus_to_host(pdev->bus);
> +		/*
> +		 * make dev point to pci controller device
> +		 * so we can get the LIODN programmed by
> +		 * u-boot.
> +		 */
> +		dev =3D pci_ctl->parent;
> +	}
> +
> +	liodn =3D of_get_property(dev->of_node, "fsl,liodn", &len);
> +	if (liodn) {
> +		liodn_cnt =3D len / sizeof(u32);
> +		ret =3D handle_attach_device(dma_domain, dev,
> +					 liodn, liodn_cnt);
> +	} else {
> +		pr_debug("missing fsl,liodn property at %s\n",
> +		          dev->of_node->full_name);
> +			ret =3D -EINVAL;
> +	}
> +
> +	return ret;
> +}
> +
> +static void fsl_pamu_detach_device(struct iommu_domain *domain,
> +				      struct device *dev)
> +{
> +	struct fsl_dma_domain *dma_domain =3D domain->priv;
> +	const u32 *prop;
> +	int len;
> +	struct pci_dev *pdev =3D NULL;
> +	struct pci_controller *pci_ctl;
> +
> +	/*
> +	 * Use LIODN of the PCI controller while detaching a
> +	 * PCI device.
> +	 */
> +	if (dev->bus =3D=3D &pci_bus_type) {
> +		pdev =3D to_pci_dev(dev);
> +		pci_ctl =3D pci_bus_to_host(pdev->bus);
> +		/*
> +		 * make dev point to pci controller device
> +		 * so we can get the LIODN programmed by
> +		 * u-boot.
> +		 */
> +		dev =3D pci_ctl->parent;
> +	}
> +
> +	prop =3D of_get_property(dev->of_node, "fsl,liodn", &len);
> +	if (prop)
> +		detach_device(dev, dma_domain);
> +	else
> +		pr_debug("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 =3D data;
> +	struct fsl_dma_domain *dma_domain =3D domain->priv;
> +	dma_addr_t geom_size;
> +	unsigned long flags;
> +
> +	geom_size =3D 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_debug("Invalid PAMU geometry attributes\n");
> +			return -EINVAL;
> +		}
> +
> +	spin_lock_irqsave(&dma_domain->domain_lock, flags);
> +	if (dma_domain->enabled) {
> +		pr_debug("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 =3D 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 =3D 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 =3D get_stash_id(stash_attr->cache,
> +					    stash_attr->cpu);
> +	if (dma_domain->stash_id =3D=3D ~(u32)0) {
> +		pr_debug("Invalid stash attributes\n");
> +		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
> +		return -EINVAL;
> +	}
> +
> +	ret =3D 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_debug("Can't enable DMA domain without valid mapping\n");
> +		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
> +		return -ENODEV;
> +	}
> +
> +	dma_domain->enabled =3D enable;
> +	list_for_each_entry(info, &dma_domain->devices,
> +				 link) {
> +		ret =3D (enable) ? pamu_enable_liodn(info->liodn) :
> +			pamu_disable_liodn(info->liodn);
> +		if (ret)
> +			pr_debug("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 =3D domain->priv;
> +	int ret =3D 0;
> +
> +
> +	switch (attr_type) {
> +	case DOMAIN_ATTR_GEOMETRY:
> +		ret =3D configure_domain_geometry(domain, data);
> +		break;
> +	case DOMAIN_ATTR_FSL_PAMU_STASH:
> +		ret =3D configure_domain_stash(dma_domain, data);
> +		break;
> +	case DOMAIN_ATTR_FSL_PAMU_ENABLE:
> +		ret =3D configure_domain_dma_state(dma_domain, *(int *)data);
> +		break;
> +	default:
> +		pr_debug("Unsupported attribute type\n");
> +		ret =3D -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 =3D domain->priv;
> +	int ret =3D 0;
> +
> +
> +	switch (attr_type) {
> +	case DOMAIN_ATTR_FSL_PAMU_STASH:
> +		memcpy((struct pamu_stash_attribute *) data, &dma_domain-
> >dma_stash,
> +				 sizeof(struct pamu_stash_attribute));
> +		break;
> +	case DOMAIN_ATTR_FSL_PAMU_ENABLE:
> +		*(int *)data =3D dma_domain->enabled;
> +		break;
> +	case DOMAIN_ATTR_FSL_PAMUV1:
> +		*(int *)data =3D DOMAIN_ATTR_FSL_PAMUV1;
> +		break;
> +	default:
> +		pr_debug("Unsupported attribute type\n");
> +		ret =3D -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 =3D iommu_group_get(dev);
> +	if (!group)
> +		group =3D 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 =3D in_be32(pci_ctl->cfg_addr + (PCI_FSL_BRR1 >> 2));
> +	version &=3D PCI_FSL_BRR1_VER;
> +	/* If PCI controller version is >=3D 0x204 we can partition
> endpoints*/
> +	if (version >=3D 0x204)
> +		return 1;
> +
> +	return 0;
> +}
> +
> +/* Get iommu group information from peer devices or devices on the
> parent bus */
> +static struct iommu_group *get_shared_pci_device_group(struct pci_dev
> *pdev)
> +{
> +	struct pci_dev *tmp;
> +	struct iommu_group *group;
> +	struct pci_bus *bus =3D pdev->bus;
> +
> +	/*
> +	 * Traverese the pci bus device list to get
> +	 * the shared iommu group.
> +	 */
> +	while (bus) {
> +		list_for_each_entry(tmp, &bus->devices, bus_list) {
> +			if (tmp =3D=3D pdev)
> +				continue;
> +			group =3D iommu_group_get(&tmp->dev);
> +			if (group)
> +				return group;
> +		}
> +
> +		bus =3D bus->parent;
> +	}
> +
> +	return NULL;
> +}
> +
> +static struct iommu_group *get_pci_device_group(struct pci_dev *pdev)
> +{
> +	struct pci_controller *pci_ctl;
> +	bool pci_endpt_partioning;
> +	struct iommu_group *group =3D NULL;
> +	struct pci_dev *bridge, *dma_pdev =3D NULL;
> +
> +	pci_ctl =3D pci_bus_to_host(pdev->bus);
> +	pci_endpt_partioning =3D check_pci_ctl_endpt_part(pci_ctl);
> +	/* We can partition PCIe devices so assign device group to the
> device */
> +	if (pci_endpt_partioning) {
> +		bridge =3D pci_find_upstream_pcie_bridge(pdev);
> +		if (bridge) {
> +			if (pci_is_pcie(bridge))
> +				dma_pdev =3D pci_get_domain_bus_and_slot(
> +						pci_domain_nr(pdev->bus),
> +						bridge->subordinate->number, 0);
> +			if (!dma_pdev)
> +				dma_pdev =3D pci_dev_get(bridge);
> +		} else
> +			dma_pdev =3D 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 lowest
> numbered
> +		 * function that also does not suport the required ACS flags.
> +		 */
> +		if (dma_pdev->multifunction &&
> +		    !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) {
> +			u8 i, slot =3D PCI_SLOT(dma_pdev->devfn);
> +
> +			for (i =3D 0; i < 8; i++) {
> +				struct pci_dev *tmp;
> +
> +				tmp =3D pci_get_slot(dma_pdev->bus, PCI_DEVFN(slot,
> i));
> +				if (!tmp)
> +					continue;
> +
> +				if (!pci_acs_enabled(tmp, REQ_ACS_FLAGS)) {
> +					swap_pci_ref(&dma_pdev, tmp);
> +					break;
> +				}
> +				pci_dev_put(tmp);
> +			}
> +		}
> +
> +		/*
> +		 * Devices on the root bus go through the iommu.  If that's
> not us,
> +	 	 * find the next upstream device and test ACS up to the root
> bus.
> +		 * Finding the next device may require skipping virtual
> buses.
> +		 */
> +		while (!pci_is_root_bus(dma_pdev->bus)) {
> +			struct pci_bus *bus =3D dma_pdev->bus;
> +
> +			while (!bus->self) {
> +				if (!pci_is_root_bus(bus))
> +					bus =3D bus->parent;
> +				else
> +					goto root_bus;
> +			}
> +
> +			if (pci_acs_path_enabled(bus->self, NULL,
> REQ_ACS_FLAGS))
> +				break;
> +
> +			swap_pci_ref(&dma_pdev, pci_dev_get(bus->self));
> +		}
> +
> +root_bus:
> +		group =3D get_device_iommu_group(&dma_pdev->dev);
> +		pci_dev_put(dma_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 =3D get_device_iommu_group(pci_ctl->parent);
> +			iommu_group_remove_device(pci_ctl->parent);
> +		} else
> +			group =3D get_shared_pci_device_group(pdev);
> +	}
> +
> +	return group;
> +}
> +
> +static int fsl_pamu_add_device(struct device *dev)
> +{
> +	struct iommu_group *group =3D 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 =3D=3D &pci_bus_type) {
> +		pdev =3D to_pci_dev(dev);
> +		/* Don't create device groups for virtual PCI bridges */
> +		if (pdev->subordinate)
> +			return 0;
> +
> +		group =3D get_pci_device_group(pdev);
> +
> +	} else {
> +		prop =3D of_get_property(dev->of_node, "fsl,liodn", &len);
> +		if (prop)
> +			group =3D get_device_iommu_group(dev);
> +	}
> +
> +	if (!group || IS_ERR(group))
> +		return PTR_ERR(group);
> +
> +	ret =3D 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 =3D 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_debug("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_debug("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_debug("Invalid window count\n");
> +		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
> +		return -EINVAL;
> +	}
> +
> +	ret =3D 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 =3D kzalloc(sizeof(struct dma_window) *
> +							  w_count, GFP_ATOMIC);
> +		if (!dma_domain->win_arr) {
> +			spin_unlock_irqrestore(&dma_domain->domain_lock,
> flags);
> +			return -ENOMEM;
> +		}
> +		dma_domain->win_cnt =3D 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 =3D domain->priv;
> +
> +	return dma_domain->win_cnt;
> +}
> +
> +static struct iommu_ops fsl_pamu_ops =3D {
> +	.domain_init	=3D fsl_pamu_domain_init,
> +	.domain_destroy =3D fsl_pamu_domain_destroy,
> +	.attach_dev	=3D fsl_pamu_attach_device,
> +	.detach_dev	=3D fsl_pamu_detach_device,
> +	.domain_window_enable =3D fsl_pamu_window_enable,
> +	.domain_window_disable =3D fsl_pamu_window_disable,
> +	.domain_get_windows =3D fsl_pamu_get_windows,
> +	.domain_set_windows =3D fsl_pamu_set_windows,
> +	.iova_to_phys	=3D fsl_pamu_iova_to_phys,
> +	.domain_has_cap =3D fsl_pamu_domain_has_cap,
> +	.domain_set_attr =3D fsl_pamu_set_domain_attr,
> +	.domain_get_attr =3D fsl_pamu_get_domain_attr,
> +	.add_device	=3D fsl_pamu_add_device,
> +	.remove_device	=3D fsl_pamu_remove_device,
> +};
> +
> +int pamu_domain_init()
> +{
> +	int ret =3D 0;
> +
> +	ret =3D 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	[flat|nested] 20+ messages in thread

* RE: [PATCH 3/3 v18] iommu/fsl: Freescale PAMU driver and iommu implementation.
@ 2013-07-29 12:14     ` Sethi Varun-B16395
  0 siblings, 0 replies; 20+ messages in thread
From: Sethi Varun-B16395 @ 2013-07-29 12:14 UTC (permalink / raw)
  To: Sethi Varun-B16395, joro-zLv9SwRftAIdnm+yROfE0A,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r,
	galak-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r,
	alex.williamson-H+wXaHxf7aLQT0dZR+AlfA, Yoder Stuart-B08248,
	Wood Scott-B07421
  Cc: Timur Tabi

Hi Joerg,
Do you have any further comments on this patch set?

Regards
Varun

> -----Original Message-----
> From: Sethi Varun-B16395
> Sent: Monday, July 15, 2013 10:21 AM
> To: joro-zLv9SwRftAIdnm+yROfE0A@public.gmane.org; iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org; linuxppc-
> dev-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org; linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org;
> benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r@public.gmane.org; galak-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r@public.gmane.org;
> alex.williamson-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org; Yoder Stuart-B08248; Wood Scott-B07421
> Cc: Sethi Varun-B16395; Timur Tabi
> Subject: [PATCH 3/3 v18] iommu/fsl: Freescale PAMU driver and iommu
> implementation.
> 
> 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.
> 
> [For iommu group support]
> Acked-by: Alex Williamson <alex.williamson-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> 
> Signed-off-by: Timur Tabi <timur-N01EOCouUvQ@public.gmane.org>
> Signed-off-by: Varun Sethi <Varun.Sethi-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
> 
> ---
> changes in v19:
> - rebased to 3.11-rc1
> changes in v18:
> - Merged the two loops for searching shared iommu_group
> in to a single loop.
> - Renamed function used for searching shared iommu groups.
> changes in v17
> - Fixed iommu group check for peer/parent bus devices.
> - Check for ACS till root node while allocating device
> groups.
> - Fix the reference to pdev instead of dma_dev.
> changes in v16
> - rebased to kernel 3.10-rc6
> changes in v15:
> - Updated path for fsl_pamu_stash.h.
> changes in v14:
> - Use updated PAMU specific attributes.
> 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 | 1172
> +++++++++++++++++++++++++++++++++++
>  drivers/iommu/fsl_pamu_domain.h |   85 +++
>  7 files changed, 2992 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 72b5625..1e01291 100644
> --- a/arch/powerpc/sysdev/fsl_pci.h
> +++ b/arch/powerpc/sysdev/fsl_pci.h
> @@ -16,6 +16,11 @@
> 
>  struct platform_device;
> 
> +
> +/* 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 820d85c..fe302e3 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 bbe7041..14c1f47 100644
> --- a/drivers/iommu/Makefile
> +++ b/drivers/iommu/Makefile
> @@ -16,3 +16,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..a831fee
> --- /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_debug("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_debug("Invalid primary paace entry\n");
> +		return -ENOENT;
> +	}
> +
> +	if (!get_bf(ppaace->addr_bitfields, PPAACE_AF_WSE)) {
> +		pr_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("window size too small or not a power of two
> %llx\n", win_size);
> +		return -EINVAL;
> +	}
> +
> +	if (win_addr & (win_size - 1)) {
> +		pr_debug("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_debug("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_debug("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_debug("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_debug("Invalid liodn entry\n");
> +		return -ENOENT;
> +	}
> +
> +	if (!is_power_of_2(subwin_size) || subwin_size < PAMU_PAGE_SIZE) {
> +		pr_debug("subwindow size out of range, or not a power of
> 2\n");
> +		return -EINVAL;
> +	}
> +
> +	if (rpn == ULONG_MAX) {
> +		pr_debug("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_debug("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_debug("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_debug("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_debug("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_debug("Invalid node for cache hierarchy %s\n",
> +				node->full_name);
> +			return ~(u32)0;
> +		}
> +	}
> +
> +	pr_debug("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_debug("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..8fc1a12
> --- /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 <asm/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..14d803a
> --- /dev/null
> +++ b/drivers/iommu/fsl_pamu_domain.c
> @@ -0,0 +1,1172 @@
> +/*
> + * 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-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
> + *
> + */
> +
> +#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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("%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_debug("%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_ATOMIC);
> +
> +	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_debug("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_debug("Number of windows not configured\n");
> +		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
> +		return;
> +	}
> +
> +	if (wnd_nr >= dma_domain->win_cnt) {
> +		pr_debug("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_debug("Number of windows not configured\n");
> +		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
> +		return -ENODEV;
> +	}
> +
> +	if (wnd_nr >= dma_domain->win_cnt) {
> +		pr_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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_debug("Invalid PAMU geometry attributes\n");
> +			return -EINVAL;
> +		}
> +
> +	spin_lock_irqsave(&dma_domain->domain_lock, flags);
> +	if (dma_domain->enabled) {
> +		pr_debug("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_debug("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_debug("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_debug("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_FSL_PAMU_STASH:
> +		ret = configure_domain_stash(dma_domain, data);
> +		break;
> +	case DOMAIN_ATTR_FSL_PAMU_ENABLE:
> +		ret = configure_domain_dma_state(dma_domain, *(int *)data);
> +		break;
> +	default:
> +		pr_debug("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_FSL_PAMU_STASH:
> +		memcpy((struct pamu_stash_attribute *) data, &dma_domain-
> >dma_stash,
> +				 sizeof(struct pamu_stash_attribute));
> +		break;
> +	case DOMAIN_ATTR_FSL_PAMU_ENABLE:
> +		*(int *)data = dma_domain->enabled;
> +		break;
> +	case DOMAIN_ATTR_FSL_PAMUV1:
> +		*(int *)data = DOMAIN_ATTR_FSL_PAMUV1;
> +		break;
> +	default:
> +		pr_debug("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;
> +}
> +
> +/* Get iommu group information from peer devices or devices on the
> parent bus */
> +static struct iommu_group *get_shared_pci_device_group(struct pci_dev
> *pdev)
> +{
> +	struct pci_dev *tmp;
> +	struct iommu_group *group;
> +	struct pci_bus *bus = pdev->bus;
> +
> +	/*
> +	 * Traverese the pci bus device list to get
> +	 * the shared iommu group.
> +	 */
> +	while (bus) {
> +		list_for_each_entry(tmp, &bus->devices, bus_list) {
> +			if (tmp == pdev)
> +				continue;
> +			group = iommu_group_get(&tmp->dev);
> +			if (group)
> +				return group;
> +		}
> +
> +		bus = bus->parent;
> +	}
> +
> +	return NULL;
> +}
> +
> +static struct iommu_group *get_pci_device_group(struct pci_dev *pdev)
> +{
> +	struct pci_controller *pci_ctl;
> +	bool pci_endpt_partioning;
> +	struct iommu_group *group = NULL;
> +	struct pci_dev *bridge, *dma_pdev = NULL;
> +
> +	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 lowest
> numbered
> +		 * function that also does not suport the required ACS flags.
> +		 */
> +		if (dma_pdev->multifunction &&
> +		    !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) {
> +			u8 i, slot = PCI_SLOT(dma_pdev->devfn);
> +
> +			for (i = 0; i < 8; i++) {
> +				struct pci_dev *tmp;
> +
> +				tmp = pci_get_slot(dma_pdev->bus, PCI_DEVFN(slot,
> i));
> +				if (!tmp)
> +					continue;
> +
> +				if (!pci_acs_enabled(tmp, REQ_ACS_FLAGS)) {
> +					swap_pci_ref(&dma_pdev, tmp);
> +					break;
> +				}
> +				pci_dev_put(tmp);
> +			}
> +		}
> +
> +		/*
> +		 * Devices on the root bus go through the iommu.  If that's
> not us,
> +	 	 * find the next upstream device and test ACS up to the root
> bus.
> +		 * Finding the next device may require skipping virtual
> buses.
> +		 */
> +		while (!pci_is_root_bus(dma_pdev->bus)) {
> +			struct pci_bus *bus = dma_pdev->bus;
> +
> +			while (!bus->self) {
> +				if (!pci_is_root_bus(bus))
> +					bus = bus->parent;
> +				else
> +					goto root_bus;
> +			}
> +
> +			if (pci_acs_path_enabled(bus->self, NULL,
> REQ_ACS_FLAGS))
> +				break;
> +
> +			swap_pci_ref(&dma_pdev, pci_dev_get(bus->self));
> +		}
> +
> +root_bus:
> +		group = get_device_iommu_group(&dma_pdev->dev);
> +		pci_dev_put(dma_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_shared_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_debug("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_debug("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_debug("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_ATOMIC);
> +		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	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/3] powerpc: Add iommu domain pointer to device archdata
  2013-07-15  4:50 ` Varun Sethi
  (?)
@ 2013-08-14  9:48   ` Joerg Roedel
  -1 siblings, 0 replies; 20+ messages in thread
From: Joerg Roedel @ 2013-08-14  9:48 UTC (permalink / raw)
  To: Varun Sethi
  Cc: iommu, linuxppc-dev, linux-kernel, benh, galak, alex.williamson,
	stuart.yoder, scottwood

On Mon, Jul 15, 2013 at 10:20:55AM +0530, Varun Sethi wrote:
> Add an iommu domain pointer to device (powerpc) archdata.  Devices
> are attached to iommu domains and this pointer provides a mechanism
> to correlate between a device and the associated iommu domain.  This
> field is set when a device is attached to a domain.
> 
> Signed-off-by: Varun Sethi <Varun.Sethi@freescale.com>
> Acked-by: Kumar Gala <galak@kernel.crashing.org>
> ---
> - rebased patch to 3.11-rc1
>  arch/powerpc/include/asm/device.h |    3 +++
>  1 files changed, 3 insertions(+), 0 deletions(-)

Okay, I applied these patches to my ppc/pamu branch. But before I merge
it to my next branch (so that it can go upstream) I want to have a
compile-test-case first. Can you send me a working .config which
includes this driver?

Thanks,

	Joerg



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/3] powerpc: Add iommu domain pointer to device archdata
@ 2013-08-14  9:48   ` Joerg Roedel
  0 siblings, 0 replies; 20+ messages in thread
From: Joerg Roedel @ 2013-08-14  9:48 UTC (permalink / raw)
  To: Varun Sethi
  Cc: stuart.yoder, iommu, linux-kernel, alex.williamson, scottwood,
	linuxppc-dev

On Mon, Jul 15, 2013 at 10:20:55AM +0530, Varun Sethi wrote:
> Add an iommu domain pointer to device (powerpc) archdata.  Devices
> are attached to iommu domains and this pointer provides a mechanism
> to correlate between a device and the associated iommu domain.  This
> field is set when a device is attached to a domain.
> 
> Signed-off-by: Varun Sethi <Varun.Sethi@freescale.com>
> Acked-by: Kumar Gala <galak@kernel.crashing.org>
> ---
> - rebased patch to 3.11-rc1
>  arch/powerpc/include/asm/device.h |    3 +++
>  1 files changed, 3 insertions(+), 0 deletions(-)

Okay, I applied these patches to my ppc/pamu branch. But before I merge
it to my next branch (so that it can go upstream) I want to have a
compile-test-case first. Can you send me a working .config which
includes this driver?

Thanks,

	Joerg

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/3] powerpc: Add iommu domain pointer to device archdata
@ 2013-08-14  9:48   ` Joerg Roedel
  0 siblings, 0 replies; 20+ messages in thread
From: Joerg Roedel @ 2013-08-14  9:48 UTC (permalink / raw)
  To: Varun Sethi
  Cc: galak-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r,
	stuart.yoder-KZfg59tc24xl57MIdRCFDg,
	benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	scottwood-KZfg59tc24xl57MIdRCFDg,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ

On Mon, Jul 15, 2013 at 10:20:55AM +0530, Varun Sethi wrote:
> Add an iommu domain pointer to device (powerpc) archdata.  Devices
> are attached to iommu domains and this pointer provides a mechanism
> to correlate between a device and the associated iommu domain.  This
> field is set when a device is attached to a domain.
> 
> Signed-off-by: Varun Sethi <Varun.Sethi-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
> Acked-by: Kumar Gala <galak-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r@public.gmane.org>
> ---
> - rebased patch to 3.11-rc1
>  arch/powerpc/include/asm/device.h |    3 +++
>  1 files changed, 3 insertions(+), 0 deletions(-)

Okay, I applied these patches to my ppc/pamu branch. But before I merge
it to my next branch (so that it can go upstream) I want to have a
compile-test-case first. Can you send me a working .config which
includes this driver?

Thanks,

	Joerg

^ permalink raw reply	[flat|nested] 20+ messages in thread

* RE: [PATCH 1/3] powerpc: Add iommu domain pointer to device archdata
  2013-08-14  9:48   ` Joerg Roedel
  (?)
@ 2013-08-14  9:56     ` Sethi Varun-B16395
  -1 siblings, 0 replies; 20+ messages in thread
From: Sethi Varun-B16395 @ 2013-08-14  9:56 UTC (permalink / raw)
  To: Joerg Roedel
  Cc: iommu, linuxppc-dev, linux-kernel, benh, galak, alex.williamson,
	Yoder Stuart-B08248, Wood Scott-B07421

[-- Attachment #1: Type: text/plain, Size: 1441 bytes --]

Hi Joerg,
Please find the .config file attached with this mail.

Regards
Varun

> -----Original Message-----
> From: Joerg Roedel [mailto:joro@8bytes.org]
> Sent: Wednesday, August 14, 2013 3:18 PM
> To: Sethi Varun-B16395
> Cc: iommu@lists.linux-foundation.org; linuxppc-dev@lists.ozlabs.org;
> linux-kernel@vger.kernel.org; benh@kernel.crashing.org;
> galak@kernel.crashing.org; alex.williamson@redhat.com; Yoder Stuart-
> B08248; Wood Scott-B07421
> Subject: Re: [PATCH 1/3] powerpc: Add iommu domain pointer to device
> archdata
> 
> On Mon, Jul 15, 2013 at 10:20:55AM +0530, Varun Sethi wrote:
> > Add an iommu domain pointer to device (powerpc) archdata.  Devices are
> > attached to iommu domains and this pointer provides a mechanism to
> > correlate between a device and the associated iommu domain.  This
> > field is set when a device is attached to a domain.
> >
> > Signed-off-by: Varun Sethi <Varun.Sethi@freescale.com>
> > Acked-by: Kumar Gala <galak@kernel.crashing.org>
> > ---
> > - rebased patch to 3.11-rc1
> >  arch/powerpc/include/asm/device.h |    3 +++
> >  1 files changed, 3 insertions(+), 0 deletions(-)
> 
> Okay, I applied these patches to my ppc/pamu branch. But before I merge
> it to my next branch (so that it can go upstream) I want to have a
> compile-test-case first. Can you send me a working .config which includes
> this driver?
> 
> Thanks,
> 
> 	Joerg
> 
> 


[-- Attachment #2: pamu_build_config --]
[-- Type: application/octet-stream, Size: 65153 bytes --]

#
# Automatically generated file; DO NOT EDIT.
# Linux/powerpc 3.11.0-rc1 Kernel Configuration
#
# CONFIG_PPC64 is not set

#
# Processor support
#
# CONFIG_PPC_BOOK3S_32 is not set
CONFIG_PPC_85xx=y
# CONFIG_PPC_8xx is not set
# CONFIG_40x is not set
# CONFIG_44x is not set
# CONFIG_E200 is not set
CONFIG_E500=y
CONFIG_PPC_E500MC=y
CONFIG_PPC_FPU=y
CONFIG_FSL_EMB_PERFMON=y
CONFIG_FSL_EMB_PERF_EVENT=y
CONFIG_FSL_EMB_PERF_EVENT_E500=y
CONFIG_BOOKE=y
CONFIG_FSL_BOOKE=y
CONFIG_PPC_FSL_BOOK3E=y
CONFIG_PTE_64BIT=y
CONFIG_PHYS_64BIT=y
CONFIG_PPC_MMU_NOHASH=y
CONFIG_PPC_BOOK3E_MMU=y
# CONFIG_PPC_MM_SLICES is not set
CONFIG_SMP=y
CONFIG_NR_CPUS=8
CONFIG_PPC_DOORBELL=y
CONFIG_PPC32=y
CONFIG_32BIT=y
CONFIG_WORD_SIZE=32
CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
CONFIG_MMU=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_NR_IRQS=512
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_ARCH_HAS_ILOG2_U32=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_PPC=y
CONFIG_EARLY_PRINTK=y
CONFIG_GENERIC_NVRAM=y
CONFIG_SCHED_OMIT_FRAME_POINTER=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_PPC_OF=y
CONFIG_PPC_UDBG_16550=y
CONFIG_GENERIC_TBSYNC=y
CONFIG_AUDIT_ARCH=y
CONFIG_GENERIC_BUG=y
# CONFIG_EPAPR_BOOT is not set
CONFIG_DEFAULT_UIMAGE=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_PPC_ADV_DEBUG_REGS=y
CONFIG_PPC_ADV_DEBUG_IACS=2
CONFIG_PPC_ADV_DEBUG_DACS=2
CONFIG_PPC_ADV_DEBUG_DVCS=0
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_IRQ_WORK=y

#
# General setup
#
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_CROSS_COMPILE=""
# CONFIG_COMPILE_TEST is not set
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_DEFAULT_HOSTNAME="(none)"
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
CONFIG_POSIX_MQUEUE_SYSCTL=y
# CONFIG_FHANDLE is not set
CONFIG_AUDIT=y
# CONFIG_AUDITSYSCALL is not set
# CONFIG_AUDIT_LOGINUID_IMMUTABLE is not set
CONFIG_HAVE_GENERIC_HARDIRQS=y

#
# IRQ subsystem
#
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
CONFIG_IRQ_DOMAIN=y
# CONFIG_IRQ_DOMAIN_DEBUG is not set
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_SPARSE_IRQ=y
CONFIG_GENERIC_TIME_VSYSCALL_OLD=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_CMOS_UPDATE=y

#
# Timers subsystem
#
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ_COMMON=y
# CONFIG_HZ_PERIODIC is not set
CONFIG_NO_HZ_IDLE=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y

#
# CPU/Task time and stats accounting
#
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set

#
# RCU Subsystem
#
CONFIG_TREE_RCU=y
# CONFIG_PREEMPT_RCU is not set
CONFIG_RCU_STALL_COMMON=y
CONFIG_RCU_FANOUT=32
CONFIG_RCU_FANOUT_LEAF=16
# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_RCU_FAST_NO_HZ is not set
CONFIG_TREE_RCU_TRACE=y
# CONFIG_RCU_NOCB_CPU is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
# CONFIG_CHECKPOINT_RESTORE is not set
# CONFIG_NAMESPACES is not set
CONFIG_UIDGID_CONVERTED=y
# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
# CONFIG_SCHED_AUTOGROUP is not set
# CONFIG_SYSFS_DEPRECATED is not set
# CONFIG_RELAY is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
# CONFIG_RD_XZ is not set
# CONFIG_RD_LZO is not set
# CONFIG_RD_LZ4 is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
CONFIG_EXPERT=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_PCI_QUIRKS=y
CONFIG_EMBEDDED=y
CONFIG_HAVE_PERF_EVENTS=y

#
# Kernel Performance Events And Counters
#
CONFIG_PERF_EVENTS=y
# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
# CONFIG_JUMP_LABEL is not set
# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_DMA_ATTRS=y
CONFIG_USE_GENERIC_SMP_HELPERS=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_CLK=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_HAVE_RCU_TABLE_FREE=y
CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
CONFIG_MODULES_USE_ELF_RELA=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_OLD_SIGSUSPEND=y
CONFIG_OLD_SIGACTION=y

#
# GCOV-based kernel profiling
#
# CONFIG_GCOV_KERNEL is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODVERSIONS=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
# CONFIG_MODULE_SIG is not set
CONFIG_STOP_MACHINE=y
CONFIG_BLOCK=y
CONFIG_LBDAF=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_BSGLIB is not set
# CONFIG_BLK_DEV_INTEGRITY is not set

#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
# CONFIG_ACORN_PARTITION is not set
# CONFIG_AIX_PARTITION is not set
# CONFIG_OSF_PARTITION is not set
# CONFIG_AMIGA_PARTITION is not set
# CONFIG_ATARI_PARTITION is not set
CONFIG_MAC_PARTITION=y
CONFIG_MSDOS_PARTITION=y
# CONFIG_BSD_DISKLABEL is not set
# CONFIG_MINIX_SUBPARTITION is not set
# CONFIG_SOLARIS_X86_PARTITION is not set
# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_LDM_PARTITION is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_KARMA_PARTITION is not set
CONFIG_EFI_PARTITION=y
# CONFIG_SYSV68_PARTITION is not set

#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
# CONFIG_DEFAULT_DEADLINE is not set
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
CONFIG_INLINE_READ_UNLOCK=y
CONFIG_INLINE_READ_UNLOCK_IRQ=y
CONFIG_INLINE_WRITE_UNLOCK=y
CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
CONFIG_MUTEX_SPIN_ON_OWNER=y
# CONFIG_FREEZER is not set
CONFIG_PPC_MSI_BITMAP=y
# CONFIG_PPC_XICS is not set
# CONFIG_PPC_ICP_NATIVE is not set
# CONFIG_PPC_ICP_HV is not set
# CONFIG_PPC_ICS_RTAS is not set
# CONFIG_GE_FPGA is not set

#
# Platform support
#
CONFIG_POWERNV_MSI=y
# CONFIG_PPC_CELL is not set
# CONFIG_PPC_CELL_NATIVE is not set
# CONFIG_PQ2ADS is not set
CONFIG_FSL_SOC_BOOKE=y
# CONFIG_BSC9131_RDB is not set
# CONFIG_MPC8540_ADS is not set
# CONFIG_MPC8560_ADS is not set
# CONFIG_MPC85xx_CDS is not set
# CONFIG_MPC85xx_MDS is not set
# CONFIG_MPC8536_DS is not set
# CONFIG_MPC85xx_DS is not set
# CONFIG_MPC85xx_RDB is not set
# CONFIG_P1010_RDB is not set
# CONFIG_P1022_DS is not set
# CONFIG_P1022_RDK is not set
# CONFIG_P1023_RDS is not set
# CONFIG_SOCRATES is not set
# CONFIG_KSI8560 is not set
# CONFIG_XES_MPC85xx is not set
# CONFIG_STX_GP3 is not set
# CONFIG_TQM8540 is not set
# CONFIG_TQM8541 is not set
# CONFIG_TQM8548 is not set
# CONFIG_TQM8555 is not set
# CONFIG_TQM8560 is not set
# CONFIG_SBC8548 is not set
# CONFIG_PPA8548 is not set
# CONFIG_GE_IMP3A is not set
CONFIG_P2041_RDB=y
CONFIG_P3041_DS=y
CONFIG_P4080_DS=y
# CONFIG_SGY_CTS1000 is not set
CONFIG_P5020_DS=y
CONFIG_P5040_DS=y
# CONFIG_PPC_QEMU_E500 is not set
# CONFIG_PPC_WSP is not set
# CONFIG_KVM_GUEST is not set
CONFIG_EPAPR_PARAVIRT=y
CONFIG_PPC_SMP_MUXED_IPI=y
# CONFIG_IPIC is not set
CONFIG_MPIC=y
# CONFIG_MPIC_TIMER is not set
CONFIG_PPC_EPAPR_HV_PIC=y
# CONFIG_MPIC_WEIRD is not set
# CONFIG_MPIC_MSGR is not set
# CONFIG_PPC_I8259 is not set
# CONFIG_PPC_RTAS is not set
# CONFIG_MMIO_NVRAM is not set
# CONFIG_MPIC_U3_HT_IRQS is not set
# CONFIG_PPC_MPC106 is not set
# CONFIG_PPC_970_NAP is not set
# CONFIG_PPC_P7_NAP is not set

#
# CPU Frequency scaling
#
# CONFIG_CPU_FREQ is not set

#
# CPUIdle driver
#
# CONFIG_CPU_IDLE is not set
# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
# CONFIG_QUICC_ENGINE is not set
# CONFIG_CPM2 is not set
# CONFIG_FSL_ULI1575 is not set
# CONFIG_SIMPLE_GPIO is not set

#
# Kernel options
#
CONFIG_HIGHMEM=y
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
CONFIG_SCHED_HRTICK=y
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
CONFIG_BINFMT_ELF=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_BINFMT_SCRIPT=y
# CONFIG_HAVE_AOUT is not set
CONFIG_BINFMT_MISC=m
CONFIG_COREDUMP=y
CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y
# CONFIG_MATH_EMULATION is not set
CONFIG_IOMMU_HELPER=y
CONFIG_SWIOTLB=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
CONFIG_KEXEC=y
# CONFIG_CRASH_DUMP is not set
# CONFIG_IRQ_ALL_CPUS is not set
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_SYS_SUPPORTS_HUGETLBFS=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_HAVE_MEMBLOCK=y
CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_COMPACTION=y
CONFIG_MIGRATION=y
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_CROSS_MEMORY_ATTACH=y
# CONFIG_CLEANCACHE is not set
# CONFIG_FRONTSWAP is not set
# CONFIG_ZBUD is not set
CONFIG_PPC_4K_PAGES=y
CONFIG_FORCE_MAX_ZONEORDER=13
# CONFIG_CMDLINE_BOOL is not set
CONFIG_EXTRA_TARGETS=""
# CONFIG_HIBERNATION is not set
# CONFIG_PM_RUNTIME is not set
CONFIG_SECCOMP=y
CONFIG_ISA_DMA_API=y

#
# Bus options
#
CONFIG_ZONE_DMA=y
# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
CONFIG_FSL_PCI=y
CONFIG_FSL_LBC=y
CONFIG_FSL_IFC=y
CONFIG_PPC_PCI_CHOICE=y
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_SYSCALL=y
CONFIG_PCIEPORTBUS=y
CONFIG_PCIEAER=y
# CONFIG_PCIE_ECRC is not set
# CONFIG_PCIEAER_INJECT is not set
# CONFIG_PCIEASPM is not set
CONFIG_ARCH_SUPPORTS_MSI=y
CONFIG_PCI_MSI=y
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_PCI_PRI is not set
# CONFIG_PCI_PASID is not set

#
# PCI host controller drivers
#
# CONFIG_PCCARD is not set
# CONFIG_HOTPLUG_PCI is not set
CONFIG_HAS_RAPIDIO=y
CONFIG_RAPIDIO=y
CONFIG_FSL_RIO=y
# CONFIG_RAPIDIO_TSI721 is not set
CONFIG_RAPIDIO_DISC_TIMEOUT=30
# CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS is not set
# CONFIG_RAPIDIO_DMA_ENGINE is not set
# CONFIG_RAPIDIO_DEBUG is not set
# CONFIG_RAPIDIO_ENUM_BASIC is not set

#
# RapidIO Switch drivers
#
# CONFIG_RAPIDIO_TSI57X is not set
# CONFIG_RAPIDIO_CPS_XX is not set
# CONFIG_RAPIDIO_TSI568 is not set
# CONFIG_RAPIDIO_CPS_GEN2 is not set
# CONFIG_NONSTATIC_KERNEL is not set

#
# Advanced setup
#
# CONFIG_ADVANCED_OPTIONS is not set

#
# Default settings for advanced configuration options are used
#
CONFIG_LOWMEM_SIZE=0x30000000
CONFIG_LOWMEM_CAM_NUM=3
CONFIG_PAGE_OFFSET=0xc0000000
CONFIG_KERNEL_START=0xc0000000
CONFIG_PHYSICAL_START=0x00000000
CONFIG_PHYSICAL_ALIGN=0x04000000
CONFIG_TASK_SIZE=0xc0000000
CONFIG_NET=y

#
# Networking options
#
CONFIG_PACKET=y
# CONFIG_PACKET_DIAG is not set
CONFIG_UNIX=y
# CONFIG_UNIX_DIAG is not set
CONFIG_XFRM=y
CONFIG_XFRM_ALGO=y
CONFIG_XFRM_USER=y
CONFIG_XFRM_SUB_POLICY=y
CONFIG_XFRM_MIGRATE=y
CONFIG_XFRM_STATISTICS=y
CONFIG_XFRM_IPCOMP=y
CONFIG_NET_KEY=y
CONFIG_NET_KEY_MIGRATE=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
# CONFIG_IP_FIB_TRIE_STATS is not set
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_MULTIPATH=y
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_RARP=y
CONFIG_NET_IPIP=y
# CONFIG_NET_IPGRE_DEMUX is not set
CONFIG_NET_IP_TUNNEL=y
CONFIG_IP_MROUTE=y
# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
CONFIG_ARPD=y
# CONFIG_SYN_COOKIES is not set
# CONFIG_NET_IPVTI is not set
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
CONFIG_INET_IPCOMP=y
CONFIG_INET_XFRM_TUNNEL=y
CONFIG_INET_TUNNEL=y
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_XFRM_MODE_BEET=y
# CONFIG_INET_LRO is not set
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_INET_UDP_DIAG is not set
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TCP_MD5SIG is not set
CONFIG_IPV6=y
# CONFIG_IPV6_PRIVACY is not set
# CONFIG_IPV6_ROUTER_PREF is not set
# CONFIG_IPV6_OPTIMISTIC_DAD is not set
# CONFIG_INET6_AH is not set
# CONFIG_INET6_ESP is not set
# CONFIG_INET6_IPCOMP is not set
# CONFIG_IPV6_MIP6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
CONFIG_INET6_XFRM_MODE_TRANSPORT=y
CONFIG_INET6_XFRM_MODE_TUNNEL=y
CONFIG_INET6_XFRM_MODE_BEET=y
# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
CONFIG_IPV6_SIT=y
# CONFIG_IPV6_SIT_6RD is not set
CONFIG_IPV6_NDISC_NODETYPE=y
# CONFIG_IPV6_TUNNEL is not set
# CONFIG_IPV6_GRE is not set
# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_IPV6_MROUTE is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
CONFIG_IP_SCTP=m
# CONFIG_SCTP_DBG_OBJCNT is not set
CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y
# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 is not set
# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set
CONFIG_SCTP_COOKIE_HMAC_MD5=y
# CONFIG_SCTP_COOKIE_HMAC_SHA1 is not set
# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_L2TP is not set
# CONFIG_BRIDGE is not set
CONFIG_HAVE_NET_DSA=y
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_PHONET is not set
# CONFIG_IEEE802154 is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
CONFIG_DNS_RESOLVER=y
# CONFIG_BATMAN_ADV is not set
# CONFIG_OPENVSWITCH is not set
# CONFIG_VSOCKETS is not set
# CONFIG_NETLINK_MMAP is not set
# CONFIG_NETLINK_DIAG is not set
# CONFIG_NET_MPLS_GSO is not set
CONFIG_RPS=y
CONFIG_RFS_ACCEL=y
CONFIG_XPS=y
CONFIG_NET_LL_RX_POLL=y
CONFIG_BQL=y
CONFIG_NET_FLOW_LIMIT=y

#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_LIB80211 is not set

#
# CFG80211 needs to be enabled for MAC80211
#
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
# CONFIG_CAIF is not set
# CONFIG_CEPH_LIB is not set
# CONFIG_NFC is not set

#
# Device Drivers
#

#
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
# CONFIG_DEVTMPFS_MOUNT is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
CONFIG_FIRMWARE_IN_KERNEL=y
CONFIG_EXTRA_FIRMWARE=""
CONFIG_FW_LOADER_USER_HELPER=y
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_GENERIC_CPU_DEVICES is not set
# CONFIG_DMA_SHARED_BUFFER is not set

#
# Bus devices
#
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_OF_PARTS=y
# CONFIG_MTD_AR7_PARTS is not set

#
# User Modules And Translation Layers
#
CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_BLOCK=y
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
# CONFIG_SSFDC is not set
# CONFIG_SM_FTL is not set
# CONFIG_MTD_OOPS is not set
# CONFIG_MTD_SWAP is not set

#
# RAM/ROM/Flash chip drivers
#
CONFIG_MTD_CFI=y
# CONFIG_MTD_JEDECPROBE is not set
CONFIG_MTD_GEN_PROBE=y
# CONFIG_MTD_CFI_ADV_OPTIONS is not set
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
# CONFIG_MTD_CFI_INTELEXT is not set
CONFIG_MTD_CFI_AMDSTD=y
# CONFIG_MTD_CFI_STAA is not set
CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set

#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set
CONFIG_MTD_PHYSMAP_OF=y
# CONFIG_MTD_INTEL_VR_NOR is not set
# CONFIG_MTD_PLATRAM is not set

#
# Self-contained MTD device drivers
#
# CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_DATAFLASH is not set
CONFIG_MTD_M25P80=y
CONFIG_M25PXX_USE_FAST_READ=y
# CONFIG_MTD_SST25L is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
# CONFIG_MTD_BLOCK2MTD is not set

#
# Disk-On-Chip Device Drivers
#
# CONFIG_MTD_DOCG3 is not set
CONFIG_MTD_NAND_ECC=y
# CONFIG_MTD_NAND_ECC_SMC is not set
CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_ECC_BCH is not set
# CONFIG_MTD_SM_COMMON is not set
# CONFIG_MTD_NAND_DENALI is not set
CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_RICOH is not set
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_NAND_DOCG4 is not set
# CONFIG_MTD_NAND_CAFE is not set
# CONFIG_MTD_NAND_NANDSIM is not set
# CONFIG_MTD_NAND_PLATFORM is not set
# CONFIG_MTD_ALAUDA is not set
CONFIG_MTD_NAND_FSL_ELBC=y
CONFIG_MTD_NAND_FSL_IFC=y
# CONFIG_MTD_NAND_FSL_UPM is not set
# CONFIG_MTD_ONENAND is not set

#
# LPDDR flash memory drivers
#
# CONFIG_MTD_LPDDR is not set
# CONFIG_MTD_UBI is not set
CONFIG_DTC=y
CONFIG_OF=y

#
# Device Tree and Open Firmware support
#
CONFIG_PROC_DEVICETREE=y
# CONFIG_OF_SELFTEST is not set
CONFIG_OF_FLATTREE=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_IRQ=y
CONFIG_OF_I2C=y
CONFIG_OF_NET=y
CONFIG_OF_MDIO=y
CONFIG_OF_PCI=y
CONFIG_OF_PCI_IRQ=y
CONFIG_OF_MTD=y
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_DRBD is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_NVME is not set
# CONFIG_BLK_DEV_SX8 is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=131072
# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
# CONFIG_BLK_DEV_RBD is not set
# CONFIG_BLK_DEV_RSXX is not set

#
# Misc devices
#
# CONFIG_SENSORS_LIS3LV02D is not set
# CONFIG_AD525X_DPOT is not set
# CONFIG_ATMEL_PWM is not set
# CONFIG_DUMMY_IRQ is not set
# CONFIG_PHANTOM is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ATMEL_SSC is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
# CONFIG_APDS9802ALS is not set
# CONFIG_ISL29003 is not set
# CONFIG_ISL29020 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_SENSORS_BH1780 is not set
# CONFIG_SENSORS_BH1770 is not set
# CONFIG_SENSORS_APDS990X is not set
# CONFIG_HMC6352 is not set
# CONFIG_DS1682 is not set
# CONFIG_TI_DAC7512 is not set
# CONFIG_BMP085_I2C is not set
# CONFIG_BMP085_SPI is not set
# CONFIG_PCH_PHUB is not set
# CONFIG_USB_SWITCH_FSA9480 is not set
# CONFIG_LATTICE_ECP3_CONFIG is not set
# CONFIG_SRAM is not set
# CONFIG_C2PORT is not set

#
# EEPROM support
#
# CONFIG_EEPROM_AT24 is not set
# CONFIG_EEPROM_AT25 is not set
# CONFIG_EEPROM_LEGACY is not set
# CONFIG_EEPROM_MAX6875 is not set
# CONFIG_EEPROM_93CX6 is not set
# CONFIG_EEPROM_93XX46 is not set
# CONFIG_CB710_CORE is not set

#
# Texas Instruments shared transport line discipline
#
# CONFIG_TI_ST is not set
# CONFIG_SENSORS_LIS3_SPI is not set
# CONFIG_SENSORS_LIS3_I2C is not set

#
# Altera FPGA firmware download module
#
# CONFIG_ALTERA_STAPL is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set

#
# SCSI device support
#
CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
# CONFIG_SCSI_TGT is not set
# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y

#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y
# CONFIG_CHR_DEV_OSST is not set
CONFIG_BLK_DEV_SR=y
# CONFIG_BLK_DEV_SR_VENDOR is not set
CONFIG_CHR_DEV_SG=y
# CONFIG_CHR_DEV_SCH is not set
CONFIG_SCSI_MULTI_LUN=y
# CONFIG_SCSI_CONSTANTS is not set
CONFIG_SCSI_LOGGING=y
# CONFIG_SCSI_SCAN_ASYNC is not set

#
# SCSI Transports
#
CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
# CONFIG_SCSI_SAS_ATTRS is not set
# CONFIG_SCSI_SAS_LIBSAS is not set
# CONFIG_SCSI_SRP_ATTRS is not set
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_ISCSI_BOOT_SYSFS is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_CXGB4_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
# CONFIG_SCSI_BNX2X_FCOE is not set
# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_HPSA is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_3W_SAS is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AACRAID is not set
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_SCSI_AIC94XX is not set
# CONFIG_SCSI_MVSAS is not set
# CONFIG_SCSI_MVUMI is not set
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_ARCMSR is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_MPT3SAS is not set
# CONFIG_SCSI_UFSHCD is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_LIBFC is not set
# CONFIG_LIBFCOE is not set
# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_STEX is not set
CONFIG_SCSI_SYM53C8XX_2=y
CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
CONFIG_SCSI_SYM53C8XX_MMIO=y
# CONFIG_SCSI_IPR is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
# CONFIG_SCSI_QLA_FC is not set
# CONFIG_SCSI_QLA_ISCSI is not set
# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_PM8001 is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_CHELSIO_FCOE is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y

#
# Controllers with non-SFF native interface
#
CONFIG_SATA_AHCI=y
# CONFIG_SATA_AHCI_PLATFORM is not set
CONFIG_SATA_FSL=y
# CONFIG_SATA_INIC162X is not set
# CONFIG_SATA_ACARD_AHCI is not set
CONFIG_SATA_SIL24=y
CONFIG_ATA_SFF=y

#
# SFF controllers with custom DMA interface
#
# CONFIG_PDC_ADMA is not set
# CONFIG_SATA_QSTOR is not set
# CONFIG_SATA_SX4 is not set
CONFIG_ATA_BMDMA=y

#
# SATA SFF controllers with BMDMA
#
# CONFIG_ATA_PIIX is not set
# CONFIG_SATA_HIGHBANK is not set
# CONFIG_SATA_MV is not set
# CONFIG_SATA_NV is not set
# CONFIG_SATA_PROMISE is not set
# CONFIG_SATA_RCAR is not set
CONFIG_SATA_SIL=y
# CONFIG_SATA_SIS is not set
# CONFIG_SATA_SVW is not set
# CONFIG_SATA_ULI is not set
# CONFIG_SATA_VIA is not set
# CONFIG_SATA_VITESSE is not set

#
# PATA SFF controllers with BMDMA
#
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_CMD64X is not set
# CONFIG_PATA_CS5520 is not set
# CONFIG_PATA_CS5530 is not set
# CONFIG_PATA_CS5536 is not set
# CONFIG_PATA_CYPRESS is not set
# CONFIG_PATA_EFAR is not set
# CONFIG_PATA_HPT366 is not set
# CONFIG_PATA_HPT37X is not set
# CONFIG_PATA_HPT3X2N is not set
# CONFIG_PATA_HPT3X3 is not set
# CONFIG_PATA_IT8213 is not set
# CONFIG_PATA_IT821X is not set
# CONFIG_PATA_JMICRON is not set
# CONFIG_PATA_MARVELL is not set
# CONFIG_PATA_NETCELL is not set
# CONFIG_PATA_NINJA32 is not set
# CONFIG_PATA_NS87415 is not set
# CONFIG_PATA_OLDPIIX is not set
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC2027X is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
# CONFIG_PATA_RDC is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SCH is not set
# CONFIG_PATA_SERVERWORKS is not set
CONFIG_PATA_SIL680=y
# CONFIG_PATA_SIS is not set
# CONFIG_PATA_TOSHIBA is not set
# CONFIG_PATA_TRIFLEX is not set
# CONFIG_PATA_VIA is not set
# CONFIG_PATA_WINBOND is not set

#
# PIO-only SFF controllers
#
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_MPIIX is not set
# CONFIG_PATA_NS87410 is not set
# CONFIG_PATA_OPTI is not set
# CONFIG_PATA_PLATFORM is not set
# CONFIG_PATA_RZ1000 is not set

#
# Generic fallback / legacy drivers
#
# CONFIG_ATA_GENERIC is not set
# CONFIG_PATA_LEGACY is not set
# CONFIG_MD is not set
# CONFIG_TARGET_CORE is not set
# CONFIG_FUSION is not set

#
# IEEE 1394 (FireWire) support
#
# CONFIG_FIREWIRE is not set
# CONFIG_FIREWIRE_NOSY is not set
# CONFIG_I2O is not set
# CONFIG_MACINTOSH_DRIVERS is not set
CONFIG_NETDEVICES=y
CONFIG_NET_CORE=y
# CONFIG_BONDING is not set
# CONFIG_DUMMY is not set
# CONFIG_EQUALIZER is not set
# CONFIG_NET_FC is not set
# CONFIG_NET_TEAM is not set
# CONFIG_MACVLAN is not set
# CONFIG_VXLAN is not set
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
# CONFIG_RIONET is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
# CONFIG_NLMON is not set
# CONFIG_ARCNET is not set

#
# CAIF transport drivers
#

#
# Distributed Switch Architecture drivers
#
# CONFIG_NET_DSA_MV88E6XXX is not set
# CONFIG_NET_DSA_MV88E6060 is not set
# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
# CONFIG_NET_DSA_MV88E6131 is not set
# CONFIG_NET_DSA_MV88E6123_61_65 is not set
CONFIG_ETHERNET=y
CONFIG_NET_VENDOR_3COM=y
# CONFIG_VORTEX is not set
# CONFIG_TYPHOON is not set
CONFIG_NET_VENDOR_ADAPTEC=y
# CONFIG_ADAPTEC_STARFIRE is not set
CONFIG_NET_VENDOR_ALTEON=y
# CONFIG_ACENIC is not set
CONFIG_NET_VENDOR_AMD=y
# CONFIG_AMD8111_ETH is not set
# CONFIG_PCNET32 is not set
CONFIG_NET_VENDOR_ARC=y
# CONFIG_ARC_EMAC is not set
CONFIG_NET_VENDOR_ATHEROS=y
# CONFIG_ATL2 is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
# CONFIG_ATL1C is not set
# CONFIG_ALX is not set
CONFIG_NET_CADENCE=y
# CONFIG_ARM_AT91_ETHER is not set
# CONFIG_MACB is not set
CONFIG_NET_VENDOR_BROADCOM=y
# CONFIG_B44 is not set
# CONFIG_BNX2 is not set
# CONFIG_CNIC is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2X is not set
CONFIG_NET_VENDOR_BROCADE=y
# CONFIG_BNA is not set
# CONFIG_NET_CALXEDA_XGMAC is not set
CONFIG_NET_VENDOR_CHELSIO=y
# CONFIG_CHELSIO_T1 is not set
# CONFIG_CHELSIO_T3 is not set
# CONFIG_CHELSIO_T4 is not set
# CONFIG_CHELSIO_T4VF is not set
CONFIG_NET_VENDOR_CISCO=y
# CONFIG_ENIC is not set
# CONFIG_DNET is not set
CONFIG_NET_VENDOR_DEC=y
# CONFIG_NET_TULIP is not set
CONFIG_NET_VENDOR_DLINK=y
# CONFIG_DL2K is not set
# CONFIG_SUNDANCE is not set
CONFIG_NET_VENDOR_EMULEX=y
# CONFIG_BE2NET is not set
CONFIG_NET_VENDOR_EXAR=y
# CONFIG_S2IO is not set
# CONFIG_VXGE is not set
CONFIG_NET_VENDOR_FREESCALE=y
CONFIG_FSL_PQ_MDIO=y
# CONFIG_FSL_XGMAC_MDIO is not set
# CONFIG_GIANFAR is not set
CONFIG_NET_VENDOR_HP=y
# CONFIG_HP100 is not set
CONFIG_NET_VENDOR_INTEL=y
# CONFIG_E100 is not set
CONFIG_E1000=y
CONFIG_E1000E=y
# CONFIG_IGB is not set
# CONFIG_IGBVF is not set
# CONFIG_IXGB is not set
# CONFIG_IXGBE is not set
# CONFIG_IXGBEVF is not set
CONFIG_NET_VENDOR_I825XX=y
# CONFIG_IP1000 is not set
# CONFIG_JME is not set
CONFIG_NET_VENDOR_MARVELL=y
# CONFIG_MV643XX_ETH is not set
# CONFIG_MVMDIO is not set
# CONFIG_SKGE is not set
# CONFIG_SKY2 is not set
CONFIG_NET_VENDOR_MELLANOX=y
# CONFIG_MLX4_EN is not set
# CONFIG_MLX4_CORE is not set
CONFIG_NET_VENDOR_MICREL=y
# CONFIG_KS8851 is not set
# CONFIG_KS8851_MLL is not set
# CONFIG_KSZ884X_PCI is not set
CONFIG_NET_VENDOR_MICROCHIP=y
# CONFIG_ENC28J60 is not set
CONFIG_NET_VENDOR_MYRI=y
# CONFIG_MYRI10GE is not set
# CONFIG_FEALNX is not set
CONFIG_NET_VENDOR_NATSEMI=y
# CONFIG_NATSEMI is not set
# CONFIG_NS83820 is not set
CONFIG_NET_VENDOR_8390=y
# CONFIG_NE2K_PCI is not set
CONFIG_NET_VENDOR_NVIDIA=y
# CONFIG_FORCEDETH is not set
CONFIG_NET_VENDOR_OKI=y
# CONFIG_PCH_GBE is not set
# CONFIG_ETHOC is not set
CONFIG_NET_PACKET_ENGINE=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
CONFIG_NET_VENDOR_QLOGIC=y
# CONFIG_QLA3XXX is not set
# CONFIG_QLCNIC is not set
# CONFIG_QLGE is not set
# CONFIG_NETXEN_NIC is not set
CONFIG_NET_VENDOR_REALTEK=y
# CONFIG_8139CP is not set
# CONFIG_8139TOO is not set
# CONFIG_R8169 is not set
# CONFIG_SH_ETH is not set
CONFIG_NET_VENDOR_RDC=y
# CONFIG_R6040 is not set
CONFIG_NET_VENDOR_SEEQ=y
CONFIG_NET_VENDOR_SILAN=y
# CONFIG_SC92031 is not set
CONFIG_NET_VENDOR_SIS=y
# CONFIG_SIS900 is not set
# CONFIG_SIS190 is not set
# CONFIG_SFC is not set
CONFIG_NET_VENDOR_SMSC=y
# CONFIG_EPIC100 is not set
# CONFIG_SMSC911X is not set
# CONFIG_SMSC9420 is not set
CONFIG_NET_VENDOR_STMICRO=y
# CONFIG_STMMAC_ETH is not set
CONFIG_NET_VENDOR_SUN=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
# CONFIG_CASSINI is not set
# CONFIG_NIU is not set
CONFIG_NET_VENDOR_TEHUTI=y
# CONFIG_TEHUTI is not set
CONFIG_NET_VENDOR_TI=y
# CONFIG_TLAN is not set
CONFIG_NET_VENDOR_VIA=y
# CONFIG_VIA_RHINE is not set
# CONFIG_VIA_VELOCITY is not set
CONFIG_NET_VENDOR_WIZNET=y
# CONFIG_WIZNET_W5100 is not set
# CONFIG_WIZNET_W5300 is not set
CONFIG_NET_VENDOR_XILINX=y
# CONFIG_XILINX_EMACLITE is not set
# CONFIG_XILINX_LL_TEMAC is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
CONFIG_PHYLIB=y

#
# MII PHY device drivers
#
# CONFIG_AT803X_PHY is not set
# CONFIG_AMD_PHY is not set
# CONFIG_MARVELL_PHY is not set
# CONFIG_DAVICOM_PHY is not set
# CONFIG_QSEMI_PHY is not set
# CONFIG_LXT_PHY is not set
# CONFIG_CICADA_PHY is not set
CONFIG_VITESSE_PHY=y
# CONFIG_SMSC_PHY is not set
# CONFIG_BROADCOM_PHY is not set
# CONFIG_BCM87XX_PHY is not set
# CONFIG_ICPLUS_PHY is not set
# CONFIG_REALTEK_PHY is not set
# CONFIG_NATIONAL_PHY is not set
# CONFIG_STE10XP is not set
# CONFIG_LSI_ET1011C_PHY is not set
# CONFIG_MICREL_PHY is not set
CONFIG_FIXED_PHY=y
# CONFIG_MDIO_BITBANG is not set
# CONFIG_MDIO_BUS_MUX_GPIO is not set
# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
# CONFIG_MICREL_KS8995MA is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set

#
# USB Network Adapters
#
# CONFIG_USB_CATC is not set
# CONFIG_USB_KAWETH is not set
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_RTL8152 is not set
# CONFIG_USB_USBNET is not set
# CONFIG_USB_IPHETH is not set
CONFIG_WLAN=y
# CONFIG_AIRO is not set
# CONFIG_ATMEL is not set
# CONFIG_PRISM54 is not set
# CONFIG_USB_ZD1201 is not set
# CONFIG_HOSTAP is not set
# CONFIG_WL_TI is not set

#
# Enable WiMAX (Networking options) to see the WiMAX drivers
#
# CONFIG_WAN is not set
# CONFIG_VMXNET3 is not set
# CONFIG_ISDN is not set

#
# Input device support
#
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
# CONFIG_INPUT_POLLDEV is not set
# CONFIG_INPUT_SPARSEKMAP is not set
# CONFIG_INPUT_MATRIXKMAP is not set

#
# Userland interfaces
#
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set

#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set

#
# Hardware I/O ports
#
CONFIG_SERIO=y
CONFIG_SERIO_I8042=y
CONFIG_SERIO_SERPORT=y
# CONFIG_SERIO_PCIPS2 is not set
CONFIG_SERIO_LIBPS2=y
# CONFIG_SERIO_RAW is not set
# CONFIG_SERIO_XILINX_XPS_PS2 is not set
# CONFIG_SERIO_ALTERA_PS2 is not set
# CONFIG_SERIO_PS2MULT is not set
# CONFIG_SERIO_ARC_PS2 is not set
# CONFIG_SERIO_APBPS2 is not set
# CONFIG_SERIO_OLPC_APSP is not set
# CONFIG_GAMEPORT is not set

#
# Character devices
#
CONFIG_TTY=y
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
# CONFIG_VT_HW_CONSOLE_BINDING is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
# CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_NOZOMI is not set
# CONFIG_N_GSM is not set
# CONFIG_TRACE_SINK is not set
CONFIG_PPC_EPAPR_HV_BYTECHAN=y
# CONFIG_PPC_EARLY_DEBUG_EHV_BC is not set
CONFIG_DEVKMEM=y

#
# Serial drivers
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_PCI=y
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250_DETECT_IRQ=y
CONFIG_SERIAL_8250_RSA=y
CONFIG_SERIAL_8250_FSL=y
# CONFIG_SERIAL_8250_DW is not set

#
# Non-8250 serial port support
#
# CONFIG_SERIAL_MAX3100 is not set
# CONFIG_SERIAL_MAX310X is not set
# CONFIG_SERIAL_MFD_HSU is not set
# CONFIG_SERIAL_UARTLITE is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
# CONFIG_SERIAL_SCCNXP is not set
# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_ALTERA_JTAGUART is not set
# CONFIG_SERIAL_ALTERA_UART is not set
# CONFIG_SERIAL_IFX6X60 is not set
# CONFIG_SERIAL_PCH_UART is not set
# CONFIG_SERIAL_XILINX_PS_UART is not set
# CONFIG_SERIAL_ARC is not set
# CONFIG_SERIAL_RP2 is not set
# CONFIG_SERIAL_FSL_LPUART is not set
# CONFIG_TTY_PRINTK is not set
# CONFIG_HVC_UDBG is not set
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_HW_RANDOM_ATMEL is not set
# CONFIG_HW_RANDOM_EXYNOS is not set
CONFIG_NVRAM=y
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
# CONFIG_I2C_MUX is not set
CONFIG_I2C_HELPER_AUTO=y

#
# I2C Hardware Bus support
#

#
# PC SMBus host controller drivers
#
# CONFIG_I2C_ALI1535 is not set
# CONFIG_I2C_ALI1563 is not set
# CONFIG_I2C_ALI15X3 is not set
# CONFIG_I2C_AMD756 is not set
# CONFIG_I2C_AMD8111 is not set
# CONFIG_I2C_I801 is not set
# CONFIG_I2C_ISCH is not set
# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
# CONFIG_I2C_SIS96X is not set
# CONFIG_I2C_VIA is not set
# CONFIG_I2C_VIAPRO is not set

#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
# CONFIG_I2C_CBUS_GPIO is not set
# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
# CONFIG_I2C_DESIGNWARE_PCI is not set
# CONFIG_I2C_EG20T is not set
# CONFIG_I2C_GPIO is not set
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_PXA_PCI is not set
# CONFIG_I2C_SIMTEC is not set
# CONFIG_I2C_XILINX is not set

#
# External I2C/SMBus adapter drivers
#
# CONFIG_I2C_DIOLAN_U2C is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_TAOS_EVM is not set
# CONFIG_I2C_TINY_USB is not set

#
# Other I2C/SMBus bus drivers
#
# CONFIG_I2C_STUB is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
CONFIG_SPI=y
# CONFIG_SPI_DEBUG is not set
CONFIG_SPI_MASTER=y

#
# SPI Master Controller Drivers
#
# CONFIG_SPI_ALTERA is not set
CONFIG_SPI_BITBANG=y
CONFIG_SPI_GPIO=y
CONFIG_SPI_FSL_LIB=y
CONFIG_SPI_FSL_CPM=y
CONFIG_SPI_FSL_SPI=y
CONFIG_SPI_FSL_ESPI=y
# CONFIG_SPI_OC_TINY is not set
# CONFIG_SPI_PXA2XX is not set
# CONFIG_SPI_PXA2XX_PCI is not set
# CONFIG_SPI_SC18IS602 is not set
# CONFIG_SPI_TOPCLIFF_PCH is not set
# CONFIG_SPI_XCOMM is not set
# CONFIG_SPI_XILINX is not set
# CONFIG_SPI_DESIGNWARE is not set

#
# SPI Protocol Masters
#
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
# CONFIG_HSI is not set

#
# PPS support
#
CONFIG_PPS=y
# CONFIG_PPS_DEBUG is not set

#
# PPS clients support
#
# CONFIG_PPS_CLIENT_KTIMER is not set
# CONFIG_PPS_CLIENT_LDISC is not set
# CONFIG_PPS_CLIENT_GPIO is not set

#
# PPS generators support
#

#
# PTP clock support
#
CONFIG_PTP_1588_CLOCK=y

#
# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
#
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_ARCH_REQUIRE_GPIOLIB=y
CONFIG_GPIO_DEVRES=y
CONFIG_GPIOLIB=y
CONFIG_OF_GPIO=y
# CONFIG_DEBUG_GPIO is not set
# CONFIG_GPIO_SYSFS is not set

#
# Memory mapped GPIO drivers:
#
# CONFIG_GPIO_GENERIC_PLATFORM is not set
CONFIG_GPIO_MPC8XXX=y
# CONFIG_GPIO_TS5500 is not set
# CONFIG_GPIO_XILINX is not set
# CONFIG_GPIO_VX855 is not set
# CONFIG_GPIO_GRGPIO is not set

#
# I2C GPIO expanders:
#
# CONFIG_GPIO_MAX7300 is not set
# CONFIG_GPIO_MAX732X is not set
# CONFIG_GPIO_PCA953X is not set
# CONFIG_GPIO_PCF857X is not set
# CONFIG_GPIO_SX150X is not set
# CONFIG_GPIO_ADP5588 is not set
# CONFIG_GPIO_ADNP is not set

#
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
# CONFIG_GPIO_AMD8111 is not set
# CONFIG_GPIO_ML_IOH is not set
# CONFIG_GPIO_RDC321X is not set

#
# SPI GPIO expanders:
#
# CONFIG_GPIO_MAX7301 is not set
# CONFIG_GPIO_MCP23S08 is not set
# CONFIG_GPIO_MC33880 is not set
# CONFIG_GPIO_74X164 is not set

#
# AC97 GPIO expanders:
#

#
# MODULbus GPIO expanders:
#

#
# USB GPIO expanders:
#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_POWER_AVS is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y

#
# Sonics Silicon Backplane
#
# CONFIG_SSB is not set
CONFIG_BCMA_POSSIBLE=y

#
# Broadcom specific AMBA
#
# CONFIG_BCMA is not set

#
# Multifunction device drivers
#
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_AS3711 is not set
# CONFIG_PMIC_ADP5520 is not set
# CONFIG_MFD_AAT2870_CORE is not set
# CONFIG_MFD_CROS_EC is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_DA9052_SPI is not set
# CONFIG_MFD_DA9052_I2C is not set
# CONFIG_MFD_DA9055 is not set
# CONFIG_MFD_MC13XXX_SPI is not set
# CONFIG_MFD_MC13XXX_I2C is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_HTC_I2CPLD is not set
# CONFIG_LPC_ICH is not set
# CONFIG_LPC_SCH is not set
# CONFIG_MFD_JANZ_CMODIO is not set
# CONFIG_MFD_KEMPLD is not set
# CONFIG_MFD_88PM800 is not set
# CONFIG_MFD_88PM805 is not set
# CONFIG_MFD_88PM860X is not set
# CONFIG_MFD_MAX77686 is not set
# CONFIG_MFD_MAX77693 is not set
# CONFIG_MFD_MAX8907 is not set
# CONFIG_MFD_MAX8925 is not set
# CONFIG_MFD_MAX8997 is not set
# CONFIG_MFD_MAX8998 is not set
# CONFIG_EZX_PCAP is not set
# CONFIG_MFD_VIPERBOARD is not set
# CONFIG_MFD_RETU is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_MFD_RDC321X is not set
# CONFIG_MFD_RTSX_PCI is not set
# CONFIG_MFD_RC5T583 is not set
# CONFIG_MFD_SEC_CORE is not set
# CONFIG_MFD_SI476X_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_MFD_SMSC is not set
# CONFIG_ABX500_CORE is not set
# CONFIG_MFD_STMPE is not set
# CONFIG_MFD_SYSCON is not set
# CONFIG_MFD_TI_AM335X_TSCADC is not set
# CONFIG_MFD_LP8788 is not set
# CONFIG_MFD_PALMAS is not set
# CONFIG_TPS6105X is not set
# CONFIG_TPS65010 is not set
# CONFIG_TPS6507X is not set
# CONFIG_MFD_TPS65090 is not set
# CONFIG_MFD_TPS65217 is not set
# CONFIG_MFD_TPS6586X is not set
# CONFIG_MFD_TPS65910 is not set
# CONFIG_MFD_TPS65912 is not set
# CONFIG_MFD_TPS65912_I2C is not set
# CONFIG_MFD_TPS65912_SPI is not set
# CONFIG_MFD_TPS80031 is not set
# CONFIG_TWL4030_CORE is not set
# CONFIG_TWL6040_CORE is not set
# CONFIG_MFD_WL1273_CORE is not set
# CONFIG_MFD_LM3533 is not set
# CONFIG_MFD_TIMBERDALE is not set
# CONFIG_MFD_TC3589X is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_VX855 is not set
# CONFIG_MFD_ARIZONA_I2C is not set
# CONFIG_MFD_ARIZONA_SPI is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM831X_I2C is not set
# CONFIG_MFD_WM831X_SPI is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_WM8994 is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set

#
# Graphics support
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
# CONFIG_FB is not set
# CONFIG_EXYNOS_VIDEO is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set

#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
# CONFIG_VGACON_SOFT_SCROLLBACK is not set
CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set

#
# HID support
#
CONFIG_HID=y
# CONFIG_HIDRAW is not set
# CONFIG_UHID is not set
CONFIG_HID_GENERIC=y

#
# Special HID drivers
#
# CONFIG_HID_A4TECH is not set
# CONFIG_HID_ACRUX is not set
# CONFIG_HID_APPLE is not set
# CONFIG_HID_APPLEIR is not set
# CONFIG_HID_AUREAL is not set
# CONFIG_HID_BELKIN is not set
# CONFIG_HID_CHERRY is not set
# CONFIG_HID_CHICONY is not set
# CONFIG_HID_CYPRESS is not set
# CONFIG_HID_DRAGONRISE is not set
# CONFIG_HID_EMS_FF is not set
# CONFIG_HID_ELECOM is not set
# CONFIG_HID_ELO is not set
# CONFIG_HID_EZKEY is not set
# CONFIG_HID_HOLTEK is not set
# CONFIG_HID_HUION is not set
# CONFIG_HID_KEYTOUCH is not set
# CONFIG_HID_KYE is not set
# CONFIG_HID_UCLOGIC is not set
# CONFIG_HID_WALTOP is not set
# CONFIG_HID_GYRATION is not set
# CONFIG_HID_ICADE is not set
# CONFIG_HID_TWINHAN is not set
# CONFIG_HID_KENSINGTON is not set
# CONFIG_HID_LCPOWER is not set
# CONFIG_HID_LENOVO_TPKBD is not set
# CONFIG_HID_LOGITECH is not set
# CONFIG_HID_MAGICMOUSE is not set
# CONFIG_HID_MICROSOFT is not set
# CONFIG_HID_MONTEREY is not set
# CONFIG_HID_MULTITOUCH is not set
# CONFIG_HID_NTRIG is not set
# CONFIG_HID_ORTEK is not set
# CONFIG_HID_PANTHERLORD is not set
# CONFIG_HID_PETALYNX is not set
# CONFIG_HID_PICOLCD is not set
# CONFIG_HID_PRIMAX is not set
# CONFIG_HID_ROCCAT is not set
# CONFIG_HID_SAITEK is not set
# CONFIG_HID_SAMSUNG is not set
# CONFIG_HID_SPEEDLINK is not set
# CONFIG_HID_STEELSERIES is not set
# CONFIG_HID_SUNPLUS is not set
# CONFIG_HID_GREENASIA is not set
# CONFIG_HID_SMARTJOYPLUS is not set
# CONFIG_HID_TIVO is not set
# CONFIG_HID_TOPSEED is not set
# CONFIG_HID_THRUSTMASTER is not set
# CONFIG_HID_ZEROPLUS is not set
# CONFIG_HID_ZYDACRON is not set
# CONFIG_HID_SENSOR_HUB is not set

#
# USB HID support
#
CONFIG_USB_HID=m
# CONFIG_HID_PID is not set
# CONFIG_USB_HIDDEV is not set

#
# USB HID Boot Protocol drivers
#
# CONFIG_USB_KBD is not set
# CONFIG_USB_MOUSE is not set

#
# I2C HID support
#
# CONFIG_I2C_HID is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_COMMON=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set

#
# Miscellaneous USB options
#
CONFIG_USB_DEFAULT_PERSIST=y
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_OTG_WHITELIST is not set
# CONFIG_USB_OTG_BLACKLIST_HUB is not set
CONFIG_USB_MON=y
# CONFIG_USB_WUSB_CBAF is not set

#
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
# CONFIG_USB_XHCI_HCD is not set
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_TT_NEWSCHED=y
CONFIG_USB_FSL_MPH_DR_OF=y
CONFIG_USB_EHCI_PCI=y
# CONFIG_XPS_USB_HCD_XILINX is not set
CONFIG_USB_EHCI_FSL=y
CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_EHCI_HCD_PLATFORM is not set
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
# CONFIG_USB_ISP1362_HCD is not set
# CONFIG_USB_FUSBH200_HCD is not set
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
CONFIG_USB_OHCI_HCD_PPC_OF=y
CONFIG_USB_OHCI_HCD_PCI=y
# CONFIG_USB_OHCI_HCD_PLATFORM is not set
CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_UHCI_HCD is not set
# CONFIG_USB_SL811_HCD is not set
# CONFIG_USB_R8A66597_HCD is not set

#
# USB Device Class drivers
#
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
# CONFIG_USB_WDM is not set
# CONFIG_USB_TMC is not set

#
# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#

#
# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_REALTEK is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
# CONFIG_USB_STORAGE_ALAUDA is not set
# CONFIG_USB_STORAGE_ONETOUCH is not set
# CONFIG_USB_STORAGE_KARMA is not set
# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
# CONFIG_USB_STORAGE_ENE_UB6250 is not set

#
# USB Imaging devices
#
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_MICROTEK is not set
# CONFIG_USB_DWC3 is not set
# CONFIG_USB_CHIPIDEA is not set

#
# USB port drivers
#
# CONFIG_USB_SERIAL is not set

#
# USB Miscellaneous drivers
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
# CONFIG_USB_ADUTUX is not set
# CONFIG_USB_SEVSEG is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
# CONFIG_USB_TEST is not set
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_YUREX is not set
# CONFIG_USB_EZUSB_FX2 is not set
# CONFIG_USB_HSIC_USB3503 is not set
# CONFIG_USB_PHY is not set
# CONFIG_USB_GADGET is not set
# CONFIG_UWB is not set
CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_UNSAFE_RESUME is not set
# CONFIG_MMC_CLKGATE is not set

#
# MMC/SD/SDIO Card Drivers
#
CONFIG_MMC_BLOCK=y
CONFIG_MMC_BLOCK_MINORS=8
CONFIG_MMC_BLOCK_BOUNCE=y
# CONFIG_SDIO_UART is not set
# CONFIG_MMC_TEST is not set

#
# MMC/SD/SDIO Host Controller Drivers
#
CONFIG_MMC_SDHCI=y
# CONFIG_MMC_SDHCI_PCI is not set
# CONFIG_MMC_SDHCI_PLTFM is not set
# CONFIG_MMC_SDHCI_PXAV3 is not set
# CONFIG_MMC_SDHCI_PXAV2 is not set
# CONFIG_MMC_WBSD is not set
# CONFIG_MMC_TIFM_SD is not set
# CONFIG_MMC_CB710 is not set
# CONFIG_MMC_VIA_SDMMC is not set
# CONFIG_MMC_VUB300 is not set
# CONFIG_MMC_USHC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_INFINIBAND is not set
CONFIG_EDAC=y
CONFIG_EDAC_LEGACY_SYSFS=y
# CONFIG_EDAC_DEBUG is not set
CONFIG_EDAC_MM_EDAC=y
CONFIG_EDAC_MPC85XX=y
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
CONFIG_RTC_SYSTOHC=y
CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
# CONFIG_RTC_DEBUG is not set

#
# RTC interfaces
#
CONFIG_RTC_INTF_SYSFS=y
CONFIG_RTC_INTF_PROC=y
CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
# CONFIG_RTC_DRV_TEST is not set

#
# I2C RTC drivers
#
# CONFIG_RTC_DRV_DS1307 is not set
# CONFIG_RTC_DRV_DS1374 is not set
# CONFIG_RTC_DRV_DS1672 is not set
CONFIG_RTC_DRV_DS3232=y
# CONFIG_RTC_DRV_MAX6900 is not set
# CONFIG_RTC_DRV_RS5C372 is not set
# CONFIG_RTC_DRV_ISL1208 is not set
# CONFIG_RTC_DRV_ISL12022 is not set
# CONFIG_RTC_DRV_X1205 is not set
# CONFIG_RTC_DRV_PCF2127 is not set
# CONFIG_RTC_DRV_PCF8523 is not set
# CONFIG_RTC_DRV_PCF8563 is not set
# CONFIG_RTC_DRV_PCF8583 is not set
# CONFIG_RTC_DRV_M41T80 is not set
# CONFIG_RTC_DRV_BQ32K is not set
# CONFIG_RTC_DRV_S35390A is not set
# CONFIG_RTC_DRV_FM3130 is not set
# CONFIG_RTC_DRV_RX8581 is not set
# CONFIG_RTC_DRV_RX8025 is not set
# CONFIG_RTC_DRV_EM3027 is not set
# CONFIG_RTC_DRV_RV3029C2 is not set

#
# SPI RTC drivers
#
# CONFIG_RTC_DRV_M41T93 is not set
# CONFIG_RTC_DRV_M41T94 is not set
# CONFIG_RTC_DRV_DS1305 is not set
# CONFIG_RTC_DRV_DS1390 is not set
# CONFIG_RTC_DRV_MAX6902 is not set
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_DS3234 is not set
# CONFIG_RTC_DRV_PCF2123 is not set
# CONFIG_RTC_DRV_RX4581 is not set

#
# Platform RTC drivers
#
CONFIG_RTC_DRV_CMOS=y
# CONFIG_RTC_DRV_DS1286 is not set
# CONFIG_RTC_DRV_DS1511 is not set
# CONFIG_RTC_DRV_DS1553 is not set
# CONFIG_RTC_DRV_DS1742 is not set
# CONFIG_RTC_DRV_STK17TA8 is not set
# CONFIG_RTC_DRV_M48T86 is not set
# CONFIG_RTC_DRV_M48T35 is not set
# CONFIG_RTC_DRV_M48T59 is not set
# CONFIG_RTC_DRV_MSM6242 is not set
# CONFIG_RTC_DRV_BQ4802 is not set
# CONFIG_RTC_DRV_RP5C01 is not set
# CONFIG_RTC_DRV_V3020 is not set
# CONFIG_RTC_DRV_DS2404 is not set

#
# on-CPU RTC drivers
#
# CONFIG_RTC_DRV_GENERIC is not set
# CONFIG_RTC_DRV_SNVS is not set

#
# HID Sensor RTC drivers
#
# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
# CONFIG_DMADEVICES is not set
# CONFIG_AUXDISPLAY is not set
CONFIG_UIO=y
# CONFIG_UIO_CIF is not set
# CONFIG_UIO_PDRV is not set
# CONFIG_UIO_PDRV_GENIRQ is not set
# CONFIG_UIO_DMEM_GENIRQ is not set
# CONFIG_UIO_AEC is not set
# CONFIG_UIO_SERCOS3 is not set
# CONFIG_UIO_PCI_GENERIC is not set
# CONFIG_UIO_NETX is not set
# CONFIG_VFIO is not set
CONFIG_VIRT_DRIVERS=y
CONFIG_FSL_HV_MANAGER=y

#
# Virtio drivers
#
# CONFIG_VIRTIO_PCI is not set
# CONFIG_VIRTIO_MMIO is not set

#
# Microsoft Hyper-V guest support
#
CONFIG_STAGING=y
# CONFIG_ET131X is not set
# CONFIG_USBIP_CORE is not set
# CONFIG_ECHO is not set
# CONFIG_COMEDI is not set
# CONFIG_ASUS_OLED is not set
# CONFIG_R8187SE is not set
# CONFIG_RTL8192U is not set
# CONFIG_RTLLIB is not set
# CONFIG_R8712U is not set
# CONFIG_RTS5139 is not set
# CONFIG_TRANZPORT is not set
# CONFIG_IDE_PHISON is not set
# CONFIG_VT6655 is not set
# CONFIG_VT6656 is not set
# CONFIG_DX_SEP is not set
# CONFIG_ZSMALLOC is not set
# CONFIG_CRYSTALHD is not set
# CONFIG_USB_ENESTORAGE is not set
# CONFIG_BCM_WIMAX is not set
# CONFIG_FT1000 is not set

#
# Speakup console speech
#
# CONFIG_SPEAKUP is not set
# CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set
# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set
# CONFIG_STAGING_MEDIA is not set

#
# Android
#
# CONFIG_ANDROID is not set
# CONFIG_USB_WPAN_HCD is not set
# CONFIG_WIMAX_GDM72XX is not set
CONFIG_NET_VENDOR_SILICOM=y
# CONFIG_SBYPASS is not set
# CONFIG_BPCTL is not set
# CONFIG_CED1401 is not set
# CONFIG_DGRP is not set
# CONFIG_USB_DWC2 is not set
CONFIG_CLKDEV_LOOKUP=y
CONFIG_HAVE_CLK_PREPARE=y
CONFIG_COMMON_CLK=y

#
# Common Clock Framework
#
# CONFIG_COMMON_CLK_DEBUG is not set
# CONFIG_COMMON_CLK_SI5351 is not set
# CONFIG_CLK_PPC_CORENET is not set

#
# Hardware Spinlock drivers
#
# CONFIG_MAILBOX is not set
CONFIG_IOMMU_API=y
CONFIG_IOMMU_SUPPORT=y
CONFIG_OF_IOMMU=y
CONFIG_FSL_PAMU=y

#
# Remoteproc drivers
#
# CONFIG_STE_MODEM_RPROC is not set

#
# Rpmsg drivers
#
# CONFIG_PM_DEVFREQ is not set
# CONFIG_EXTCON is not set
# CONFIG_MEMORY is not set
# CONFIG_IIO is not set
# CONFIG_VME_BUS is not set
# CONFIG_PWM is not set
CONFIG_IRQCHIP=y
# CONFIG_IPACK_BUS is not set
# CONFIG_RESET_CONTROLLER is not set
# CONFIG_FMC is not set

#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
# CONFIG_EXT4_FS is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_BTRFS_FS is not set
# CONFIG_NILFS2_FS is not set
# CONFIG_FS_POSIX_ACL is not set
CONFIG_EXPORTFS=m
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_FANOTIFY is not set
# CONFIG_QUOTA is not set
# CONFIG_QUOTACTL is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set

#
# Caches
#
# CONFIG_FSCACHE is not set

#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
CONFIG_ZISOFS=y
CONFIG_UDF_FS=m
CONFIG_UDF_NLS=y

#
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=y
CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_NTFS_FS=y
# CONFIG_NTFS_DEBUG is not set
# CONFIG_NTFS_RW is not set

#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_PROC_SYSCTL=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_TMPFS_XATTR is not set
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
# CONFIG_CONFIGFS_FS is not set
CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_ECRYPT_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_HFSPLUS_FS is not set
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
# CONFIG_JFFS2_SUMMARY is not set
# CONFIG_JFFS2_FS_XATTR is not set
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
CONFIG_JFFS2_ZLIB=y
# CONFIG_JFFS2_LZO is not set
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_LOGFS is not set
CONFIG_CRAMFS=y
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_QNX6FS_FS is not set
# CONFIG_ROMFS_FS is not set
# CONFIG_PSTORE is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
# CONFIG_F2FS_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V2=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
CONFIG_NFS_V4=y
# CONFIG_NFS_SWAP is not set
# CONFIG_NFS_V4_1 is not set
CONFIG_ROOT_NFS=y
# CONFIG_NFS_USE_LEGACY_DNS is not set
CONFIG_NFS_USE_KERNEL_DNS=y
CONFIG_NFSD=m
# CONFIG_NFSD_V3 is not set
# CONFIG_NFSD_V4 is not set
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
# CONFIG_SUNRPC_DEBUG is not set
# CONFIG_CEPH_FS is not set
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NLS_CODEPAGE_437 is not set
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
# CONFIG_NLS_CODEPAGE_850 is not set
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not set
# CONFIG_NLS_CODEPAGE_860 is not set
# CONFIG_NLS_CODEPAGE_861 is not set
# CONFIG_NLS_CODEPAGE_862 is not set
# CONFIG_NLS_CODEPAGE_863 is not set
# CONFIG_NLS_CODEPAGE_864 is not set
# CONFIG_NLS_CODEPAGE_865 is not set
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_936 is not set
# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_CODEPAGE_932 is not set
# CONFIG_NLS_CODEPAGE_949 is not set
# CONFIG_NLS_CODEPAGE_874 is not set
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
# CONFIG_NLS_ASCII is not set
CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
# CONFIG_NLS_ISO8859_5 is not set
# CONFIG_NLS_ISO8859_6 is not set
# CONFIG_NLS_ISO8859_7 is not set
# CONFIG_NLS_ISO8859_9 is not set
# CONFIG_NLS_ISO8859_13 is not set
# CONFIG_NLS_ISO8859_14 is not set
# CONFIG_NLS_ISO8859_15 is not set
# CONFIG_NLS_KOI8_R is not set
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_MAC_ROMAN is not set
# CONFIG_NLS_MAC_CELTIC is not set
# CONFIG_NLS_MAC_CENTEURO is not set
# CONFIG_NLS_MAC_CROATIAN is not set
# CONFIG_NLS_MAC_CYRILLIC is not set
# CONFIG_NLS_MAC_GAELIC is not set
# CONFIG_NLS_MAC_GREEK is not set
# CONFIG_NLS_MAC_ICELAND is not set
# CONFIG_NLS_MAC_INUIT is not set
# CONFIG_NLS_MAC_ROMANIAN is not set
# CONFIG_NLS_MAC_TURKISH is not set
CONFIG_NLS_UTF8=m
# CONFIG_BINARY_PRINTF is not set

#
# Library routines
#
CONFIG_BITREVERSE=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_NET_UTILS=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_IO=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
# CONFIG_CRC_T10DIF is not set
CONFIG_CRC_ITU_T=m
CONFIG_CRC32=y
# CONFIG_CRC32_SELFTEST is not set
CONFIG_CRC32_SLICEBY8=y
# CONFIG_CRC32_SLICEBY4 is not set
# CONFIG_CRC32_SARWATE is not set
# CONFIG_CRC32_BIT is not set
# CONFIG_CRC7 is not set
CONFIG_LIBCRC32C=m
# CONFIG_CRC8 is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
# CONFIG_XZ_DEC is not set
# CONFIG_XZ_DEC_BCJ is not set
CONFIG_DECOMPRESS_GZIP=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_CPU_RMAP=y
CONFIG_DQL=y
CONFIG_NLATTR=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
# CONFIG_AVERAGE is not set
# CONFIG_CORDIC is not set
# CONFIG_DDR is not set
CONFIG_OID_REGISTRY=y

#
# Kernel hacking
#

#
# printk and dmesg options
#
# CONFIG_PRINTK_TIME is not set
CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
# CONFIG_DYNAMIC_DEBUG is not set

#
# Compile-time checks and compiler options
#
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_INFO_REDUCED is not set
CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_READABLE_ASM is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
# CONFIG_DEBUG_SECTION_MISMATCH is not set
# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y

#
# Memory Debugging
#
# CONFIG_DEBUG_PAGEALLOC is not set
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_DEBUG_SLAB is not set
CONFIG_HAVE_DEBUG_KMEMLEAK=y
# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_MEMORY_INIT is not set
# CONFIG_DEBUG_PER_CPU_MAPS is not set
# CONFIG_DEBUG_HIGHMEM is not set
CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
# CONFIG_DEBUG_STACKOVERFLOW is not set
CONFIG_DEBUG_SHIRQ=y

#
# Debug Lockups and Hangs
#
# CONFIG_LOCKUP_DETECTOR is not set
CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
# CONFIG_PANIC_ON_OOPS is not set
CONFIG_PANIC_ON_OOPS_VALUE=0
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set

#
# Lock Debugging (spinlocks, mutexes, etc...)
#
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
# CONFIG_DEBUG_LOCK_ALLOC is not set
# CONFIG_PROVE_LOCKING is not set
# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_ATOMIC_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_WRITECOUNT is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
# CONFIG_DEBUG_CREDENTIALS is not set

#
# RCU Debugging
#
# CONFIG_SPARSE_RCU_POINTER is not set
# CONFIG_RCU_TORTURE_TEST is not set
CONFIG_RCU_CPU_STALL_TIMEOUT=21
# CONFIG_RCU_CPU_STALL_INFO is not set
CONFIG_RCU_TRACE=y
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_NOTIFIER_ERROR_INJECTION is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_TRACE_CLOCK=y
CONFIG_TRACING_SUPPORT=y
CONFIG_FTRACE=y
# CONFIG_FUNCTION_TRACER is not set
# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_ENABLE_DEFAULT_TRACERS is not set
# CONFIG_FTRACE_SYSCALLS is not set
# CONFIG_TRACER_SNAPSHOT is not set
CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
# CONFIG_PROFILE_ALL_BRANCHES is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_UPROBE_EVENT is not set
# CONFIG_PROBE_EVENTS is not set

#
# Runtime Testing
#
# CONFIG_LKDTM is not set
# CONFIG_TEST_LIST_SORT is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_RBTREE_TEST is not set
# CONFIG_INTERVAL_TREE_TEST is not set
# CONFIG_ATOMIC64_SELFTEST is not set
# CONFIG_TEST_STRING_HELPERS is not set
# CONFIG_TEST_KSTRTOX is not set
# CONFIG_DMA_API_DEBUG is not set
CONFIG_SAMPLES=y
CONFIG_SAMPLE_KOBJECT=m
# CONFIG_SAMPLE_KFIFO is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
# CONFIG_PPC_DISABLE_WERROR is not set
CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
# CONFIG_PPC_EMULATED_STATS is not set
# CONFIG_CODE_PATCHING_SELFTEST is not set
# CONFIG_FTR_FIXUP_SELFTEST is not set
# CONFIG_MSI_BITMAP_SELFTEST is not set
# CONFIG_XMON is not set
# CONFIG_BDI_SWITCH is not set
# CONFIG_PPC_EARLY_DEBUG is not set
CONFIG_STRICT_DEVMEM=y

#
# Security options
#
CONFIG_KEYS=y
# CONFIG_ENCRYPTED_KEYS is not set
# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
# CONFIG_SECURITY_DMESG_RESTRICT is not set
# CONFIG_SECURITY is not set
# CONFIG_SECURITYFS is not set
CONFIG_DEFAULT_SECURITY_DAC=y
CONFIG_DEFAULT_SECURITY=""
CONFIG_CRYPTO=y

#
# Crypto core or helper
#
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=y
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_PCOMP2=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_USER is not set
CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
# CONFIG_CRYPTO_GF128MUL is not set
CONFIG_CRYPTO_NULL=y
# CONFIG_CRYPTO_PCRYPT is not set
CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_AUTHENC=y
# CONFIG_CRYPTO_TEST is not set

#
# Authenticated Encryption with Associated Data
#
# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_GCM is not set
# CONFIG_CRYPTO_SEQIV is not set

#
# Block modes
#
CONFIG_CRYPTO_CBC=y
# CONFIG_CRYPTO_CTR is not set
# CONFIG_CRYPTO_CTS is not set
# CONFIG_CRYPTO_ECB is not set
# CONFIG_CRYPTO_LRW is not set
CONFIG_CRYPTO_PCBC=m
# CONFIG_CRYPTO_XTS is not set

#
# Hash modes
#
# CONFIG_CRYPTO_CMAC is not set
CONFIG_CRYPTO_HMAC=y
# CONFIG_CRYPTO_XCBC is not set
# CONFIG_CRYPTO_VMAC is not set

#
# Digest
#
CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_CRC32 is not set
# CONFIG_CRYPTO_CRCT10DIF is not set
# CONFIG_CRYPTO_GHASH is not set
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_RMD128 is not set
# CONFIG_CRYPTO_RMD160 is not set
# CONFIG_CRYPTO_RMD256 is not set
# CONFIG_CRYPTO_RMD320 is not set
CONFIG_CRYPTO_SHA1=y
# CONFIG_CRYPTO_SHA1_PPC is not set
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA512=y
# CONFIG_CRYPTO_TGR192 is not set
# CONFIG_CRYPTO_WP512 is not set

#
# Ciphers
#
CONFIG_CRYPTO_AES=y
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_ARC4 is not set
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_CAST5 is not set
# CONFIG_CRYPTO_CAST6 is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_FCRYPT is not set
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_SALSA20 is not set
# CONFIG_CRYPTO_SEED is not set
# CONFIG_CRYPTO_SERPENT is not set
# CONFIG_CRYPTO_TEA is not set
# CONFIG_CRYPTO_TWOFISH is not set

#
# Compression
#
CONFIG_CRYPTO_DEFLATE=y
# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
# CONFIG_CRYPTO_LZ4 is not set
# CONFIG_CRYPTO_LZ4HC is not set

#
# Random Number Generation
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_USER_API_HASH is not set
# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
CONFIG_CRYPTO_HW=y
CONFIG_CRYPTO_DEV_FSL_CAAM=y
CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE=9
# CONFIG_CRYPTO_DEV_FSL_CAAM_INTC is not set
CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API=y
CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API=y
CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API=y
# CONFIG_CRYPTO_DEV_TALITOS is not set
# CONFIG_ASYMMETRIC_KEY_TYPE is not set
# CONFIG_PPC_CLOCK is not set
# CONFIG_VIRTUALIZATION is not set

^ permalink raw reply	[flat|nested] 20+ messages in thread

* RE: [PATCH 1/3] powerpc: Add iommu domain pointer to device archdata
@ 2013-08-14  9:56     ` Sethi Varun-B16395
  0 siblings, 0 replies; 20+ messages in thread
From: Sethi Varun-B16395 @ 2013-08-14  9:56 UTC (permalink / raw)
  To: Joerg Roedel
  Cc: Wood Scott-B07421, iommu, linux-kernel, Yoder Stuart-B08248,
	alex.williamson, linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 1441 bytes --]

Hi Joerg,
Please find the .config file attached with this mail.

Regards
Varun

> -----Original Message-----
> From: Joerg Roedel [mailto:joro@8bytes.org]
> Sent: Wednesday, August 14, 2013 3:18 PM
> To: Sethi Varun-B16395
> Cc: iommu@lists.linux-foundation.org; linuxppc-dev@lists.ozlabs.org;
> linux-kernel@vger.kernel.org; benh@kernel.crashing.org;
> galak@kernel.crashing.org; alex.williamson@redhat.com; Yoder Stuart-
> B08248; Wood Scott-B07421
> Subject: Re: [PATCH 1/3] powerpc: Add iommu domain pointer to device
> archdata
> 
> On Mon, Jul 15, 2013 at 10:20:55AM +0530, Varun Sethi wrote:
> > Add an iommu domain pointer to device (powerpc) archdata.  Devices are
> > attached to iommu domains and this pointer provides a mechanism to
> > correlate between a device and the associated iommu domain.  This
> > field is set when a device is attached to a domain.
> >
> > Signed-off-by: Varun Sethi <Varun.Sethi@freescale.com>
> > Acked-by: Kumar Gala <galak@kernel.crashing.org>
> > ---
> > - rebased patch to 3.11-rc1
> >  arch/powerpc/include/asm/device.h |    3 +++
> >  1 files changed, 3 insertions(+), 0 deletions(-)
> 
> Okay, I applied these patches to my ppc/pamu branch. But before I merge
> it to my next branch (so that it can go upstream) I want to have a
> compile-test-case first. Can you send me a working .config which includes
> this driver?
> 
> Thanks,
> 
> 	Joerg
> 
> 


[-- Attachment #2: pamu_build_config --]
[-- Type: application/octet-stream, Size: 65153 bytes --]

#
# Automatically generated file; DO NOT EDIT.
# Linux/powerpc 3.11.0-rc1 Kernel Configuration
#
# CONFIG_PPC64 is not set

#
# Processor support
#
# CONFIG_PPC_BOOK3S_32 is not set
CONFIG_PPC_85xx=y
# CONFIG_PPC_8xx is not set
# CONFIG_40x is not set
# CONFIG_44x is not set
# CONFIG_E200 is not set
CONFIG_E500=y
CONFIG_PPC_E500MC=y
CONFIG_PPC_FPU=y
CONFIG_FSL_EMB_PERFMON=y
CONFIG_FSL_EMB_PERF_EVENT=y
CONFIG_FSL_EMB_PERF_EVENT_E500=y
CONFIG_BOOKE=y
CONFIG_FSL_BOOKE=y
CONFIG_PPC_FSL_BOOK3E=y
CONFIG_PTE_64BIT=y
CONFIG_PHYS_64BIT=y
CONFIG_PPC_MMU_NOHASH=y
CONFIG_PPC_BOOK3E_MMU=y
# CONFIG_PPC_MM_SLICES is not set
CONFIG_SMP=y
CONFIG_NR_CPUS=8
CONFIG_PPC_DOORBELL=y
CONFIG_PPC32=y
CONFIG_32BIT=y
CONFIG_WORD_SIZE=32
CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
CONFIG_MMU=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_NR_IRQS=512
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_ARCH_HAS_ILOG2_U32=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_PPC=y
CONFIG_EARLY_PRINTK=y
CONFIG_GENERIC_NVRAM=y
CONFIG_SCHED_OMIT_FRAME_POINTER=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_PPC_OF=y
CONFIG_PPC_UDBG_16550=y
CONFIG_GENERIC_TBSYNC=y
CONFIG_AUDIT_ARCH=y
CONFIG_GENERIC_BUG=y
# CONFIG_EPAPR_BOOT is not set
CONFIG_DEFAULT_UIMAGE=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_PPC_ADV_DEBUG_REGS=y
CONFIG_PPC_ADV_DEBUG_IACS=2
CONFIG_PPC_ADV_DEBUG_DACS=2
CONFIG_PPC_ADV_DEBUG_DVCS=0
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_IRQ_WORK=y

#
# General setup
#
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_CROSS_COMPILE=""
# CONFIG_COMPILE_TEST is not set
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_DEFAULT_HOSTNAME="(none)"
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
CONFIG_POSIX_MQUEUE_SYSCTL=y
# CONFIG_FHANDLE is not set
CONFIG_AUDIT=y
# CONFIG_AUDITSYSCALL is not set
# CONFIG_AUDIT_LOGINUID_IMMUTABLE is not set
CONFIG_HAVE_GENERIC_HARDIRQS=y

#
# IRQ subsystem
#
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
CONFIG_IRQ_DOMAIN=y
# CONFIG_IRQ_DOMAIN_DEBUG is not set
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_SPARSE_IRQ=y
CONFIG_GENERIC_TIME_VSYSCALL_OLD=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_CMOS_UPDATE=y

#
# Timers subsystem
#
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ_COMMON=y
# CONFIG_HZ_PERIODIC is not set
CONFIG_NO_HZ_IDLE=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y

#
# CPU/Task time and stats accounting
#
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set

#
# RCU Subsystem
#
CONFIG_TREE_RCU=y
# CONFIG_PREEMPT_RCU is not set
CONFIG_RCU_STALL_COMMON=y
CONFIG_RCU_FANOUT=32
CONFIG_RCU_FANOUT_LEAF=16
# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_RCU_FAST_NO_HZ is not set
CONFIG_TREE_RCU_TRACE=y
# CONFIG_RCU_NOCB_CPU is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
# CONFIG_CHECKPOINT_RESTORE is not set
# CONFIG_NAMESPACES is not set
CONFIG_UIDGID_CONVERTED=y
# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
# CONFIG_SCHED_AUTOGROUP is not set
# CONFIG_SYSFS_DEPRECATED is not set
# CONFIG_RELAY is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
# CONFIG_RD_XZ is not set
# CONFIG_RD_LZO is not set
# CONFIG_RD_LZ4 is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
CONFIG_EXPERT=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_PCI_QUIRKS=y
CONFIG_EMBEDDED=y
CONFIG_HAVE_PERF_EVENTS=y

#
# Kernel Performance Events And Counters
#
CONFIG_PERF_EVENTS=y
# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
# CONFIG_JUMP_LABEL is not set
# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_DMA_ATTRS=y
CONFIG_USE_GENERIC_SMP_HELPERS=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_CLK=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_HAVE_RCU_TABLE_FREE=y
CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
CONFIG_MODULES_USE_ELF_RELA=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_OLD_SIGSUSPEND=y
CONFIG_OLD_SIGACTION=y

#
# GCOV-based kernel profiling
#
# CONFIG_GCOV_KERNEL is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODVERSIONS=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
# CONFIG_MODULE_SIG is not set
CONFIG_STOP_MACHINE=y
CONFIG_BLOCK=y
CONFIG_LBDAF=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_BSGLIB is not set
# CONFIG_BLK_DEV_INTEGRITY is not set

#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
# CONFIG_ACORN_PARTITION is not set
# CONFIG_AIX_PARTITION is not set
# CONFIG_OSF_PARTITION is not set
# CONFIG_AMIGA_PARTITION is not set
# CONFIG_ATARI_PARTITION is not set
CONFIG_MAC_PARTITION=y
CONFIG_MSDOS_PARTITION=y
# CONFIG_BSD_DISKLABEL is not set
# CONFIG_MINIX_SUBPARTITION is not set
# CONFIG_SOLARIS_X86_PARTITION is not set
# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_LDM_PARTITION is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_KARMA_PARTITION is not set
CONFIG_EFI_PARTITION=y
# CONFIG_SYSV68_PARTITION is not set

#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
# CONFIG_DEFAULT_DEADLINE is not set
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
CONFIG_INLINE_READ_UNLOCK=y
CONFIG_INLINE_READ_UNLOCK_IRQ=y
CONFIG_INLINE_WRITE_UNLOCK=y
CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
CONFIG_MUTEX_SPIN_ON_OWNER=y
# CONFIG_FREEZER is not set
CONFIG_PPC_MSI_BITMAP=y
# CONFIG_PPC_XICS is not set
# CONFIG_PPC_ICP_NATIVE is not set
# CONFIG_PPC_ICP_HV is not set
# CONFIG_PPC_ICS_RTAS is not set
# CONFIG_GE_FPGA is not set

#
# Platform support
#
CONFIG_POWERNV_MSI=y
# CONFIG_PPC_CELL is not set
# CONFIG_PPC_CELL_NATIVE is not set
# CONFIG_PQ2ADS is not set
CONFIG_FSL_SOC_BOOKE=y
# CONFIG_BSC9131_RDB is not set
# CONFIG_MPC8540_ADS is not set
# CONFIG_MPC8560_ADS is not set
# CONFIG_MPC85xx_CDS is not set
# CONFIG_MPC85xx_MDS is not set
# CONFIG_MPC8536_DS is not set
# CONFIG_MPC85xx_DS is not set
# CONFIG_MPC85xx_RDB is not set
# CONFIG_P1010_RDB is not set
# CONFIG_P1022_DS is not set
# CONFIG_P1022_RDK is not set
# CONFIG_P1023_RDS is not set
# CONFIG_SOCRATES is not set
# CONFIG_KSI8560 is not set
# CONFIG_XES_MPC85xx is not set
# CONFIG_STX_GP3 is not set
# CONFIG_TQM8540 is not set
# CONFIG_TQM8541 is not set
# CONFIG_TQM8548 is not set
# CONFIG_TQM8555 is not set
# CONFIG_TQM8560 is not set
# CONFIG_SBC8548 is not set
# CONFIG_PPA8548 is not set
# CONFIG_GE_IMP3A is not set
CONFIG_P2041_RDB=y
CONFIG_P3041_DS=y
CONFIG_P4080_DS=y
# CONFIG_SGY_CTS1000 is not set
CONFIG_P5020_DS=y
CONFIG_P5040_DS=y
# CONFIG_PPC_QEMU_E500 is not set
# CONFIG_PPC_WSP is not set
# CONFIG_KVM_GUEST is not set
CONFIG_EPAPR_PARAVIRT=y
CONFIG_PPC_SMP_MUXED_IPI=y
# CONFIG_IPIC is not set
CONFIG_MPIC=y
# CONFIG_MPIC_TIMER is not set
CONFIG_PPC_EPAPR_HV_PIC=y
# CONFIG_MPIC_WEIRD is not set
# CONFIG_MPIC_MSGR is not set
# CONFIG_PPC_I8259 is not set
# CONFIG_PPC_RTAS is not set
# CONFIG_MMIO_NVRAM is not set
# CONFIG_MPIC_U3_HT_IRQS is not set
# CONFIG_PPC_MPC106 is not set
# CONFIG_PPC_970_NAP is not set
# CONFIG_PPC_P7_NAP is not set

#
# CPU Frequency scaling
#
# CONFIG_CPU_FREQ is not set

#
# CPUIdle driver
#
# CONFIG_CPU_IDLE is not set
# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
# CONFIG_QUICC_ENGINE is not set
# CONFIG_CPM2 is not set
# CONFIG_FSL_ULI1575 is not set
# CONFIG_SIMPLE_GPIO is not set

#
# Kernel options
#
CONFIG_HIGHMEM=y
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
CONFIG_SCHED_HRTICK=y
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
CONFIG_BINFMT_ELF=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_BINFMT_SCRIPT=y
# CONFIG_HAVE_AOUT is not set
CONFIG_BINFMT_MISC=m
CONFIG_COREDUMP=y
CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y
# CONFIG_MATH_EMULATION is not set
CONFIG_IOMMU_HELPER=y
CONFIG_SWIOTLB=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
CONFIG_KEXEC=y
# CONFIG_CRASH_DUMP is not set
# CONFIG_IRQ_ALL_CPUS is not set
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_SYS_SUPPORTS_HUGETLBFS=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_HAVE_MEMBLOCK=y
CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_COMPACTION=y
CONFIG_MIGRATION=y
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_CROSS_MEMORY_ATTACH=y
# CONFIG_CLEANCACHE is not set
# CONFIG_FRONTSWAP is not set
# CONFIG_ZBUD is not set
CONFIG_PPC_4K_PAGES=y
CONFIG_FORCE_MAX_ZONEORDER=13
# CONFIG_CMDLINE_BOOL is not set
CONFIG_EXTRA_TARGETS=""
# CONFIG_HIBERNATION is not set
# CONFIG_PM_RUNTIME is not set
CONFIG_SECCOMP=y
CONFIG_ISA_DMA_API=y

#
# Bus options
#
CONFIG_ZONE_DMA=y
# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
CONFIG_FSL_PCI=y
CONFIG_FSL_LBC=y
CONFIG_FSL_IFC=y
CONFIG_PPC_PCI_CHOICE=y
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_SYSCALL=y
CONFIG_PCIEPORTBUS=y
CONFIG_PCIEAER=y
# CONFIG_PCIE_ECRC is not set
# CONFIG_PCIEAER_INJECT is not set
# CONFIG_PCIEASPM is not set
CONFIG_ARCH_SUPPORTS_MSI=y
CONFIG_PCI_MSI=y
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_PCI_PRI is not set
# CONFIG_PCI_PASID is not set

#
# PCI host controller drivers
#
# CONFIG_PCCARD is not set
# CONFIG_HOTPLUG_PCI is not set
CONFIG_HAS_RAPIDIO=y
CONFIG_RAPIDIO=y
CONFIG_FSL_RIO=y
# CONFIG_RAPIDIO_TSI721 is not set
CONFIG_RAPIDIO_DISC_TIMEOUT=30
# CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS is not set
# CONFIG_RAPIDIO_DMA_ENGINE is not set
# CONFIG_RAPIDIO_DEBUG is not set
# CONFIG_RAPIDIO_ENUM_BASIC is not set

#
# RapidIO Switch drivers
#
# CONFIG_RAPIDIO_TSI57X is not set
# CONFIG_RAPIDIO_CPS_XX is not set
# CONFIG_RAPIDIO_TSI568 is not set
# CONFIG_RAPIDIO_CPS_GEN2 is not set
# CONFIG_NONSTATIC_KERNEL is not set

#
# Advanced setup
#
# CONFIG_ADVANCED_OPTIONS is not set

#
# Default settings for advanced configuration options are used
#
CONFIG_LOWMEM_SIZE=0x30000000
CONFIG_LOWMEM_CAM_NUM=3
CONFIG_PAGE_OFFSET=0xc0000000
CONFIG_KERNEL_START=0xc0000000
CONFIG_PHYSICAL_START=0x00000000
CONFIG_PHYSICAL_ALIGN=0x04000000
CONFIG_TASK_SIZE=0xc0000000
CONFIG_NET=y

#
# Networking options
#
CONFIG_PACKET=y
# CONFIG_PACKET_DIAG is not set
CONFIG_UNIX=y
# CONFIG_UNIX_DIAG is not set
CONFIG_XFRM=y
CONFIG_XFRM_ALGO=y
CONFIG_XFRM_USER=y
CONFIG_XFRM_SUB_POLICY=y
CONFIG_XFRM_MIGRATE=y
CONFIG_XFRM_STATISTICS=y
CONFIG_XFRM_IPCOMP=y
CONFIG_NET_KEY=y
CONFIG_NET_KEY_MIGRATE=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
# CONFIG_IP_FIB_TRIE_STATS is not set
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_MULTIPATH=y
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_RARP=y
CONFIG_NET_IPIP=y
# CONFIG_NET_IPGRE_DEMUX is not set
CONFIG_NET_IP_TUNNEL=y
CONFIG_IP_MROUTE=y
# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
CONFIG_ARPD=y
# CONFIG_SYN_COOKIES is not set
# CONFIG_NET_IPVTI is not set
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
CONFIG_INET_IPCOMP=y
CONFIG_INET_XFRM_TUNNEL=y
CONFIG_INET_TUNNEL=y
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_XFRM_MODE_BEET=y
# CONFIG_INET_LRO is not set
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_INET_UDP_DIAG is not set
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TCP_MD5SIG is not set
CONFIG_IPV6=y
# CONFIG_IPV6_PRIVACY is not set
# CONFIG_IPV6_ROUTER_PREF is not set
# CONFIG_IPV6_OPTIMISTIC_DAD is not set
# CONFIG_INET6_AH is not set
# CONFIG_INET6_ESP is not set
# CONFIG_INET6_IPCOMP is not set
# CONFIG_IPV6_MIP6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
CONFIG_INET6_XFRM_MODE_TRANSPORT=y
CONFIG_INET6_XFRM_MODE_TUNNEL=y
CONFIG_INET6_XFRM_MODE_BEET=y
# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
CONFIG_IPV6_SIT=y
# CONFIG_IPV6_SIT_6RD is not set
CONFIG_IPV6_NDISC_NODETYPE=y
# CONFIG_IPV6_TUNNEL is not set
# CONFIG_IPV6_GRE is not set
# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_IPV6_MROUTE is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
CONFIG_IP_SCTP=m
# CONFIG_SCTP_DBG_OBJCNT is not set
CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y
# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 is not set
# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set
CONFIG_SCTP_COOKIE_HMAC_MD5=y
# CONFIG_SCTP_COOKIE_HMAC_SHA1 is not set
# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_L2TP is not set
# CONFIG_BRIDGE is not set
CONFIG_HAVE_NET_DSA=y
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_PHONET is not set
# CONFIG_IEEE802154 is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
CONFIG_DNS_RESOLVER=y
# CONFIG_BATMAN_ADV is not set
# CONFIG_OPENVSWITCH is not set
# CONFIG_VSOCKETS is not set
# CONFIG_NETLINK_MMAP is not set
# CONFIG_NETLINK_DIAG is not set
# CONFIG_NET_MPLS_GSO is not set
CONFIG_RPS=y
CONFIG_RFS_ACCEL=y
CONFIG_XPS=y
CONFIG_NET_LL_RX_POLL=y
CONFIG_BQL=y
CONFIG_NET_FLOW_LIMIT=y

#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_LIB80211 is not set

#
# CFG80211 needs to be enabled for MAC80211
#
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
# CONFIG_CAIF is not set
# CONFIG_CEPH_LIB is not set
# CONFIG_NFC is not set

#
# Device Drivers
#

#
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
# CONFIG_DEVTMPFS_MOUNT is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
CONFIG_FIRMWARE_IN_KERNEL=y
CONFIG_EXTRA_FIRMWARE=""
CONFIG_FW_LOADER_USER_HELPER=y
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_GENERIC_CPU_DEVICES is not set
# CONFIG_DMA_SHARED_BUFFER is not set

#
# Bus devices
#
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_OF_PARTS=y
# CONFIG_MTD_AR7_PARTS is not set

#
# User Modules And Translation Layers
#
CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_BLOCK=y
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
# CONFIG_SSFDC is not set
# CONFIG_SM_FTL is not set
# CONFIG_MTD_OOPS is not set
# CONFIG_MTD_SWAP is not set

#
# RAM/ROM/Flash chip drivers
#
CONFIG_MTD_CFI=y
# CONFIG_MTD_JEDECPROBE is not set
CONFIG_MTD_GEN_PROBE=y
# CONFIG_MTD_CFI_ADV_OPTIONS is not set
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
# CONFIG_MTD_CFI_INTELEXT is not set
CONFIG_MTD_CFI_AMDSTD=y
# CONFIG_MTD_CFI_STAA is not set
CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set

#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set
CONFIG_MTD_PHYSMAP_OF=y
# CONFIG_MTD_INTEL_VR_NOR is not set
# CONFIG_MTD_PLATRAM is not set

#
# Self-contained MTD device drivers
#
# CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_DATAFLASH is not set
CONFIG_MTD_M25P80=y
CONFIG_M25PXX_USE_FAST_READ=y
# CONFIG_MTD_SST25L is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
# CONFIG_MTD_BLOCK2MTD is not set

#
# Disk-On-Chip Device Drivers
#
# CONFIG_MTD_DOCG3 is not set
CONFIG_MTD_NAND_ECC=y
# CONFIG_MTD_NAND_ECC_SMC is not set
CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_ECC_BCH is not set
# CONFIG_MTD_SM_COMMON is not set
# CONFIG_MTD_NAND_DENALI is not set
CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_RICOH is not set
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_NAND_DOCG4 is not set
# CONFIG_MTD_NAND_CAFE is not set
# CONFIG_MTD_NAND_NANDSIM is not set
# CONFIG_MTD_NAND_PLATFORM is not set
# CONFIG_MTD_ALAUDA is not set
CONFIG_MTD_NAND_FSL_ELBC=y
CONFIG_MTD_NAND_FSL_IFC=y
# CONFIG_MTD_NAND_FSL_UPM is not set
# CONFIG_MTD_ONENAND is not set

#
# LPDDR flash memory drivers
#
# CONFIG_MTD_LPDDR is not set
# CONFIG_MTD_UBI is not set
CONFIG_DTC=y
CONFIG_OF=y

#
# Device Tree and Open Firmware support
#
CONFIG_PROC_DEVICETREE=y
# CONFIG_OF_SELFTEST is not set
CONFIG_OF_FLATTREE=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_IRQ=y
CONFIG_OF_I2C=y
CONFIG_OF_NET=y
CONFIG_OF_MDIO=y
CONFIG_OF_PCI=y
CONFIG_OF_PCI_IRQ=y
CONFIG_OF_MTD=y
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_DRBD is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_NVME is not set
# CONFIG_BLK_DEV_SX8 is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=131072
# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
# CONFIG_BLK_DEV_RBD is not set
# CONFIG_BLK_DEV_RSXX is not set

#
# Misc devices
#
# CONFIG_SENSORS_LIS3LV02D is not set
# CONFIG_AD525X_DPOT is not set
# CONFIG_ATMEL_PWM is not set
# CONFIG_DUMMY_IRQ is not set
# CONFIG_PHANTOM is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ATMEL_SSC is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
# CONFIG_APDS9802ALS is not set
# CONFIG_ISL29003 is not set
# CONFIG_ISL29020 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_SENSORS_BH1780 is not set
# CONFIG_SENSORS_BH1770 is not set
# CONFIG_SENSORS_APDS990X is not set
# CONFIG_HMC6352 is not set
# CONFIG_DS1682 is not set
# CONFIG_TI_DAC7512 is not set
# CONFIG_BMP085_I2C is not set
# CONFIG_BMP085_SPI is not set
# CONFIG_PCH_PHUB is not set
# CONFIG_USB_SWITCH_FSA9480 is not set
# CONFIG_LATTICE_ECP3_CONFIG is not set
# CONFIG_SRAM is not set
# CONFIG_C2PORT is not set

#
# EEPROM support
#
# CONFIG_EEPROM_AT24 is not set
# CONFIG_EEPROM_AT25 is not set
# CONFIG_EEPROM_LEGACY is not set
# CONFIG_EEPROM_MAX6875 is not set
# CONFIG_EEPROM_93CX6 is not set
# CONFIG_EEPROM_93XX46 is not set
# CONFIG_CB710_CORE is not set

#
# Texas Instruments shared transport line discipline
#
# CONFIG_TI_ST is not set
# CONFIG_SENSORS_LIS3_SPI is not set
# CONFIG_SENSORS_LIS3_I2C is not set

#
# Altera FPGA firmware download module
#
# CONFIG_ALTERA_STAPL is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set

#
# SCSI device support
#
CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
# CONFIG_SCSI_TGT is not set
# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y

#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y
# CONFIG_CHR_DEV_OSST is not set
CONFIG_BLK_DEV_SR=y
# CONFIG_BLK_DEV_SR_VENDOR is not set
CONFIG_CHR_DEV_SG=y
# CONFIG_CHR_DEV_SCH is not set
CONFIG_SCSI_MULTI_LUN=y
# CONFIG_SCSI_CONSTANTS is not set
CONFIG_SCSI_LOGGING=y
# CONFIG_SCSI_SCAN_ASYNC is not set

#
# SCSI Transports
#
CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
# CONFIG_SCSI_SAS_ATTRS is not set
# CONFIG_SCSI_SAS_LIBSAS is not set
# CONFIG_SCSI_SRP_ATTRS is not set
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_ISCSI_BOOT_SYSFS is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_CXGB4_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
# CONFIG_SCSI_BNX2X_FCOE is not set
# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_HPSA is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_3W_SAS is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AACRAID is not set
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_SCSI_AIC94XX is not set
# CONFIG_SCSI_MVSAS is not set
# CONFIG_SCSI_MVUMI is not set
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_ARCMSR is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_MPT3SAS is not set
# CONFIG_SCSI_UFSHCD is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_LIBFC is not set
# CONFIG_LIBFCOE is not set
# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_STEX is not set
CONFIG_SCSI_SYM53C8XX_2=y
CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
CONFIG_SCSI_SYM53C8XX_MMIO=y
# CONFIG_SCSI_IPR is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
# CONFIG_SCSI_QLA_FC is not set
# CONFIG_SCSI_QLA_ISCSI is not set
# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_PM8001 is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_CHELSIO_FCOE is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y

#
# Controllers with non-SFF native interface
#
CONFIG_SATA_AHCI=y
# CONFIG_SATA_AHCI_PLATFORM is not set
CONFIG_SATA_FSL=y
# CONFIG_SATA_INIC162X is not set
# CONFIG_SATA_ACARD_AHCI is not set
CONFIG_SATA_SIL24=y
CONFIG_ATA_SFF=y

#
# SFF controllers with custom DMA interface
#
# CONFIG_PDC_ADMA is not set
# CONFIG_SATA_QSTOR is not set
# CONFIG_SATA_SX4 is not set
CONFIG_ATA_BMDMA=y

#
# SATA SFF controllers with BMDMA
#
# CONFIG_ATA_PIIX is not set
# CONFIG_SATA_HIGHBANK is not set
# CONFIG_SATA_MV is not set
# CONFIG_SATA_NV is not set
# CONFIG_SATA_PROMISE is not set
# CONFIG_SATA_RCAR is not set
CONFIG_SATA_SIL=y
# CONFIG_SATA_SIS is not set
# CONFIG_SATA_SVW is not set
# CONFIG_SATA_ULI is not set
# CONFIG_SATA_VIA is not set
# CONFIG_SATA_VITESSE is not set

#
# PATA SFF controllers with BMDMA
#
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_CMD64X is not set
# CONFIG_PATA_CS5520 is not set
# CONFIG_PATA_CS5530 is not set
# CONFIG_PATA_CS5536 is not set
# CONFIG_PATA_CYPRESS is not set
# CONFIG_PATA_EFAR is not set
# CONFIG_PATA_HPT366 is not set
# CONFIG_PATA_HPT37X is not set
# CONFIG_PATA_HPT3X2N is not set
# CONFIG_PATA_HPT3X3 is not set
# CONFIG_PATA_IT8213 is not set
# CONFIG_PATA_IT821X is not set
# CONFIG_PATA_JMICRON is not set
# CONFIG_PATA_MARVELL is not set
# CONFIG_PATA_NETCELL is not set
# CONFIG_PATA_NINJA32 is not set
# CONFIG_PATA_NS87415 is not set
# CONFIG_PATA_OLDPIIX is not set
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC2027X is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
# CONFIG_PATA_RDC is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SCH is not set
# CONFIG_PATA_SERVERWORKS is not set
CONFIG_PATA_SIL680=y
# CONFIG_PATA_SIS is not set
# CONFIG_PATA_TOSHIBA is not set
# CONFIG_PATA_TRIFLEX is not set
# CONFIG_PATA_VIA is not set
# CONFIG_PATA_WINBOND is not set

#
# PIO-only SFF controllers
#
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_MPIIX is not set
# CONFIG_PATA_NS87410 is not set
# CONFIG_PATA_OPTI is not set
# CONFIG_PATA_PLATFORM is not set
# CONFIG_PATA_RZ1000 is not set

#
# Generic fallback / legacy drivers
#
# CONFIG_ATA_GENERIC is not set
# CONFIG_PATA_LEGACY is not set
# CONFIG_MD is not set
# CONFIG_TARGET_CORE is not set
# CONFIG_FUSION is not set

#
# IEEE 1394 (FireWire) support
#
# CONFIG_FIREWIRE is not set
# CONFIG_FIREWIRE_NOSY is not set
# CONFIG_I2O is not set
# CONFIG_MACINTOSH_DRIVERS is not set
CONFIG_NETDEVICES=y
CONFIG_NET_CORE=y
# CONFIG_BONDING is not set
# CONFIG_DUMMY is not set
# CONFIG_EQUALIZER is not set
# CONFIG_NET_FC is not set
# CONFIG_NET_TEAM is not set
# CONFIG_MACVLAN is not set
# CONFIG_VXLAN is not set
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
# CONFIG_RIONET is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
# CONFIG_NLMON is not set
# CONFIG_ARCNET is not set

#
# CAIF transport drivers
#

#
# Distributed Switch Architecture drivers
#
# CONFIG_NET_DSA_MV88E6XXX is not set
# CONFIG_NET_DSA_MV88E6060 is not set
# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
# CONFIG_NET_DSA_MV88E6131 is not set
# CONFIG_NET_DSA_MV88E6123_61_65 is not set
CONFIG_ETHERNET=y
CONFIG_NET_VENDOR_3COM=y
# CONFIG_VORTEX is not set
# CONFIG_TYPHOON is not set
CONFIG_NET_VENDOR_ADAPTEC=y
# CONFIG_ADAPTEC_STARFIRE is not set
CONFIG_NET_VENDOR_ALTEON=y
# CONFIG_ACENIC is not set
CONFIG_NET_VENDOR_AMD=y
# CONFIG_AMD8111_ETH is not set
# CONFIG_PCNET32 is not set
CONFIG_NET_VENDOR_ARC=y
# CONFIG_ARC_EMAC is not set
CONFIG_NET_VENDOR_ATHEROS=y
# CONFIG_ATL2 is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
# CONFIG_ATL1C is not set
# CONFIG_ALX is not set
CONFIG_NET_CADENCE=y
# CONFIG_ARM_AT91_ETHER is not set
# CONFIG_MACB is not set
CONFIG_NET_VENDOR_BROADCOM=y
# CONFIG_B44 is not set
# CONFIG_BNX2 is not set
# CONFIG_CNIC is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2X is not set
CONFIG_NET_VENDOR_BROCADE=y
# CONFIG_BNA is not set
# CONFIG_NET_CALXEDA_XGMAC is not set
CONFIG_NET_VENDOR_CHELSIO=y
# CONFIG_CHELSIO_T1 is not set
# CONFIG_CHELSIO_T3 is not set
# CONFIG_CHELSIO_T4 is not set
# CONFIG_CHELSIO_T4VF is not set
CONFIG_NET_VENDOR_CISCO=y
# CONFIG_ENIC is not set
# CONFIG_DNET is not set
CONFIG_NET_VENDOR_DEC=y
# CONFIG_NET_TULIP is not set
CONFIG_NET_VENDOR_DLINK=y
# CONFIG_DL2K is not set
# CONFIG_SUNDANCE is not set
CONFIG_NET_VENDOR_EMULEX=y
# CONFIG_BE2NET is not set
CONFIG_NET_VENDOR_EXAR=y
# CONFIG_S2IO is not set
# CONFIG_VXGE is not set
CONFIG_NET_VENDOR_FREESCALE=y
CONFIG_FSL_PQ_MDIO=y
# CONFIG_FSL_XGMAC_MDIO is not set
# CONFIG_GIANFAR is not set
CONFIG_NET_VENDOR_HP=y
# CONFIG_HP100 is not set
CONFIG_NET_VENDOR_INTEL=y
# CONFIG_E100 is not set
CONFIG_E1000=y
CONFIG_E1000E=y
# CONFIG_IGB is not set
# CONFIG_IGBVF is not set
# CONFIG_IXGB is not set
# CONFIG_IXGBE is not set
# CONFIG_IXGBEVF is not set
CONFIG_NET_VENDOR_I825XX=y
# CONFIG_IP1000 is not set
# CONFIG_JME is not set
CONFIG_NET_VENDOR_MARVELL=y
# CONFIG_MV643XX_ETH is not set
# CONFIG_MVMDIO is not set
# CONFIG_SKGE is not set
# CONFIG_SKY2 is not set
CONFIG_NET_VENDOR_MELLANOX=y
# CONFIG_MLX4_EN is not set
# CONFIG_MLX4_CORE is not set
CONFIG_NET_VENDOR_MICREL=y
# CONFIG_KS8851 is not set
# CONFIG_KS8851_MLL is not set
# CONFIG_KSZ884X_PCI is not set
CONFIG_NET_VENDOR_MICROCHIP=y
# CONFIG_ENC28J60 is not set
CONFIG_NET_VENDOR_MYRI=y
# CONFIG_MYRI10GE is not set
# CONFIG_FEALNX is not set
CONFIG_NET_VENDOR_NATSEMI=y
# CONFIG_NATSEMI is not set
# CONFIG_NS83820 is not set
CONFIG_NET_VENDOR_8390=y
# CONFIG_NE2K_PCI is not set
CONFIG_NET_VENDOR_NVIDIA=y
# CONFIG_FORCEDETH is not set
CONFIG_NET_VENDOR_OKI=y
# CONFIG_PCH_GBE is not set
# CONFIG_ETHOC is not set
CONFIG_NET_PACKET_ENGINE=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
CONFIG_NET_VENDOR_QLOGIC=y
# CONFIG_QLA3XXX is not set
# CONFIG_QLCNIC is not set
# CONFIG_QLGE is not set
# CONFIG_NETXEN_NIC is not set
CONFIG_NET_VENDOR_REALTEK=y
# CONFIG_8139CP is not set
# CONFIG_8139TOO is not set
# CONFIG_R8169 is not set
# CONFIG_SH_ETH is not set
CONFIG_NET_VENDOR_RDC=y
# CONFIG_R6040 is not set
CONFIG_NET_VENDOR_SEEQ=y
CONFIG_NET_VENDOR_SILAN=y
# CONFIG_SC92031 is not set
CONFIG_NET_VENDOR_SIS=y
# CONFIG_SIS900 is not set
# CONFIG_SIS190 is not set
# CONFIG_SFC is not set
CONFIG_NET_VENDOR_SMSC=y
# CONFIG_EPIC100 is not set
# CONFIG_SMSC911X is not set
# CONFIG_SMSC9420 is not set
CONFIG_NET_VENDOR_STMICRO=y
# CONFIG_STMMAC_ETH is not set
CONFIG_NET_VENDOR_SUN=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
# CONFIG_CASSINI is not set
# CONFIG_NIU is not set
CONFIG_NET_VENDOR_TEHUTI=y
# CONFIG_TEHUTI is not set
CONFIG_NET_VENDOR_TI=y
# CONFIG_TLAN is not set
CONFIG_NET_VENDOR_VIA=y
# CONFIG_VIA_RHINE is not set
# CONFIG_VIA_VELOCITY is not set
CONFIG_NET_VENDOR_WIZNET=y
# CONFIG_WIZNET_W5100 is not set
# CONFIG_WIZNET_W5300 is not set
CONFIG_NET_VENDOR_XILINX=y
# CONFIG_XILINX_EMACLITE is not set
# CONFIG_XILINX_LL_TEMAC is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
CONFIG_PHYLIB=y

#
# MII PHY device drivers
#
# CONFIG_AT803X_PHY is not set
# CONFIG_AMD_PHY is not set
# CONFIG_MARVELL_PHY is not set
# CONFIG_DAVICOM_PHY is not set
# CONFIG_QSEMI_PHY is not set
# CONFIG_LXT_PHY is not set
# CONFIG_CICADA_PHY is not set
CONFIG_VITESSE_PHY=y
# CONFIG_SMSC_PHY is not set
# CONFIG_BROADCOM_PHY is not set
# CONFIG_BCM87XX_PHY is not set
# CONFIG_ICPLUS_PHY is not set
# CONFIG_REALTEK_PHY is not set
# CONFIG_NATIONAL_PHY is not set
# CONFIG_STE10XP is not set
# CONFIG_LSI_ET1011C_PHY is not set
# CONFIG_MICREL_PHY is not set
CONFIG_FIXED_PHY=y
# CONFIG_MDIO_BITBANG is not set
# CONFIG_MDIO_BUS_MUX_GPIO is not set
# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
# CONFIG_MICREL_KS8995MA is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set

#
# USB Network Adapters
#
# CONFIG_USB_CATC is not set
# CONFIG_USB_KAWETH is not set
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_RTL8152 is not set
# CONFIG_USB_USBNET is not set
# CONFIG_USB_IPHETH is not set
CONFIG_WLAN=y
# CONFIG_AIRO is not set
# CONFIG_ATMEL is not set
# CONFIG_PRISM54 is not set
# CONFIG_USB_ZD1201 is not set
# CONFIG_HOSTAP is not set
# CONFIG_WL_TI is not set

#
# Enable WiMAX (Networking options) to see the WiMAX drivers
#
# CONFIG_WAN is not set
# CONFIG_VMXNET3 is not set
# CONFIG_ISDN is not set

#
# Input device support
#
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
# CONFIG_INPUT_POLLDEV is not set
# CONFIG_INPUT_SPARSEKMAP is not set
# CONFIG_INPUT_MATRIXKMAP is not set

#
# Userland interfaces
#
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set

#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set

#
# Hardware I/O ports
#
CONFIG_SERIO=y
CONFIG_SERIO_I8042=y
CONFIG_SERIO_SERPORT=y
# CONFIG_SERIO_PCIPS2 is not set
CONFIG_SERIO_LIBPS2=y
# CONFIG_SERIO_RAW is not set
# CONFIG_SERIO_XILINX_XPS_PS2 is not set
# CONFIG_SERIO_ALTERA_PS2 is not set
# CONFIG_SERIO_PS2MULT is not set
# CONFIG_SERIO_ARC_PS2 is not set
# CONFIG_SERIO_APBPS2 is not set
# CONFIG_SERIO_OLPC_APSP is not set
# CONFIG_GAMEPORT is not set

#
# Character devices
#
CONFIG_TTY=y
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
# CONFIG_VT_HW_CONSOLE_BINDING is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
# CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_NOZOMI is not set
# CONFIG_N_GSM is not set
# CONFIG_TRACE_SINK is not set
CONFIG_PPC_EPAPR_HV_BYTECHAN=y
# CONFIG_PPC_EARLY_DEBUG_EHV_BC is not set
CONFIG_DEVKMEM=y

#
# Serial drivers
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_PCI=y
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250_DETECT_IRQ=y
CONFIG_SERIAL_8250_RSA=y
CONFIG_SERIAL_8250_FSL=y
# CONFIG_SERIAL_8250_DW is not set

#
# Non-8250 serial port support
#
# CONFIG_SERIAL_MAX3100 is not set
# CONFIG_SERIAL_MAX310X is not set
# CONFIG_SERIAL_MFD_HSU is not set
# CONFIG_SERIAL_UARTLITE is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
# CONFIG_SERIAL_SCCNXP is not set
# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_ALTERA_JTAGUART is not set
# CONFIG_SERIAL_ALTERA_UART is not set
# CONFIG_SERIAL_IFX6X60 is not set
# CONFIG_SERIAL_PCH_UART is not set
# CONFIG_SERIAL_XILINX_PS_UART is not set
# CONFIG_SERIAL_ARC is not set
# CONFIG_SERIAL_RP2 is not set
# CONFIG_SERIAL_FSL_LPUART is not set
# CONFIG_TTY_PRINTK is not set
# CONFIG_HVC_UDBG is not set
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_HW_RANDOM_ATMEL is not set
# CONFIG_HW_RANDOM_EXYNOS is not set
CONFIG_NVRAM=y
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
# CONFIG_I2C_MUX is not set
CONFIG_I2C_HELPER_AUTO=y

#
# I2C Hardware Bus support
#

#
# PC SMBus host controller drivers
#
# CONFIG_I2C_ALI1535 is not set
# CONFIG_I2C_ALI1563 is not set
# CONFIG_I2C_ALI15X3 is not set
# CONFIG_I2C_AMD756 is not set
# CONFIG_I2C_AMD8111 is not set
# CONFIG_I2C_I801 is not set
# CONFIG_I2C_ISCH is not set
# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
# CONFIG_I2C_SIS96X is not set
# CONFIG_I2C_VIA is not set
# CONFIG_I2C_VIAPRO is not set

#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
# CONFIG_I2C_CBUS_GPIO is not set
# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
# CONFIG_I2C_DESIGNWARE_PCI is not set
# CONFIG_I2C_EG20T is not set
# CONFIG_I2C_GPIO is not set
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_PXA_PCI is not set
# CONFIG_I2C_SIMTEC is not set
# CONFIG_I2C_XILINX is not set

#
# External I2C/SMBus adapter drivers
#
# CONFIG_I2C_DIOLAN_U2C is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_TAOS_EVM is not set
# CONFIG_I2C_TINY_USB is not set

#
# Other I2C/SMBus bus drivers
#
# CONFIG_I2C_STUB is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
CONFIG_SPI=y
# CONFIG_SPI_DEBUG is not set
CONFIG_SPI_MASTER=y

#
# SPI Master Controller Drivers
#
# CONFIG_SPI_ALTERA is not set
CONFIG_SPI_BITBANG=y
CONFIG_SPI_GPIO=y
CONFIG_SPI_FSL_LIB=y
CONFIG_SPI_FSL_CPM=y
CONFIG_SPI_FSL_SPI=y
CONFIG_SPI_FSL_ESPI=y
# CONFIG_SPI_OC_TINY is not set
# CONFIG_SPI_PXA2XX is not set
# CONFIG_SPI_PXA2XX_PCI is not set
# CONFIG_SPI_SC18IS602 is not set
# CONFIG_SPI_TOPCLIFF_PCH is not set
# CONFIG_SPI_XCOMM is not set
# CONFIG_SPI_XILINX is not set
# CONFIG_SPI_DESIGNWARE is not set

#
# SPI Protocol Masters
#
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
# CONFIG_HSI is not set

#
# PPS support
#
CONFIG_PPS=y
# CONFIG_PPS_DEBUG is not set

#
# PPS clients support
#
# CONFIG_PPS_CLIENT_KTIMER is not set
# CONFIG_PPS_CLIENT_LDISC is not set
# CONFIG_PPS_CLIENT_GPIO is not set

#
# PPS generators support
#

#
# PTP clock support
#
CONFIG_PTP_1588_CLOCK=y

#
# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
#
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_ARCH_REQUIRE_GPIOLIB=y
CONFIG_GPIO_DEVRES=y
CONFIG_GPIOLIB=y
CONFIG_OF_GPIO=y
# CONFIG_DEBUG_GPIO is not set
# CONFIG_GPIO_SYSFS is not set

#
# Memory mapped GPIO drivers:
#
# CONFIG_GPIO_GENERIC_PLATFORM is not set
CONFIG_GPIO_MPC8XXX=y
# CONFIG_GPIO_TS5500 is not set
# CONFIG_GPIO_XILINX is not set
# CONFIG_GPIO_VX855 is not set
# CONFIG_GPIO_GRGPIO is not set

#
# I2C GPIO expanders:
#
# CONFIG_GPIO_MAX7300 is not set
# CONFIG_GPIO_MAX732X is not set
# CONFIG_GPIO_PCA953X is not set
# CONFIG_GPIO_PCF857X is not set
# CONFIG_GPIO_SX150X is not set
# CONFIG_GPIO_ADP5588 is not set
# CONFIG_GPIO_ADNP is not set

#
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
# CONFIG_GPIO_AMD8111 is not set
# CONFIG_GPIO_ML_IOH is not set
# CONFIG_GPIO_RDC321X is not set

#
# SPI GPIO expanders:
#
# CONFIG_GPIO_MAX7301 is not set
# CONFIG_GPIO_MCP23S08 is not set
# CONFIG_GPIO_MC33880 is not set
# CONFIG_GPIO_74X164 is not set

#
# AC97 GPIO expanders:
#

#
# MODULbus GPIO expanders:
#

#
# USB GPIO expanders:
#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_POWER_AVS is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y

#
# Sonics Silicon Backplane
#
# CONFIG_SSB is not set
CONFIG_BCMA_POSSIBLE=y

#
# Broadcom specific AMBA
#
# CONFIG_BCMA is not set

#
# Multifunction device drivers
#
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_AS3711 is not set
# CONFIG_PMIC_ADP5520 is not set
# CONFIG_MFD_AAT2870_CORE is not set
# CONFIG_MFD_CROS_EC is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_DA9052_SPI is not set
# CONFIG_MFD_DA9052_I2C is not set
# CONFIG_MFD_DA9055 is not set
# CONFIG_MFD_MC13XXX_SPI is not set
# CONFIG_MFD_MC13XXX_I2C is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_HTC_I2CPLD is not set
# CONFIG_LPC_ICH is not set
# CONFIG_LPC_SCH is not set
# CONFIG_MFD_JANZ_CMODIO is not set
# CONFIG_MFD_KEMPLD is not set
# CONFIG_MFD_88PM800 is not set
# CONFIG_MFD_88PM805 is not set
# CONFIG_MFD_88PM860X is not set
# CONFIG_MFD_MAX77686 is not set
# CONFIG_MFD_MAX77693 is not set
# CONFIG_MFD_MAX8907 is not set
# CONFIG_MFD_MAX8925 is not set
# CONFIG_MFD_MAX8997 is not set
# CONFIG_MFD_MAX8998 is not set
# CONFIG_EZX_PCAP is not set
# CONFIG_MFD_VIPERBOARD is not set
# CONFIG_MFD_RETU is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_MFD_RDC321X is not set
# CONFIG_MFD_RTSX_PCI is not set
# CONFIG_MFD_RC5T583 is not set
# CONFIG_MFD_SEC_CORE is not set
# CONFIG_MFD_SI476X_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_MFD_SMSC is not set
# CONFIG_ABX500_CORE is not set
# CONFIG_MFD_STMPE is not set
# CONFIG_MFD_SYSCON is not set
# CONFIG_MFD_TI_AM335X_TSCADC is not set
# CONFIG_MFD_LP8788 is not set
# CONFIG_MFD_PALMAS is not set
# CONFIG_TPS6105X is not set
# CONFIG_TPS65010 is not set
# CONFIG_TPS6507X is not set
# CONFIG_MFD_TPS65090 is not set
# CONFIG_MFD_TPS65217 is not set
# CONFIG_MFD_TPS6586X is not set
# CONFIG_MFD_TPS65910 is not set
# CONFIG_MFD_TPS65912 is not set
# CONFIG_MFD_TPS65912_I2C is not set
# CONFIG_MFD_TPS65912_SPI is not set
# CONFIG_MFD_TPS80031 is not set
# CONFIG_TWL4030_CORE is not set
# CONFIG_TWL6040_CORE is not set
# CONFIG_MFD_WL1273_CORE is not set
# CONFIG_MFD_LM3533 is not set
# CONFIG_MFD_TIMBERDALE is not set
# CONFIG_MFD_TC3589X is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_VX855 is not set
# CONFIG_MFD_ARIZONA_I2C is not set
# CONFIG_MFD_ARIZONA_SPI is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM831X_I2C is not set
# CONFIG_MFD_WM831X_SPI is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_WM8994 is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set

#
# Graphics support
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
# CONFIG_FB is not set
# CONFIG_EXYNOS_VIDEO is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set

#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
# CONFIG_VGACON_SOFT_SCROLLBACK is not set
CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set

#
# HID support
#
CONFIG_HID=y
# CONFIG_HIDRAW is not set
# CONFIG_UHID is not set
CONFIG_HID_GENERIC=y

#
# Special HID drivers
#
# CONFIG_HID_A4TECH is not set
# CONFIG_HID_ACRUX is not set
# CONFIG_HID_APPLE is not set
# CONFIG_HID_APPLEIR is not set
# CONFIG_HID_AUREAL is not set
# CONFIG_HID_BELKIN is not set
# CONFIG_HID_CHERRY is not set
# CONFIG_HID_CHICONY is not set
# CONFIG_HID_CYPRESS is not set
# CONFIG_HID_DRAGONRISE is not set
# CONFIG_HID_EMS_FF is not set
# CONFIG_HID_ELECOM is not set
# CONFIG_HID_ELO is not set
# CONFIG_HID_EZKEY is not set
# CONFIG_HID_HOLTEK is not set
# CONFIG_HID_HUION is not set
# CONFIG_HID_KEYTOUCH is not set
# CONFIG_HID_KYE is not set
# CONFIG_HID_UCLOGIC is not set
# CONFIG_HID_WALTOP is not set
# CONFIG_HID_GYRATION is not set
# CONFIG_HID_ICADE is not set
# CONFIG_HID_TWINHAN is not set
# CONFIG_HID_KENSINGTON is not set
# CONFIG_HID_LCPOWER is not set
# CONFIG_HID_LENOVO_TPKBD is not set
# CONFIG_HID_LOGITECH is not set
# CONFIG_HID_MAGICMOUSE is not set
# CONFIG_HID_MICROSOFT is not set
# CONFIG_HID_MONTEREY is not set
# CONFIG_HID_MULTITOUCH is not set
# CONFIG_HID_NTRIG is not set
# CONFIG_HID_ORTEK is not set
# CONFIG_HID_PANTHERLORD is not set
# CONFIG_HID_PETALYNX is not set
# CONFIG_HID_PICOLCD is not set
# CONFIG_HID_PRIMAX is not set
# CONFIG_HID_ROCCAT is not set
# CONFIG_HID_SAITEK is not set
# CONFIG_HID_SAMSUNG is not set
# CONFIG_HID_SPEEDLINK is not set
# CONFIG_HID_STEELSERIES is not set
# CONFIG_HID_SUNPLUS is not set
# CONFIG_HID_GREENASIA is not set
# CONFIG_HID_SMARTJOYPLUS is not set
# CONFIG_HID_TIVO is not set
# CONFIG_HID_TOPSEED is not set
# CONFIG_HID_THRUSTMASTER is not set
# CONFIG_HID_ZEROPLUS is not set
# CONFIG_HID_ZYDACRON is not set
# CONFIG_HID_SENSOR_HUB is not set

#
# USB HID support
#
CONFIG_USB_HID=m
# CONFIG_HID_PID is not set
# CONFIG_USB_HIDDEV is not set

#
# USB HID Boot Protocol drivers
#
# CONFIG_USB_KBD is not set
# CONFIG_USB_MOUSE is not set

#
# I2C HID support
#
# CONFIG_I2C_HID is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_COMMON=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set

#
# Miscellaneous USB options
#
CONFIG_USB_DEFAULT_PERSIST=y
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_OTG_WHITELIST is not set
# CONFIG_USB_OTG_BLACKLIST_HUB is not set
CONFIG_USB_MON=y
# CONFIG_USB_WUSB_CBAF is not set

#
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
# CONFIG_USB_XHCI_HCD is not set
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_TT_NEWSCHED=y
CONFIG_USB_FSL_MPH_DR_OF=y
CONFIG_USB_EHCI_PCI=y
# CONFIG_XPS_USB_HCD_XILINX is not set
CONFIG_USB_EHCI_FSL=y
CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_EHCI_HCD_PLATFORM is not set
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
# CONFIG_USB_ISP1362_HCD is not set
# CONFIG_USB_FUSBH200_HCD is not set
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
CONFIG_USB_OHCI_HCD_PPC_OF=y
CONFIG_USB_OHCI_HCD_PCI=y
# CONFIG_USB_OHCI_HCD_PLATFORM is not set
CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_UHCI_HCD is not set
# CONFIG_USB_SL811_HCD is not set
# CONFIG_USB_R8A66597_HCD is not set

#
# USB Device Class drivers
#
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
# CONFIG_USB_WDM is not set
# CONFIG_USB_TMC is not set

#
# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#

#
# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_REALTEK is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
# CONFIG_USB_STORAGE_ALAUDA is not set
# CONFIG_USB_STORAGE_ONETOUCH is not set
# CONFIG_USB_STORAGE_KARMA is not set
# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
# CONFIG_USB_STORAGE_ENE_UB6250 is not set

#
# USB Imaging devices
#
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_MICROTEK is not set
# CONFIG_USB_DWC3 is not set
# CONFIG_USB_CHIPIDEA is not set

#
# USB port drivers
#
# CONFIG_USB_SERIAL is not set

#
# USB Miscellaneous drivers
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
# CONFIG_USB_ADUTUX is not set
# CONFIG_USB_SEVSEG is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
# CONFIG_USB_TEST is not set
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_YUREX is not set
# CONFIG_USB_EZUSB_FX2 is not set
# CONFIG_USB_HSIC_USB3503 is not set
# CONFIG_USB_PHY is not set
# CONFIG_USB_GADGET is not set
# CONFIG_UWB is not set
CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_UNSAFE_RESUME is not set
# CONFIG_MMC_CLKGATE is not set

#
# MMC/SD/SDIO Card Drivers
#
CONFIG_MMC_BLOCK=y
CONFIG_MMC_BLOCK_MINORS=8
CONFIG_MMC_BLOCK_BOUNCE=y
# CONFIG_SDIO_UART is not set
# CONFIG_MMC_TEST is not set

#
# MMC/SD/SDIO Host Controller Drivers
#
CONFIG_MMC_SDHCI=y
# CONFIG_MMC_SDHCI_PCI is not set
# CONFIG_MMC_SDHCI_PLTFM is not set
# CONFIG_MMC_SDHCI_PXAV3 is not set
# CONFIG_MMC_SDHCI_PXAV2 is not set
# CONFIG_MMC_WBSD is not set
# CONFIG_MMC_TIFM_SD is not set
# CONFIG_MMC_CB710 is not set
# CONFIG_MMC_VIA_SDMMC is not set
# CONFIG_MMC_VUB300 is not set
# CONFIG_MMC_USHC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_INFINIBAND is not set
CONFIG_EDAC=y
CONFIG_EDAC_LEGACY_SYSFS=y
# CONFIG_EDAC_DEBUG is not set
CONFIG_EDAC_MM_EDAC=y
CONFIG_EDAC_MPC85XX=y
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
CONFIG_RTC_SYSTOHC=y
CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
# CONFIG_RTC_DEBUG is not set

#
# RTC interfaces
#
CONFIG_RTC_INTF_SYSFS=y
CONFIG_RTC_INTF_PROC=y
CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
# CONFIG_RTC_DRV_TEST is not set

#
# I2C RTC drivers
#
# CONFIG_RTC_DRV_DS1307 is not set
# CONFIG_RTC_DRV_DS1374 is not set
# CONFIG_RTC_DRV_DS1672 is not set
CONFIG_RTC_DRV_DS3232=y
# CONFIG_RTC_DRV_MAX6900 is not set
# CONFIG_RTC_DRV_RS5C372 is not set
# CONFIG_RTC_DRV_ISL1208 is not set
# CONFIG_RTC_DRV_ISL12022 is not set
# CONFIG_RTC_DRV_X1205 is not set
# CONFIG_RTC_DRV_PCF2127 is not set
# CONFIG_RTC_DRV_PCF8523 is not set
# CONFIG_RTC_DRV_PCF8563 is not set
# CONFIG_RTC_DRV_PCF8583 is not set
# CONFIG_RTC_DRV_M41T80 is not set
# CONFIG_RTC_DRV_BQ32K is not set
# CONFIG_RTC_DRV_S35390A is not set
# CONFIG_RTC_DRV_FM3130 is not set
# CONFIG_RTC_DRV_RX8581 is not set
# CONFIG_RTC_DRV_RX8025 is not set
# CONFIG_RTC_DRV_EM3027 is not set
# CONFIG_RTC_DRV_RV3029C2 is not set

#
# SPI RTC drivers
#
# CONFIG_RTC_DRV_M41T93 is not set
# CONFIG_RTC_DRV_M41T94 is not set
# CONFIG_RTC_DRV_DS1305 is not set
# CONFIG_RTC_DRV_DS1390 is not set
# CONFIG_RTC_DRV_MAX6902 is not set
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_DS3234 is not set
# CONFIG_RTC_DRV_PCF2123 is not set
# CONFIG_RTC_DRV_RX4581 is not set

#
# Platform RTC drivers
#
CONFIG_RTC_DRV_CMOS=y
# CONFIG_RTC_DRV_DS1286 is not set
# CONFIG_RTC_DRV_DS1511 is not set
# CONFIG_RTC_DRV_DS1553 is not set
# CONFIG_RTC_DRV_DS1742 is not set
# CONFIG_RTC_DRV_STK17TA8 is not set
# CONFIG_RTC_DRV_M48T86 is not set
# CONFIG_RTC_DRV_M48T35 is not set
# CONFIG_RTC_DRV_M48T59 is not set
# CONFIG_RTC_DRV_MSM6242 is not set
# CONFIG_RTC_DRV_BQ4802 is not set
# CONFIG_RTC_DRV_RP5C01 is not set
# CONFIG_RTC_DRV_V3020 is not set
# CONFIG_RTC_DRV_DS2404 is not set

#
# on-CPU RTC drivers
#
# CONFIG_RTC_DRV_GENERIC is not set
# CONFIG_RTC_DRV_SNVS is not set

#
# HID Sensor RTC drivers
#
# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
# CONFIG_DMADEVICES is not set
# CONFIG_AUXDISPLAY is not set
CONFIG_UIO=y
# CONFIG_UIO_CIF is not set
# CONFIG_UIO_PDRV is not set
# CONFIG_UIO_PDRV_GENIRQ is not set
# CONFIG_UIO_DMEM_GENIRQ is not set
# CONFIG_UIO_AEC is not set
# CONFIG_UIO_SERCOS3 is not set
# CONFIG_UIO_PCI_GENERIC is not set
# CONFIG_UIO_NETX is not set
# CONFIG_VFIO is not set
CONFIG_VIRT_DRIVERS=y
CONFIG_FSL_HV_MANAGER=y

#
# Virtio drivers
#
# CONFIG_VIRTIO_PCI is not set
# CONFIG_VIRTIO_MMIO is not set

#
# Microsoft Hyper-V guest support
#
CONFIG_STAGING=y
# CONFIG_ET131X is not set
# CONFIG_USBIP_CORE is not set
# CONFIG_ECHO is not set
# CONFIG_COMEDI is not set
# CONFIG_ASUS_OLED is not set
# CONFIG_R8187SE is not set
# CONFIG_RTL8192U is not set
# CONFIG_RTLLIB is not set
# CONFIG_R8712U is not set
# CONFIG_RTS5139 is not set
# CONFIG_TRANZPORT is not set
# CONFIG_IDE_PHISON is not set
# CONFIG_VT6655 is not set
# CONFIG_VT6656 is not set
# CONFIG_DX_SEP is not set
# CONFIG_ZSMALLOC is not set
# CONFIG_CRYSTALHD is not set
# CONFIG_USB_ENESTORAGE is not set
# CONFIG_BCM_WIMAX is not set
# CONFIG_FT1000 is not set

#
# Speakup console speech
#
# CONFIG_SPEAKUP is not set
# CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set
# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set
# CONFIG_STAGING_MEDIA is not set

#
# Android
#
# CONFIG_ANDROID is not set
# CONFIG_USB_WPAN_HCD is not set
# CONFIG_WIMAX_GDM72XX is not set
CONFIG_NET_VENDOR_SILICOM=y
# CONFIG_SBYPASS is not set
# CONFIG_BPCTL is not set
# CONFIG_CED1401 is not set
# CONFIG_DGRP is not set
# CONFIG_USB_DWC2 is not set
CONFIG_CLKDEV_LOOKUP=y
CONFIG_HAVE_CLK_PREPARE=y
CONFIG_COMMON_CLK=y

#
# Common Clock Framework
#
# CONFIG_COMMON_CLK_DEBUG is not set
# CONFIG_COMMON_CLK_SI5351 is not set
# CONFIG_CLK_PPC_CORENET is not set

#
# Hardware Spinlock drivers
#
# CONFIG_MAILBOX is not set
CONFIG_IOMMU_API=y
CONFIG_IOMMU_SUPPORT=y
CONFIG_OF_IOMMU=y
CONFIG_FSL_PAMU=y

#
# Remoteproc drivers
#
# CONFIG_STE_MODEM_RPROC is not set

#
# Rpmsg drivers
#
# CONFIG_PM_DEVFREQ is not set
# CONFIG_EXTCON is not set
# CONFIG_MEMORY is not set
# CONFIG_IIO is not set
# CONFIG_VME_BUS is not set
# CONFIG_PWM is not set
CONFIG_IRQCHIP=y
# CONFIG_IPACK_BUS is not set
# CONFIG_RESET_CONTROLLER is not set
# CONFIG_FMC is not set

#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
# CONFIG_EXT4_FS is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_BTRFS_FS is not set
# CONFIG_NILFS2_FS is not set
# CONFIG_FS_POSIX_ACL is not set
CONFIG_EXPORTFS=m
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_FANOTIFY is not set
# CONFIG_QUOTA is not set
# CONFIG_QUOTACTL is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set

#
# Caches
#
# CONFIG_FSCACHE is not set

#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
CONFIG_ZISOFS=y
CONFIG_UDF_FS=m
CONFIG_UDF_NLS=y

#
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=y
CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_NTFS_FS=y
# CONFIG_NTFS_DEBUG is not set
# CONFIG_NTFS_RW is not set

#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_PROC_SYSCTL=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_TMPFS_XATTR is not set
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
# CONFIG_CONFIGFS_FS is not set
CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_ECRYPT_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_HFSPLUS_FS is not set
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
# CONFIG_JFFS2_SUMMARY is not set
# CONFIG_JFFS2_FS_XATTR is not set
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
CONFIG_JFFS2_ZLIB=y
# CONFIG_JFFS2_LZO is not set
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_LOGFS is not set
CONFIG_CRAMFS=y
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_QNX6FS_FS is not set
# CONFIG_ROMFS_FS is not set
# CONFIG_PSTORE is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
# CONFIG_F2FS_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V2=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
CONFIG_NFS_V4=y
# CONFIG_NFS_SWAP is not set
# CONFIG_NFS_V4_1 is not set
CONFIG_ROOT_NFS=y
# CONFIG_NFS_USE_LEGACY_DNS is not set
CONFIG_NFS_USE_KERNEL_DNS=y
CONFIG_NFSD=m
# CONFIG_NFSD_V3 is not set
# CONFIG_NFSD_V4 is not set
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
# CONFIG_SUNRPC_DEBUG is not set
# CONFIG_CEPH_FS is not set
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NLS_CODEPAGE_437 is not set
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
# CONFIG_NLS_CODEPAGE_850 is not set
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not set
# CONFIG_NLS_CODEPAGE_860 is not set
# CONFIG_NLS_CODEPAGE_861 is not set
# CONFIG_NLS_CODEPAGE_862 is not set
# CONFIG_NLS_CODEPAGE_863 is not set
# CONFIG_NLS_CODEPAGE_864 is not set
# CONFIG_NLS_CODEPAGE_865 is not set
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_936 is not set
# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_CODEPAGE_932 is not set
# CONFIG_NLS_CODEPAGE_949 is not set
# CONFIG_NLS_CODEPAGE_874 is not set
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
# CONFIG_NLS_ASCII is not set
CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
# CONFIG_NLS_ISO8859_5 is not set
# CONFIG_NLS_ISO8859_6 is not set
# CONFIG_NLS_ISO8859_7 is not set
# CONFIG_NLS_ISO8859_9 is not set
# CONFIG_NLS_ISO8859_13 is not set
# CONFIG_NLS_ISO8859_14 is not set
# CONFIG_NLS_ISO8859_15 is not set
# CONFIG_NLS_KOI8_R is not set
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_MAC_ROMAN is not set
# CONFIG_NLS_MAC_CELTIC is not set
# CONFIG_NLS_MAC_CENTEURO is not set
# CONFIG_NLS_MAC_CROATIAN is not set
# CONFIG_NLS_MAC_CYRILLIC is not set
# CONFIG_NLS_MAC_GAELIC is not set
# CONFIG_NLS_MAC_GREEK is not set
# CONFIG_NLS_MAC_ICELAND is not set
# CONFIG_NLS_MAC_INUIT is not set
# CONFIG_NLS_MAC_ROMANIAN is not set
# CONFIG_NLS_MAC_TURKISH is not set
CONFIG_NLS_UTF8=m
# CONFIG_BINARY_PRINTF is not set

#
# Library routines
#
CONFIG_BITREVERSE=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_NET_UTILS=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_IO=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
# CONFIG_CRC_T10DIF is not set
CONFIG_CRC_ITU_T=m
CONFIG_CRC32=y
# CONFIG_CRC32_SELFTEST is not set
CONFIG_CRC32_SLICEBY8=y
# CONFIG_CRC32_SLICEBY4 is not set
# CONFIG_CRC32_SARWATE is not set
# CONFIG_CRC32_BIT is not set
# CONFIG_CRC7 is not set
CONFIG_LIBCRC32C=m
# CONFIG_CRC8 is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
# CONFIG_XZ_DEC is not set
# CONFIG_XZ_DEC_BCJ is not set
CONFIG_DECOMPRESS_GZIP=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_CPU_RMAP=y
CONFIG_DQL=y
CONFIG_NLATTR=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
# CONFIG_AVERAGE is not set
# CONFIG_CORDIC is not set
# CONFIG_DDR is not set
CONFIG_OID_REGISTRY=y

#
# Kernel hacking
#

#
# printk and dmesg options
#
# CONFIG_PRINTK_TIME is not set
CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
# CONFIG_DYNAMIC_DEBUG is not set

#
# Compile-time checks and compiler options
#
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_INFO_REDUCED is not set
CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_READABLE_ASM is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
# CONFIG_DEBUG_SECTION_MISMATCH is not set
# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y

#
# Memory Debugging
#
# CONFIG_DEBUG_PAGEALLOC is not set
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_DEBUG_SLAB is not set
CONFIG_HAVE_DEBUG_KMEMLEAK=y
# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_MEMORY_INIT is not set
# CONFIG_DEBUG_PER_CPU_MAPS is not set
# CONFIG_DEBUG_HIGHMEM is not set
CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
# CONFIG_DEBUG_STACKOVERFLOW is not set
CONFIG_DEBUG_SHIRQ=y

#
# Debug Lockups and Hangs
#
# CONFIG_LOCKUP_DETECTOR is not set
CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
# CONFIG_PANIC_ON_OOPS is not set
CONFIG_PANIC_ON_OOPS_VALUE=0
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set

#
# Lock Debugging (spinlocks, mutexes, etc...)
#
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
# CONFIG_DEBUG_LOCK_ALLOC is not set
# CONFIG_PROVE_LOCKING is not set
# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_ATOMIC_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_WRITECOUNT is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
# CONFIG_DEBUG_CREDENTIALS is not set

#
# RCU Debugging
#
# CONFIG_SPARSE_RCU_POINTER is not set
# CONFIG_RCU_TORTURE_TEST is not set
CONFIG_RCU_CPU_STALL_TIMEOUT=21
# CONFIG_RCU_CPU_STALL_INFO is not set
CONFIG_RCU_TRACE=y
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_NOTIFIER_ERROR_INJECTION is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_TRACE_CLOCK=y
CONFIG_TRACING_SUPPORT=y
CONFIG_FTRACE=y
# CONFIG_FUNCTION_TRACER is not set
# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_ENABLE_DEFAULT_TRACERS is not set
# CONFIG_FTRACE_SYSCALLS is not set
# CONFIG_TRACER_SNAPSHOT is not set
CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
# CONFIG_PROFILE_ALL_BRANCHES is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_UPROBE_EVENT is not set
# CONFIG_PROBE_EVENTS is not set

#
# Runtime Testing
#
# CONFIG_LKDTM is not set
# CONFIG_TEST_LIST_SORT is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_RBTREE_TEST is not set
# CONFIG_INTERVAL_TREE_TEST is not set
# CONFIG_ATOMIC64_SELFTEST is not set
# CONFIG_TEST_STRING_HELPERS is not set
# CONFIG_TEST_KSTRTOX is not set
# CONFIG_DMA_API_DEBUG is not set
CONFIG_SAMPLES=y
CONFIG_SAMPLE_KOBJECT=m
# CONFIG_SAMPLE_KFIFO is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
# CONFIG_PPC_DISABLE_WERROR is not set
CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
# CONFIG_PPC_EMULATED_STATS is not set
# CONFIG_CODE_PATCHING_SELFTEST is not set
# CONFIG_FTR_FIXUP_SELFTEST is not set
# CONFIG_MSI_BITMAP_SELFTEST is not set
# CONFIG_XMON is not set
# CONFIG_BDI_SWITCH is not set
# CONFIG_PPC_EARLY_DEBUG is not set
CONFIG_STRICT_DEVMEM=y

#
# Security options
#
CONFIG_KEYS=y
# CONFIG_ENCRYPTED_KEYS is not set
# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
# CONFIG_SECURITY_DMESG_RESTRICT is not set
# CONFIG_SECURITY is not set
# CONFIG_SECURITYFS is not set
CONFIG_DEFAULT_SECURITY_DAC=y
CONFIG_DEFAULT_SECURITY=""
CONFIG_CRYPTO=y

#
# Crypto core or helper
#
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=y
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_PCOMP2=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_USER is not set
CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
# CONFIG_CRYPTO_GF128MUL is not set
CONFIG_CRYPTO_NULL=y
# CONFIG_CRYPTO_PCRYPT is not set
CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_AUTHENC=y
# CONFIG_CRYPTO_TEST is not set

#
# Authenticated Encryption with Associated Data
#
# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_GCM is not set
# CONFIG_CRYPTO_SEQIV is not set

#
# Block modes
#
CONFIG_CRYPTO_CBC=y
# CONFIG_CRYPTO_CTR is not set
# CONFIG_CRYPTO_CTS is not set
# CONFIG_CRYPTO_ECB is not set
# CONFIG_CRYPTO_LRW is not set
CONFIG_CRYPTO_PCBC=m
# CONFIG_CRYPTO_XTS is not set

#
# Hash modes
#
# CONFIG_CRYPTO_CMAC is not set
CONFIG_CRYPTO_HMAC=y
# CONFIG_CRYPTO_XCBC is not set
# CONFIG_CRYPTO_VMAC is not set

#
# Digest
#
CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_CRC32 is not set
# CONFIG_CRYPTO_CRCT10DIF is not set
# CONFIG_CRYPTO_GHASH is not set
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_RMD128 is not set
# CONFIG_CRYPTO_RMD160 is not set
# CONFIG_CRYPTO_RMD256 is not set
# CONFIG_CRYPTO_RMD320 is not set
CONFIG_CRYPTO_SHA1=y
# CONFIG_CRYPTO_SHA1_PPC is not set
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA512=y
# CONFIG_CRYPTO_TGR192 is not set
# CONFIG_CRYPTO_WP512 is not set

#
# Ciphers
#
CONFIG_CRYPTO_AES=y
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_ARC4 is not set
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_CAST5 is not set
# CONFIG_CRYPTO_CAST6 is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_FCRYPT is not set
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_SALSA20 is not set
# CONFIG_CRYPTO_SEED is not set
# CONFIG_CRYPTO_SERPENT is not set
# CONFIG_CRYPTO_TEA is not set
# CONFIG_CRYPTO_TWOFISH is not set

#
# Compression
#
CONFIG_CRYPTO_DEFLATE=y
# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
# CONFIG_CRYPTO_LZ4 is not set
# CONFIG_CRYPTO_LZ4HC is not set

#
# Random Number Generation
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_USER_API_HASH is not set
# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
CONFIG_CRYPTO_HW=y
CONFIG_CRYPTO_DEV_FSL_CAAM=y
CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE=9
# CONFIG_CRYPTO_DEV_FSL_CAAM_INTC is not set
CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API=y
CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API=y
CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API=y
# CONFIG_CRYPTO_DEV_TALITOS is not set
# CONFIG_ASYMMETRIC_KEY_TYPE is not set
# CONFIG_PPC_CLOCK is not set
# CONFIG_VIRTUALIZATION is not set

^ permalink raw reply	[flat|nested] 20+ messages in thread

* RE: [PATCH 1/3] powerpc: Add iommu domain pointer to device archdata
@ 2013-08-14  9:56     ` Sethi Varun-B16395
  0 siblings, 0 replies; 20+ messages in thread
From: Sethi Varun-B16395 @ 2013-08-14  9:56 UTC (permalink / raw)
  To: Joerg Roedel
  Cc: galak-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r, Wood Scott-B07421,
	benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Yoder Stuart-B08248,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ

[-- Attachment #1: Type: text/plain, Size: 1696 bytes --]

Hi Joerg,
Please find the .config file attached with this mail.

Regards
Varun

> -----Original Message-----
> From: Joerg Roedel [mailto:joro-zLv9SwRftAIdnm+yROfE0A@public.gmane.org]
> Sent: Wednesday, August 14, 2013 3:18 PM
> To: Sethi Varun-B16395
> Cc: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org; linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org;
> linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r@public.gmane.org;
> galak-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r@public.gmane.org; alex.williamson-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org; Yoder Stuart-
> B08248; Wood Scott-B07421
> Subject: Re: [PATCH 1/3] powerpc: Add iommu domain pointer to device
> archdata
> 
> On Mon, Jul 15, 2013 at 10:20:55AM +0530, Varun Sethi wrote:
> > Add an iommu domain pointer to device (powerpc) archdata.  Devices are
> > attached to iommu domains and this pointer provides a mechanism to
> > correlate between a device and the associated iommu domain.  This
> > field is set when a device is attached to a domain.
> >
> > Signed-off-by: Varun Sethi <Varun.Sethi-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
> > Acked-by: Kumar Gala <galak-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r@public.gmane.org>
> > ---
> > - rebased patch to 3.11-rc1
> >  arch/powerpc/include/asm/device.h |    3 +++
> >  1 files changed, 3 insertions(+), 0 deletions(-)
> 
> Okay, I applied these patches to my ppc/pamu branch. But before I merge
> it to my next branch (so that it can go upstream) I want to have a
> compile-test-case first. Can you send me a working .config which includes
> this driver?
> 
> Thanks,
> 
> 	Joerg
> 
> 


[-- Attachment #2: pamu_build_config --]
[-- Type: application/octet-stream, Size: 65153 bytes --]

#
# Automatically generated file; DO NOT EDIT.
# Linux/powerpc 3.11.0-rc1 Kernel Configuration
#
# CONFIG_PPC64 is not set

#
# Processor support
#
# CONFIG_PPC_BOOK3S_32 is not set
CONFIG_PPC_85xx=y
# CONFIG_PPC_8xx is not set
# CONFIG_40x is not set
# CONFIG_44x is not set
# CONFIG_E200 is not set
CONFIG_E500=y
CONFIG_PPC_E500MC=y
CONFIG_PPC_FPU=y
CONFIG_FSL_EMB_PERFMON=y
CONFIG_FSL_EMB_PERF_EVENT=y
CONFIG_FSL_EMB_PERF_EVENT_E500=y
CONFIG_BOOKE=y
CONFIG_FSL_BOOKE=y
CONFIG_PPC_FSL_BOOK3E=y
CONFIG_PTE_64BIT=y
CONFIG_PHYS_64BIT=y
CONFIG_PPC_MMU_NOHASH=y
CONFIG_PPC_BOOK3E_MMU=y
# CONFIG_PPC_MM_SLICES is not set
CONFIG_SMP=y
CONFIG_NR_CPUS=8
CONFIG_PPC_DOORBELL=y
CONFIG_PPC32=y
CONFIG_32BIT=y
CONFIG_WORD_SIZE=32
CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
CONFIG_MMU=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
CONFIG_NR_IRQS=512
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_ARCH_HAS_ILOG2_U32=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_PPC=y
CONFIG_EARLY_PRINTK=y
CONFIG_GENERIC_NVRAM=y
CONFIG_SCHED_OMIT_FRAME_POINTER=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_PPC_OF=y
CONFIG_PPC_UDBG_16550=y
CONFIG_GENERIC_TBSYNC=y
CONFIG_AUDIT_ARCH=y
CONFIG_GENERIC_BUG=y
# CONFIG_EPAPR_BOOT is not set
CONFIG_DEFAULT_UIMAGE=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_PPC_ADV_DEBUG_REGS=y
CONFIG_PPC_ADV_DEBUG_IACS=2
CONFIG_PPC_ADV_DEBUG_DACS=2
CONFIG_PPC_ADV_DEBUG_DVCS=0
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_IRQ_WORK=y

#
# General setup
#
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_CROSS_COMPILE=""
# CONFIG_COMPILE_TEST is not set
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_DEFAULT_HOSTNAME="(none)"
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
CONFIG_POSIX_MQUEUE_SYSCTL=y
# CONFIG_FHANDLE is not set
CONFIG_AUDIT=y
# CONFIG_AUDITSYSCALL is not set
# CONFIG_AUDIT_LOGINUID_IMMUTABLE is not set
CONFIG_HAVE_GENERIC_HARDIRQS=y

#
# IRQ subsystem
#
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
CONFIG_IRQ_DOMAIN=y
# CONFIG_IRQ_DOMAIN_DEBUG is not set
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_SPARSE_IRQ=y
CONFIG_GENERIC_TIME_VSYSCALL_OLD=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_CMOS_UPDATE=y

#
# Timers subsystem
#
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ_COMMON=y
# CONFIG_HZ_PERIODIC is not set
CONFIG_NO_HZ_IDLE=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y

#
# CPU/Task time and stats accounting
#
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set

#
# RCU Subsystem
#
CONFIG_TREE_RCU=y
# CONFIG_PREEMPT_RCU is not set
CONFIG_RCU_STALL_COMMON=y
CONFIG_RCU_FANOUT=32
CONFIG_RCU_FANOUT_LEAF=16
# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_RCU_FAST_NO_HZ is not set
CONFIG_TREE_RCU_TRACE=y
# CONFIG_RCU_NOCB_CPU is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
# CONFIG_CHECKPOINT_RESTORE is not set
# CONFIG_NAMESPACES is not set
CONFIG_UIDGID_CONVERTED=y
# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
# CONFIG_SCHED_AUTOGROUP is not set
# CONFIG_SYSFS_DEPRECATED is not set
# CONFIG_RELAY is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
# CONFIG_RD_XZ is not set
# CONFIG_RD_LZO is not set
# CONFIG_RD_LZ4 is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
CONFIG_EXPERT=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_PCI_QUIRKS=y
CONFIG_EMBEDDED=y
CONFIG_HAVE_PERF_EVENTS=y

#
# Kernel Performance Events And Counters
#
CONFIG_PERF_EVENTS=y
# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
# CONFIG_JUMP_LABEL is not set
# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_DMA_ATTRS=y
CONFIG_USE_GENERIC_SMP_HELPERS=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_CLK=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_HAVE_RCU_TABLE_FREE=y
CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
CONFIG_MODULES_USE_ELF_RELA=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_OLD_SIGSUSPEND=y
CONFIG_OLD_SIGACTION=y

#
# GCOV-based kernel profiling
#
# CONFIG_GCOV_KERNEL is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODVERSIONS=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
# CONFIG_MODULE_SIG is not set
CONFIG_STOP_MACHINE=y
CONFIG_BLOCK=y
CONFIG_LBDAF=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_BSGLIB is not set
# CONFIG_BLK_DEV_INTEGRITY is not set

#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
# CONFIG_ACORN_PARTITION is not set
# CONFIG_AIX_PARTITION is not set
# CONFIG_OSF_PARTITION is not set
# CONFIG_AMIGA_PARTITION is not set
# CONFIG_ATARI_PARTITION is not set
CONFIG_MAC_PARTITION=y
CONFIG_MSDOS_PARTITION=y
# CONFIG_BSD_DISKLABEL is not set
# CONFIG_MINIX_SUBPARTITION is not set
# CONFIG_SOLARIS_X86_PARTITION is not set
# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_LDM_PARTITION is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_KARMA_PARTITION is not set
CONFIG_EFI_PARTITION=y
# CONFIG_SYSV68_PARTITION is not set

#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
# CONFIG_DEFAULT_DEADLINE is not set
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
CONFIG_INLINE_READ_UNLOCK=y
CONFIG_INLINE_READ_UNLOCK_IRQ=y
CONFIG_INLINE_WRITE_UNLOCK=y
CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
CONFIG_MUTEX_SPIN_ON_OWNER=y
# CONFIG_FREEZER is not set
CONFIG_PPC_MSI_BITMAP=y
# CONFIG_PPC_XICS is not set
# CONFIG_PPC_ICP_NATIVE is not set
# CONFIG_PPC_ICP_HV is not set
# CONFIG_PPC_ICS_RTAS is not set
# CONFIG_GE_FPGA is not set

#
# Platform support
#
CONFIG_POWERNV_MSI=y
# CONFIG_PPC_CELL is not set
# CONFIG_PPC_CELL_NATIVE is not set
# CONFIG_PQ2ADS is not set
CONFIG_FSL_SOC_BOOKE=y
# CONFIG_BSC9131_RDB is not set
# CONFIG_MPC8540_ADS is not set
# CONFIG_MPC8560_ADS is not set
# CONFIG_MPC85xx_CDS is not set
# CONFIG_MPC85xx_MDS is not set
# CONFIG_MPC8536_DS is not set
# CONFIG_MPC85xx_DS is not set
# CONFIG_MPC85xx_RDB is not set
# CONFIG_P1010_RDB is not set
# CONFIG_P1022_DS is not set
# CONFIG_P1022_RDK is not set
# CONFIG_P1023_RDS is not set
# CONFIG_SOCRATES is not set
# CONFIG_KSI8560 is not set
# CONFIG_XES_MPC85xx is not set
# CONFIG_STX_GP3 is not set
# CONFIG_TQM8540 is not set
# CONFIG_TQM8541 is not set
# CONFIG_TQM8548 is not set
# CONFIG_TQM8555 is not set
# CONFIG_TQM8560 is not set
# CONFIG_SBC8548 is not set
# CONFIG_PPA8548 is not set
# CONFIG_GE_IMP3A is not set
CONFIG_P2041_RDB=y
CONFIG_P3041_DS=y
CONFIG_P4080_DS=y
# CONFIG_SGY_CTS1000 is not set
CONFIG_P5020_DS=y
CONFIG_P5040_DS=y
# CONFIG_PPC_QEMU_E500 is not set
# CONFIG_PPC_WSP is not set
# CONFIG_KVM_GUEST is not set
CONFIG_EPAPR_PARAVIRT=y
CONFIG_PPC_SMP_MUXED_IPI=y
# CONFIG_IPIC is not set
CONFIG_MPIC=y
# CONFIG_MPIC_TIMER is not set
CONFIG_PPC_EPAPR_HV_PIC=y
# CONFIG_MPIC_WEIRD is not set
# CONFIG_MPIC_MSGR is not set
# CONFIG_PPC_I8259 is not set
# CONFIG_PPC_RTAS is not set
# CONFIG_MMIO_NVRAM is not set
# CONFIG_MPIC_U3_HT_IRQS is not set
# CONFIG_PPC_MPC106 is not set
# CONFIG_PPC_970_NAP is not set
# CONFIG_PPC_P7_NAP is not set

#
# CPU Frequency scaling
#
# CONFIG_CPU_FREQ is not set

#
# CPUIdle driver
#
# CONFIG_CPU_IDLE is not set
# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
# CONFIG_QUICC_ENGINE is not set
# CONFIG_CPM2 is not set
# CONFIG_FSL_ULI1575 is not set
# CONFIG_SIMPLE_GPIO is not set

#
# Kernel options
#
CONFIG_HIGHMEM=y
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
CONFIG_SCHED_HRTICK=y
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
CONFIG_BINFMT_ELF=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_BINFMT_SCRIPT=y
# CONFIG_HAVE_AOUT is not set
CONFIG_BINFMT_MISC=m
CONFIG_COREDUMP=y
CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y
# CONFIG_MATH_EMULATION is not set
CONFIG_IOMMU_HELPER=y
CONFIG_SWIOTLB=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
CONFIG_KEXEC=y
# CONFIG_CRASH_DUMP is not set
# CONFIG_IRQ_ALL_CPUS is not set
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_SYS_SUPPORTS_HUGETLBFS=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_HAVE_MEMBLOCK=y
CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_COMPACTION=y
CONFIG_MIGRATION=y
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_CROSS_MEMORY_ATTACH=y
# CONFIG_CLEANCACHE is not set
# CONFIG_FRONTSWAP is not set
# CONFIG_ZBUD is not set
CONFIG_PPC_4K_PAGES=y
CONFIG_FORCE_MAX_ZONEORDER=13
# CONFIG_CMDLINE_BOOL is not set
CONFIG_EXTRA_TARGETS=""
# CONFIG_HIBERNATION is not set
# CONFIG_PM_RUNTIME is not set
CONFIG_SECCOMP=y
CONFIG_ISA_DMA_API=y

#
# Bus options
#
CONFIG_ZONE_DMA=y
# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
CONFIG_FSL_PCI=y
CONFIG_FSL_LBC=y
CONFIG_FSL_IFC=y
CONFIG_PPC_PCI_CHOICE=y
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_SYSCALL=y
CONFIG_PCIEPORTBUS=y
CONFIG_PCIEAER=y
# CONFIG_PCIE_ECRC is not set
# CONFIG_PCIEAER_INJECT is not set
# CONFIG_PCIEASPM is not set
CONFIG_ARCH_SUPPORTS_MSI=y
CONFIG_PCI_MSI=y
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_PCI_PRI is not set
# CONFIG_PCI_PASID is not set

#
# PCI host controller drivers
#
# CONFIG_PCCARD is not set
# CONFIG_HOTPLUG_PCI is not set
CONFIG_HAS_RAPIDIO=y
CONFIG_RAPIDIO=y
CONFIG_FSL_RIO=y
# CONFIG_RAPIDIO_TSI721 is not set
CONFIG_RAPIDIO_DISC_TIMEOUT=30
# CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS is not set
# CONFIG_RAPIDIO_DMA_ENGINE is not set
# CONFIG_RAPIDIO_DEBUG is not set
# CONFIG_RAPIDIO_ENUM_BASIC is not set

#
# RapidIO Switch drivers
#
# CONFIG_RAPIDIO_TSI57X is not set
# CONFIG_RAPIDIO_CPS_XX is not set
# CONFIG_RAPIDIO_TSI568 is not set
# CONFIG_RAPIDIO_CPS_GEN2 is not set
# CONFIG_NONSTATIC_KERNEL is not set

#
# Advanced setup
#
# CONFIG_ADVANCED_OPTIONS is not set

#
# Default settings for advanced configuration options are used
#
CONFIG_LOWMEM_SIZE=0x30000000
CONFIG_LOWMEM_CAM_NUM=3
CONFIG_PAGE_OFFSET=0xc0000000
CONFIG_KERNEL_START=0xc0000000
CONFIG_PHYSICAL_START=0x00000000
CONFIG_PHYSICAL_ALIGN=0x04000000
CONFIG_TASK_SIZE=0xc0000000
CONFIG_NET=y

#
# Networking options
#
CONFIG_PACKET=y
# CONFIG_PACKET_DIAG is not set
CONFIG_UNIX=y
# CONFIG_UNIX_DIAG is not set
CONFIG_XFRM=y
CONFIG_XFRM_ALGO=y
CONFIG_XFRM_USER=y
CONFIG_XFRM_SUB_POLICY=y
CONFIG_XFRM_MIGRATE=y
CONFIG_XFRM_STATISTICS=y
CONFIG_XFRM_IPCOMP=y
CONFIG_NET_KEY=y
CONFIG_NET_KEY_MIGRATE=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
# CONFIG_IP_FIB_TRIE_STATS is not set
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_MULTIPATH=y
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_RARP=y
CONFIG_NET_IPIP=y
# CONFIG_NET_IPGRE_DEMUX is not set
CONFIG_NET_IP_TUNNEL=y
CONFIG_IP_MROUTE=y
# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
CONFIG_ARPD=y
# CONFIG_SYN_COOKIES is not set
# CONFIG_NET_IPVTI is not set
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
CONFIG_INET_IPCOMP=y
CONFIG_INET_XFRM_TUNNEL=y
CONFIG_INET_TUNNEL=y
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_XFRM_MODE_BEET=y
# CONFIG_INET_LRO is not set
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_INET_UDP_DIAG is not set
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TCP_MD5SIG is not set
CONFIG_IPV6=y
# CONFIG_IPV6_PRIVACY is not set
# CONFIG_IPV6_ROUTER_PREF is not set
# CONFIG_IPV6_OPTIMISTIC_DAD is not set
# CONFIG_INET6_AH is not set
# CONFIG_INET6_ESP is not set
# CONFIG_INET6_IPCOMP is not set
# CONFIG_IPV6_MIP6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
CONFIG_INET6_XFRM_MODE_TRANSPORT=y
CONFIG_INET6_XFRM_MODE_TUNNEL=y
CONFIG_INET6_XFRM_MODE_BEET=y
# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
CONFIG_IPV6_SIT=y
# CONFIG_IPV6_SIT_6RD is not set
CONFIG_IPV6_NDISC_NODETYPE=y
# CONFIG_IPV6_TUNNEL is not set
# CONFIG_IPV6_GRE is not set
# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_IPV6_MROUTE is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
CONFIG_IP_SCTP=m
# CONFIG_SCTP_DBG_OBJCNT is not set
CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y
# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 is not set
# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set
CONFIG_SCTP_COOKIE_HMAC_MD5=y
# CONFIG_SCTP_COOKIE_HMAC_SHA1 is not set
# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_L2TP is not set
# CONFIG_BRIDGE is not set
CONFIG_HAVE_NET_DSA=y
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_PHONET is not set
# CONFIG_IEEE802154 is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
CONFIG_DNS_RESOLVER=y
# CONFIG_BATMAN_ADV is not set
# CONFIG_OPENVSWITCH is not set
# CONFIG_VSOCKETS is not set
# CONFIG_NETLINK_MMAP is not set
# CONFIG_NETLINK_DIAG is not set
# CONFIG_NET_MPLS_GSO is not set
CONFIG_RPS=y
CONFIG_RFS_ACCEL=y
CONFIG_XPS=y
CONFIG_NET_LL_RX_POLL=y
CONFIG_BQL=y
CONFIG_NET_FLOW_LIMIT=y

#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_LIB80211 is not set

#
# CFG80211 needs to be enabled for MAC80211
#
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
# CONFIG_CAIF is not set
# CONFIG_CEPH_LIB is not set
# CONFIG_NFC is not set

#
# Device Drivers
#

#
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
# CONFIG_DEVTMPFS_MOUNT is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
CONFIG_FIRMWARE_IN_KERNEL=y
CONFIG_EXTRA_FIRMWARE=""
CONFIG_FW_LOADER_USER_HELPER=y
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_GENERIC_CPU_DEVICES is not set
# CONFIG_DMA_SHARED_BUFFER is not set

#
# Bus devices
#
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_OF_PARTS=y
# CONFIG_MTD_AR7_PARTS is not set

#
# User Modules And Translation Layers
#
CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_BLOCK=y
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
# CONFIG_SSFDC is not set
# CONFIG_SM_FTL is not set
# CONFIG_MTD_OOPS is not set
# CONFIG_MTD_SWAP is not set

#
# RAM/ROM/Flash chip drivers
#
CONFIG_MTD_CFI=y
# CONFIG_MTD_JEDECPROBE is not set
CONFIG_MTD_GEN_PROBE=y
# CONFIG_MTD_CFI_ADV_OPTIONS is not set
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
# CONFIG_MTD_CFI_INTELEXT is not set
CONFIG_MTD_CFI_AMDSTD=y
# CONFIG_MTD_CFI_STAA is not set
CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set

#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set
CONFIG_MTD_PHYSMAP_OF=y
# CONFIG_MTD_INTEL_VR_NOR is not set
# CONFIG_MTD_PLATRAM is not set

#
# Self-contained MTD device drivers
#
# CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_DATAFLASH is not set
CONFIG_MTD_M25P80=y
CONFIG_M25PXX_USE_FAST_READ=y
# CONFIG_MTD_SST25L is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
# CONFIG_MTD_BLOCK2MTD is not set

#
# Disk-On-Chip Device Drivers
#
# CONFIG_MTD_DOCG3 is not set
CONFIG_MTD_NAND_ECC=y
# CONFIG_MTD_NAND_ECC_SMC is not set
CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_ECC_BCH is not set
# CONFIG_MTD_SM_COMMON is not set
# CONFIG_MTD_NAND_DENALI is not set
CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_RICOH is not set
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_NAND_DOCG4 is not set
# CONFIG_MTD_NAND_CAFE is not set
# CONFIG_MTD_NAND_NANDSIM is not set
# CONFIG_MTD_NAND_PLATFORM is not set
# CONFIG_MTD_ALAUDA is not set
CONFIG_MTD_NAND_FSL_ELBC=y
CONFIG_MTD_NAND_FSL_IFC=y
# CONFIG_MTD_NAND_FSL_UPM is not set
# CONFIG_MTD_ONENAND is not set

#
# LPDDR flash memory drivers
#
# CONFIG_MTD_LPDDR is not set
# CONFIG_MTD_UBI is not set
CONFIG_DTC=y
CONFIG_OF=y

#
# Device Tree and Open Firmware support
#
CONFIG_PROC_DEVICETREE=y
# CONFIG_OF_SELFTEST is not set
CONFIG_OF_FLATTREE=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_IRQ=y
CONFIG_OF_I2C=y
CONFIG_OF_NET=y
CONFIG_OF_MDIO=y
CONFIG_OF_PCI=y
CONFIG_OF_PCI_IRQ=y
CONFIG_OF_MTD=y
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_DRBD is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_NVME is not set
# CONFIG_BLK_DEV_SX8 is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=131072
# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
# CONFIG_BLK_DEV_RBD is not set
# CONFIG_BLK_DEV_RSXX is not set

#
# Misc devices
#
# CONFIG_SENSORS_LIS3LV02D is not set
# CONFIG_AD525X_DPOT is not set
# CONFIG_ATMEL_PWM is not set
# CONFIG_DUMMY_IRQ is not set
# CONFIG_PHANTOM is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ATMEL_SSC is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
# CONFIG_APDS9802ALS is not set
# CONFIG_ISL29003 is not set
# CONFIG_ISL29020 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_SENSORS_BH1780 is not set
# CONFIG_SENSORS_BH1770 is not set
# CONFIG_SENSORS_APDS990X is not set
# CONFIG_HMC6352 is not set
# CONFIG_DS1682 is not set
# CONFIG_TI_DAC7512 is not set
# CONFIG_BMP085_I2C is not set
# CONFIG_BMP085_SPI is not set
# CONFIG_PCH_PHUB is not set
# CONFIG_USB_SWITCH_FSA9480 is not set
# CONFIG_LATTICE_ECP3_CONFIG is not set
# CONFIG_SRAM is not set
# CONFIG_C2PORT is not set

#
# EEPROM support
#
# CONFIG_EEPROM_AT24 is not set
# CONFIG_EEPROM_AT25 is not set
# CONFIG_EEPROM_LEGACY is not set
# CONFIG_EEPROM_MAX6875 is not set
# CONFIG_EEPROM_93CX6 is not set
# CONFIG_EEPROM_93XX46 is not set
# CONFIG_CB710_CORE is not set

#
# Texas Instruments shared transport line discipline
#
# CONFIG_TI_ST is not set
# CONFIG_SENSORS_LIS3_SPI is not set
# CONFIG_SENSORS_LIS3_I2C is not set

#
# Altera FPGA firmware download module
#
# CONFIG_ALTERA_STAPL is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set

#
# SCSI device support
#
CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
# CONFIG_SCSI_TGT is not set
# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y

#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y
# CONFIG_CHR_DEV_OSST is not set
CONFIG_BLK_DEV_SR=y
# CONFIG_BLK_DEV_SR_VENDOR is not set
CONFIG_CHR_DEV_SG=y
# CONFIG_CHR_DEV_SCH is not set
CONFIG_SCSI_MULTI_LUN=y
# CONFIG_SCSI_CONSTANTS is not set
CONFIG_SCSI_LOGGING=y
# CONFIG_SCSI_SCAN_ASYNC is not set

#
# SCSI Transports
#
CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
# CONFIG_SCSI_SAS_ATTRS is not set
# CONFIG_SCSI_SAS_LIBSAS is not set
# CONFIG_SCSI_SRP_ATTRS is not set
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_ISCSI_BOOT_SYSFS is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_CXGB4_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
# CONFIG_SCSI_BNX2X_FCOE is not set
# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_HPSA is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_3W_SAS is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AACRAID is not set
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_SCSI_AIC94XX is not set
# CONFIG_SCSI_MVSAS is not set
# CONFIG_SCSI_MVUMI is not set
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_ARCMSR is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_MPT3SAS is not set
# CONFIG_SCSI_UFSHCD is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_LIBFC is not set
# CONFIG_LIBFCOE is not set
# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_STEX is not set
CONFIG_SCSI_SYM53C8XX_2=y
CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
CONFIG_SCSI_SYM53C8XX_MMIO=y
# CONFIG_SCSI_IPR is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
# CONFIG_SCSI_QLA_FC is not set
# CONFIG_SCSI_QLA_ISCSI is not set
# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_PM8001 is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_BFA_FC is not set
# CONFIG_SCSI_CHELSIO_FCOE is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y

#
# Controllers with non-SFF native interface
#
CONFIG_SATA_AHCI=y
# CONFIG_SATA_AHCI_PLATFORM is not set
CONFIG_SATA_FSL=y
# CONFIG_SATA_INIC162X is not set
# CONFIG_SATA_ACARD_AHCI is not set
CONFIG_SATA_SIL24=y
CONFIG_ATA_SFF=y

#
# SFF controllers with custom DMA interface
#
# CONFIG_PDC_ADMA is not set
# CONFIG_SATA_QSTOR is not set
# CONFIG_SATA_SX4 is not set
CONFIG_ATA_BMDMA=y

#
# SATA SFF controllers with BMDMA
#
# CONFIG_ATA_PIIX is not set
# CONFIG_SATA_HIGHBANK is not set
# CONFIG_SATA_MV is not set
# CONFIG_SATA_NV is not set
# CONFIG_SATA_PROMISE is not set
# CONFIG_SATA_RCAR is not set
CONFIG_SATA_SIL=y
# CONFIG_SATA_SIS is not set
# CONFIG_SATA_SVW is not set
# CONFIG_SATA_ULI is not set
# CONFIG_SATA_VIA is not set
# CONFIG_SATA_VITESSE is not set

#
# PATA SFF controllers with BMDMA
#
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_CMD64X is not set
# CONFIG_PATA_CS5520 is not set
# CONFIG_PATA_CS5530 is not set
# CONFIG_PATA_CS5536 is not set
# CONFIG_PATA_CYPRESS is not set
# CONFIG_PATA_EFAR is not set
# CONFIG_PATA_HPT366 is not set
# CONFIG_PATA_HPT37X is not set
# CONFIG_PATA_HPT3X2N is not set
# CONFIG_PATA_HPT3X3 is not set
# CONFIG_PATA_IT8213 is not set
# CONFIG_PATA_IT821X is not set
# CONFIG_PATA_JMICRON is not set
# CONFIG_PATA_MARVELL is not set
# CONFIG_PATA_NETCELL is not set
# CONFIG_PATA_NINJA32 is not set
# CONFIG_PATA_NS87415 is not set
# CONFIG_PATA_OLDPIIX is not set
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC2027X is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
# CONFIG_PATA_RDC is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SCH is not set
# CONFIG_PATA_SERVERWORKS is not set
CONFIG_PATA_SIL680=y
# CONFIG_PATA_SIS is not set
# CONFIG_PATA_TOSHIBA is not set
# CONFIG_PATA_TRIFLEX is not set
# CONFIG_PATA_VIA is not set
# CONFIG_PATA_WINBOND is not set

#
# PIO-only SFF controllers
#
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_MPIIX is not set
# CONFIG_PATA_NS87410 is not set
# CONFIG_PATA_OPTI is not set
# CONFIG_PATA_PLATFORM is not set
# CONFIG_PATA_RZ1000 is not set

#
# Generic fallback / legacy drivers
#
# CONFIG_ATA_GENERIC is not set
# CONFIG_PATA_LEGACY is not set
# CONFIG_MD is not set
# CONFIG_TARGET_CORE is not set
# CONFIG_FUSION is not set

#
# IEEE 1394 (FireWire) support
#
# CONFIG_FIREWIRE is not set
# CONFIG_FIREWIRE_NOSY is not set
# CONFIG_I2O is not set
# CONFIG_MACINTOSH_DRIVERS is not set
CONFIG_NETDEVICES=y
CONFIG_NET_CORE=y
# CONFIG_BONDING is not set
# CONFIG_DUMMY is not set
# CONFIG_EQUALIZER is not set
# CONFIG_NET_FC is not set
# CONFIG_NET_TEAM is not set
# CONFIG_MACVLAN is not set
# CONFIG_VXLAN is not set
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
# CONFIG_RIONET is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
# CONFIG_NLMON is not set
# CONFIG_ARCNET is not set

#
# CAIF transport drivers
#

#
# Distributed Switch Architecture drivers
#
# CONFIG_NET_DSA_MV88E6XXX is not set
# CONFIG_NET_DSA_MV88E6060 is not set
# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
# CONFIG_NET_DSA_MV88E6131 is not set
# CONFIG_NET_DSA_MV88E6123_61_65 is not set
CONFIG_ETHERNET=y
CONFIG_NET_VENDOR_3COM=y
# CONFIG_VORTEX is not set
# CONFIG_TYPHOON is not set
CONFIG_NET_VENDOR_ADAPTEC=y
# CONFIG_ADAPTEC_STARFIRE is not set
CONFIG_NET_VENDOR_ALTEON=y
# CONFIG_ACENIC is not set
CONFIG_NET_VENDOR_AMD=y
# CONFIG_AMD8111_ETH is not set
# CONFIG_PCNET32 is not set
CONFIG_NET_VENDOR_ARC=y
# CONFIG_ARC_EMAC is not set
CONFIG_NET_VENDOR_ATHEROS=y
# CONFIG_ATL2 is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
# CONFIG_ATL1C is not set
# CONFIG_ALX is not set
CONFIG_NET_CADENCE=y
# CONFIG_ARM_AT91_ETHER is not set
# CONFIG_MACB is not set
CONFIG_NET_VENDOR_BROADCOM=y
# CONFIG_B44 is not set
# CONFIG_BNX2 is not set
# CONFIG_CNIC is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2X is not set
CONFIG_NET_VENDOR_BROCADE=y
# CONFIG_BNA is not set
# CONFIG_NET_CALXEDA_XGMAC is not set
CONFIG_NET_VENDOR_CHELSIO=y
# CONFIG_CHELSIO_T1 is not set
# CONFIG_CHELSIO_T3 is not set
# CONFIG_CHELSIO_T4 is not set
# CONFIG_CHELSIO_T4VF is not set
CONFIG_NET_VENDOR_CISCO=y
# CONFIG_ENIC is not set
# CONFIG_DNET is not set
CONFIG_NET_VENDOR_DEC=y
# CONFIG_NET_TULIP is not set
CONFIG_NET_VENDOR_DLINK=y
# CONFIG_DL2K is not set
# CONFIG_SUNDANCE is not set
CONFIG_NET_VENDOR_EMULEX=y
# CONFIG_BE2NET is not set
CONFIG_NET_VENDOR_EXAR=y
# CONFIG_S2IO is not set
# CONFIG_VXGE is not set
CONFIG_NET_VENDOR_FREESCALE=y
CONFIG_FSL_PQ_MDIO=y
# CONFIG_FSL_XGMAC_MDIO is not set
# CONFIG_GIANFAR is not set
CONFIG_NET_VENDOR_HP=y
# CONFIG_HP100 is not set
CONFIG_NET_VENDOR_INTEL=y
# CONFIG_E100 is not set
CONFIG_E1000=y
CONFIG_E1000E=y
# CONFIG_IGB is not set
# CONFIG_IGBVF is not set
# CONFIG_IXGB is not set
# CONFIG_IXGBE is not set
# CONFIG_IXGBEVF is not set
CONFIG_NET_VENDOR_I825XX=y
# CONFIG_IP1000 is not set
# CONFIG_JME is not set
CONFIG_NET_VENDOR_MARVELL=y
# CONFIG_MV643XX_ETH is not set
# CONFIG_MVMDIO is not set
# CONFIG_SKGE is not set
# CONFIG_SKY2 is not set
CONFIG_NET_VENDOR_MELLANOX=y
# CONFIG_MLX4_EN is not set
# CONFIG_MLX4_CORE is not set
CONFIG_NET_VENDOR_MICREL=y
# CONFIG_KS8851 is not set
# CONFIG_KS8851_MLL is not set
# CONFIG_KSZ884X_PCI is not set
CONFIG_NET_VENDOR_MICROCHIP=y
# CONFIG_ENC28J60 is not set
CONFIG_NET_VENDOR_MYRI=y
# CONFIG_MYRI10GE is not set
# CONFIG_FEALNX is not set
CONFIG_NET_VENDOR_NATSEMI=y
# CONFIG_NATSEMI is not set
# CONFIG_NS83820 is not set
CONFIG_NET_VENDOR_8390=y
# CONFIG_NE2K_PCI is not set
CONFIG_NET_VENDOR_NVIDIA=y
# CONFIG_FORCEDETH is not set
CONFIG_NET_VENDOR_OKI=y
# CONFIG_PCH_GBE is not set
# CONFIG_ETHOC is not set
CONFIG_NET_PACKET_ENGINE=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
CONFIG_NET_VENDOR_QLOGIC=y
# CONFIG_QLA3XXX is not set
# CONFIG_QLCNIC is not set
# CONFIG_QLGE is not set
# CONFIG_NETXEN_NIC is not set
CONFIG_NET_VENDOR_REALTEK=y
# CONFIG_8139CP is not set
# CONFIG_8139TOO is not set
# CONFIG_R8169 is not set
# CONFIG_SH_ETH is not set
CONFIG_NET_VENDOR_RDC=y
# CONFIG_R6040 is not set
CONFIG_NET_VENDOR_SEEQ=y
CONFIG_NET_VENDOR_SILAN=y
# CONFIG_SC92031 is not set
CONFIG_NET_VENDOR_SIS=y
# CONFIG_SIS900 is not set
# CONFIG_SIS190 is not set
# CONFIG_SFC is not set
CONFIG_NET_VENDOR_SMSC=y
# CONFIG_EPIC100 is not set
# CONFIG_SMSC911X is not set
# CONFIG_SMSC9420 is not set
CONFIG_NET_VENDOR_STMICRO=y
# CONFIG_STMMAC_ETH is not set
CONFIG_NET_VENDOR_SUN=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
# CONFIG_CASSINI is not set
# CONFIG_NIU is not set
CONFIG_NET_VENDOR_TEHUTI=y
# CONFIG_TEHUTI is not set
CONFIG_NET_VENDOR_TI=y
# CONFIG_TLAN is not set
CONFIG_NET_VENDOR_VIA=y
# CONFIG_VIA_RHINE is not set
# CONFIG_VIA_VELOCITY is not set
CONFIG_NET_VENDOR_WIZNET=y
# CONFIG_WIZNET_W5100 is not set
# CONFIG_WIZNET_W5300 is not set
CONFIG_NET_VENDOR_XILINX=y
# CONFIG_XILINX_EMACLITE is not set
# CONFIG_XILINX_LL_TEMAC is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
CONFIG_PHYLIB=y

#
# MII PHY device drivers
#
# CONFIG_AT803X_PHY is not set
# CONFIG_AMD_PHY is not set
# CONFIG_MARVELL_PHY is not set
# CONFIG_DAVICOM_PHY is not set
# CONFIG_QSEMI_PHY is not set
# CONFIG_LXT_PHY is not set
# CONFIG_CICADA_PHY is not set
CONFIG_VITESSE_PHY=y
# CONFIG_SMSC_PHY is not set
# CONFIG_BROADCOM_PHY is not set
# CONFIG_BCM87XX_PHY is not set
# CONFIG_ICPLUS_PHY is not set
# CONFIG_REALTEK_PHY is not set
# CONFIG_NATIONAL_PHY is not set
# CONFIG_STE10XP is not set
# CONFIG_LSI_ET1011C_PHY is not set
# CONFIG_MICREL_PHY is not set
CONFIG_FIXED_PHY=y
# CONFIG_MDIO_BITBANG is not set
# CONFIG_MDIO_BUS_MUX_GPIO is not set
# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
# CONFIG_MICREL_KS8995MA is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set

#
# USB Network Adapters
#
# CONFIG_USB_CATC is not set
# CONFIG_USB_KAWETH is not set
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_RTL8152 is not set
# CONFIG_USB_USBNET is not set
# CONFIG_USB_IPHETH is not set
CONFIG_WLAN=y
# CONFIG_AIRO is not set
# CONFIG_ATMEL is not set
# CONFIG_PRISM54 is not set
# CONFIG_USB_ZD1201 is not set
# CONFIG_HOSTAP is not set
# CONFIG_WL_TI is not set

#
# Enable WiMAX (Networking options) to see the WiMAX drivers
#
# CONFIG_WAN is not set
# CONFIG_VMXNET3 is not set
# CONFIG_ISDN is not set

#
# Input device support
#
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
# CONFIG_INPUT_POLLDEV is not set
# CONFIG_INPUT_SPARSEKMAP is not set
# CONFIG_INPUT_MATRIXKMAP is not set

#
# Userland interfaces
#
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set

#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set

#
# Hardware I/O ports
#
CONFIG_SERIO=y
CONFIG_SERIO_I8042=y
CONFIG_SERIO_SERPORT=y
# CONFIG_SERIO_PCIPS2 is not set
CONFIG_SERIO_LIBPS2=y
# CONFIG_SERIO_RAW is not set
# CONFIG_SERIO_XILINX_XPS_PS2 is not set
# CONFIG_SERIO_ALTERA_PS2 is not set
# CONFIG_SERIO_PS2MULT is not set
# CONFIG_SERIO_ARC_PS2 is not set
# CONFIG_SERIO_APBPS2 is not set
# CONFIG_SERIO_OLPC_APSP is not set
# CONFIG_GAMEPORT is not set

#
# Character devices
#
CONFIG_TTY=y
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
# CONFIG_VT_HW_CONSOLE_BINDING is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
# CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_NOZOMI is not set
# CONFIG_N_GSM is not set
# CONFIG_TRACE_SINK is not set
CONFIG_PPC_EPAPR_HV_BYTECHAN=y
# CONFIG_PPC_EARLY_DEBUG_EHV_BC is not set
CONFIG_DEVKMEM=y

#
# Serial drivers
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_PCI=y
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250_DETECT_IRQ=y
CONFIG_SERIAL_8250_RSA=y
CONFIG_SERIAL_8250_FSL=y
# CONFIG_SERIAL_8250_DW is not set

#
# Non-8250 serial port support
#
# CONFIG_SERIAL_MAX3100 is not set
# CONFIG_SERIAL_MAX310X is not set
# CONFIG_SERIAL_MFD_HSU is not set
# CONFIG_SERIAL_UARTLITE is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
# CONFIG_SERIAL_SCCNXP is not set
# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_ALTERA_JTAGUART is not set
# CONFIG_SERIAL_ALTERA_UART is not set
# CONFIG_SERIAL_IFX6X60 is not set
# CONFIG_SERIAL_PCH_UART is not set
# CONFIG_SERIAL_XILINX_PS_UART is not set
# CONFIG_SERIAL_ARC is not set
# CONFIG_SERIAL_RP2 is not set
# CONFIG_SERIAL_FSL_LPUART is not set
# CONFIG_TTY_PRINTK is not set
# CONFIG_HVC_UDBG is not set
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_HW_RANDOM_ATMEL is not set
# CONFIG_HW_RANDOM_EXYNOS is not set
CONFIG_NVRAM=y
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
# CONFIG_I2C_MUX is not set
CONFIG_I2C_HELPER_AUTO=y

#
# I2C Hardware Bus support
#

#
# PC SMBus host controller drivers
#
# CONFIG_I2C_ALI1535 is not set
# CONFIG_I2C_ALI1563 is not set
# CONFIG_I2C_ALI15X3 is not set
# CONFIG_I2C_AMD756 is not set
# CONFIG_I2C_AMD8111 is not set
# CONFIG_I2C_I801 is not set
# CONFIG_I2C_ISCH is not set
# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
# CONFIG_I2C_SIS96X is not set
# CONFIG_I2C_VIA is not set
# CONFIG_I2C_VIAPRO is not set

#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
# CONFIG_I2C_CBUS_GPIO is not set
# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
# CONFIG_I2C_DESIGNWARE_PCI is not set
# CONFIG_I2C_EG20T is not set
# CONFIG_I2C_GPIO is not set
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_PXA_PCI is not set
# CONFIG_I2C_SIMTEC is not set
# CONFIG_I2C_XILINX is not set

#
# External I2C/SMBus adapter drivers
#
# CONFIG_I2C_DIOLAN_U2C is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_TAOS_EVM is not set
# CONFIG_I2C_TINY_USB is not set

#
# Other I2C/SMBus bus drivers
#
# CONFIG_I2C_STUB is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
CONFIG_SPI=y
# CONFIG_SPI_DEBUG is not set
CONFIG_SPI_MASTER=y

#
# SPI Master Controller Drivers
#
# CONFIG_SPI_ALTERA is not set
CONFIG_SPI_BITBANG=y
CONFIG_SPI_GPIO=y
CONFIG_SPI_FSL_LIB=y
CONFIG_SPI_FSL_CPM=y
CONFIG_SPI_FSL_SPI=y
CONFIG_SPI_FSL_ESPI=y
# CONFIG_SPI_OC_TINY is not set
# CONFIG_SPI_PXA2XX is not set
# CONFIG_SPI_PXA2XX_PCI is not set
# CONFIG_SPI_SC18IS602 is not set
# CONFIG_SPI_TOPCLIFF_PCH is not set
# CONFIG_SPI_XCOMM is not set
# CONFIG_SPI_XILINX is not set
# CONFIG_SPI_DESIGNWARE is not set

#
# SPI Protocol Masters
#
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
# CONFIG_HSI is not set

#
# PPS support
#
CONFIG_PPS=y
# CONFIG_PPS_DEBUG is not set

#
# PPS clients support
#
# CONFIG_PPS_CLIENT_KTIMER is not set
# CONFIG_PPS_CLIENT_LDISC is not set
# CONFIG_PPS_CLIENT_GPIO is not set

#
# PPS generators support
#

#
# PTP clock support
#
CONFIG_PTP_1588_CLOCK=y

#
# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
#
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_ARCH_REQUIRE_GPIOLIB=y
CONFIG_GPIO_DEVRES=y
CONFIG_GPIOLIB=y
CONFIG_OF_GPIO=y
# CONFIG_DEBUG_GPIO is not set
# CONFIG_GPIO_SYSFS is not set

#
# Memory mapped GPIO drivers:
#
# CONFIG_GPIO_GENERIC_PLATFORM is not set
CONFIG_GPIO_MPC8XXX=y
# CONFIG_GPIO_TS5500 is not set
# CONFIG_GPIO_XILINX is not set
# CONFIG_GPIO_VX855 is not set
# CONFIG_GPIO_GRGPIO is not set

#
# I2C GPIO expanders:
#
# CONFIG_GPIO_MAX7300 is not set
# CONFIG_GPIO_MAX732X is not set
# CONFIG_GPIO_PCA953X is not set
# CONFIG_GPIO_PCF857X is not set
# CONFIG_GPIO_SX150X is not set
# CONFIG_GPIO_ADP5588 is not set
# CONFIG_GPIO_ADNP is not set

#
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
# CONFIG_GPIO_AMD8111 is not set
# CONFIG_GPIO_ML_IOH is not set
# CONFIG_GPIO_RDC321X is not set

#
# SPI GPIO expanders:
#
# CONFIG_GPIO_MAX7301 is not set
# CONFIG_GPIO_MCP23S08 is not set
# CONFIG_GPIO_MC33880 is not set
# CONFIG_GPIO_74X164 is not set

#
# AC97 GPIO expanders:
#

#
# MODULbus GPIO expanders:
#

#
# USB GPIO expanders:
#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_POWER_AVS is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y

#
# Sonics Silicon Backplane
#
# CONFIG_SSB is not set
CONFIG_BCMA_POSSIBLE=y

#
# Broadcom specific AMBA
#
# CONFIG_BCMA is not set

#
# Multifunction device drivers
#
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_AS3711 is not set
# CONFIG_PMIC_ADP5520 is not set
# CONFIG_MFD_AAT2870_CORE is not set
# CONFIG_MFD_CROS_EC is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_DA9052_SPI is not set
# CONFIG_MFD_DA9052_I2C is not set
# CONFIG_MFD_DA9055 is not set
# CONFIG_MFD_MC13XXX_SPI is not set
# CONFIG_MFD_MC13XXX_I2C is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_HTC_I2CPLD is not set
# CONFIG_LPC_ICH is not set
# CONFIG_LPC_SCH is not set
# CONFIG_MFD_JANZ_CMODIO is not set
# CONFIG_MFD_KEMPLD is not set
# CONFIG_MFD_88PM800 is not set
# CONFIG_MFD_88PM805 is not set
# CONFIG_MFD_88PM860X is not set
# CONFIG_MFD_MAX77686 is not set
# CONFIG_MFD_MAX77693 is not set
# CONFIG_MFD_MAX8907 is not set
# CONFIG_MFD_MAX8925 is not set
# CONFIG_MFD_MAX8997 is not set
# CONFIG_MFD_MAX8998 is not set
# CONFIG_EZX_PCAP is not set
# CONFIG_MFD_VIPERBOARD is not set
# CONFIG_MFD_RETU is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_MFD_RDC321X is not set
# CONFIG_MFD_RTSX_PCI is not set
# CONFIG_MFD_RC5T583 is not set
# CONFIG_MFD_SEC_CORE is not set
# CONFIG_MFD_SI476X_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_MFD_SMSC is not set
# CONFIG_ABX500_CORE is not set
# CONFIG_MFD_STMPE is not set
# CONFIG_MFD_SYSCON is not set
# CONFIG_MFD_TI_AM335X_TSCADC is not set
# CONFIG_MFD_LP8788 is not set
# CONFIG_MFD_PALMAS is not set
# CONFIG_TPS6105X is not set
# CONFIG_TPS65010 is not set
# CONFIG_TPS6507X is not set
# CONFIG_MFD_TPS65090 is not set
# CONFIG_MFD_TPS65217 is not set
# CONFIG_MFD_TPS6586X is not set
# CONFIG_MFD_TPS65910 is not set
# CONFIG_MFD_TPS65912 is not set
# CONFIG_MFD_TPS65912_I2C is not set
# CONFIG_MFD_TPS65912_SPI is not set
# CONFIG_MFD_TPS80031 is not set
# CONFIG_TWL4030_CORE is not set
# CONFIG_TWL6040_CORE is not set
# CONFIG_MFD_WL1273_CORE is not set
# CONFIG_MFD_LM3533 is not set
# CONFIG_MFD_TIMBERDALE is not set
# CONFIG_MFD_TC3589X is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_VX855 is not set
# CONFIG_MFD_ARIZONA_I2C is not set
# CONFIG_MFD_ARIZONA_SPI is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM831X_I2C is not set
# CONFIG_MFD_WM831X_SPI is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_WM8994 is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set

#
# Graphics support
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
# CONFIG_FB is not set
# CONFIG_EXYNOS_VIDEO is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set

#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
# CONFIG_VGACON_SOFT_SCROLLBACK is not set
CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set

#
# HID support
#
CONFIG_HID=y
# CONFIG_HIDRAW is not set
# CONFIG_UHID is not set
CONFIG_HID_GENERIC=y

#
# Special HID drivers
#
# CONFIG_HID_A4TECH is not set
# CONFIG_HID_ACRUX is not set
# CONFIG_HID_APPLE is not set
# CONFIG_HID_APPLEIR is not set
# CONFIG_HID_AUREAL is not set
# CONFIG_HID_BELKIN is not set
# CONFIG_HID_CHERRY is not set
# CONFIG_HID_CHICONY is not set
# CONFIG_HID_CYPRESS is not set
# CONFIG_HID_DRAGONRISE is not set
# CONFIG_HID_EMS_FF is not set
# CONFIG_HID_ELECOM is not set
# CONFIG_HID_ELO is not set
# CONFIG_HID_EZKEY is not set
# CONFIG_HID_HOLTEK is not set
# CONFIG_HID_HUION is not set
# CONFIG_HID_KEYTOUCH is not set
# CONFIG_HID_KYE is not set
# CONFIG_HID_UCLOGIC is not set
# CONFIG_HID_WALTOP is not set
# CONFIG_HID_GYRATION is not set
# CONFIG_HID_ICADE is not set
# CONFIG_HID_TWINHAN is not set
# CONFIG_HID_KENSINGTON is not set
# CONFIG_HID_LCPOWER is not set
# CONFIG_HID_LENOVO_TPKBD is not set
# CONFIG_HID_LOGITECH is not set
# CONFIG_HID_MAGICMOUSE is not set
# CONFIG_HID_MICROSOFT is not set
# CONFIG_HID_MONTEREY is not set
# CONFIG_HID_MULTITOUCH is not set
# CONFIG_HID_NTRIG is not set
# CONFIG_HID_ORTEK is not set
# CONFIG_HID_PANTHERLORD is not set
# CONFIG_HID_PETALYNX is not set
# CONFIG_HID_PICOLCD is not set
# CONFIG_HID_PRIMAX is not set
# CONFIG_HID_ROCCAT is not set
# CONFIG_HID_SAITEK is not set
# CONFIG_HID_SAMSUNG is not set
# CONFIG_HID_SPEEDLINK is not set
# CONFIG_HID_STEELSERIES is not set
# CONFIG_HID_SUNPLUS is not set
# CONFIG_HID_GREENASIA is not set
# CONFIG_HID_SMARTJOYPLUS is not set
# CONFIG_HID_TIVO is not set
# CONFIG_HID_TOPSEED is not set
# CONFIG_HID_THRUSTMASTER is not set
# CONFIG_HID_ZEROPLUS is not set
# CONFIG_HID_ZYDACRON is not set
# CONFIG_HID_SENSOR_HUB is not set

#
# USB HID support
#
CONFIG_USB_HID=m
# CONFIG_HID_PID is not set
# CONFIG_USB_HIDDEV is not set

#
# USB HID Boot Protocol drivers
#
# CONFIG_USB_KBD is not set
# CONFIG_USB_MOUSE is not set

#
# I2C HID support
#
# CONFIG_I2C_HID is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_COMMON=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set

#
# Miscellaneous USB options
#
CONFIG_USB_DEFAULT_PERSIST=y
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_OTG_WHITELIST is not set
# CONFIG_USB_OTG_BLACKLIST_HUB is not set
CONFIG_USB_MON=y
# CONFIG_USB_WUSB_CBAF is not set

#
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
# CONFIG_USB_XHCI_HCD is not set
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_TT_NEWSCHED=y
CONFIG_USB_FSL_MPH_DR_OF=y
CONFIG_USB_EHCI_PCI=y
# CONFIG_XPS_USB_HCD_XILINX is not set
CONFIG_USB_EHCI_FSL=y
CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_USB_EHCI_HCD_PLATFORM is not set
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
# CONFIG_USB_ISP1362_HCD is not set
# CONFIG_USB_FUSBH200_HCD is not set
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
CONFIG_USB_OHCI_HCD_PPC_OF=y
CONFIG_USB_OHCI_HCD_PCI=y
# CONFIG_USB_OHCI_HCD_PLATFORM is not set
CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_UHCI_HCD is not set
# CONFIG_USB_SL811_HCD is not set
# CONFIG_USB_R8A66597_HCD is not set

#
# USB Device Class drivers
#
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
# CONFIG_USB_WDM is not set
# CONFIG_USB_TMC is not set

#
# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#

#
# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_REALTEK is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
# CONFIG_USB_STORAGE_ALAUDA is not set
# CONFIG_USB_STORAGE_ONETOUCH is not set
# CONFIG_USB_STORAGE_KARMA is not set
# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
# CONFIG_USB_STORAGE_ENE_UB6250 is not set

#
# USB Imaging devices
#
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_MICROTEK is not set
# CONFIG_USB_DWC3 is not set
# CONFIG_USB_CHIPIDEA is not set

#
# USB port drivers
#
# CONFIG_USB_SERIAL is not set

#
# USB Miscellaneous drivers
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
# CONFIG_USB_ADUTUX is not set
# CONFIG_USB_SEVSEG is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
# CONFIG_USB_TEST is not set
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_YUREX is not set
# CONFIG_USB_EZUSB_FX2 is not set
# CONFIG_USB_HSIC_USB3503 is not set
# CONFIG_USB_PHY is not set
# CONFIG_USB_GADGET is not set
# CONFIG_UWB is not set
CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_UNSAFE_RESUME is not set
# CONFIG_MMC_CLKGATE is not set

#
# MMC/SD/SDIO Card Drivers
#
CONFIG_MMC_BLOCK=y
CONFIG_MMC_BLOCK_MINORS=8
CONFIG_MMC_BLOCK_BOUNCE=y
# CONFIG_SDIO_UART is not set
# CONFIG_MMC_TEST is not set

#
# MMC/SD/SDIO Host Controller Drivers
#
CONFIG_MMC_SDHCI=y
# CONFIG_MMC_SDHCI_PCI is not set
# CONFIG_MMC_SDHCI_PLTFM is not set
# CONFIG_MMC_SDHCI_PXAV3 is not set
# CONFIG_MMC_SDHCI_PXAV2 is not set
# CONFIG_MMC_WBSD is not set
# CONFIG_MMC_TIFM_SD is not set
# CONFIG_MMC_CB710 is not set
# CONFIG_MMC_VIA_SDMMC is not set
# CONFIG_MMC_VUB300 is not set
# CONFIG_MMC_USHC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_INFINIBAND is not set
CONFIG_EDAC=y
CONFIG_EDAC_LEGACY_SYSFS=y
# CONFIG_EDAC_DEBUG is not set
CONFIG_EDAC_MM_EDAC=y
CONFIG_EDAC_MPC85XX=y
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
CONFIG_RTC_SYSTOHC=y
CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
# CONFIG_RTC_DEBUG is not set

#
# RTC interfaces
#
CONFIG_RTC_INTF_SYSFS=y
CONFIG_RTC_INTF_PROC=y
CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
# CONFIG_RTC_DRV_TEST is not set

#
# I2C RTC drivers
#
# CONFIG_RTC_DRV_DS1307 is not set
# CONFIG_RTC_DRV_DS1374 is not set
# CONFIG_RTC_DRV_DS1672 is not set
CONFIG_RTC_DRV_DS3232=y
# CONFIG_RTC_DRV_MAX6900 is not set
# CONFIG_RTC_DRV_RS5C372 is not set
# CONFIG_RTC_DRV_ISL1208 is not set
# CONFIG_RTC_DRV_ISL12022 is not set
# CONFIG_RTC_DRV_X1205 is not set
# CONFIG_RTC_DRV_PCF2127 is not set
# CONFIG_RTC_DRV_PCF8523 is not set
# CONFIG_RTC_DRV_PCF8563 is not set
# CONFIG_RTC_DRV_PCF8583 is not set
# CONFIG_RTC_DRV_M41T80 is not set
# CONFIG_RTC_DRV_BQ32K is not set
# CONFIG_RTC_DRV_S35390A is not set
# CONFIG_RTC_DRV_FM3130 is not set
# CONFIG_RTC_DRV_RX8581 is not set
# CONFIG_RTC_DRV_RX8025 is not set
# CONFIG_RTC_DRV_EM3027 is not set
# CONFIG_RTC_DRV_RV3029C2 is not set

#
# SPI RTC drivers
#
# CONFIG_RTC_DRV_M41T93 is not set
# CONFIG_RTC_DRV_M41T94 is not set
# CONFIG_RTC_DRV_DS1305 is not set
# CONFIG_RTC_DRV_DS1390 is not set
# CONFIG_RTC_DRV_MAX6902 is not set
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_DS3234 is not set
# CONFIG_RTC_DRV_PCF2123 is not set
# CONFIG_RTC_DRV_RX4581 is not set

#
# Platform RTC drivers
#
CONFIG_RTC_DRV_CMOS=y
# CONFIG_RTC_DRV_DS1286 is not set
# CONFIG_RTC_DRV_DS1511 is not set
# CONFIG_RTC_DRV_DS1553 is not set
# CONFIG_RTC_DRV_DS1742 is not set
# CONFIG_RTC_DRV_STK17TA8 is not set
# CONFIG_RTC_DRV_M48T86 is not set
# CONFIG_RTC_DRV_M48T35 is not set
# CONFIG_RTC_DRV_M48T59 is not set
# CONFIG_RTC_DRV_MSM6242 is not set
# CONFIG_RTC_DRV_BQ4802 is not set
# CONFIG_RTC_DRV_RP5C01 is not set
# CONFIG_RTC_DRV_V3020 is not set
# CONFIG_RTC_DRV_DS2404 is not set

#
# on-CPU RTC drivers
#
# CONFIG_RTC_DRV_GENERIC is not set
# CONFIG_RTC_DRV_SNVS is not set

#
# HID Sensor RTC drivers
#
# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
# CONFIG_DMADEVICES is not set
# CONFIG_AUXDISPLAY is not set
CONFIG_UIO=y
# CONFIG_UIO_CIF is not set
# CONFIG_UIO_PDRV is not set
# CONFIG_UIO_PDRV_GENIRQ is not set
# CONFIG_UIO_DMEM_GENIRQ is not set
# CONFIG_UIO_AEC is not set
# CONFIG_UIO_SERCOS3 is not set
# CONFIG_UIO_PCI_GENERIC is not set
# CONFIG_UIO_NETX is not set
# CONFIG_VFIO is not set
CONFIG_VIRT_DRIVERS=y
CONFIG_FSL_HV_MANAGER=y

#
# Virtio drivers
#
# CONFIG_VIRTIO_PCI is not set
# CONFIG_VIRTIO_MMIO is not set

#
# Microsoft Hyper-V guest support
#
CONFIG_STAGING=y
# CONFIG_ET131X is not set
# CONFIG_USBIP_CORE is not set
# CONFIG_ECHO is not set
# CONFIG_COMEDI is not set
# CONFIG_ASUS_OLED is not set
# CONFIG_R8187SE is not set
# CONFIG_RTL8192U is not set
# CONFIG_RTLLIB is not set
# CONFIG_R8712U is not set
# CONFIG_RTS5139 is not set
# CONFIG_TRANZPORT is not set
# CONFIG_IDE_PHISON is not set
# CONFIG_VT6655 is not set
# CONFIG_VT6656 is not set
# CONFIG_DX_SEP is not set
# CONFIG_ZSMALLOC is not set
# CONFIG_CRYSTALHD is not set
# CONFIG_USB_ENESTORAGE is not set
# CONFIG_BCM_WIMAX is not set
# CONFIG_FT1000 is not set

#
# Speakup console speech
#
# CONFIG_SPEAKUP is not set
# CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set
# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set
# CONFIG_STAGING_MEDIA is not set

#
# Android
#
# CONFIG_ANDROID is not set
# CONFIG_USB_WPAN_HCD is not set
# CONFIG_WIMAX_GDM72XX is not set
CONFIG_NET_VENDOR_SILICOM=y
# CONFIG_SBYPASS is not set
# CONFIG_BPCTL is not set
# CONFIG_CED1401 is not set
# CONFIG_DGRP is not set
# CONFIG_USB_DWC2 is not set
CONFIG_CLKDEV_LOOKUP=y
CONFIG_HAVE_CLK_PREPARE=y
CONFIG_COMMON_CLK=y

#
# Common Clock Framework
#
# CONFIG_COMMON_CLK_DEBUG is not set
# CONFIG_COMMON_CLK_SI5351 is not set
# CONFIG_CLK_PPC_CORENET is not set

#
# Hardware Spinlock drivers
#
# CONFIG_MAILBOX is not set
CONFIG_IOMMU_API=y
CONFIG_IOMMU_SUPPORT=y
CONFIG_OF_IOMMU=y
CONFIG_FSL_PAMU=y

#
# Remoteproc drivers
#
# CONFIG_STE_MODEM_RPROC is not set

#
# Rpmsg drivers
#
# CONFIG_PM_DEVFREQ is not set
# CONFIG_EXTCON is not set
# CONFIG_MEMORY is not set
# CONFIG_IIO is not set
# CONFIG_VME_BUS is not set
# CONFIG_PWM is not set
CONFIG_IRQCHIP=y
# CONFIG_IPACK_BUS is not set
# CONFIG_RESET_CONTROLLER is not set
# CONFIG_FMC is not set

#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
# CONFIG_EXT4_FS is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_BTRFS_FS is not set
# CONFIG_NILFS2_FS is not set
# CONFIG_FS_POSIX_ACL is not set
CONFIG_EXPORTFS=m
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_FANOTIFY is not set
# CONFIG_QUOTA is not set
# CONFIG_QUOTACTL is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set

#
# Caches
#
# CONFIG_FSCACHE is not set

#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
CONFIG_ZISOFS=y
CONFIG_UDF_FS=m
CONFIG_UDF_NLS=y

#
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=y
CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_NTFS_FS=y
# CONFIG_NTFS_DEBUG is not set
# CONFIG_NTFS_RW is not set

#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_PROC_SYSCTL=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_TMPFS_XATTR is not set
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
# CONFIG_CONFIGFS_FS is not set
CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_ECRYPT_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_HFSPLUS_FS is not set
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
# CONFIG_JFFS2_SUMMARY is not set
# CONFIG_JFFS2_FS_XATTR is not set
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
CONFIG_JFFS2_ZLIB=y
# CONFIG_JFFS2_LZO is not set
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_LOGFS is not set
CONFIG_CRAMFS=y
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_QNX6FS_FS is not set
# CONFIG_ROMFS_FS is not set
# CONFIG_PSTORE is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
# CONFIG_F2FS_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V2=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
CONFIG_NFS_V4=y
# CONFIG_NFS_SWAP is not set
# CONFIG_NFS_V4_1 is not set
CONFIG_ROOT_NFS=y
# CONFIG_NFS_USE_LEGACY_DNS is not set
CONFIG_NFS_USE_KERNEL_DNS=y
CONFIG_NFSD=m
# CONFIG_NFSD_V3 is not set
# CONFIG_NFSD_V4 is not set
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
# CONFIG_SUNRPC_DEBUG is not set
# CONFIG_CEPH_FS is not set
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NLS_CODEPAGE_437 is not set
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
# CONFIG_NLS_CODEPAGE_850 is not set
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not set
# CONFIG_NLS_CODEPAGE_860 is not set
# CONFIG_NLS_CODEPAGE_861 is not set
# CONFIG_NLS_CODEPAGE_862 is not set
# CONFIG_NLS_CODEPAGE_863 is not set
# CONFIG_NLS_CODEPAGE_864 is not set
# CONFIG_NLS_CODEPAGE_865 is not set
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_936 is not set
# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_CODEPAGE_932 is not set
# CONFIG_NLS_CODEPAGE_949 is not set
# CONFIG_NLS_CODEPAGE_874 is not set
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
# CONFIG_NLS_ASCII is not set
CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
# CONFIG_NLS_ISO8859_5 is not set
# CONFIG_NLS_ISO8859_6 is not set
# CONFIG_NLS_ISO8859_7 is not set
# CONFIG_NLS_ISO8859_9 is not set
# CONFIG_NLS_ISO8859_13 is not set
# CONFIG_NLS_ISO8859_14 is not set
# CONFIG_NLS_ISO8859_15 is not set
# CONFIG_NLS_KOI8_R is not set
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_MAC_ROMAN is not set
# CONFIG_NLS_MAC_CELTIC is not set
# CONFIG_NLS_MAC_CENTEURO is not set
# CONFIG_NLS_MAC_CROATIAN is not set
# CONFIG_NLS_MAC_CYRILLIC is not set
# CONFIG_NLS_MAC_GAELIC is not set
# CONFIG_NLS_MAC_GREEK is not set
# CONFIG_NLS_MAC_ICELAND is not set
# CONFIG_NLS_MAC_INUIT is not set
# CONFIG_NLS_MAC_ROMANIAN is not set
# CONFIG_NLS_MAC_TURKISH is not set
CONFIG_NLS_UTF8=m
# CONFIG_BINARY_PRINTF is not set

#
# Library routines
#
CONFIG_BITREVERSE=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_NET_UTILS=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_IO=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
# CONFIG_CRC_T10DIF is not set
CONFIG_CRC_ITU_T=m
CONFIG_CRC32=y
# CONFIG_CRC32_SELFTEST is not set
CONFIG_CRC32_SLICEBY8=y
# CONFIG_CRC32_SLICEBY4 is not set
# CONFIG_CRC32_SARWATE is not set
# CONFIG_CRC32_BIT is not set
# CONFIG_CRC7 is not set
CONFIG_LIBCRC32C=m
# CONFIG_CRC8 is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
# CONFIG_XZ_DEC is not set
# CONFIG_XZ_DEC_BCJ is not set
CONFIG_DECOMPRESS_GZIP=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_CPU_RMAP=y
CONFIG_DQL=y
CONFIG_NLATTR=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
# CONFIG_AVERAGE is not set
# CONFIG_CORDIC is not set
# CONFIG_DDR is not set
CONFIG_OID_REGISTRY=y

#
# Kernel hacking
#

#
# printk and dmesg options
#
# CONFIG_PRINTK_TIME is not set
CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
# CONFIG_DYNAMIC_DEBUG is not set

#
# Compile-time checks and compiler options
#
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_INFO_REDUCED is not set
CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_READABLE_ASM is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
# CONFIG_DEBUG_SECTION_MISMATCH is not set
# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y

#
# Memory Debugging
#
# CONFIG_DEBUG_PAGEALLOC is not set
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_DEBUG_SLAB is not set
CONFIG_HAVE_DEBUG_KMEMLEAK=y
# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_MEMORY_INIT is not set
# CONFIG_DEBUG_PER_CPU_MAPS is not set
# CONFIG_DEBUG_HIGHMEM is not set
CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
# CONFIG_DEBUG_STACKOVERFLOW is not set
CONFIG_DEBUG_SHIRQ=y

#
# Debug Lockups and Hangs
#
# CONFIG_LOCKUP_DETECTOR is not set
CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
# CONFIG_PANIC_ON_OOPS is not set
CONFIG_PANIC_ON_OOPS_VALUE=0
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set

#
# Lock Debugging (spinlocks, mutexes, etc...)
#
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
# CONFIG_DEBUG_LOCK_ALLOC is not set
# CONFIG_PROVE_LOCKING is not set
# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_ATOMIC_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_WRITECOUNT is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
# CONFIG_DEBUG_CREDENTIALS is not set

#
# RCU Debugging
#
# CONFIG_SPARSE_RCU_POINTER is not set
# CONFIG_RCU_TORTURE_TEST is not set
CONFIG_RCU_CPU_STALL_TIMEOUT=21
# CONFIG_RCU_CPU_STALL_INFO is not set
CONFIG_RCU_TRACE=y
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_NOTIFIER_ERROR_INJECTION is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_TRACE_CLOCK=y
CONFIG_TRACING_SUPPORT=y
CONFIG_FTRACE=y
# CONFIG_FUNCTION_TRACER is not set
# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_ENABLE_DEFAULT_TRACERS is not set
# CONFIG_FTRACE_SYSCALLS is not set
# CONFIG_TRACER_SNAPSHOT is not set
CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
# CONFIG_PROFILE_ALL_BRANCHES is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_UPROBE_EVENT is not set
# CONFIG_PROBE_EVENTS is not set

#
# Runtime Testing
#
# CONFIG_LKDTM is not set
# CONFIG_TEST_LIST_SORT is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_RBTREE_TEST is not set
# CONFIG_INTERVAL_TREE_TEST is not set
# CONFIG_ATOMIC64_SELFTEST is not set
# CONFIG_TEST_STRING_HELPERS is not set
# CONFIG_TEST_KSTRTOX is not set
# CONFIG_DMA_API_DEBUG is not set
CONFIG_SAMPLES=y
CONFIG_SAMPLE_KOBJECT=m
# CONFIG_SAMPLE_KFIFO is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
# CONFIG_PPC_DISABLE_WERROR is not set
CONFIG_PPC_WERROR=y
CONFIG_PRINT_STACK_DEPTH=64
# CONFIG_PPC_EMULATED_STATS is not set
# CONFIG_CODE_PATCHING_SELFTEST is not set
# CONFIG_FTR_FIXUP_SELFTEST is not set
# CONFIG_MSI_BITMAP_SELFTEST is not set
# CONFIG_XMON is not set
# CONFIG_BDI_SWITCH is not set
# CONFIG_PPC_EARLY_DEBUG is not set
CONFIG_STRICT_DEVMEM=y

#
# Security options
#
CONFIG_KEYS=y
# CONFIG_ENCRYPTED_KEYS is not set
# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
# CONFIG_SECURITY_DMESG_RESTRICT is not set
# CONFIG_SECURITY is not set
# CONFIG_SECURITYFS is not set
CONFIG_DEFAULT_SECURITY_DAC=y
CONFIG_DEFAULT_SECURITY=""
CONFIG_CRYPTO=y

#
# Crypto core or helper
#
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=y
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_PCOMP2=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_USER is not set
CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
# CONFIG_CRYPTO_GF128MUL is not set
CONFIG_CRYPTO_NULL=y
# CONFIG_CRYPTO_PCRYPT is not set
CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_AUTHENC=y
# CONFIG_CRYPTO_TEST is not set

#
# Authenticated Encryption with Associated Data
#
# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_GCM is not set
# CONFIG_CRYPTO_SEQIV is not set

#
# Block modes
#
CONFIG_CRYPTO_CBC=y
# CONFIG_CRYPTO_CTR is not set
# CONFIG_CRYPTO_CTS is not set
# CONFIG_CRYPTO_ECB is not set
# CONFIG_CRYPTO_LRW is not set
CONFIG_CRYPTO_PCBC=m
# CONFIG_CRYPTO_XTS is not set

#
# Hash modes
#
# CONFIG_CRYPTO_CMAC is not set
CONFIG_CRYPTO_HMAC=y
# CONFIG_CRYPTO_XCBC is not set
# CONFIG_CRYPTO_VMAC is not set

#
# Digest
#
CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_CRC32 is not set
# CONFIG_CRYPTO_CRCT10DIF is not set
# CONFIG_CRYPTO_GHASH is not set
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_RMD128 is not set
# CONFIG_CRYPTO_RMD160 is not set
# CONFIG_CRYPTO_RMD256 is not set
# CONFIG_CRYPTO_RMD320 is not set
CONFIG_CRYPTO_SHA1=y
# CONFIG_CRYPTO_SHA1_PPC is not set
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA512=y
# CONFIG_CRYPTO_TGR192 is not set
# CONFIG_CRYPTO_WP512 is not set

#
# Ciphers
#
CONFIG_CRYPTO_AES=y
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_ARC4 is not set
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_CAST5 is not set
# CONFIG_CRYPTO_CAST6 is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_FCRYPT is not set
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_SALSA20 is not set
# CONFIG_CRYPTO_SEED is not set
# CONFIG_CRYPTO_SERPENT is not set
# CONFIG_CRYPTO_TEA is not set
# CONFIG_CRYPTO_TWOFISH is not set

#
# Compression
#
CONFIG_CRYPTO_DEFLATE=y
# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
# CONFIG_CRYPTO_LZ4 is not set
# CONFIG_CRYPTO_LZ4HC is not set

#
# Random Number Generation
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_USER_API_HASH is not set
# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
CONFIG_CRYPTO_HW=y
CONFIG_CRYPTO_DEV_FSL_CAAM=y
CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE=9
# CONFIG_CRYPTO_DEV_FSL_CAAM_INTC is not set
CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API=y
CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API=y
CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API=y
# CONFIG_CRYPTO_DEV_TALITOS is not set
# CONFIG_ASYMMETRIC_KEY_TYPE is not set
# CONFIG_PPC_CLOCK is not set
# CONFIG_VIRTUALIZATION is not set

[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/3] powerpc: Add iommu domain pointer to device archdata
  2013-08-14  9:56     ` Sethi Varun-B16395
  (?)
@ 2013-08-14 16:15       ` Joerg Roedel
  -1 siblings, 0 replies; 20+ messages in thread
From: Joerg Roedel @ 2013-08-14 16:15 UTC (permalink / raw)
  To: Sethi Varun-B16395
  Cc: iommu, linuxppc-dev, linux-kernel, benh, galak, alex.williamson,
	Yoder Stuart-B08248, Wood Scott-B07421

On Wed, Aug 14, 2013 at 09:56:11AM +0000, Sethi Varun-B16395 wrote:
> Please find the .config file attached with this mail.

Fantastic, thanks. The build works fine, I'll include the driver into my
next-branch. I also have two minor clean-up patches on-top, just if you
where wondering.


	Joerg



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/3] powerpc: Add iommu domain pointer to device archdata
@ 2013-08-14 16:15       ` Joerg Roedel
  0 siblings, 0 replies; 20+ messages in thread
From: Joerg Roedel @ 2013-08-14 16:15 UTC (permalink / raw)
  To: Sethi Varun-B16395
  Cc: Wood Scott-B07421, iommu, linux-kernel, Yoder Stuart-B08248,
	alex.williamson, linuxppc-dev

On Wed, Aug 14, 2013 at 09:56:11AM +0000, Sethi Varun-B16395 wrote:
> Please find the .config file attached with this mail.

Fantastic, thanks. The build works fine, I'll include the driver into my
next-branch. I also have two minor clean-up patches on-top, just if you
where wondering.


	Joerg

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/3] powerpc: Add iommu domain pointer to device archdata
@ 2013-08-14 16:15       ` Joerg Roedel
  0 siblings, 0 replies; 20+ messages in thread
From: Joerg Roedel @ 2013-08-14 16:15 UTC (permalink / raw)
  To: Sethi Varun-B16395
  Cc: galak-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r, Wood Scott-B07421,
	benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Yoder Stuart-B08248,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ

On Wed, Aug 14, 2013 at 09:56:11AM +0000, Sethi Varun-B16395 wrote:
> Please find the .config file attached with this mail.

Fantastic, thanks. The build works fine, I'll include the driver into my
next-branch. I also have two minor clean-up patches on-top, just if you
where wondering.


	Joerg

^ permalink raw reply	[flat|nested] 20+ messages in thread

* RE: [PATCH 1/3] powerpc: Add iommu domain pointer to device archdata
  2013-08-14 16:15       ` Joerg Roedel
@ 2013-08-14 16:44         ` Sethi Varun-B16395
  -1 siblings, 0 replies; 20+ messages in thread
From: Sethi Varun-B16395 @ 2013-08-14 16:44 UTC (permalink / raw)
  To: Joerg Roedel
  Cc: iommu, linuxppc-dev, linux-kernel, benh, galak, alex.williamson,
	Yoder Stuart-B08248, Wood Scott-B07421

Thanks Joerg.

> -----Original Message-----
> From: Joerg Roedel [mailto:joro@8bytes.org]
> Sent: Wednesday, August 14, 2013 9:45 PM
> To: Sethi Varun-B16395
> Cc: iommu@lists.linux-foundation.org; linuxppc-dev@lists.ozlabs.org;
> linux-kernel@vger.kernel.org; benh@kernel.crashing.org;
> galak@kernel.crashing.org; alex.williamson@redhat.com; Yoder Stuart-
> B08248; Wood Scott-B07421
> Subject: Re: [PATCH 1/3] powerpc: Add iommu domain pointer to device
> archdata
> 
> On Wed, Aug 14, 2013 at 09:56:11AM +0000, Sethi Varun-B16395 wrote:
> > Please find the .config file attached with this mail.
> 
> Fantastic, thanks. The build works fine, I'll include the driver into my
> next-branch. I also have two minor clean-up patches on-top, just if you
> where wondering.
> 
> 
> 	Joerg
> 
> 



^ permalink raw reply	[flat|nested] 20+ messages in thread

* RE: [PATCH 1/3] powerpc: Add iommu domain pointer to device archdata
@ 2013-08-14 16:44         ` Sethi Varun-B16395
  0 siblings, 0 replies; 20+ messages in thread
From: Sethi Varun-B16395 @ 2013-08-14 16:44 UTC (permalink / raw)
  To: Joerg Roedel
  Cc: Wood Scott-B07421, iommu, linux-kernel, Yoder Stuart-B08248,
	alex.williamson, linuxppc-dev

Thanks Joerg.

> -----Original Message-----
> From: Joerg Roedel [mailto:joro@8bytes.org]
> Sent: Wednesday, August 14, 2013 9:45 PM
> To: Sethi Varun-B16395
> Cc: iommu@lists.linux-foundation.org; linuxppc-dev@lists.ozlabs.org;
> linux-kernel@vger.kernel.org; benh@kernel.crashing.org;
> galak@kernel.crashing.org; alex.williamson@redhat.com; Yoder Stuart-
> B08248; Wood Scott-B07421
> Subject: Re: [PATCH 1/3] powerpc: Add iommu domain pointer to device
> archdata
>=20
> On Wed, Aug 14, 2013 at 09:56:11AM +0000, Sethi Varun-B16395 wrote:
> > Please find the .config file attached with this mail.
>=20
> Fantastic, thanks. The build works fine, I'll include the driver into my
> next-branch. I also have two minor clean-up patches on-top, just if you
> where wondering.
>=20
>=20
> 	Joerg
>=20
>=20

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2013-08-14 16:44 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-15  4:50 [PATCH 1/3] powerpc: Add iommu domain pointer to device archdata Varun Sethi
2013-07-15  4:50 ` Varun Sethi
2013-07-15  4:50 ` [PATCH 2/3 v19] iommu/fsl: Add additional iommu attributes required by the PAMU driver Varun Sethi
2013-07-15  4:50   ` Varun Sethi
2013-07-15  4:50 ` [PATCH 3/3 v18] iommu/fsl: Freescale PAMU driver and iommu implementation Varun Sethi
2013-07-15  4:50   ` Varun Sethi
2013-07-29 12:14   ` Sethi Varun-B16395
2013-07-29 12:14     ` Sethi Varun-B16395
2013-07-29 12:14     ` Sethi Varun-B16395
2013-08-14  9:48 ` [PATCH 1/3] powerpc: Add iommu domain pointer to device archdata Joerg Roedel
2013-08-14  9:48   ` Joerg Roedel
2013-08-14  9:48   ` Joerg Roedel
2013-08-14  9:56   ` Sethi Varun-B16395
2013-08-14  9:56     ` Sethi Varun-B16395
2013-08-14  9:56     ` Sethi Varun-B16395
2013-08-14 16:15     ` Joerg Roedel
2013-08-14 16:15       ` Joerg Roedel
2013-08-14 16:15       ` Joerg Roedel
2013-08-14 16:44       ` Sethi Varun-B16395
2013-08-14 16:44         ` Sethi Varun-B16395

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.