Skip to content

Commit

Permalink
[SPARC64]: Probe PCI bus using OF device tree.
Browse files Browse the repository at this point in the history
Almost entirely taken from the 64-bit PowerPC PCI code.

This allowed to eliminate a ton of cruft from the sparc64
PCI layer.

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Apr 26, 2007
1 parent deb66c4 commit a2fb23a
Show file tree
Hide file tree
Showing 10 changed files with 426 additions and 1,063 deletions.
375 changes: 357 additions & 18 deletions arch/sparc64/kernel/pci.c

Large diffs are not rendered by default.

707 changes: 0 additions & 707 deletions arch/sparc64/kernel/pci_common.c

Large diffs are not rendered by default.

15 changes: 1 addition & 14 deletions arch/sparc64/kernel/pci_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,7 @@ extern struct pci_controller_info *pci_controller_root;
extern int pci_num_controllers;

/* PCI bus scanning and fixup support. */
extern void pci_fixup_host_bridge_self(struct pci_bus *pbus);
extern void pci_fill_in_pbm_cookies(struct pci_bus *pbus,
struct pci_pbm_info *pbm,
struct device_node *prom_node);
extern void pci_record_assignments(struct pci_pbm_info *pbm,
struct pci_bus *pbus);
extern void pci_assign_unassigned(struct pci_pbm_info *pbm,
struct pci_bus *pbus);
extern void pci_fixup_irq(struct pci_pbm_info *pbm,
struct pci_bus *pbus);
extern void pci_determine_66mhz_disposition(struct pci_pbm_info *pbm,
struct pci_bus *pbus);
extern void pci_setup_busmastering(struct pci_pbm_info *pbm,
struct pci_bus *pbus);
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);

