summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-08-27 04:54:04 -0700
committerDavid S. Miller <davem@davemloft.net>2008-08-29 02:15:21 -0700
commit046e26a8ba10b8ceff822f8d91451ab6c1e08c4e (patch)
tree92e95380c0f7f6c5257023a59b88d4221d3f9744 /arch
parent5059625ed8862e897760b86effff0f8a35989c0d (diff)
downloadlwn-046e26a8ba10b8ceff822f8d91451ab6c1e08c4e.tar.gz
lwn-046e26a8ba10b8ceff822f8d91451ab6c1e08c4e.zip
sparc: Remove generic SBUS probing layer.
The individual SBUS IOMMU arch code now sets the IOMMU information directly into the OF device objects. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc/include/asm/io-unit.h2
-rw-r--r--arch/sparc/include/asm/iommu_32.h2
-rw-r--r--arch/sparc/include/asm/irq_64.h1
-rw-r--r--arch/sparc/kernel/ioport.c23
-rw-r--r--arch/sparc/mm/io-unit.c30
-rw-r--r--arch/sparc/mm/iommu.c40
-rw-r--r--arch/sparc64/kernel/sbus.c122
7 files changed, 108 insertions, 112 deletions
diff --git a/arch/sparc/include/asm/io-unit.h b/arch/sparc/include/asm/io-unit.h
index 5df63ef95cf2..96823b47fd45 100644
--- a/arch/sparc/include/asm/io-unit.h
+++ b/arch/sparc/include/asm/io-unit.h
@@ -59,6 +59,4 @@ extern __u32 iounit_map_dma_init(struct sbus_bus *, int);
#define iounit_map_dma_finish(sbus, addr, len) mmu_release_scsi_one(addr, len, sbus)
extern __u32 iounit_map_dma_page(__u32, void *, struct sbus_bus *);
-extern void iounit_init(struct sbus_bus *sbus);
-
#endif /* !(_SPARC_IO_UNIT_H) */
diff --git a/arch/sparc/include/asm/iommu_32.h b/arch/sparc/include/asm/iommu_32.h
index 6b115a174c0c..70c589c05a10 100644
--- a/arch/sparc/include/asm/iommu_32.h
+++ b/arch/sparc/include/asm/iommu_32.h
@@ -118,6 +118,4 @@ static inline void iommu_invalidate_page(struct iommu_regs *regs, unsigned long
regs->pageflush = (ba & PAGE_MASK);
}
-extern void iommu_init(struct device_node *dp, struct sbus_bus *sbus);
-
#endif /* !(_SPARC_IOMMU_H) */
diff --git a/arch/sparc/include/asm/irq_64.h b/arch/sparc/include/asm/irq_64.h
index e3dd9303643d..71673eca3660 100644
--- a/arch/sparc/include/asm/irq_64.h
+++ b/arch/sparc/include/asm/irq_64.h
@@ -56,7 +56,6 @@ extern unsigned int sun4u_build_msi(u32 portid, unsigned int *virt_irq_p,
unsigned long imap_base,
unsigned long iclr_base);
extern void sun4u_destroy_msi(unsigned int virt_irq);
-extern unsigned int sbus_build_irq(void *sbus, unsigned int ino);
extern unsigned char virt_irq_alloc(unsigned int dev_handle,
unsigned int dev_ino);
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 24645f9f56f5..bca2d6fd5c4c 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -377,22 +377,6 @@ void sbus_dma_sync_single_for_device(struct device *dev, dma_addr_t ba, size_t s
{
}
-/* Support code for sbus_init(). */
-void __init sbus_setup_iommu(struct sbus_bus *sbus, struct device_node *dp)
-{
-#ifndef CONFIG_SUN4
- struct device_node *parent = dp->parent;
-
- if (sparc_cpu_model != sun4d &&
- parent != NULL &&
- !strcmp(parent->name, "iommu"))
- iommu_init(parent, sbus);
-
- if (sparc_cpu_model == sun4d)
- iounit_init(sbus);
-#endif
-}
-
static int __init sparc_register_ioport(void)
{
register_proc_sparc_ioport();
@@ -402,13 +386,6 @@ static int __init sparc_register_ioport(void)
arch_initcall(sparc_register_ioport);
-void __init sbus_arch_postinit(void)
-{
- if (sparc_cpu_model == sun4d) {
- extern void sun4d_init_sbi_irq(void);
- sun4d_init_sbi_irq();
- }
-}
#endif /* CONFIG_SBUS */
#ifdef CONFIG_PCI
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c
index 0f97ab30df3f..caf551ad9d8c 100644
--- a/arch/sparc/mm/io-unit.c
+++ b/arch/sparc/mm/io-unit.c
@@ -34,18 +34,10 @@
#define IOPERM (IOUPTE_CACHE | IOUPTE_WRITE | IOUPTE_VALID)
#define MKIOPTE(phys) __iopte((((phys)>>4) & IOUPTE_PAGE) | IOPERM)
-void __init iounit_init(struct sbus_bus *sbus)
+static void __init iounit_iommu_init(struct of_device *op)
{
- struct device_node *dp = sbus->ofdev.node;
struct iounit_struct *iounit;
iopte_t *xpt, *xptend;
- struct of_device *op;
-
- op = of_find_device_by_node(dp);
- if (!op) {
- prom_printf("SUN4D: Cannot find SBI of_device.\n");
- prom_halt();
- }
iounit = kzalloc(sizeof(struct iounit_struct), GFP_ATOMIC);
if (!iounit) {
@@ -66,7 +58,6 @@ void __init iounit_init(struct sbus_bus *sbus)
prom_halt();
}
- sbus->ofdev.dev.archdata.iommu = iounit;
op->dev.archdata.iommu = iounit;
iounit->page_table = xpt;
spin_lock_init(&iounit->lock);
@@ -76,6 +67,25 @@ void __init iounit_init(struct sbus_bus *sbus)
iopte_val(*xpt++) = 0;
}
+static int __init iounit_init(void)
+{
+ extern void sun4d_init_sbi_irq(void);
+ struct device_node *dp;
+
+ for_each_node_by_name(dp, "sbi") {
+ struct of_device *op = of_find_device_by_node(dp);
+
+ iounit_iommu_init(op);
+ of_propagate_archdata(op);
+ }
+
+ sun4d_init_sbi_irq();
+
+ return 0;
+}
+
+subsys_initcall(iounit_init);
+
/* One has to hold iounit->lock to call this */
static unsigned long iounit_get_area(struct iounit_struct *iounit, unsigned long vaddr, int size)
{
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
index 2970cea877b1..7c55450b55b9 100644
--- a/arch/sparc/mm/iommu.c
+++ b/arch/sparc/mm/iommu.c
@@ -55,33 +55,20 @@ static pgprot_t dvma_prot; /* Consistent mapping pte flags */
#define IOPERM (IOPTE_CACHE | IOPTE_WRITE | IOPTE_VALID)
#define MKIOPTE(pfn, perm) (((((pfn)<<8) & IOPTE_PAGE) | (perm)) & ~IOPTE_WAZ)
-void __init iommu_init(struct device_node *parent, struct sbus_bus *sbus)
+static void __init sbus_iommu_init(struct of_device *op)
{
- struct of_device *parent_op, *op;
struct iommu_struct *iommu;
unsigned int impl, vers;
unsigned long *bitmap;
unsigned long tmp;
- parent_op = of_find_device_by_node(parent);
- if (!parent_op) {
- prom_printf("Unable to find IOMMU of_device\n");
- prom_halt();
- }
-
- op = of_find_device_by_node(sbus->ofdev.node);
- if (!op) {
- prom_printf("Unable to find SBUS of_device\n");
- prom_halt();
- }
-
iommu = kmalloc(sizeof(struct iommu_struct), GFP_ATOMIC);
if (!iommu) {
prom_printf("Unable to allocate iommu structure\n");
prom_halt();
}
- iommu->regs = of_ioremap(&parent_op->resource[0], 0, PAGE_SIZE * 3,
+ iommu->regs = of_ioremap(&op->resource[0], 0, PAGE_SIZE * 3,
"iommu_regs");
if (!iommu->regs) {
prom_printf("Cannot map IOMMU registers\n");
@@ -132,14 +119,29 @@ void __init iommu_init(struct device_node *parent, struct sbus_bus *sbus)
else
iommu->usemap.num_colors = 1;
- printk("IOMMU: impl %d vers %d table 0x%p[%d B] map [%d b]\n",
- impl, vers, iommu->page_table,
- (int)(IOMMU_NPTES*sizeof(iopte_t)), (int)IOMMU_NPTES);
+ printk(KERN_INFO "IOMMU: impl %d vers %d table 0x%p[%d B] map [%d b]\n",
+ impl, vers, iommu->page_table,
+ (int)(IOMMU_NPTES*sizeof(iopte_t)), (int)IOMMU_NPTES);
- sbus->ofdev.dev.archdata.iommu = iommu;
op->dev.archdata.iommu = iommu;
}
+static int __init iommu_init(void)
+{
+ struct device_node *dp;
+
+ for_each_node_by_name(dp, "iommu") {
+ struct of_device *op = of_find_device_by_node(dp);
+
+ sbus_iommu_init(op);
+ of_propagate_archdata(op);
+ }
+
+ return 0;
+}
+
+subsys_initcall(iommu_init);
+
/* This begs to be btfixup-ed by srmmu. */
/* Flush the iotlb entries to ram. */
/* This could be better if we didn't have to flush whole pages. */
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c
index 0b3e7bc96f61..60605eaf49bb 100644
--- a/arch/sparc64/kernel/sbus.c
+++ b/arch/sparc64/kernel/sbus.c
@@ -201,10 +201,9 @@ static unsigned long sysio_imap_to_iclr(unsigned long imap)
return imap + diff;
}
-unsigned int sbus_build_irq(void *buscookie, unsigned int ino)
+static unsigned int sbus_build_irq(struct of_device *op, unsigned int ino)
{
- struct sbus_bus *sbus = (struct sbus_bus *)buscookie;
- struct iommu *iommu = sbus->ofdev.dev.archdata.iommu;
+ struct iommu *iommu = op->dev.archdata.iommu;
unsigned long reg_base = iommu->write_complete_reg - 0x2000UL;
unsigned long imap, iclr;
int sbus_level = 0;
@@ -265,12 +264,12 @@ unsigned int sbus_build_irq(void *buscookie, unsigned int ino)
#define SYSIO_UEAFSR_RESV2 0x0000001fffffffffUL /* Reserved */
static irqreturn_t sysio_ue_handler(int irq, void *dev_id)
{
- struct sbus_bus *sbus = dev_id;
- struct iommu *iommu = sbus->ofdev.dev.archdata.iommu;
+ struct of_device *op = dev_id;
+ struct iommu *iommu = op->dev.archdata.iommu;
unsigned long reg_base = iommu->write_complete_reg - 0x2000UL;
unsigned long afsr_reg, afar_reg;
unsigned long afsr, afar, error_bits;
- int reported;
+ int reported, portid;
afsr_reg = reg_base + SYSIO_UE_AFSR;
afar_reg = reg_base + SYSIO_UE_AFAR;
@@ -285,9 +284,11 @@ static irqreturn_t sysio_ue_handler(int irq, void *dev_id)
SYSIO_UEAFSR_SPIO | SYSIO_UEAFSR_SDRD | SYSIO_UEAFSR_SDWR);
upa_writeq(error_bits, afsr_reg);
+ portid = of_getintprop_default(op->node, "portid", -1);
+
/* Log the error. */
printk("SYSIO[%x]: Uncorrectable ECC Error, primary error type[%s]\n",
- sbus->portid,
+ portid,
(((error_bits & SYSIO_UEAFSR_PPIO) ?
"PIO" :
((error_bits & SYSIO_UEAFSR_PDRD) ?
@@ -295,12 +296,12 @@ static irqreturn_t sysio_ue_handler(int irq, void *dev_id)
((error_bits & SYSIO_UEAFSR_PDWR) ?
"DVMA Write" : "???")))));
printk("SYSIO[%x]: DOFF[%lx] SIZE[%lx] MID[%lx]\n",
- sbus->portid,
+ portid,
(afsr & SYSIO_UEAFSR_DOFF) >> 45UL,
(afsr & SYSIO_UEAFSR_SIZE) >> 42UL,
(afsr & SYSIO_UEAFSR_MID) >> 37UL);
- printk("SYSIO[%x]: AFAR[%016lx]\n", sbus->portid, afar);
- printk("SYSIO[%x]: Secondary UE errors [", sbus->portid);
+ printk("SYSIO[%x]: AFAR[%016lx]\n", portid, afar);
+ printk("SYSIO[%x]: Secondary UE errors [", portid);
reported = 0;
if (afsr & SYSIO_UEAFSR_SPIO) {
reported++;
@@ -337,12 +338,12 @@ static irqreturn_t sysio_ue_handler(int irq, void *dev_id)
#define SYSIO_CEAFSR_RESV2 0x0000001fffffffffUL /* Reserved */
static irqreturn_t sysio_ce_handler(int irq, void *dev_id)
{
- struct sbus_bus *sbus = dev_id;
- struct iommu *iommu = sbus->ofdev.dev.archdata.iommu;
+ struct of_device *op = dev_id;
+ struct iommu *iommu = op->dev.archdata.iommu;
unsigned long reg_base = iommu->write_complete_reg - 0x2000UL;
unsigned long afsr_reg, afar_reg;
unsigned long afsr, afar, error_bits;
- int reported;
+ int reported, portid;
afsr_reg = reg_base + SYSIO_CE_AFSR;
afar_reg = reg_base + SYSIO_CE_AFAR;
@@ -357,8 +358,10 @@ static irqreturn_t sysio_ce_handler(int irq, void *dev_id)
SYSIO_CEAFSR_SPIO | SYSIO_CEAFSR_SDRD | SYSIO_CEAFSR_SDWR);
upa_writeq(error_bits, afsr_reg);
+ portid = of_getintprop_default(op->node, "portid", -1);
+
printk("SYSIO[%x]: Correctable ECC Error, primary error type[%s]\n",
- sbus->portid,
+ portid,
(((error_bits & SYSIO_CEAFSR_PPIO) ?
"PIO" :
((error_bits & SYSIO_CEAFSR_PDRD) ?
@@ -370,14 +373,14 @@ static irqreturn_t sysio_ce_handler(int irq, void *dev_id)
* XXX UDB CE trap handler does... -DaveM
*/
printk("SYSIO[%x]: DOFF[%lx] ECC Syndrome[%lx] Size[%lx] MID[%lx]\n",
- sbus->portid,
+ portid,
(afsr & SYSIO_CEAFSR_DOFF) >> 45UL,
(afsr & SYSIO_CEAFSR_ESYND) >> 48UL,
(afsr & SYSIO_CEAFSR_SIZE) >> 42UL,
(afsr & SYSIO_CEAFSR_MID) >> 37UL);
- printk("SYSIO[%x]: AFAR[%016lx]\n", sbus->portid, afar);
+ printk("SYSIO[%x]: AFAR[%016lx]\n", portid, afar);
- printk("SYSIO[%x]: Secondary CE errors [", sbus->portid);
+ printk("SYSIO[%x]: Secondary CE errors [", portid);
reported = 0;
if (afsr & SYSIO_CEAFSR_SPIO) {
reported++;
@@ -414,11 +417,11 @@ static irqreturn_t sysio_ce_handler(int irq, void *dev_id)
#define SYSIO_SBAFSR_RESV3 0x0000001fffffffffUL /* Reserved */
static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id)
{
- struct sbus_bus *sbus = dev_id;
- struct iommu *iommu = sbus->ofdev.dev.archdata.iommu;
+ struct of_device *op = dev_id;
+ struct iommu *iommu = op->dev.archdata.iommu;
unsigned long afsr_reg, afar_reg, reg_base;
unsigned long afsr, afar, error_bits;
- int reported;
+ int reported, portid;
reg_base = iommu->write_complete_reg - 0x2000UL;
afsr_reg = reg_base + SYSIO_SBUS_AFSR;
@@ -433,9 +436,11 @@ static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id)
SYSIO_SBAFSR_SLE | SYSIO_SBAFSR_STO | SYSIO_SBAFSR_SBERR);
upa_writeq(error_bits, afsr_reg);
+ portid = of_getintprop_default(op->node, "portid", -1);
+
/* Log the error. */
printk("SYSIO[%x]: SBUS Error, primary error type[%s] read(%d)\n",
- sbus->portid,
+ portid,
(((error_bits & SYSIO_SBAFSR_PLE) ?
"Late PIO Error" :
((error_bits & SYSIO_SBAFSR_PTO) ?
@@ -444,11 +449,11 @@ static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id)
"Error Ack" : "???")))),
(afsr & SYSIO_SBAFSR_RD) ? 1 : 0);
printk("SYSIO[%x]: size[%lx] MID[%lx]\n",
- sbus->portid,
+ portid,
(afsr & SYSIO_SBAFSR_SIZE) >> 42UL,
(afsr & SYSIO_SBAFSR_MID) >> 37UL);
- printk("SYSIO[%x]: AFAR[%016lx]\n", sbus->portid, afar);
- printk("SYSIO[%x]: Secondary SBUS errors [", sbus->portid);
+ printk("SYSIO[%x]: AFAR[%016lx]\n", portid, afar);
+ printk("SYSIO[%x]: Secondary SBUS errors [", portid);
reported = 0;
if (afsr & SYSIO_SBAFSR_SLE) {
reported++;
@@ -480,34 +485,37 @@ static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id)
#define SYSIO_CE_INO 0x35
#define SYSIO_SBUSERR_INO 0x36
-static void __init sysio_register_error_handlers(struct sbus_bus *sbus)
+static void __init sysio_register_error_handlers(struct of_device *op)
{
- struct iommu *iommu = sbus->ofdev.dev.archdata.iommu;
+ struct iommu *iommu = op->dev.archdata.iommu;
unsigned long reg_base = iommu->write_complete_reg - 0x2000UL;
unsigned int irq;
u64 control;
+ int portid;
+
+ portid = of_getintprop_default(op->node, "portid", -1);
- irq = sbus_build_irq(sbus, SYSIO_UE_INO);
+ irq = sbus_build_irq(op, SYSIO_UE_INO);
if (request_irq(irq, sysio_ue_handler, 0,
- "SYSIO_UE", sbus) < 0) {
+ "SYSIO_UE", op) < 0) {
prom_printf("SYSIO[%x]: Cannot register UE interrupt.\n",
- sbus->portid);
+ portid);
prom_halt();
}
- irq = sbus_build_irq(sbus, SYSIO_CE_INO);
+ irq = sbus_build_irq(op, SYSIO_CE_INO);
if (request_irq(irq, sysio_ce_handler, 0,
- "SYSIO_CE", sbus) < 0) {
+ "SYSIO_CE", op) < 0) {
prom_printf("SYSIO[%x]: Cannot register CE interrupt.\n",
- sbus->portid);
+ portid);
prom_halt();
}
- irq = sbus_build_irq(sbus, SYSIO_SBUSERR_INO);
+ irq = sbus_build_irq(op, SYSIO_SBUSERR_INO);
if (request_irq(irq, sysio_sbus_error_handler, 0,
- "SYSIO_SBERR", sbus) < 0) {
+ "SYSIO_SBERR", op) < 0) {
prom_printf("SYSIO[%x]: Cannot register SBUS Error interrupt.\n",
- sbus->portid);
+ portid);
prom_halt();
}
@@ -523,19 +531,15 @@ static void __init sysio_register_error_handlers(struct sbus_bus *sbus)
}
/* Boot time initialization. */
-static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus)
+static void __init sbus_iommu_init(struct of_device *op)
{
const struct linux_prom64_registers *pr;
- struct device_node *dp;
+ struct device_node *dp = op->node;
struct iommu *iommu;
struct strbuf *strbuf;
unsigned long regs, reg_base;
+ int i, portid;
u64 control;
- int i;
-
- dp = of_find_node_by_phandle(__node);
-
- sbus->portid = of_getintprop_default(dp, "upa-portid", -1);
pr = of_get_property(dp, "reg", NULL);
if (!pr) {
@@ -552,9 +556,9 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus)
if (!strbuf)
goto fatal_memory_error;
- sbus->ofdev.dev.archdata.iommu = iommu;
- sbus->ofdev.dev.archdata.stc = strbuf;
- sbus->ofdev.dev.archdata.numa_node = -1;
+ op->dev.archdata.iommu = iommu;
+ op->dev.archdata.stc = strbuf;
+ op->dev.archdata.numa_node = -1;
reg_base = regs + SYSIO_IOMMUREG_BASE;
iommu->iommu_control = reg_base + IOMMU_CONTROL;
@@ -582,8 +586,9 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus)
*/
iommu->write_complete_reg = regs + 0x2000UL;
- printk("SYSIO: UPA portID %x, at %016lx\n",
- sbus->portid, regs);
+ portid = of_getintprop_default(op->node, "portid", -1);
+ printk(KERN_INFO "SYSIO: UPA portID %x, at %016lx\n",
+ portid, regs);
/* Setup for TSB_SIZE=7, TBW_SIZE=0, MMU_DE=1, MMU_EN=1 */
if (iommu_table_init(iommu, IO_TSB_SIZE, MAP_BASE, 0xffffffff, -1))
@@ -641,23 +646,30 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus)
/* Now some Xfire specific grot... */
if (this_is_starfire)
- starfire_hookup(sbus->portid);
+ starfire_hookup(portid);
- sysio_register_error_handlers(sbus);
+ sysio_register_error_handlers(op);
return;
fatal_memory_error:
prom_printf("sbus_iommu_init: Fatal memory allocation error.\n");
}
-void __init sbus_setup_iommu(struct sbus_bus *sbus, struct device_node *dp)
-{
- sbus_iommu_init(dp->node, sbus);
-}
-
-void __init sbus_arch_postinit(void)
+static int __init sbus_init(void)
{
extern void firetruck_init(void);
+ struct device_node *dp;
+
+ for_each_node_by_name(dp, "sbus") {
+ struct of_device *op = of_find_device_by_node(dp);
+
+ sbus_iommu_init(op);
+ of_propagate_archdata(op);
+ }
firetruck_init();
+
+ return 0;
}
+
+subsys_initcall(sbus_init);