Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 204887
b: refs/heads/master
c: b83da29
h: refs/heads/master
i:
  204885: addb3cb
  204883: f3111cb
  204879: 7a992f4
v: v3
  • Loading branch information
Grant Likely committed Jul 5, 2010
1 parent 9dc4949 commit 47730b3
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 101 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b6295c8b85fe83e5679b7b8bebe4df85deebebfc
refs/heads/master: b83da291b4c73eaddc20e2edb614123a6d681b3b
24 changes: 15 additions & 9 deletions trunk/arch/powerpc/include/asm/prom.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,18 +109,24 @@ extern const void *of_get_mac_address(struct device_node *np);
* OF interrupt mapping
*/

/**
* of_irq_map_init - Initialize the irq remapper
* @flags: flags defining workarounds to enable
*
* Some machines have bugs in the device-tree which require certain workarounds
* to be applied. Call this before any interrupt mapping attempts to enable
* those workarounds.
*/
#define OF_IMAP_OLDWORLD_MAC 0x00000001
#define OF_IMAP_NO_PHANDLE 0x00000002

extern void of_irq_map_init(unsigned int flags);
#if defined(CONFIG_PPC32) && defined(CONFIG_PPC_PMAC)
/* Workarounds only needed for 32bit powermac machines */
extern unsigned int of_irq_workarounds;
extern struct device_node *of_irq_dflt_pic;
extern int of_irq_map_oldworld(struct device_node *device, int index,
struct of_irq *out_irq);
#else
#define of_irq_workarounds (0)
#define of_irq_dflt_pic (NULL)
static inline int of_irq_map_oldworld(struct device_node *device, int index,
struct of_irq *out_irq)
{
return -EINVAL;
}
#endif

/**
* of_irq_map_raw - Low level interrupt tree parsing
Expand Down
85 changes: 0 additions & 85 deletions trunk/arch/powerpc/kernel/prom_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -682,9 +682,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
* 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;
Expand All @@ -710,44 +707,6 @@ static struct device_node *of_irq_find_parent(struct device_node *child)
return p;
}

/* 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_each_node_with_property(np, "interrupt-controller") {
/* 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, const u32 *intspec, u32 ointsize,
const u32 *addr, struct of_irq *out_irq)
{
Expand Down Expand Up @@ -922,50 +881,6 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
}
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)
{
const u32 *ints = NULL;
int intlen;

/*
* Old machines just have a list of interrupt numbers
* and no interrupt-controller nodes. We also have dodgy
* cases where the APPL,interrupts property is completely
* missing behind pci-pci bridges and we have to get it
* from the parent (the bridge itself, as apple just wired
* everything together on these)
*/
while (device) {
ints = of_get_property(device, "AAPL,interrupts", &intlen);
if (ints != NULL)
break;
device = device->parent;
if (device && strcmp(device->type, "pci") != 0)
break;
}
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;
Expand Down
72 changes: 66 additions & 6 deletions trunk/arch/powerpc/platforms/powermac/pic.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ struct pmac_irq_hw {
unsigned int level;
};

/* Workaround flags for 32bit powermac machines */
unsigned int of_irq_workarounds;
struct device_node *of_irq_dflt_pic;

/* Default addresses */
static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4];

Expand Down Expand Up @@ -428,6 +432,42 @@ static void __init pmac_pic_probe_oldstyle(void)
setup_irq(irq_create_mapping(NULL, 20), &xmon_action);
#endif
}

int of_irq_map_oldworld(struct device_node *device, int index,
struct of_irq *out_irq)
{
const u32 *ints = NULL;
int intlen;

/*
* Old machines just have a list of interrupt numbers
* and no interrupt-controller nodes. We also have dodgy
* cases where the APPL,interrupts property is completely
* missing behind pci-pci bridges and we have to get it
* from the parent (the bridge itself, as apple just wired
* everything together on these)
*/
while (device) {
ints = of_get_property(device, "AAPL,interrupts", &intlen);
if (ints != NULL)
break;
device = device->parent;
if (device && strcmp(device->type, "pci") != 0)
break;
}
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;
}
#endif /* CONFIG_PPC32 */

static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc)
Expand Down Expand Up @@ -559,19 +599,39 @@ static int __init pmac_pic_probe_mpic(void)

void __init pmac_pic_init(void)
{
unsigned int flags = 0;

/* We configure the OF parsing based on our oldworld vs. newworld
* platform type and wether we were booted by BootX.
*/
#ifdef CONFIG_PPC32
if (!pmac_newworld)
flags |= OF_IMAP_OLDWORLD_MAC;
of_irq_workarounds |= OF_IMAP_OLDWORLD_MAC;
if (of_get_property(of_chosen, "linux,bootx", NULL) != NULL)
flags |= OF_IMAP_NO_PHANDLE;
#endif /* CONFIG_PPC_32 */
of_irq_workarounds |= OF_IMAP_NO_PHANDLE;

of_irq_map_init(flags);
/* If we don't have phandles on a newworld, then 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 (pmac_newworld && (of_irq_workarounds & OF_IMAP_NO_PHANDLE)) {
struct device_node *np;

for_each_node_with_property(np, "interrupt-controller") {
/* Skip /chosen/interrupt-controller */
if (strcmp(np->name, "chosen") == 0)
continue;
/* It seems like at least one person 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;
}
}
#endif /* CONFIG_PPC32 */

/* We first try to detect Apple's new Core99 chipset, since mac-io
* is quite different on those machines and contains an IBM MPIC2.
Expand Down

0 comments on commit 47730b3

Please sign in to comment.