Expand Down
47 changes: 15 additions & 32 deletions arch/sparc64/kernel/pci_iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,6 @@ static inline void iommu_free_ctx(struct pci_iommu *iommu, int ctx)
*/
static void *pci_4u_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp, gfp_t gfp)
{
struct pcidev_cookie *pcp;
struct pci_iommu *iommu;
iopte_t *iopte;
unsigned long flags, order, first_page;
Expand All @@ -237,8 +236,7 @@ static void *pci_4u_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr
return NULL;
memset((char *)first_page, 0, PAGE_SIZE << order);

pcp = pdev->sysdata;
iommu = pcp->pbm->iommu;
iommu = pdev->dev.archdata.iommu;

spin_lock_irqsave(&iommu->lock, flags);
iopte = alloc_npages(iommu, size >> IO_PAGE_SHIFT);
Expand Down Expand Up @@ -268,14 +266,12 @@ static void *pci_4u_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr
/* Free and unmap a consistent DMA translation. */
static void pci_4u_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_t dvma)
{
struct pcidev_cookie *pcp;
struct pci_iommu *iommu;
iopte_t *iopte;
unsigned long flags, order, npages;

npages = IO_PAGE_ALIGN(size) >> IO_PAGE_SHIFT;
pcp = pdev->sysdata;
iommu = pcp->pbm->iommu;
iommu = pdev->dev.archdata.iommu;
iopte = iommu->page_table +
((dvma - iommu->page_table_map_base) >> IO_PAGE_SHIFT);

Expand All @@ -295,7 +291,6 @@ static void pci_4u_free_consistent(struct pci_dev *pdev, size_t size, void *cpu,
*/
static dma_addr_t pci_4u_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direction)
{
struct pcidev_cookie *pcp;
struct pci_iommu *iommu;
struct pci_strbuf *strbuf;
iopte_t *base;
Expand All @@ -304,9 +299,8 @@ static dma_addr_t pci_4u_map_single(struct pci_dev *pdev, void *ptr, size_t sz,
u32 bus_addr, ret;
unsigned long iopte_protection;

pcp = pdev->sysdata;
iommu = pcp->pbm->iommu;
strbuf = &pcp->pbm->stc;
iommu = pdev->dev.archdata.iommu;
strbuf = pdev->dev.archdata.stc;

if (unlikely(direction == PCI_DMA_NONE))
goto bad_no_ctx;
Expand Down Expand Up @@ -416,7 +410,6 @@ static void pci_strbuf_flush(struct pci_strbuf *strbuf, struct pci_iommu *iommu,
/* Unmap a single streaming mode DMA translation. */
static void pci_4u_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction)
{
struct pcidev_cookie *pcp;
struct pci_iommu *iommu;
struct pci_strbuf *strbuf;
iopte_t *base;
Expand All @@ -428,9 +421,8 @@ static void pci_4u_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_
return;
}

pcp = pdev->sysdata;
iommu = pcp->pbm->iommu;
strbuf = &pcp->pbm->stc;
iommu = pdev->dev.archdata.iommu;
strbuf = pdev->dev.archdata.stc;

npages = IO_PAGE_ALIGN(bus_addr + sz) - (bus_addr & IO_PAGE_MASK);
npages >>= IO_PAGE_SHIFT;
Expand Down Expand Up @@ -549,7 +541,6 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg,
*/
static int pci_4u_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction)
{
struct pcidev_cookie *pcp;
struct pci_iommu *iommu;
struct pci_strbuf *strbuf;
unsigned long flags, ctx, npages, iopte_protection;
Expand All @@ -570,9 +561,8 @@ static int pci_4u_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int n
return 1;
}

pcp = pdev->sysdata;
iommu = pcp->pbm->iommu;
strbuf = &pcp->pbm->stc;
iommu = pdev->dev.archdata.iommu;
strbuf = pdev->dev.archdata.stc;

if (unlikely(direction == PCI_DMA_NONE))
goto bad_no_ctx;
Expand Down Expand Up @@ -636,7 +626,6 @@ static int pci_4u_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int n
/* Unmap a set of streaming mode DMA translations. */
static void pci_4u_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction)
{
struct pcidev_cookie *pcp;
struct pci_iommu *iommu;
struct pci_strbuf *strbuf;
iopte_t *base;
Expand All @@ -648,9 +637,8 @@ static void pci_4u_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, in
WARN_ON(1);
}

pcp = pdev->sysdata;
iommu = pcp->pbm->iommu;
strbuf = &pcp->pbm->stc;
iommu = pdev->dev.archdata.iommu;
strbuf = pdev->dev.archdata.stc;

bus_addr = sglist->dma_address & IO_PAGE_MASK;

Expand Down Expand Up @@ -696,14 +684,12 @@ static void pci_4u_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, in
*/
static void pci_4u_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction)
{
struct pcidev_cookie *pcp;
struct pci_iommu *iommu;
struct pci_strbuf *strbuf;
unsigned long flags, ctx, npages;

pcp = pdev->sysdata;
iommu = pcp->pbm->iommu;
strbuf = &pcp->pbm->stc;
iommu = pdev->dev.archdata.iommu;
strbuf = pdev->dev.archdata.stc;

if (!strbuf->strbuf_enabled)
return;
Expand Down Expand Up @@ -736,15 +722,13 @@ static void pci_4u_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_
*/
static void pci_4u_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction)
{
struct pcidev_cookie *pcp;
struct pci_iommu *iommu;
struct pci_strbuf *strbuf;
unsigned long flags, ctx, npages, i;
u32 bus_addr;

pcp = pdev->sysdata;
iommu = pcp->pbm->iommu;
strbuf = &pcp->pbm->stc;
iommu = pdev->dev.archdata.iommu;
strbuf = pdev->dev.archdata.stc;

if (!strbuf->strbuf_enabled)
return;
Expand Down Expand Up @@ -809,13 +793,12 @@ static void ali_sound_dma_hack(struct pci_dev *pdev, int set_bit)

int pci_dma_supported(struct pci_dev *pdev, u64 device_mask)
{
struct pcidev_cookie *pcp = pdev->sysdata;
u64 dma_addr_mask;

if (pdev == NULL) {
dma_addr_mask = 0xffffffff;
} else {
struct pci_iommu *iommu = pcp->pbm->iommu;
struct pci_iommu *iommu = pdev->dev.archdata.iommu;

dma_addr_mask = iommu->dma_addr_mask;

Expand Down
26 changes: 2 additions & 24 deletions arch/sparc64/kernel/pci_psycho.c
Original file line number Diff line number Diff line change
Expand Up @@ -905,8 +905,7 @@ static void psycho_resource_adjust(struct pci_dev *pdev,

static void psycho_base_address_update(struct pci_dev *pdev, int resource)
{
struct pcidev_cookie *pcp = pdev->sysdata;
struct pci_pbm_info *pbm = pcp->pbm;
struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller;
struct resource *res, *root;
u32 reg;
int where, size, is_64bit;
Expand Down Expand Up @@ -968,28 +967,7 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm)
static void pbm_scan_bus(struct pci_controller_info *p,
struct pci_pbm_info *pbm)
{
struct pcidev_cookie *cookie = kzalloc(sizeof(*cookie), GFP_KERNEL);

if (!cookie) {
prom_printf("PSYCHO: Critical allocation failure.\n");
prom_halt();
}

/* All we care about is the PBM. */
cookie->pbm = pbm;

pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno,
p->pci_ops,
pbm);
pci_fixup_host_bridge_self(pbm->pci_bus);
pbm->pci_bus->self->sysdata = cookie;

pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node);
pci_record_assignments(pbm, pbm->pci_bus);
pci_assign_unassigned(pbm, pbm->pci_bus);
pci_fixup_irq(pbm, pbm->pci_bus);
pci_determine_66mhz_disposition(pbm, pbm->pci_bus);
pci_setup_busmastering(pbm, pbm->pci_bus);
pbm->pci_bus = pci_scan_one_pbm(pbm);
}

static void psycho_scan_bus(struct pci_controller_info *p)
Expand Down
53 changes: 8 additions & 45 deletions arch/sparc64/kernel/pci_sabre.c
Original file line number Diff line number Diff line change
Expand Up @@ -710,17 +710,17 @@ static irqreturn_t sabre_pcierr_intr_other(struct pci_controller_info *p)
p->index);
ret = IRQ_HANDLED;
}
pci_read_config_word(sabre_root_bus->self,
PCI_STATUS, &stat);
pci_bus_read_config_word(sabre_root_bus, 0,
PCI_STATUS, &stat);
if (stat & (PCI_STATUS_PARITY |
PCI_STATUS_SIG_TARGET_ABORT |
PCI_STATUS_REC_TARGET_ABORT |
PCI_STATUS_REC_MASTER_ABORT |
PCI_STATUS_SIG_SYSTEM_ERROR)) {
printk("SABRE%d: PCI bus error, PCI_STATUS[%04x]\n",
p->index, stat);
pci_write_config_word(sabre_root_bus->self,
PCI_STATUS, 0xffff);
pci_bus_write_config_word(sabre_root_bus, 0,
PCI_STATUS, 0xffff);
ret = IRQ_HANDLED;
}
return ret;
Expand Down Expand Up @@ -887,8 +887,7 @@ static void sabre_resource_adjust(struct pci_dev *pdev,

static void sabre_base_address_update(struct pci_dev *pdev, int resource)
{
struct pcidev_cookie *pcp = pdev->sysdata;
struct pci_pbm_info *pbm = pcp->pbm;
struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller;
struct resource *res;
unsigned long base;
u32 reg;
Expand Down Expand Up @@ -978,27 +977,11 @@ static void apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus)
}
}

