/* * linux/arch/alpha/kernel/core_marvel.c * * Code common to all Marvel based systems. */ #define __EXTERN_INLINE inline #include #include #undef __EXTERN_INLINE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "proto.h" #include "pci_impl.h" /* * Debug helpers */ #define DEBUG_CONFIG 0 #if DEBUG_CONFIG # define DBG_CFG(args) printk args #else # define DBG_CFG(args) #endif /* * Private data */ static struct io7 *io7_head = NULL; /* * Helper functions */ static unsigned long __attribute__ ((unused)) read_ev7_csr(int pe, unsigned long offset) { ev7_csr *ev7csr = EV7_CSR_KERN(pe, offset); unsigned long q; mb(); q = ev7csr->csr; mb(); return q; } static void __attribute__ ((unused)) write_ev7_csr(int pe, unsigned long offset, unsigned long q) { ev7_csr *ev7csr = EV7_CSR_KERN(pe, offset); mb(); ev7csr->csr = q; mb(); } static char * __init mk_resource_name(int pe, int port, char *str) { char tmp[80]; char *name; sprintf(tmp, "PCI %s PE %d PORT %d", str, pe, port); name = alloc_bootmem(strlen(tmp) + 1); strcpy(name, tmp); return name; } inline struct io7 * marvel_next_io7(struct io7 *prev) { return (prev ? prev->next : io7_head); } struct io7 * marvel_find_io7(int pe) { struct io7 *io7; for (io7 = io7_head; io7 && io7->pe != pe; io7 = io7->next) continue; return io7; } static struct io7 * __init alloc_io7(unsigned int pe) { struct io7 *io7; struct io7 *insp; int h; if (marvel_find_io7(pe)) { printk(KERN_WARNING "IO7 at PE %d already allocated!\n", pe); return NULL; } io7 = alloc_bootmem(sizeof(*io7)); io7->pe = pe; spin_lock_init(&io7->irq_lock); for (h = 0; h < 4; h++) { io7->ports[h].io7 = io7; io7->ports[h].port = h; io7->ports[h].enabled = 0; /* default to disabled */ } /* * Insert in pe sorted order. */ if (NULL == io7_head) /* empty list */ io7_head = io7; else if (io7_head->pe > io7->pe) { /* insert at head */ io7->next = io7_head; io7_head = io7; } else { /* insert at position */ for (insp = io7_head; insp; insp = insp->next) { if (insp->pe == io7->pe) { printk(KERN_ERR "Too many IO7s at PE %d\n", io7->pe); return NULL; } if (NULL == insp->next || insp->next->pe > io7->pe) { /* insert here */ io7->next = insp->next; insp->next = io7; break; } } if (NULL == insp) { /* couldn't insert ?!? */ printk(KERN_WARNING "Failed to insert IO7 at PE %d " " - adding at head of list\n", io7->pe); io7->next = io7_head; io7_head = io7; } } return io7; } void io7_clear_errors(struct io7 *io7) { io7_port7_csrs *p7csrs; io7_ioport_csrs *csrs; int port; /* * First the IO ports. */ for (port = 0; port < 4; port++) { csrs = IO7_CSRS_KERN(io7->pe, port); csrs->POx_ERR_SUM.csr = -1UL; csrs->POx_TLB_ERR.csr = -1UL; csrs->POx_SPL_COMPLT.csr = -1UL; csrs->POx_TRANS_SUM.csr = -1UL; } /* * Then the common ones. */ p7csrs = IO7_PORT7_CSRS_KERN(io7->pe); p7csrs->PO7_ERROR_SUM.csr = -1UL; p7csrs->PO7_UNCRR_SYM.csr = -1UL; p7csrs->PO7_CRRCT_SYM.csr = -1UL; } /* * IO7 PCI, PCI/X, AGP configuration. */ static void __init io7_init_hose(struct io7 *io7, int port) { static int hose_index = 0;