[SPARC64]: Consolidate PCI mem/io resource determination.
It can be done for every PCI configuration using OF properties. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
01f94c4a6c
commit
9fd8b64761
|
@ -1,7 +1,6 @@
|
|||
/* $Id: pci_common.c,v 1.29 2002/02/01 00:56:03 davem Exp $
|
||||
* pci_common.c: PCI controller common support.
|
||||
/* pci_common.c: PCI controller common support.
|
||||
*
|
||||
* Copyright (C) 1999 David S. Miller (davem@redhat.com)
|
||||
* Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
|
||||
#include <linux/string.h>
|
||||
|
@ -16,8 +15,8 @@
|
|||
|
||||
#include "pci_impl.h"
|
||||
|
||||
void pci_register_legacy_regions(struct resource *io_res,
|
||||
struct resource *mem_res)
|
||||
static void pci_register_legacy_regions(struct resource *io_res,
|
||||
struct resource *mem_res)
|
||||
{
|
||||
struct resource *p;
|
||||
|
||||
|
@ -53,6 +52,91 @@ void pci_register_legacy_regions(struct resource *io_res,
|
|||
request_resource(mem_res, p);
|
||||
}
|
||||
|
||||
static void pci_register_iommu_region(struct pci_pbm_info *pbm)
|
||||
{
|
||||
u32 *vdma = of_get_property(pbm->prom_node, "virtual-dma", NULL);
|
||||
|
||||
if (vdma) {
|
||||
struct resource *rp = kmalloc(sizeof(*rp), GFP_KERNEL);
|
||||
|
||||
if (!rp) {
|
||||
prom_printf("Cannot allocate IOMMU resource.\n");
|
||||
prom_halt();
|
||||
}
|
||||
rp->name = "IOMMU";
|
||||
rp->start = pbm->mem_space.start + (unsigned long) vdma[0];
|
||||
rp->end = rp->start + (unsigned long) vdma[1] - 1UL;
|
||||
rp->flags = IORESOURCE_BUSY;
|
||||
request_resource(&pbm->mem_space, rp);
|
||||
}
|
||||
}
|
||||
|
||||
void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
|
||||
{
|
||||
int i, saw_mem, saw_io;
|
||||
|
||||
saw_mem = saw_io = 0;
|
||||
for (i = 0; i < pbm->num_pbm_ranges; i++) {
|
||||
struct linux_prom_pci_ranges *pr = &pbm->pbm_ranges[i];
|
||||
unsigned long a;
|
||||
int type;
|
||||
|
||||
type = (pr->child_phys_hi >> 24) & 0x3;
|
||||
a = (((unsigned long)pr->parent_phys_hi << 32UL) |
|
||||
((unsigned long)pr->parent_phys_lo << 0UL));
|
||||
|
||||
switch (type) {
|
||||
case 0:
|
||||
/* PCI config space, 16MB */
|
||||
pbm->config_space = a;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* 16-bit IO space, 16MB */
|
||||
pbm->io_space.start = a;
|
||||
pbm->io_space.end = a + ((16UL*1024UL*1024UL) - 1UL);
|
||||
pbm->io_space.flags = IORESOURCE_IO;
|
||||
saw_io = 1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* 32-bit MEM space, 2GB */
|
||||
pbm->mem_space.start = a;
|
||||
pbm->mem_space.end = a + (0x80000000UL - 1UL);
|
||||
pbm->mem_space.flags = IORESOURCE_MEM;
|
||||
saw_mem = 1;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
/* XXX 64-bit MEM handling XXX */
|
||||
|
||||
default:
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
if (!saw_io || !saw_mem) {
|
||||
prom_printf("%s: Fatal error, missing %s PBM range.\n",
|
||||
pbm->name,
|
||||
(!saw_io ? "IO" : "MEM"));
|
||||
prom_halt();
|
||||
}
|
||||
|
||||
printk("%s: PCI IO[%lx] MEM[%lx]\n",
|
||||
pbm->name,
|
||||
pbm->io_space.start,
|
||||
pbm->mem_space.start);
|
||||
|
||||
pbm->io_space.name = pbm->mem_space.name = pbm->name;
|
||||
|
||||
request_resource(&ioport_resource, &pbm->io_space);
|
||||
request_resource(&iomem_resource, &pbm->mem_space);
|
||||
|
||||
pci_register_legacy_regions(&pbm->io_space,
|
||||
&pbm->mem_space);
|
||||
pci_register_iommu_region(pbm);
|
||||
}
|
||||
|
||||
/* Generic helper routines for PCI error reporting. */
|
||||
void pci_scan_for_target_abort(struct pci_controller_info *p,
|
||||
struct pci_pbm_info *pbm,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* $Id: pci_impl.h,v 1.9 2001/06/13 06:34:30 davem Exp $
|
||||
* pci_impl.h: Helper definitions for PCI controller support.
|
||||
/* pci_impl.h: Helper definitions for PCI controller support.
|
||||
*
|
||||
* Copyright (C) 1999 David S. Miller (davem@redhat.com)
|
||||
* Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
|
||||
#ifndef PCI_IMPL_H
|
||||
|
@ -19,8 +18,7 @@ extern int pci_num_controllers;
|
|||
|
||||
/* PCI bus scanning and fixup support. */
|
||||
extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm);
|
||||
extern void pci_register_legacy_regions(struct resource *io_res,
|
||||
struct resource *mem_res);
|
||||
extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm);
|
||||
|
||||
/* Error reporting support. */
|
||||
extern void pci_scan_for_target_abort(struct pci_controller_info *, struct pci_pbm_info *, struct pci_bus *);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* $Id: pci_psycho.c,v 1.33 2002/02/01 00:58:33 davem Exp $
|
||||
* pci_psycho.c: PSYCHO/U2P specific PCI controller support.
|
||||
/* pci_psycho.c: PSYCHO/U2P specific PCI controller support.
|
||||
*
|
||||
* Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
|
||||
* Copyright (C) 1997, 1998, 1999, 2007 David S. Miller (davem@davemloft.net)
|
||||
* Copyright (C) 1998, 1999 Eddie C. Dost (ecd@skynet.be)
|
||||
* Copyright (C) 1999 Jakub Jelinek (jakub@redhat.com)
|
||||
*/
|
||||
|
@ -1072,19 +1071,6 @@ static void psycho_controller_hwinit(struct pci_controller_info *p)
|
|||
psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIB_DIAG, tmp);
|
||||
}
|
||||
|
||||
static void pbm_register_toplevel_resources(struct pci_controller_info *p,
|
||||
struct pci_pbm_info *pbm)
|
||||
{
|
||||
char *name = pbm->name;
|
||||
|
||||
pbm->io_space.name = pbm->mem_space.name = name;
|
||||
|
||||
request_resource(&ioport_resource, &pbm->io_space);
|
||||
request_resource(&iomem_resource, &pbm->mem_space);
|
||||
pci_register_legacy_regions(&pbm->io_space,
|
||||
&pbm->mem_space);
|
||||
}
|
||||
|
||||
static void psycho_pbm_strbuf_init(struct pci_controller_info *p,
|
||||
struct pci_pbm_info *pbm,
|
||||
int is_pbm_a)
|
||||
|
@ -1155,13 +1141,9 @@ static void psycho_pbm_init(struct pci_controller_info *p,
|
|||
if (is_pbm_a) {
|
||||
pbm = &p->pbm_A;
|
||||
pbm->pci_first_slot = 1;
|
||||
pbm->io_space.start = pbm->controller_regs + PSYCHO_IOSPACE_A;
|
||||
pbm->mem_space.start = pbm->controller_regs + PSYCHO_MEMSPACE_A;
|
||||
} else {
|
||||
pbm = &p->pbm_B;
|
||||
pbm->pci_first_slot = 2;
|
||||
pbm->io_space.start = pbm->controller_regs + PSYCHO_IOSPACE_B;
|
||||
pbm->mem_space.start = pbm->controller_regs + PSYCHO_MEMSPACE_B;
|
||||
}
|
||||
|
||||
pbm->chip_type = PBM_CHIP_TYPE_PSYCHO;
|
||||
|
@ -1174,17 +1156,12 @@ static void psycho_pbm_init(struct pci_controller_info *p,
|
|||
if (prop)
|
||||
pbm->chip_revision = *(int *) prop->value;
|
||||
|
||||
pbm->io_space.end = pbm->io_space.start + PSYCHO_IOSPACE_SIZE;
|
||||
pbm->io_space.flags = IORESOURCE_IO;
|
||||
pbm->mem_space.end = pbm->mem_space.start + PSYCHO_MEMSPACE_SIZE;
|
||||
pbm->mem_space.flags = IORESOURCE_MEM;
|
||||
pci_determine_mem_io_space(pbm);
|
||||
|
||||
pbm->parent = p;
|
||||
pbm->prom_node = dp;
|
||||
pbm->name = dp->full_name;
|
||||
|
||||
pbm_register_toplevel_resources(p, pbm);
|
||||
|
||||
printk("%s: PSYCHO PCI Bus Module ver[%x:%x]\n",
|
||||
pbm->name,
|
||||
pbm->chip_version, pbm->chip_revision);
|
||||
|
|
|
@ -1045,10 +1045,9 @@ static void sabre_iommu_init(struct pci_controller_info *p,
|
|||
sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL, control);
|
||||
}
|
||||
|
||||
static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 dma_start, u32 dma_end)
|
||||
static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp)
|
||||
{
|
||||
struct pci_pbm_info *pbm;
|
||||
struct resource *rp;
|
||||
|
||||
pbm = &p->pbm_A;
|
||||
pbm->name = dp->full_name;
|
||||
|
@ -1061,38 +1060,7 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp
|
|||
pbm->pci_first_busno = p->pci_first_busno;
|
||||
pbm->pci_last_busno = p->pci_last_busno;
|
||||
|
||||
pbm->io_space.name = pbm->mem_space.name = pbm->name;
|
||||
|
||||
pbm->io_space.start = p->pbm_A.controller_regs + SABRE_IOSPACE;
|
||||
pbm->io_space.end = pbm->io_space.start + (1UL << 24) - 1UL;
|
||||
pbm->io_space.flags = IORESOURCE_IO;
|
||||
|
||||
pbm->mem_space.start = (p->pbm_A.controller_regs + SABRE_MEMSPACE);
|
||||
pbm->mem_space.end = (pbm->mem_space.start + ((1UL << 32UL) - 1UL));
|
||||
pbm->mem_space.flags = IORESOURCE_MEM;
|
||||
|
||||
if (request_resource(&ioport_resource, &pbm->io_space) < 0) {
|
||||
prom_printf("Cannot register Sabre's IO space.\n");
|
||||
prom_halt();
|
||||
}
|
||||
if (request_resource(&iomem_resource, &pbm->mem_space) < 0) {
|
||||
prom_printf("Cannot register Sabre's MEM space.\n");
|
||||
prom_halt();
|
||||
}
|
||||
|
||||
rp = kmalloc(sizeof(*rp), GFP_KERNEL);
|
||||
if (!rp) {
|
||||
prom_printf("Cannot allocate IOMMU resource.\n");
|
||||
prom_halt();
|
||||
}
|
||||
rp->name = "IOMMU";
|
||||
rp->start = pbm->mem_space.start + (unsigned long) dma_start;
|
||||
rp->end = pbm->mem_space.start + (unsigned long) dma_end - 1UL;
|
||||
rp->flags = IORESOURCE_BUSY;
|
||||
request_resource(&pbm->mem_space, rp);
|
||||
|
||||
pci_register_legacy_regions(&pbm->io_space,
|
||||
&pbm->mem_space);
|
||||
pci_determine_mem_io_space(pbm);
|
||||
}
|
||||
|
||||
void sabre_init(struct device_node *dp, char *model_name)
|
||||
|
@ -1212,5 +1180,5 @@ void sabre_init(struct device_node *dp, char *model_name)
|
|||
/*
|
||||
* Look for APB underneath.
|
||||
*/
|
||||
sabre_pbm_init(p, dp, vdma[0], vdma[0] + vdma[1]);
|
||||
sabre_pbm_init(p, dp);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* $Id: pci_schizo.c,v 1.24 2002/01/23 11:27:32 davem Exp $
|
||||
* pci_schizo.c: SCHIZO/TOMATILLO specific PCI controller support.
|
||||
/* pci_schizo.c: SCHIZO/TOMATILLO specific PCI controller support.
|
||||
*
|
||||
* Copyright (C) 2001, 2002, 2003 David S. Miller (davem@redhat.com)
|
||||
* Copyright (C) 2001, 2002, 2003, 2007 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
@ -1304,79 +1303,6 @@ static void schizo_resource_adjust(struct pci_dev *pdev,
|
|||
res->end += root->start;
|
||||
}
|
||||
|
||||
/* Use ranges property to determine where PCI MEM, I/O, and Config
|
||||
* space are for this PCI bus module.
|
||||
*/
|
||||
static void schizo_determine_mem_io_space(struct pci_pbm_info *pbm)
|
||||
{
|
||||
int i, saw_cfg, saw_mem, saw_io;
|
||||
|
||||
saw_cfg = saw_mem = saw_io = 0;
|
||||
for (i = 0; i < pbm->num_pbm_ranges; i++) {
|
||||
struct linux_prom_pci_ranges *pr = &pbm->pbm_ranges[i];
|
||||
unsigned long a;
|
||||
int type;
|
||||
|
||||
type = (pr->child_phys_hi >> 24) & 0x3;
|
||||
a = (((unsigned long)pr->parent_phys_hi << 32UL) |
|
||||
((unsigned long)pr->parent_phys_lo << 0UL));
|
||||
|
||||
switch (type) {
|
||||
case 0:
|
||||
/* PCI config space, 16MB */
|
||||
pbm->config_space = a;
|
||||
saw_cfg = 1;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* 16-bit IO space, 16MB */
|
||||
pbm->io_space.start = a;
|
||||
pbm->io_space.end = a + ((16UL*1024UL*1024UL) - 1UL);
|
||||
pbm->io_space.flags = IORESOURCE_IO;
|
||||
saw_io = 1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* 32-bit MEM space, 2GB */
|
||||
pbm->mem_space.start = a;
|
||||
pbm->mem_space.end = a + (0x80000000UL - 1UL);
|
||||
pbm->mem_space.flags = IORESOURCE_MEM;
|
||||
saw_mem = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
if (!saw_cfg || !saw_io || !saw_mem) {
|
||||
prom_printf("%s: Fatal error, missing %s PBM range.\n",
|
||||
pbm->name,
|
||||
((!saw_cfg ?
|
||||
"CFG" :
|
||||
(!saw_io ?
|
||||
"IO" : "MEM"))));
|
||||
prom_halt();
|
||||
}
|
||||
|
||||
printk("%s: PCI CFG[%lx] IO[%lx] MEM[%lx]\n",
|
||||
pbm->name,
|
||||
pbm->config_space,
|
||||
pbm->io_space.start,
|
||||
pbm->mem_space.start);
|
||||
}
|
||||
|
||||
static void pbm_register_toplevel_resources(struct pci_controller_info *p,
|
||||
struct pci_pbm_info *pbm)
|
||||
{
|
||||
pbm->io_space.name = pbm->mem_space.name = pbm->name;
|
||||
|
||||
request_resource(&ioport_resource, &pbm->io_space);
|
||||
request_resource(&iomem_resource, &pbm->mem_space);
|
||||
pci_register_legacy_regions(&pbm->io_space,
|
||||
&pbm->mem_space);
|
||||
}
|
||||
|
||||
#define SCHIZO_STRBUF_CONTROL (0x02800UL)
|
||||
#define SCHIZO_STRBUF_FLUSH (0x02808UL)
|
||||
#define SCHIZO_STRBUF_FSYNC (0x02810UL)
|
||||
|
@ -1679,8 +1605,7 @@ static void schizo_pbm_init(struct pci_controller_info *p,
|
|||
pbm->num_pbm_ranges =
|
||||
(len / sizeof(struct linux_prom_pci_ranges));
|
||||
|
||||
schizo_determine_mem_io_space(pbm);
|
||||
pbm_register_toplevel_resources(p, pbm);
|
||||
pci_determine_mem_io_space(pbm);
|
||||
|
||||
pbm->pbm_intmap = of_get_property(dp, "interrupt-map", &len);
|
||||
if (pbm->pbm_intmap) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pci_sun4v.c: SUN4V specific PCI controller support.
|
||||
*
|
||||
* Copyright (C) 2006 David S. Miller (davem@davemloft.net)
|
||||
* Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
@ -751,72 +751,6 @@ static void pci_sun4v_resource_adjust(struct pci_dev *pdev,
|
|||
res->end += root->start;
|
||||
}
|
||||
|
||||
/* Use ranges property to determine where PCI MEM, I/O, and Config
|
||||
* space are for this PCI bus module.
|
||||
*/
|
||||
static void pci_sun4v_determine_mem_io_space(struct pci_pbm_info *pbm)
|
||||
{
|
||||
int i, saw_mem, saw_io;
|
||||
|
||||
saw_mem = saw_io = 0;
|
||||
for (i = 0; i < pbm->num_pbm_ranges; i++) {
|
||||
struct linux_prom_pci_ranges *pr = &pbm->pbm_ranges[i];
|
||||
unsigned long a;
|
||||
int type;
|
||||
|
||||
type = (pr->child_phys_hi >> 24) & 0x3;
|
||||
a = (((unsigned long)pr->parent_phys_hi << 32UL) |
|
||||
((unsigned long)pr->parent_phys_lo << 0UL));
|
||||
|
||||
switch (type) {
|
||||
case 1:
|
||||
/* 16-bit IO space, 16MB */
|
||||
pbm->io_space.start = a;
|
||||
pbm->io_space.end = a + ((16UL*1024UL*1024UL) - 1UL);
|
||||
pbm->io_space.flags = IORESOURCE_IO;
|
||||
saw_io = 1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* 32-bit MEM space, 2GB */
|
||||
pbm->mem_space.start = a;
|
||||
pbm->mem_space.end = a + (0x80000000UL - 1UL);
|
||||
pbm->mem_space.flags = IORESOURCE_MEM;
|
||||
saw_mem = 1;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
/* XXX 64-bit MEM handling XXX */
|
||||
|
||||
default:
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
if (!saw_io || !saw_mem) {
|
||||
prom_printf("%s: Fatal error, missing %s PBM range.\n",
|
||||
pbm->name,
|
||||
(!saw_io ? "IO" : "MEM"));
|
||||
prom_halt();
|
||||
}
|
||||
|
||||
printk("%s: PCI IO[%lx] MEM[%lx]\n",
|
||||
pbm->name,
|
||||
pbm->io_space.start,
|
||||
pbm->mem_space.start);
|
||||
}
|
||||
|
||||
static void pbm_register_toplevel_resources(struct pci_controller_info *p,
|
||||
struct pci_pbm_info *pbm)
|
||||
{
|
||||
pbm->io_space.name = pbm->mem_space.name = pbm->name;
|
||||
|
||||
request_resource(&ioport_resource, &pbm->io_space);
|
||||
request_resource(&iomem_resource, &pbm->mem_space);
|
||||
pci_register_legacy_regions(&pbm->io_space,
|
||||
&pbm->mem_space);
|
||||
}
|
||||
|
||||
static unsigned long probe_existing_entries(struct pci_pbm_info *pbm,
|
||||
struct pci_iommu *iommu)
|
||||
{
|
||||
|
@ -1396,8 +1330,7 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node
|
|||
for (i = 0; i < pbm->num_pbm_ranges; i++)
|
||||
pbm->pbm_ranges[i].parent_phys_hi &= 0x0fffffff;
|
||||
|
||||
pci_sun4v_determine_mem_io_space(pbm);
|
||||
pbm_register_toplevel_resources(p, pbm);
|
||||
pci_determine_mem_io_space(pbm);
|
||||
|
||||
prop = of_find_property(dp, "interrupt-map", &len);
|
||||
pbm->pbm_intmap = prop->value;
|
||||
|
|
Loading…
Reference in a new issue