static struct pcidev_cookie *alloc_bridge_cookie(struct pci_pbm_info *pbm)
{
struct pcidev_cookie *cookie = kzalloc(sizeof(*cookie), GFP_KERNEL);

if (!cookie) {
prom_printf("SABRE: Critical allocation failure.\n");
prom_halt();
}

/* All we care about is the PBM. */
cookie->pbm = pbm;

return cookie;
}

static void sabre_scan_bus(struct pci_controller_info *p)
{
static int once;
struct pci_bus *sabre_bus, *pbus;
struct pci_pbm_info *pbm;
struct pcidev_cookie *cookie;
int sabres_scanned;

/* The APB bridge speaks to the Sabre host PCI bridge
Expand All @@ -1020,13 +1003,9 @@ static void sabre_scan_bus(struct pci_controller_info *p)
}
once++;

cookie = alloc_bridge_cookie(&p->pbm_A);

sabre_bus = pci_scan_bus(p->pci_first_busno,
p->pci_ops,
&p->pbm_A);
pci_fixup_host_bridge_self(sabre_bus);
sabre_bus->self->sysdata = cookie;
sabre_bus = pci_scan_one_pbm(&p->pbm_A);
if (!sabre_bus)
return;

sabre_root_bus = sabre_bus;

Expand All @@ -1043,32 +1022,16 @@ static void sabre_scan_bus(struct pci_controller_info *p)
} else
continue;

cookie = alloc_bridge_cookie(pbm);
pbus->self->sysdata = cookie;

sabres_scanned++;

pbus->sysdata = pbm;
pbm->pci_bus = pbus;
pci_fill_in_pbm_cookies(pbus, pbm, pbm->prom_node);
pci_record_assignments(pbm, pbus);
pci_assign_unassigned(pbm, pbus);
pci_fixup_irq(pbm, pbus);
pci_determine_66mhz_disposition(pbm, pbus);
pci_setup_busmastering(pbm, pbus);
}

if (!sabres_scanned) {
/* Hummingbird, no APBs. */
pbm = &p->pbm_A;
sabre_bus->sysdata = pbm;
pbm->pci_bus = sabre_bus;
pci_fill_in_pbm_cookies(sabre_bus, pbm, pbm->prom_node);
pci_record_assignments(pbm, sabre_bus);
pci_assign_unassigned(pbm, sabre_bus);
pci_fixup_irq(pbm, sabre_bus);
pci_determine_66mhz_disposition(pbm, sabre_bus);
pci_setup_busmastering(pbm, sabre_bus);
}

