You need to sign in or sign up before continuing.
提交 912b2539 编写于 作者: L Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc

* git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc:
  powerpc: add defconfig for Freescale MPC8349E-mITX board
  powerpc: Add base support for the Freescale MPC8349E-mITX eval board
  Documentation: correct values in MPC8548E SEC example node
  [POWERPC] Actually copy over i8259.c to arch/ppc/syslib this time
  [POWERPC] Add new interrupt mapping core and change platforms to use it
  [POWERPC] Copy i8259 code back to arch/ppc
  [POWERPC] New device-tree interrupt parsing code
  [POWERPC] Use the genirq framework
  [PATCH] genirq: Allow fasteoi handler to retrigger disabled interrupts
  [POWERPC] Update the SWIM3 (powermac) floppy driver
  [POWERPC] Fix error handling in detecting legacy serial ports
  [POWERPC] Fix booting on Momentum "Apache" board (a Maple derivative)
  [POWERPC] Fix various offb and BootX-related issues
  [POWERPC] Add a default config for 32-bit CHRP machines
  [POWERPC] fix implicit declaration on cell.
  [POWERPC] change get_property to return void *
......@@ -1436,9 +1436,9 @@ platforms are moved over to use the flattened-device-tree model.
interrupts = <1d 3>;
interrupt-parent = <40000>;
num-channels = <4>;
channel-fifo-len = <24>;
channel-fifo-len = <18>;
exec-units-mask = <000000fe>;
descriptor-types-mask = <073f1127>;
descriptor-types-mask = <012b0ebf>;
};
......
此差异已折叠。
此差异已折叠。
......@@ -111,7 +111,7 @@ void __init btext_setup_display(int width, int height, int depth, int pitch,
logicalDisplayBase = (unsigned char *)address;
dispDeviceBase = (unsigned char *)address;
dispDeviceRowBytes = pitch;
dispDeviceDepth = depth;
dispDeviceDepth = depth == 15 ? 16 : depth;
dispDeviceRect[0] = dispDeviceRect[1] = 0;
dispDeviceRect[2] = width;
dispDeviceRect[3] = height;
......@@ -160,20 +160,28 @@ int btext_initialize(struct device_node *np)
unsigned long address = 0;
u32 *prop;
prop = (u32 *)get_property(np, "width", NULL);
prop = (u32 *)get_property(np, "linux,bootx-width", NULL);
if (prop == NULL)
prop = (u32 *)get_property(np, "width", NULL);
if (prop == NULL)
return -EINVAL;
width = *prop;
prop = (u32 *)get_property(np, "height", NULL);
prop = (u32 *)get_property(np, "linux,bootx-height", NULL);
if (prop == NULL)
prop = (u32 *)get_property(np, "height", NULL);
if (prop == NULL)
return -EINVAL;
height = *prop;
prop = (u32 *)get_property(np, "depth", NULL);
prop = (u32 *)get_property(np, "linux,bootx-depth", NULL);
if (prop == NULL)
prop = (u32 *)get_property(np, "depth", NULL);
if (prop == NULL)
return -EINVAL;
depth = *prop;
pitch = width * ((depth + 7) / 8);
prop = (u32 *)get_property(np, "linebytes", NULL);
prop = (u32 *)get_property(np, "linux,bootx-linebytes", NULL);
if (prop == NULL)
prop = (u32 *)get_property(np, "linebytes", NULL);
if (prop)
pitch = *prop;
if (pitch == 1)
......@@ -194,7 +202,7 @@ int btext_initialize(struct device_node *np)
g_max_loc_Y = height / 16;
dispDeviceBase = (unsigned char *)address;
dispDeviceRowBytes = pitch;
dispDeviceDepth = depth;
dispDeviceDepth = depth == 15 ? 16 : depth;
dispDeviceRect[0] = dispDeviceRect[1] = 0;
dispDeviceRect[2] = width;
dispDeviceRect[3] = height;
......
......@@ -323,13 +323,11 @@ int ibmebus_request_irq(struct ibmebus_dev *dev,
unsigned long irq_flags, const char * devname,
void *dev_id)
{
unsigned int irq = virt_irq_create_mapping(ist);
unsigned int irq = irq_create_mapping(NULL, ist, 0);
if (irq == NO_IRQ)
return -EINVAL;
irq = irq_offset_up(irq);
return request_irq(irq, handler,
irq_flags, devname, dev_id);
}
......@@ -337,12 +335,9 @@ EXPORT_SYMBOL(ibmebus_request_irq);
void ibmebus_free_irq(struct ibmebus_dev *dev, u32 ist, void *dev_id)
{
unsigned int irq = virt_irq_create_mapping(ist);
unsigned int irq = irq_find_mapping(NULL, ist);
irq = irq_offset_up(irq);
free_irq(irq, dev_id);
return;
}
EXPORT_SYMBOL(ibmebus_free_irq);
......
此差异已折叠。
......@@ -28,6 +28,7 @@ static struct legacy_serial_info {
struct device_node *np;
unsigned int speed;
unsigned int clock;
int irq_check_parent;
phys_addr_t taddr;
} legacy_serial_infos[MAX_LEGACY_SERIAL_PORTS];
static unsigned int legacy_serial_count;
......@@ -36,7 +37,7 @@ static int legacy_serial_console = -1;
static int __init add_legacy_port(struct device_node *np, int want_index,
int iotype, phys_addr_t base,
phys_addr_t taddr, unsigned long irq,
upf_t flags)
upf_t flags, int irq_check_parent)
{
u32 *clk, *spd, clock = BASE_BAUD * 16;
int index;
......@@ -68,7 +69,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
if (legacy_serial_infos[index].np != 0) {
/* if we still have some room, move it, else override */
if (legacy_serial_count < MAX_LEGACY_SERIAL_PORTS) {
printk(KERN_INFO "Moved legacy port %d -> %d\n",
printk(KERN_DEBUG "Moved legacy port %d -> %d\n",
index, legacy_serial_count);
legacy_serial_ports[legacy_serial_count] =
legacy_serial_ports[index];
......@@ -76,7 +77,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
legacy_serial_infos[index];
legacy_serial_count++;
} else {
printk(KERN_INFO "Replacing legacy port %d\n", index);
printk(KERN_DEBUG "Replacing legacy port %d\n", index);
}
}
......@@ -95,10 +96,11 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
legacy_serial_infos[index].np = of_node_get(np);
legacy_serial_infos[index].clock = clock;
legacy_serial_infos[index].speed = spd ? *spd : 0;
legacy_serial_infos[index].irq_check_parent = irq_check_parent;
printk(KERN_INFO "Found legacy serial port %d for %s\n",
printk(KERN_DEBUG "Found legacy serial port %d for %s\n",
index, np->full_name);
printk(KERN_INFO " %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n",
printk(KERN_DEBUG " %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n",
(iotype == UPIO_PORT) ? "port" : "mem",
(unsigned long long)base, (unsigned long long)taddr, irq,
legacy_serial_ports[index].uartclk,
......@@ -126,11 +128,13 @@ static int __init add_legacy_soc_port(struct device_node *np,
return -1;
addr = of_translate_address(soc_dev, addrp);
if (addr == OF_BAD_ADDR)
return -1;
/* Add port, irq will be dealt with later. We passed a translated
* IO port value. It will be fixed up later along with the irq
*/
return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags);
return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags, 0);
}
static int __init add_legacy_isa_port(struct device_node *np,
......@@ -141,6 +145,8 @@ static int __init add_legacy_isa_port(struct device_node *np,
int index = -1;
phys_addr_t taddr;
DBG(" -> add_legacy_isa_port(%s)\n", np->full_name);
/* Get the ISA port number */
reg = (u32 *)get_property(np, "reg", NULL);
if (reg == NULL)
......@@ -161,9 +167,12 @@ static int __init add_legacy_isa_port(struct device_node *np,
/* Translate ISA address */
taddr = of_translate_address(np, reg);
if (taddr == OF_BAD_ADDR)
return -1;
/* Add port, irq will be dealt with later */
return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr, NO_IRQ, UPF_BOOT_AUTOCONF);
return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr,
NO_IRQ, UPF_BOOT_AUTOCONF, 0);
}
......@@ -176,6 +185,8 @@ static int __init add_legacy_pci_port(struct device_node *np,
unsigned int flags;
int iotype, index = -1, lindex = 0;
DBG(" -> add_legacy_pci_port(%s)\n", np->full_name);
/* We only support ports that have a clock frequency properly
* encoded in the device-tree (that is have an fcode). Anything
* else can't be used that early and will be normally probed by
......@@ -194,6 +205,8 @@ static int __init add_legacy_pci_port(struct device_node *np,
/* We only support BAR 0 for now */
iotype = (flags & IORESOURCE_MEM) ? UPIO_MEM : UPIO_PORT;
addr = of_translate_address(pci_dev, addrp);
if (addr == OF_BAD_ADDR)
return -1;
/* Set the IO base to the same as the translated address for MMIO,
* or to the domain local IO base for PIO (it will be fixed up later)
......@@ -231,7 +244,8 @@ static int __init add_legacy_pci_port(struct device_node *np,
/* Add port, irq will be dealt with later. We passed a translated
* IO port value. It will be fixed up later along with the irq
*/
return add_legacy_port(np, index, iotype, base, addr, NO_IRQ, UPF_BOOT_AUTOCONF);
return add_legacy_port(np, index, iotype, base, addr, NO_IRQ,
UPF_BOOT_AUTOCONF, np != pci_dev);
}
#endif
......@@ -362,27 +376,22 @@ static void __init fixup_port_irq(int index,
struct device_node *np,
struct plat_serial8250_port *port)
{
unsigned int virq;
DBG("fixup_port_irq(%d)\n", index);
/* Check for interrupts in that node */
if (np->n_intrs > 0) {
port->irq = np->intrs[0].line;
DBG(" port %d (%s), irq=%d\n",
index, np->full_name, port->irq);
return;
virq = irq_of_parse_and_map(np, 0);
if (virq == NO_IRQ && legacy_serial_infos[index].irq_check_parent) {
np = of_get_parent(np);
if (np == NULL)
return;
virq = irq_of_parse_and_map(np, 0);
of_node_put(np);
}
/* Check for interrupts in the parent */
np = of_get_parent(np);
if (np == NULL)
if (virq == NO_IRQ)
return;
if (np->n_intrs > 0) {
port->irq = np->intrs[0].line;
DBG(" port %d (%s), irq=%d\n",
index, np->full_name, port->irq);
}
of_node_put(np);
port->irq = virq;
}
static void __init fixup_port_pio(int index,
......
......@@ -51,12 +51,14 @@ _GLOBAL(call_do_softirq)
mtlr r0
blr
_GLOBAL(call___do_IRQ)
_GLOBAL(call_handle_irq)
ld r8,0(r7)
mflr r0
std r0,16(r1)
stdu r1,THREAD_SIZE-112(r5)
mr r1,r5
bl .__do_IRQ
mtctr r8
stdu r1,THREAD_SIZE-112(r6)
mr r1,r6
bctrl
ld r1,0(r1)
ld r0,16(r1)
mtlr r0
......
......@@ -1404,6 +1404,43 @@ pcibios_update_irq(struct pci_dev *dev, int irq)
/* XXX FIXME - update OF device tree node interrupt property */
}
#ifdef CONFIG_PPC_MERGE
/* XXX This is a copy of the ppc64 version. This is temporary until we start
* merging the 2 PCI layers
*/
/*
* Reads the interrupt pin to determine if interrupt is use by card.
* If the interrupt is used, then gets the interrupt line from the
* openfirmware and sets it in the pci_dev and pci_config line.
*/
int pci_read_irq_line(struct pci_dev *pci_dev)
{
struct of_irq oirq;
unsigned int virq;
DBG("Try to map irq for %s...\n", pci_name(pci_dev));
if (of_irq_map_pci(pci_dev, &oirq)) {
DBG(" -> failed !\n");
return -1;
}
DBG(" -> got one, spec %d cells (0x%08x...) on %s\n",
oirq.size, oirq.specifier[0], oirq.controller->full_name);
virq = irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size);
if(virq == NO_IRQ) {
DBG(" -> failed to map !\n");
return -1;
}
pci_dev->irq = virq;
pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, virq);
return 0;
}
EXPORT_SYMBOL(pci_read_irq_line);
#endif /* CONFIG_PPC_MERGE */
int pcibios_enable_device(struct pci_dev *dev, int mask)
{
u16 cmd, old_cmd;
......
......@@ -398,12 +398,8 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
} else {
dev->hdr_type = PCI_HEADER_TYPE_NORMAL;
dev->rom_base_reg = PCI_ROM_ADDRESS;
/* Maybe do a default OF mapping here */
dev->irq = NO_IRQ;
if (node->n_intrs > 0) {
dev->irq = node->intrs[0].line;
pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
dev->irq);
}
}
pci_parse_of_addrs(node, dev);
......@@ -1288,23 +1284,26 @@ EXPORT_SYMBOL(pcibios_fixup_bus);
*/
int pci_read_irq_line(struct pci_dev *pci_dev)
{
u8 intpin;
struct device_node *node;
pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &intpin);
if (intpin == 0)
return 0;
struct of_irq oirq;
unsigned int virq;
node = pci_device_to_OF_node(pci_dev);
if (node == NULL)
return -1;
DBG("Try to map irq for %s...\n", pci_name(pci_dev));
if (node->n_intrs == 0)
if (of_irq_map_pci(pci_dev, &oirq)) {
DBG(" -> failed !\n");
return -1;
}
pci_dev->irq = node->intrs[0].line;
DBG(" -> got one, spec %d cells (0x%08x...) on %s\n",
oirq.size, oirq.specifier[0], oirq.controller->full_name);
pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, pci_dev->irq);
virq = irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size);
if(virq == NO_IRQ) {
DBG(" -> failed to map !\n");
return -1;
}
pci_dev->irq = virq;
pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, virq);
return 0;
}
......
......@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/kexec.h>
#include <linux/debugfs.h>
#include <linux/irq.h>
#include <asm/prom.h>
#include <asm/rtas.h>
......@@ -86,424 +87,6 @@ static DEFINE_RWLOCK(devtree_lock);
/* export that to outside world */
struct device_node *of_chosen;
struct device_node *dflt_interrupt_controller;
int num_interrupt_controllers;
/*
* Wrapper for allocating memory for various data that needs to be
* attached to device nodes as they are processed at boot or when
* added to the device tree later (e.g. DLPAR). At boot there is
* already a region reserved so we just increment *mem_start by size;
* otherwise we call kmalloc.
*/
static void * prom_alloc(unsigned long size, unsigned long *mem_start)
{
unsigned long tmp;
if (!mem_start)
return kmalloc(size, GFP_KERNEL);
tmp = *mem_start;
*mem_start += size;
return (void *)tmp;
}
/*
* Find the device_node with a given phandle.
*/
static struct device_node * find_phandle(phandle ph)
{
struct device_node *np;
for (np = allnodes; np != 0; np = np->allnext)
if (np->linux_phandle == ph)
return np;
return NULL;
}
/*
* Find the interrupt parent of a node.
*/
static struct device_node * __devinit intr_parent(struct device_node *p)
{
phandle *parp;
parp = (phandle *) get_property(p, "interrupt-parent", NULL);
if (parp == NULL)
return p->parent;
p = find_phandle(*parp);
if (p != NULL)
return p;
/*
* On a powermac booted with BootX, we don't get to know the
* phandles for any nodes, so find_phandle will return NULL.
* Fortunately these machines only have one interrupt controller
* so there isn't in fact any ambiguity. -- paulus
*/
if (num_interrupt_controllers == 1)
p = dflt_interrupt_controller;
return p;
}
/*
* Find out the size of each entry of the interrupts property
* for a node.
*/
int __devinit prom_n_intr_cells(struct device_node *np)
{
struct device_node *p;
unsigned int *icp;
for (p = np; (p = intr_parent(p)) != NULL; ) {
icp = (unsigned int *)
get_property(p, "#interrupt-cells", NULL);
if (icp != NULL)
return *icp;
if (get_property(p, "interrupt-controller", NULL) != NULL
|| get_property(p, "interrupt-map", NULL) != NULL) {
printk("oops, node %s doesn't have #interrupt-cells\n",
p->full_name);
return 1;
}
}
#ifdef DEBUG_IRQ
printk("prom_n_intr_cells failed for %s\n", np->full_name);
#endif
return 1;
}
/*
* Map an interrupt from a device up to the platform interrupt
* descriptor.
*/
static int __devinit map_interrupt(unsigned int **irq, struct device_node **ictrler,
struct device_node *np, unsigned int *ints,
int nintrc)
{
struct device_node *p, *ipar;
unsigned int *imap, *imask, *ip;
int i, imaplen, match;
int newintrc = 0, newaddrc = 0;
unsigned int *reg;
int naddrc;
reg = (unsigned int *) get_property(np, "reg", NULL);
naddrc = prom_n_addr_cells(np);
p = intr_parent(np);
while (p != NULL) {
if (get_property(p, "interrupt-controller", NULL) != NULL)
/* this node is an interrupt controller, stop here */
break;
imap = (unsigned int *)
get_property(p, "interrupt-map", &imaplen);
if (imap == NULL) {
p = intr_parent(p);
continue;
}
imask = (unsigned int *)
get_property(p, "interrupt-map-mask", NULL);
if (imask == NULL) {
printk("oops, %s has interrupt-map but no mask\n",
p->full_name);
return 0;
}
imaplen /= sizeof(unsigned int);
match = 0;
ipar = NULL;
while (imaplen > 0 && !match) {
/* check the child-interrupt field */
match = 1;
for (i = 0; i < naddrc && match; ++i)
match = ((reg[i] ^ imap[i]) & imask[i]) == 0;
for (; i < naddrc + nintrc && match; ++i)
match = ((ints[i-naddrc] ^ imap[i]) & imask[i]) == 0;
imap += naddrc + nintrc;
imaplen -= naddrc + nintrc;
/* grab the interrupt parent */
ipar = find_phandle((phandle) *imap++);
--imaplen;
if (ipar == NULL && num_interrupt_controllers == 1)
/* cope with BootX not giving us phandles */
ipar = dflt_interrupt_controller;
if (ipar == NULL) {
printk("oops, no int parent %x in map of %s\n",
imap[-1], p->full_name);
return 0;
}
/* find the parent's # addr and intr cells */
ip = (unsigned int *)
get_property(ipar, "#interrupt-cells", NULL);
if (ip == NULL) {
printk("oops, no #interrupt-cells on %s\n",
ipar->full_name);
return 0;
}
newintrc = *ip;
ip = (unsigned int *)
get_property(ipar, "#address-cells", NULL);
newaddrc = (ip == NULL)? 0: *ip;
imap += newaddrc + newintrc;
imaplen -= newaddrc + newintrc;
}
if (imaplen < 0) {
printk("oops, error decoding int-map on %s, len=%d\n",
p->full_name, imaplen);
return 0;
}
if (!match) {
#ifdef DEBUG_IRQ
printk("oops, no match in %s int-map for %s\n",
p->full_name, np->full_name);
#endif
return 0;
}
p = ipar;
naddrc = newaddrc;
nintrc = newintrc;
ints = imap - nintrc;
reg = ints - naddrc;
}
if (p == NULL) {
#ifdef DEBUG_IRQ
printk("hmmm, int tree for %s doesn't have ctrler\n",
np->full_name);
#endif
return 0;
}
*irq = ints;
*ictrler = p;
return nintrc;
}
static unsigned char map_isa_senses[4] = {
IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE,
IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE,
IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE,
IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE
};
static unsigned char map_mpic_senses[4] = {
IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE,
IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE,
/* 2 seems to be used for the 8259 cascade... */
IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE,
IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE,
};
static int __devinit finish_node_interrupts(struct device_node *np,
unsigned long *mem_start,
int measure_only)
{
unsigned int *ints;
int intlen, intrcells, intrcount;
int i, j, n, sense;
unsigned int *irq, virq;
struct device_node *ic;
int trace = 0;
//#define TRACE(fmt...) do { if (trace) { printk(fmt); mdelay(1000); } } while(0)
#define TRACE(fmt...)
if (!strcmp(np->name, "smu-doorbell"))
trace = 1;
TRACE("Finishing SMU doorbell ! num_interrupt_controllers = %d\n",
num_interrupt_controllers);
if (num_interrupt_controllers == 0) {
/*
* Old machines just have a list of interrupt numbers
* and no interrupt-controller nodes.
*/
ints = (unsigned int *) get_property(np, "AAPL,interrupts",
&intlen);
/* XXX old interpret_pci_props looked in parent too */
/* XXX old interpret_macio_props looked for interrupts
before AAPL,interrupts */
if (ints == NULL)
ints = (unsigned int *) get_property(np, "interrupts",
&intlen);
if (ints == NULL)
return 0;
np->n_intrs = intlen / sizeof(unsigned int);
np->intrs = prom_alloc(np->n_intrs * sizeof(np->intrs[0]),
mem_start);
if (!np->intrs)
return -ENOMEM;
if (measure_only)
return 0;
for (i = 0; i < np->n_intrs; ++i) {
np->intrs[i].line = *ints++;
np->intrs[i].sense = IRQ_SENSE_LEVEL
| IRQ_POLARITY_NEGATIVE;
}
return 0;
}
ints = (unsigned int *) get_property(np, "interrupts", &intlen);
TRACE("ints=%p, intlen=%d\n", ints, intlen);
if (ints == NULL)
return 0;
intrcells = prom_n_intr_cells(np);
intlen /= intrcells * sizeof(unsigned int);
TRACE("intrcells=%d, new intlen=%d\n", intrcells, intlen);
np->intrs = prom_alloc(intlen * sizeof(*(np->intrs)), mem_start);
if (!np->intrs)
return -ENOMEM;
if (measure_only)
return 0;
intrcount = 0;
for (i = 0; i < intlen; ++i, ints += intrcells) {
n = map_interrupt(&irq, &ic, np, ints, intrcells);
TRACE("map, irq=%d, ic=%p, n=%d\n", irq, ic, n);
if (n <= 0)
continue;
/* don't map IRQ numbers under a cascaded 8259 controller */
if (ic && device_is_compatible(ic, "chrp,iic")) {
np->intrs[intrcount].line = irq[0];
sense = (n > 1)? (irq[1] & 3): 3;
np->intrs[intrcount].sense = map_isa_senses[sense];
} else {
virq = virt_irq_create_mapping(irq[0]);
TRACE("virq=%d\n", virq);
#ifdef CONFIG_PPC64
if (virq == NO_IRQ) {
printk(KERN_CRIT "Could not allocate interrupt"
" number for %s\n", np->full_name);
continue;
}
#endif
np->intrs[intrcount].line = irq_offset_up(virq);
sense = (n > 1)? (irq[1] & 3): 1;
/* Apple uses bits in there in a different way, let's
* only keep the real sense bit on macs
*/
if (machine_is(powermac))
sense &= 0x1;
np->intrs[intrcount].sense = map_mpic_senses[sense];
}
#ifdef CONFIG_PPC64
/* We offset irq numbers for the u3 MPIC by 128 in PowerMac */
if (machine_is(powermac) && ic && ic->parent) {
char *name = get_property(ic->parent, "name", NULL);
if (name && !strcmp(name, "u3"))
np->intrs[intrcount].line += 128;
else if (!(name && (!strcmp(name, "mac-io") ||
!strcmp(name, "u4"))))
/* ignore other cascaded controllers, such as
the k2-sata-root */
break;
}
#endif /* CONFIG_PPC64 */
if (n > 2) {
printk("hmmm, got %d intr cells for %s:", n,
np->full_name);
for (j = 0; j < n; ++j)
printk(" %d", irq[j]);
printk("\n");
}
++intrcount;
}
np->n_intrs = intrcount;
return 0;
}
static int __devinit finish_node(struct device_node *np,
unsigned long *mem_start,
int measure_only)
{
struct device_node *child;
int rc = 0;
rc = finish_node_interrupts(np, mem_start, measure_only);
if (rc)
goto out;
for (child = np->child; child != NULL; child = child->sibling) {
rc = finish_node(child, mem_start, measure_only);
if (rc)
goto out;
}
out:
return rc;
}
static void __init scan_interrupt_controllers(void)
{
struct device_node *np;
int n = 0;
char *name, *ic;
int iclen;
for (np = allnodes; np != NULL; np = np->allnext) {
ic = get_property(np, "interrupt-controller", &iclen);
name = get_property(np, "name", NULL);
/* checking iclen makes sure we don't get a false
match on /chosen.interrupt_controller */
if ((name != NULL
&& strcmp(name, "interrupt-controller") == 0)
|| (ic != NULL && iclen == 0
&& strcmp(name, "AppleKiwi"))) {
if (n == 0)
dflt_interrupt_controller = np;
++n;
}
}
num_interrupt_controllers = n;
}
/**
* finish_device_tree is called once things are running normally
* (i.e. with text and data mapped to the address they were linked at).
* It traverses the device tree and fills in some of the additional,
* fields in each node like {n_}addrs and {n_}intrs, the virt interrupt
* mapping is also initialized at this point.
*/
void __init finish_device_tree(void)
{
unsigned long start, end, size = 0;
DBG(" -> finish_device_tree\n");
#ifdef CONFIG_PPC64
/* Initialize virtual IRQ map */
virt_irq_init();
#endif
scan_interrupt_controllers();
/*
* Finish device-tree (pre-parsing some properties etc...)
* We do this in 2 passes. One with "measure_only" set, which
* will only measure the amount of memory needed, then we can
* allocate that memory, and call finish_node again. However,
* we must be careful as most routines will fail nowadays when
* prom_alloc() returns 0, so we must make sure our first pass
* doesn't start at 0. We pre-initialize size to 16 for that
* reason and then remove those additional 16 bytes
*/
size = 16;
finish_node(allnodes, &size, 1);
size -= 16;
if (0 == size)
end = start = 0;
else
end = start = (unsigned long)__va(lmb_alloc(size, 128));
finish_node(allnodes, &end, 0);
BUG_ON(end != start + size);
DBG(" <- finish_device_tree\n");
}
static inline char *find_flat_dt_string(u32 offset)
{
return ((char *)initial_boot_params) +
......@@ -1388,27 +971,6 @@ prom_n_size_cells(struct device_node* np)
}
EXPORT_SYMBOL(prom_n_size_cells);
/**
* Work out the sense (active-low level / active-high edge)
* of each interrupt from the device tree.
*/
void __init prom_get_irq_senses(unsigned char *senses, int off, int max)
{
struct device_node *np;
int i, j;
/* default to level-triggered */
memset(senses, IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE, max - off);
for (np = allnodes; np != 0; np = np->allnext) {
for (j = 0; j < np->n_intrs; j++) {
i = np->intrs[j].line;
if (i >= off && i < max)
senses[i-off] = np->intrs[j].sense;
}
}
}
/**
* Construct and return a list of the device_nodes with a given name.
*/
......@@ -1808,7 +1370,6 @@ static void of_node_release(struct kref *kref)
node->deadprops = NULL;
}
}
kfree(node->intrs);
kfree(node->full_name);
kfree(node->data);
kfree(node);
......@@ -1881,13 +1442,7 @@ void of_detach_node(const struct device_node *np)
#ifdef CONFIG_PPC_PSERIES
/*
* Fix up the uninitialized fields in a new device node:
* name, type, n_addrs, addrs, n_intrs, intrs, and pci-specific fields
*
* A lot of boot-time code is duplicated here, because functions such
* as finish_node_interrupts, interpret_pci_props, etc. cannot use the
* slab allocator.
*
* This should probably be split up into smaller chunks.
* name, type and pci-specific fields
*/
static int of_finish_dynamic_node(struct device_node *node)
......@@ -1928,8 +1483,6 @@ static int prom_reconfig_notifier(struct notifier_block *nb,
switch (action) {
case PSERIES_RECONFIG_ADD:
err = of_finish_dynamic_node(node);
if (!err)
finish_node(node, NULL, 0);
if (err < 0) {
printk(KERN_ERR "finish_node returned %d\n", err);
err = NOTIFY_BAD;
......@@ -1975,8 +1528,7 @@ struct property *of_find_property(struct device_node *np, const char *name,
* Find a property with a given name for a given node
* and return the value.
*/
unsigned char *get_property(struct device_node *np, const char *name,
int *lenp)
void *get_property(struct device_node *np, const char *name, int *lenp)
{
struct property *pp = of_find_property(np,name,lenp);
return pp ? pp->value : NULL;
......
......@@ -1990,12 +1990,22 @@ static void __init flatten_device_tree(void)
static void __init fixup_device_tree_maple(void)
{
phandle isa;
u32 rloc = 0x01002000; /* IO space; PCI device = 4 */
u32 isa_ranges[6];
isa = call_prom("finddevice", 1, 1, ADDR("/ht@0/isa@4"));
char *name;
name = "/ht@0/isa@4";
isa = call_prom("finddevice", 1, 1, ADDR(name));
if (!PHANDLE_VALID(isa)) {
name = "/ht@0/isa@6";
isa = call_prom("finddevice", 1, 1, ADDR(name));
rloc = 0x01003000; /* IO space; PCI device = 6 */
}
if (!PHANDLE_VALID(isa))
return;
if (prom_getproplen(isa, "ranges") != 12)
return;
if (prom_getprop(isa, "ranges", isa_ranges, sizeof(isa_ranges))
== PROM_ERROR)
return;
......@@ -2005,15 +2015,15 @@ static void __init fixup_device_tree_maple(void)
isa_ranges[2] != 0x00010000)
return;
prom_printf("fixing up bogus ISA range on Maple...\n");
prom_printf("Fixing up bogus ISA range on Maple/Apache...\n");
isa_ranges[0] = 0x1;
isa_ranges[1] = 0x0;
isa_ranges[2] = 0x01002000; /* IO space; PCI device = 4 */
isa_ranges[2] = rloc;
isa_ranges[3] = 0x0;
isa_ranges[4] = 0x0;
isa_ranges[5] = 0x00010000;
prom_setprop(isa, "/ht@0/isa@4", "ranges",
prom_setprop(isa, name, "ranges",
isa_ranges, sizeof(isa_ranges));
}
#else
......
......@@ -38,14 +38,6 @@ static void of_dump_addr(const char *s, u32 *addr, int na)
static void of_dump_addr(const char *s, u32 *addr, int na) { }
#endif
/* Read a big address */
static inline u64 of_read_addr(u32 *cell, int size)
{
u64 r = 0;
while (size--)
r = (r << 32) | *(cell++);
return r;
}
/* Callbacks for bus specific translators */
struct of_bus {
......@@ -77,9 +69,9 @@ static u64 of_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna)
{
u64 cp, s, da;
cp = of_read_addr(range, na);
s = of_read_addr(range + na + pna, ns);
da = of_read_addr(addr, na);
cp = of_read_number(range, na);
s = of_read_number(range + na + pna, ns);
da = of_read_number(addr, na);
DBG("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n",
cp, s, da);
......@@ -91,7 +83,7 @@ static u64 of_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna)
static int of_bus_default_translate(u32 *addr, u64 offset, int na)
{
u64 a = of_read_addr(addr, na);
u64 a = of_read_number(addr, na);
memset(addr, 0, na * 4);
a += offset;
if (na > 1)
......@@ -135,9 +127,9 @@ static u64 of_bus_pci_map(u32 *addr, u32 *range, int na, int ns, int pna)
return OF_BAD_ADDR;
/* Read address values, skipping high cell */
cp = of_read_addr(range + 1, na - 1);
s = of_read_addr(range + na + pna, ns);
da = of_read_addr(addr + 1, na - 1);
cp = of_read_number(range + 1, na - 1);
s = of_read_number(range + na + pna, ns);
da = of_read_number(addr + 1, na - 1);
DBG("OF: PCI map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
......@@ -195,9 +187,9 @@ static u64 of_bus_isa_map(u32 *addr, u32 *range, int na, int ns, int pna)
return OF_BAD_ADDR;
/* Read address values, skipping high cell */
cp = of_read_addr(range + 1, na - 1);
s = of_read_addr(range + na + pna, ns);
da = of_read_addr(addr + 1, na - 1);
cp = of_read_number(range + 1, na - 1);
s = of_read_number(range + na + pna, ns);
da = of_read_number(addr + 1, na - 1);
DBG("OF: ISA map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
......@@ -295,7 +287,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
*/
ranges = (u32 *)get_property(parent, "ranges", &rlen);
if (ranges == NULL || rlen == 0) {
offset = of_read_addr(addr, na);
offset = of_read_number(addr, na);
memset(addr, 0, pna * 4);
DBG("OF: no ranges, 1:1 translation\n");
goto finish;
......@@ -378,7 +370,7 @@ u64 of_translate_address(struct device_node *dev, u32 *in_addr)
/* If root, we have finished */
if (parent == NULL) {
DBG("OF: reached root node\n");
result = of_read_addr(addr, na);
result = of_read_number(addr, na);
break;
}
......@@ -442,7 +434,7 @@ u32 *of_get_address(struct device_node *dev, int index, u64 *size,
for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
if (i == index) {
if (size)
*size = of_read_addr(prop + na, ns);
*size = of_read_number(prop + na, ns);
if (flags)
*flags = bus->get_flags(prop);
return prop;
......@@ -484,7 +476,7 @@ u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
if (size)
*size = of_read_addr(prop + na, ns);
*size = of_read_number(prop + na, ns);
if (flags)
*flags = bus->get_flags(prop);
return prop;
......@@ -565,11 +557,414 @@ void of_parse_dma_window(struct device_node *dn, unsigned char *dma_window_prop,
prop = get_property(dn, "#address-cells", NULL);
cells = prop ? *(u32 *)prop : prom_n_addr_cells(dn);
*phys = of_read_addr(dma_window, cells);
*phys = of_read_number(dma_window, cells);
dma_window += cells;
prop = get_property(dn, "ibm,#dma-size-cells", NULL);
cells = prop ? *(u32 *)prop : prom_n_size_cells(dn);
*size = of_read_addr(dma_window, cells);
*size = of_read_number(dma_window, cells);
}
/*
* Interrupt remapper
*/
static unsigned int of_irq_workarounds;
static struct device_node *of_irq_dflt_pic;
static struct device_node *of_irq_find_parent(struct device_node *child)
{
struct device_node *p;
phandle *parp;
if (!of_node_get(child))
return NULL;
do {
parp = (phandle *)get_property(child, "interrupt-parent", NULL);
if (parp == NULL)
p = of_get_parent(child);
else {
if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
p = of_node_get(of_irq_dflt_pic);
else
p = of_find_node_by_phandle(*parp);
}
of_node_put(child);
child = p;
} while (p && get_property(p, "#interrupt-cells", NULL) == NULL);
return p;
}
static u8 of_irq_pci_swizzle(u8 slot, u8 pin)
{
return (((pin - 1) + slot) % 4) + 1;
}
/* This doesn't need to be called if you don't have any special workaround
* flags to pass
*/
void of_irq_map_init(unsigned int flags)
{
of_irq_workarounds = flags;
/* OldWorld, don't bother looking at other things */
if (flags & OF_IMAP_OLDWORLD_MAC)
return;
/* If we don't have phandles, let's try to locate a default interrupt
* controller (happens when booting with BootX). We do a first match
* here, hopefully, that only ever happens on machines with one
* controller.
*/
if (flags & OF_IMAP_NO_PHANDLE) {
struct device_node *np;
for(np = NULL; (np = of_find_all_nodes(np)) != NULL;) {
if (get_property(np, "interrupt-controller", NULL)
== NULL)
continue;
/* Skip /chosen/interrupt-controller */
if (strcmp(np->name, "chosen") == 0)
continue;
/* It seems like at least one person on this planet wants
* to use BootX on a machine with an AppleKiwi controller
* which happens to pretend to be an interrupt
* controller too.
*/
if (strcmp(np->name, "AppleKiwi") == 0)
continue;
/* I think we found one ! */
of_irq_dflt_pic = np;
break;
}
}
}
int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 *addr,
struct of_irq *out_irq)
{
struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
u32 *tmp, *imap, *imask;
u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
int imaplen, match, i;
ipar = of_node_get(parent);
/* First get the #interrupt-cells property of the current cursor
* that tells us how to interpret the passed-in intspec. If there
* is none, we are nice and just walk up the tree
*/
do {
tmp = (u32 *)get_property(ipar, "#interrupt-cells", NULL);
if (tmp != NULL) {
intsize = *tmp;
break;
}
tnode = ipar;
ipar = of_irq_find_parent(ipar);
of_node_put(tnode);
} while (ipar);
if (ipar == NULL) {
DBG(" -> no parent found !\n");
goto fail;
}
DBG("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize);
/* Look for this #address-cells. We have to implement the old linux
* trick of looking for the parent here as some device-trees rely on it
*/
old = of_node_get(ipar);
do {
tmp = (u32 *)get_property(old, "#address-cells", NULL);
tnode = of_get_parent(old);
of_node_put(old);
old = tnode;
} while(old && tmp == NULL);
of_node_put(old);
old = NULL;
addrsize = (tmp == NULL) ? 2 : *tmp;
DBG(" -> addrsize=%d\n", addrsize);
/* Now start the actual "proper" walk of the interrupt tree */
while (ipar != NULL) {
/* Now check if cursor is an interrupt-controller and if it is
* then we are done
*/
if (get_property(ipar, "interrupt-controller", NULL) != NULL) {
DBG(" -> got it !\n");
memcpy(out_irq->specifier, intspec,
intsize * sizeof(u32));
out_irq->size = intsize;
out_irq->controller = ipar;
of_node_put(old);
return 0;
}
/* Now look for an interrupt-map */
imap = (u32 *)get_property(ipar, "interrupt-map", &imaplen);
/* No interrupt map, check for an interrupt parent */
if (imap == NULL) {
DBG(" -> no map, getting parent\n");
newpar = of_irq_find_parent(ipar);
goto skiplevel;
}
imaplen /= sizeof(u32);
/* Look for a mask */
imask = (u32 *)get_property(ipar, "interrupt-map-mask", NULL);
/* If we were passed no "reg" property and we attempt to parse
* an interrupt-map, then #address-cells must be 0.
* Fail if it's not.
*/
if (addr == NULL && addrsize != 0) {
DBG(" -> no reg passed in when needed !\n");
goto fail;
}
/* Parse interrupt-map */
match = 0;
while (imaplen > (addrsize + intsize + 1) && !match) {
/* Compare specifiers */
match = 1;
for (i = 0; i < addrsize && match; ++i) {
u32 mask = imask ? imask[i] : 0xffffffffu;
match = ((addr[i] ^ imap[i]) & mask) == 0;
}
for (; i < (addrsize + intsize) && match; ++i) {
u32 mask = imask ? imask[i] : 0xffffffffu;
match =
((intspec[i-addrsize] ^ imap[i]) & mask) == 0;
}
imap += addrsize + intsize;
imaplen -= addrsize + intsize;
DBG(" -> match=%d (imaplen=%d)\n", match, imaplen);
/* Get the interrupt parent */
if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
newpar = of_node_get(of_irq_dflt_pic);
else
newpar = of_find_node_by_phandle((phandle)*imap);
imap++;
--imaplen;
/* Check if not found */
if (newpar == NULL) {
DBG(" -> imap parent not found !\n");
goto fail;
}
/* Get #interrupt-cells and #address-cells of new
* parent
*/
tmp = (u32 *)get_property(newpar, "#interrupt-cells",
NULL);
if (tmp == NULL) {
DBG(" -> parent lacks #interrupt-cells !\n");
goto fail;
}
newintsize = *tmp;
tmp = (u32 *)get_property(newpar, "#address-cells",
NULL);
newaddrsize = (tmp == NULL) ? 0 : *tmp;
DBG(" -> newintsize=%d, newaddrsize=%d\n",
newintsize, newaddrsize);
/* Check for malformed properties */
if (imaplen < (newaddrsize + newintsize))
goto fail;
imap += newaddrsize + newintsize;
imaplen -= newaddrsize + newintsize;
DBG(" -> imaplen=%d\n", imaplen);
}
if (!match)
goto fail;
of_node_put(old);
old = of_node_get(newpar);
addrsize = newaddrsize;
intsize = newintsize;
intspec = imap - intsize;
addr = intspec - addrsize;
skiplevel:
/* Iterate again with new parent */
DBG(" -> new parent: %s\n", newpar ? newpar->full_name : "<>");
of_node_put(ipar);
ipar = newpar;
newpar = NULL;
}
fail:
of_node_put(ipar);
of_node_put(old);
of_node_put(newpar);
return -EINVAL;
}
EXPORT_SYMBOL_GPL(of_irq_map_raw);
#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
static int of_irq_map_oldworld(struct device_node *device, int index,
struct of_irq *out_irq)
{
u32 *ints;
int intlen;
/*
* Old machines just have a list of interrupt numbers
* and no interrupt-controller nodes.
*/
ints = (u32 *) get_property(device, "AAPL,interrupts", &intlen);
if (ints == NULL)
return -EINVAL;
intlen /= sizeof(u32);
if (index >= intlen)
return -EINVAL;
out_irq->controller = NULL;
out_irq->specifier[0] = ints[index];
out_irq->size = 1;
return 0;
}
#else /* defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) */
static int of_irq_map_oldworld(struct device_node *device, int index,
struct of_irq *out_irq)
{
return -EINVAL;
}
#endif /* !(defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)) */
int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq)
{
struct device_node *p;
u32 *intspec, *tmp, intsize, intlen, *addr;
int res;
DBG("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index);
/* OldWorld mac stuff is "special", handle out of line */
if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
return of_irq_map_oldworld(device, index, out_irq);
/* Get the interrupts property */
intspec = (u32 *)get_property(device, "interrupts", &intlen);
if (intspec == NULL)
return -EINVAL;
intlen /= sizeof(u32);
/* Get the reg property (if any) */
addr = (u32 *)get_property(device, "reg", NULL);
/* Look for the interrupt parent. */
p = of_irq_find_parent(device);
if (p == NULL)
return -EINVAL;
/* Get size of interrupt specifier */
tmp = (u32 *)get_property(p, "#interrupt-cells", NULL);
if (tmp == NULL) {
of_node_put(p);
return -EINVAL;
}
intsize = *tmp;
/* Check index */
if (index * intsize >= intlen)
return -EINVAL;
/* Get new specifier and map it */
res = of_irq_map_raw(p, intspec + index * intsize, addr, out_irq);
of_node_put(p);
return res;
}
EXPORT_SYMBOL_GPL(of_irq_map_one);
int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
{
struct device_node *dn, *ppnode;
struct pci_dev *ppdev;
u32 lspec;
u32 laddr[3];
u8 pin;
int rc;
/* Check if we have a device node, if yes, fallback to standard OF
* parsing
*/
dn = pci_device_to_OF_node(pdev);
if (dn)
return of_irq_map_one(dn, 0, out_irq);
/* Ok, we don't, time to have fun. Let's start by building up an
* interrupt spec. we assume #interrupt-cells is 1, which is standard
* for PCI. If you do different, then don't use that routine.
*/
rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
if (rc != 0)
return rc;
/* No pin, exit */
if (pin == 0)
return -ENODEV;
/* Now we walk up the PCI tree */
lspec = pin;
for (;;) {
/* Get the pci_dev of our parent */
ppdev = pdev->bus->self;
/* Ouch, it's a host bridge... */
if (ppdev == NULL) {
#ifdef CONFIG_PPC64
ppnode = pci_bus_to_OF_node(pdev->bus);
#else
struct pci_controller *host;
host = pci_bus_to_host(pdev->bus);
ppnode = host ? host->arch_data : NULL;
#endif
/* No node for host bridge ? give up */
if (ppnode == NULL)
return -EINVAL;
} else
/* We found a P2P bridge, check if it has a node */
ppnode = pci_device_to_OF_node(ppdev);
/* Ok, we have found a parent with a device-node, hand over to
* the OF parsing code.
* We build a unit address from the linux device to be used for
* resolution. Note that we use the linux bus number which may
* not match your firmware bus numbering.
* Fortunately, in most cases, interrupt-map-mask doesn't include
* the bus number as part of the matching.
* You should still be careful about that though if you intend
* to rely on this function (you ship a firmware that doesn't
* create device nodes for all PCI devices).
*/
if (ppnode)
break;
/* We can only get here if we hit a P2P bridge with no node,
* let's do standard swizzling and try again
*/
lspec = of_irq_pci_swizzle(PCI_SLOT(pdev->devfn), lspec);
pdev = ppdev;
}
laddr[0] = (pdev->bus->number << 16)
| (pdev->devfn << 8);
laddr[1] = laddr[2] = 0;
return of_irq_map_raw(ppnode, &lspec, laddr, out_irq);
}
EXPORT_SYMBOL_GPL(of_irq_map_pci);
......@@ -297,19 +297,9 @@ unsigned long __init find_and_init_phbs(void)
struct device_node *node;
struct pci_controller *phb;
unsigned int index;
unsigned int root_size_cells = 0;
unsigned int *opprop = NULL;
struct device_node *root = of_find_node_by_path("/");
if (ppc64_interrupt_controller == IC_OPEN_PIC) {
opprop = (unsigned int *)get_property(root,
"platform-open-pic", NULL);
}
root_size_cells = prom_n_size_cells(root);
index = 0;
for (node = of_get_next_child(root, NULL);
node != NULL;
node = of_get_next_child(root, node)) {
......@@ -324,13 +314,6 @@ unsigned long __init find_and_init_phbs(void)
setup_phb(node, phb);
pci_process_bridge_OF_ranges(phb, node, 0);
pci_setup_phb_io(phb, index == 0);
#ifdef CONFIG_PPC_PSERIES
/* XXX This code need serious fixing ... --BenH */
if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) {
int addr = root_size_cells * (index + 2) - 1;
mpic_assign_isu(pSeries_mpic, index, opprop[addr]);
}
#endif
index++;
}
......
......@@ -51,7 +51,6 @@
extern void bootx_init(unsigned long r4, unsigned long phys);
boot_infos_t *boot_infos;
struct ide_machdep_calls ppc_ide_md;
int boot_cpuid;
......@@ -240,7 +239,6 @@ void __init setup_arch(char **cmdline_p)
ppc_md.init_early();
find_legacy_serial_ports();
finish_device_tree();
smp_setup_cpu_maps();
......
......@@ -361,12 +361,15 @@ void __init setup_system(void)
/*
* Fill the ppc64_caches & systemcfg structures with informations
* retrieved from the device-tree. Need to be called before
* finish_device_tree() since the later requires some of the
* informations filled up here to properly parse the interrupt tree.
* retrieved from the device-tree.
*/
initialize_cache_info();
/*
* Initialize irq remapping subsystem
*/
irq_early_init();
#ifdef CONFIG_PPC_RTAS
/*
* Initialize RTAS if available
......@@ -393,12 +396,6 @@ void __init setup_system(void)
*/
find_legacy_serial_ports();
/*
* "Finish" the device-tree, that is do the actual parsing of
* some of the properties like the interrupt map
*/
finish_device_tree();
/*
* Initialize xmon
*/
......@@ -427,8 +424,6 @@ void __init setup_system(void)
printk("-----------------------------------------------------\n");
printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size);
printk("ppc64_interrupt_controller = 0x%ld\n",
ppc64_interrupt_controller);
printk("physicalMemorySize = 0x%lx\n", lmb_phys_mem_size());
printk("ppc64_caches.dcache_line_size = 0x%x\n",
ppc64_caches.dline_size);
......
......@@ -218,7 +218,6 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
{
struct vio_dev *viodev;
unsigned int *unit_address;
unsigned int *irq_p;
/* we need the 'device_type' property, in order to match with drivers */
if (of_node->type == NULL) {
......@@ -243,16 +242,7 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
viodev->dev.platform_data = of_node_get(of_node);
viodev->irq = NO_IRQ;
irq_p = (unsigned int *)get_property(of_node, "interrupts", NULL);
if (irq_p) {
int virq = virt_irq_create_mapping(*irq_p);
if (virq == NO_IRQ) {
printk(KERN_ERR "Unable to allocate interrupt "
"number for %s\n", of_node->full_name);
} else
viodev->irq = irq_offset_up(virq);
}
viodev->irq = irq_of_parse_and_map(of_node, 0);
snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address);
viodev->name = of_node->name;
......
此差异已折叠。
......@@ -4,3 +4,4 @@
obj-y := misc.o
obj-$(CONFIG_PCI) += pci.o
obj-$(CONFIG_MPC834x_SYS) += mpc834x_sys.o
obj-$(CONFIG_MPC834x_ITX) += mpc834x_itx.o
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册