summaryrefslogtreecommitdiff
path: root/drivers/iommu
diff options
context:
space:
mode:
authorVarun Sethi <Varun.Sethi@freescale.com>2013-03-28 20:31:32 (GMT)
committerFleming Andrew-AFLEMING <AFLEMING@freescale.com>2013-04-05 16:13:32 (GMT)
commit6bc0787245317962a92a3b2435e0123371eea84f (patch)
tree1d8c1151725dcf306f5926d32f0c45f555c0b6b5 /drivers/iommu
parentb2e8128d61be3f4765be626eeb5dbf5420861886 (diff)
downloadlinux-fsl-qoriq-6bc0787245317962a92a3b2435e0123371eea84f.tar.xz
iommu/fsl: PAMU driver fixes.
This patch contains the following fixes: 1. Support for finding guts node on T4 & B4 platforms. 2. Make iova dma_addr_t constistent with iova_to_phys API change. 3. Disable SPAACE while reconfiguring it. 4. Make API and internal function static. 5. Free data pointer in case of an error. 6. Update comment description and remove unneeded comment. Signed-off-by: Varun Sethi <Varun.Sethi@freescale.com> Change-Id: I4763d9783e9f3d8057c991ca424e48e337c20f3b Reviewed-on: http://git.am.freescale.net:8181/884 Reviewed-by: Yoder Stuart-B08248 <stuart.yoder@freescale.com> Reviewed-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com> Tested-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com>
Diffstat (limited to 'drivers/iommu')
-rw-r--r--drivers/iommu/fsl_pamu.c36
-rw-r--r--drivers/iommu/fsl_pamu_domain.c25
2 files changed, 41 insertions, 20 deletions
diff --git a/drivers/iommu/fsl_pamu.c b/drivers/iommu/fsl_pamu.c
index beef5a0..459f7a4 100644
--- a/drivers/iommu/fsl_pamu.c
+++ b/drivers/iommu/fsl_pamu.c
@@ -53,6 +53,19 @@ 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", },
+ {}
+};
+
/* maximum subwindows permitted per liodn */
static u32 max_subwindow_count;
@@ -739,7 +752,6 @@ static void __init setup_liodns(void)
}
}
-/* TBD: PAMU access violation interrupt handler */
irqreturn_t pamu_av_isr(int irq, void *arg)
{
struct pamu_isr_data *data = arg;
@@ -935,10 +947,11 @@ error:
}
/*
- * Table of SVRs and the corresponding PORT_ID values.
+ * 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 fixed, so this table
- * should never need to be updated. SVRs are guaranteed to be unique, so
+ * 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.
*/
@@ -970,7 +983,7 @@ static int __init fsl_pamu_probe(struct platform_device *pdev)
u32 pamubypenr, pamu_counter;
unsigned long pamu_reg_off;
unsigned long pamu_reg_base;
- struct pamu_isr_data *data;
+ struct pamu_isr_data *data = NULL;
struct device_node *guts_node;
u64 size;
struct page *p;
@@ -1004,8 +1017,9 @@ static int __init fsl_pamu_probe(struct platform_device *pdev)
data = kzalloc(sizeof(struct pamu_isr_data), GFP_KERNEL);
if (!data) {
- iounmap(pamu_regs);
- return -ENOMEM;
+ 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;
@@ -1018,8 +1032,7 @@ static int __init fsl_pamu_probe(struct platform_device *pdev)
goto error;
}
- guts_node = of_find_compatible_node(NULL, NULL,
- "fsl,qoriq-device-config-1.0");
+ 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);
@@ -1142,6 +1155,11 @@ 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);
diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c
index 4865441..d1e0e6d 100644
--- a/drivers/iommu/fsl_pamu_domain.c
+++ b/drivers/iommu/fsl_pamu_domain.c
@@ -49,7 +49,7 @@ static struct kmem_cache *fsl_pamu_domain_cache;
static struct kmem_cache *iommu_devinfo_cache;
static DEFINE_SPINLOCK(device_domain_lock);
-int __init iommu_init_mempool(void)
+static int __init iommu_init_mempool(void)
{
fsl_pamu_domain_cache = kmem_cache_create("fsl_pamu_domain",
@@ -77,7 +77,7 @@ int __init iommu_init_mempool(void)
return 0;
}
-static phys_addr_t get_phys_addr(struct fsl_dma_domain *dma_domain, u64 iova)
+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 =
@@ -93,7 +93,7 @@ static phys_addr_t get_phys_addr(struct fsl_dma_domain *dma_domain, u64 iova)
if (win_cnt > 1) {
u64 subwin_size;
- u64 subwin_iova;
+ dma_addr_t subwin_iova;
u32 wnd;
subwin_size = dma_domain->geom_size >> ilog2(win_cnt);
@@ -274,10 +274,13 @@ static int pamu_set_liodn(int liodn, struct device *dev,
subwin_size = window_size >> ilog2(win_cnt);
for (i = 0; i < win_cnt; i++) {
spin_lock(&iommu_lock);
- ret = pamu_config_spaace(liodn, win_cnt, i, subwin_size,
- omi_index, 0,
- dma_domain->snoop_id,
- dma_domain->stash_id, 0, 0);
+ 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(&iommu_lock);
if (ret) {
pr_err("PAMU SPAACE configuration failed for liodn %d\n", liodn);
@@ -289,7 +292,7 @@ static int pamu_set_liodn(int liodn, struct device *dev,
return ret;
}
-static int check_size(u64 size, unsigned long iova)
+static int check_size(u64 size, dma_addr_t iova)
{
/*
* Size must be a power of two and at least be equal
@@ -401,7 +404,7 @@ static void attach_device(struct fsl_dma_domain *dma_domain, int liodn, struct d
}
static phys_addr_t fsl_pamu_iova_to_phys(struct iommu_domain *domain,
- u64 iova)
+ dma_addr_t iova)
{
struct fsl_dma_domain *dma_domain = domain->priv;
@@ -844,7 +847,7 @@ static int configure_domain_dma_state(struct fsl_dma_domain *dma_domain, bool en
return 0;
}
-int fsl_pamu_set_domain_attr(struct iommu_domain *domain,
+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;
@@ -870,7 +873,7 @@ int fsl_pamu_set_domain_attr(struct iommu_domain *domain,
return ret;
}
-int fsl_pamu_get_domain_attr(struct iommu_domain *domain,
+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;