sabre_register_error_handlers(p);
Expand Down
26 changes: 2 additions & 24 deletions arch/sparc64/kernel/pci_schizo.c
Original file line number Diff line number Diff line change
Expand Up @@ -1232,28 +1232,7 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm)
static void pbm_scan_bus(struct pci_controller_info *p,
struct pci_pbm_info *pbm)
{
struct pcidev_cookie *cookie = kzalloc(sizeof(*cookie), GFP_KERNEL);

if (!cookie) {
prom_printf("%s: Critical allocation failure.\n", pbm->name);
prom_halt();
}

/* All we care about is the PBM. */
cookie->pbm = pbm;

pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno,
p->pci_ops,
pbm);
pci_fixup_host_bridge_self(pbm->pci_bus);
pbm->pci_bus->self->sysdata = cookie;

pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node);
pci_record_assignments(pbm, pbm->pci_bus);
pci_assign_unassigned(pbm, pbm->pci_bus);
pci_fixup_irq(pbm, pbm->pci_bus);
pci_determine_66mhz_disposition(pbm, pbm->pci_bus);
pci_setup_busmastering(pbm, pbm->pci_bus);
pbm->pci_bus = pci_scan_one_pbm(pbm);
}

static void __schizo_scan_bus(struct pci_controller_info *p,
Expand Down Expand Up @@ -1297,8 +1276,7 @@ static void tomatillo_scan_bus(struct pci_controller_info *p)

static void schizo_base_address_update(struct pci_dev *pdev, int resource)
{
struct pcidev_cookie *pcp = pdev->sysdata;
struct pci_pbm_info *pbm = pcp->pbm;
struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller;
struct resource *res, *root;
u32 reg;
int where, size, is_64bit;
Expand Down
Loading

0 comments on commit a2fb23a

Please sign in to comment.