aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc/platforms/iseries/iommu.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-06-22 22:11:30 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-22 22:11:30 -0700
commit45c091bb2d453ce4a8b06cf19872ec7a77fc4799 (patch)
tree06fb2e05518ebfba163f8424e028e7faf5672d66 /arch/powerpc/platforms/iseries/iommu.c
parentd588fcbe5a7ba8bba2cebf7799ab2d573717a806 (diff)
parent2191fe3e39159e3375f4b7ec1420df149f154101 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (139 commits) [POWERPC] re-enable OProfile for iSeries, using timer interrupt [POWERPC] support ibm,extended-*-frequency properties [POWERPC] Extra sanity check in EEH code [POWERPC] Dont look for class-code in pci children [POWERPC] Fix mdelay badness on shared processor partitions [POWERPC] disable floating point exceptions for init [POWERPC] Unify ppc syscall tables [POWERPC] mpic: add support for serial mode interrupts [POWERPC] pseries: Print PCI slot location code on failure [POWERPC] spufs: one more fix for 64k pages [POWERPC] spufs: fail spu_create with invalid flags [POWERPC] spufs: clear class2 interrupt status before wakeup [POWERPC] spufs: fix Makefile for "make clean" [POWERPC] spufs: remove stop_code from struct spu [POWERPC] spufs: fix spu irq affinity setting [POWERPC] spufs: further abstract priv1 register access [POWERPC] spufs: split the Cell BE support into generic and platform dependant parts [POWERPC] spufs: dont try to access SPE channel 1 count [POWERPC] spufs: use kzalloc in create_spu [POWERPC] spufs: fix initial state of wbox file ... Manually resolved conflicts in: drivers/net/phy/Makefile include/asm-powerpc/spu.h
Diffstat (limited to 'arch/powerpc/platforms/iseries/iommu.c')
-rw-r--r--arch/powerpc/platforms/iseries/iommu.c46
1 files changed, 25 insertions, 21 deletions
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index bea0b703f40..e3bd2015f2c 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -4,6 +4,7 @@
* Rewrite, cleanup:
*
* Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation
+ * Copyright (C) 2006 Olof Johansson <olof@lixom.net>
*
* Dynamic DMA mapping support, iSeries-specific parts.
*
@@ -31,42 +32,37 @@
#include <asm/tce.h>
#include <asm/machdep.h>
#include <asm/abs_addr.h>
+#include <asm/prom.h>
#include <asm/pci-bridge.h>
#include <asm/iseries/hv_call_xm.h>
-
-#include "iommu.h"
-
-extern struct list_head iSeries_Global_Device_List;
-
+#include <asm/iseries/iommu.h>
static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages,
unsigned long uaddr, enum dma_data_direction direction)
{
u64 rc;
- union tce_entry tce;
+ u64 tce, rpn;
index <<= TCE_PAGE_FACTOR;
npages <<= TCE_PAGE_FACTOR;
while (npages--) {
- tce.te_word = 0;
- tce.te_bits.tb_rpn = virt_to_abs(uaddr) >> TCE_SHIFT;
+ rpn = virt_to_abs(uaddr) >> TCE_SHIFT;
+ tce = (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
if (tbl->it_type == TCE_VB) {
/* Virtual Bus */
- tce.te_bits.tb_valid = 1;
- tce.te_bits.tb_allio = 1;
+ tce |= TCE_VALID|TCE_ALLIO;
if (direction != DMA_TO_DEVICE)
- tce.te_bits.tb_rdwr = 1;
+ tce |= TCE_VB_WRITE;
} else {
/* PCI Bus */
- tce.te_bits.tb_rdwr = 1; /* Read allowed */
+ tce |= TCE_PCI_READ; /* Read allowed */
if (direction != DMA_TO_DEVICE)
- tce.te_bits.tb_pciwr = 1;
+ tce |= TCE_PCI_WRITE;
}
- rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index,
- tce.te_word);
+ rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, tce);
if (rc)
panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n",
rc);
@@ -124,7 +120,7 @@ void iommu_table_getparms_iSeries(unsigned long busno,
/* itc_size is in pages worth of table, it_size is in # of entries */
tbl->it_size = ((parms->itc_size * TCE_PAGE_SIZE) /
- sizeof(union tce_entry)) >> TCE_PAGE_FACTOR;
+ TCE_ENTRY_SIZE) >> TCE_PAGE_FACTOR;
tbl->it_busno = parms->itc_busno;
tbl->it_offset = parms->itc_offset >> TCE_PAGE_FACTOR;
tbl->it_index = parms->itc_index;
@@ -142,10 +138,15 @@ void iommu_table_getparms_iSeries(unsigned long busno,
*/
static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
{
- struct pci_dn *pdn;
+ struct device_node *node;
- list_for_each_entry(pdn, &iSeries_Global_Device_List, Device_List) {
- struct iommu_table *it = pdn->iommu_table;
+ for (node = NULL; (node = of_find_all_nodes(node)); ) {
+ struct pci_dn *pdn = PCI_DN(node);
+ struct iommu_table *it;
+
+ if (pdn == NULL)
+ continue;
+ it = pdn->iommu_table;
if ((it != NULL) &&
(it->it_type == TCE_PCI) &&
(it->it_offset == tbl->it_offset) &&
@@ -161,15 +162,18 @@ void iommu_devnode_init_iSeries(struct device_node *dn)
{
struct iommu_table *tbl;
struct pci_dn *pdn = PCI_DN(dn);
+ u32 *lsn = (u32 *)get_property(dn, "linux,logical-slot-number", NULL);
+
+ BUG_ON(lsn == NULL);
tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
- iommu_table_getparms_iSeries(pdn->busno, pdn->LogicalSlot, 0, tbl);
+ iommu_table_getparms_iSeries(pdn->busno, *lsn, 0, tbl);
/* Look for existing tce table */
pdn->iommu_table = iommu_table_find(tbl);
if (pdn->iommu_table == NULL)
- pdn->iommu_table = iommu_init_table(tbl);
+ pdn->iommu_table = iommu_init_table(tbl, -1);
else
kfree(tbl);
}