*/
static DEFINE_RWLOCK(devtree_lock);
-int of_device_is_compatible(struct device_node *device, const char *compat)
+int of_device_is_compatible(const struct device_node *device,
+ const char *compat)
{
const char* cp;
int cplen, l;
- cp = (char *) of_get_property(device, "compatible", &cplen);
+ cp = of_get_property(device, "compatible", &cplen);
if (cp == NULL)
return 0;
while (cplen > 0) {
}
EXPORT_SYMBOL(of_find_compatible_node);
-struct property *of_find_property(struct device_node *np, const char *name,
+struct property *of_find_property(const struct device_node *np,
+ const char *name,
int *lenp)
{
struct property *pp;
for (pp = np->properties; pp != 0; pp = pp->next) {
- if (strcmp(pp->name, name) == 0) {
+ if (strcasecmp(pp->name, name) == 0) {
if (lenp != 0)
*lenp = pp->length;
break;
* Find a property with a given name for a given node
* and return the value.
*/
-void *of_get_property(struct device_node *np, const char *name, int *lenp)
+const void *of_get_property(const struct device_node *np, const char *name,
+ int *lenp)
{
struct property *pp = of_find_property(np,name,lenp);
return pp ? pp->value : NULL;
while (*prevp) {
struct property *prop = *prevp;
- if (!strcmp(prop->name, name)) {
+ if (!strcasecmp(prop->name, name)) {
void *old_val = prop->value;
int ret;
/* Now build the IRQ bucket. */
imap = controller_regs + imap_off;
- imap += 4;
iclr_off = psycho_iclr_offset(ino);
iclr = controller_regs + iclr_off;
- iclr += 4;
if ((ino & 0x20) == 0)
inofixup = ino & 0x03;
return build_irq(inofixup, iclr, imap);
}
-static void psycho_irq_trans_init(struct device_node *dp)
+static void __init psycho_irq_trans_init(struct device_node *dp)
{
const struct linux_prom64_registers *regs;
/* Now build the IRQ bucket. */
imap = controller_regs + imap_off;
- imap += 4;
iclr_off = sabre_iclr_offset(ino);
iclr = controller_regs + iclr_off;
- iclr += 4;
if ((ino & 0x20) == 0)
inofixup = ino & 0x03;
return virt_irq;
}
-static void sabre_irq_trans_init(struct device_node *dp)
+static void __init sabre_irq_trans_init(struct device_node *dp)
{
const struct linux_prom64_registers *regs;
struct sabre_irq_data *irq_data;
static unsigned long schizo_ino_to_iclr(unsigned long pbm_regs,
unsigned int ino)
{
- return pbm_regs + schizo_iclr_offset(ino) + 4;
+
+ return pbm_regs + schizo_iclr_offset(ino);
}
static unsigned long schizo_ino_to_imap(unsigned long pbm_regs,
unsigned int ino)
{
- return pbm_regs + schizo_imap_offset(ino) + 4;
+ return pbm_regs + schizo_imap_offset(ino);
}
#define schizo_read(__reg) \
return virt_irq;
}
-static void __schizo_irq_trans_init(struct device_node *dp, int is_tomatillo)
+static void __init __schizo_irq_trans_init(struct device_node *dp,
+ int is_tomatillo)
{
const struct linux_prom64_registers *regs;
struct schizo_irq_data *irq_data;
irq_data->chip_version = of_getintprop_default(dp, "version#", 0);
}
-static void schizo_irq_trans_init(struct device_node *dp)
+static void __init schizo_irq_trans_init(struct device_node *dp)
{
__schizo_irq_trans_init(dp, 0);
}
-static void tomatillo_irq_trans_init(struct device_node *dp)
+static void __init tomatillo_irq_trans_init(struct device_node *dp)
{
__schizo_irq_trans_init(dp, 1);
}
return sun4v_build_irq(devhandle, devino);
}
-static void pci_sun4v_irq_trans_init(struct device_node *dp)
+static void __init pci_sun4v_irq_trans_init(struct device_node *dp)
{
const struct linux_prom64_registers *regs;
dp->irq_trans->data = (void *) (unsigned long)
((regs->phys_addr >> 32UL) & 0x0fffffff);
}
+
+struct fire_irq_data {
+ unsigned long pbm_regs;
+ u32 portid;
+};
+
+#define FIRE_IMAP_BASE 0x001000
+#define FIRE_ICLR_BASE 0x001400
+
+static unsigned long fire_imap_offset(unsigned long ino)
+{
+ return FIRE_IMAP_BASE + (ino * 8UL);
+}
+
+static unsigned long fire_iclr_offset(unsigned long ino)
+{
+ return FIRE_ICLR_BASE + (ino * 8UL);
+}
+
+static unsigned long fire_ino_to_iclr(unsigned long pbm_regs,
+ unsigned int ino)
+{
+ return pbm_regs + fire_iclr_offset(ino);
+}
+
+static unsigned long fire_ino_to_imap(unsigned long pbm_regs,
+ unsigned int ino)
+{
+ return pbm_regs + fire_imap_offset(ino);
+}
+
+static unsigned int fire_irq_build(struct device_node *dp,
+ unsigned int ino,
+ void *_data)
+{
+ struct fire_irq_data *irq_data = _data;
+ unsigned long pbm_regs = irq_data->pbm_regs;
+ unsigned long imap, iclr;
+ unsigned long int_ctrlr;
+
+ ino &= 0x3f;
+
+ /* Now build the IRQ bucket. */
+ imap = fire_ino_to_imap(pbm_regs, ino);
+ iclr = fire_ino_to_iclr(pbm_regs, ino);
+
+ /* Set the interrupt controller number. */
+ int_ctrlr = 1 << 6;
+ upa_writeq(int_ctrlr, imap);
+
+ /* The interrupt map registers do not have an INO field
+ * like other chips do. They return zero in the INO
+ * field, and the interrupt controller number is controlled
+ * in bits 6 thru 9. So in order for build_irq() to get
+ * the INO right we pass it in as part of the fixup
+ * which will get added to the map register zero value
+ * read by build_irq().
+ */
+ ino |= (irq_data->portid << 6);
+ ino -= int_ctrlr;
+ return build_irq(ino, iclr, imap);
+}
+
+static void __init fire_irq_trans_init(struct device_node *dp)
+{
+ const struct linux_prom64_registers *regs;
+ struct fire_irq_data *irq_data;
+
+ dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
+ dp->irq_trans->irq_build = fire_irq_build;
+
+ irq_data = prom_early_alloc(sizeof(struct fire_irq_data));
+
+ regs = of_get_property(dp, "reg", NULL);
+ dp->irq_trans->data = irq_data;
+
+ irq_data->pbm_regs = regs[0].phys_addr;
+ irq_data->portid = of_getintprop_default(dp, "portid", 0);
+}
#endif /* CONFIG_PCI */
#ifdef CONFIG_SBUS
return build_irq(sbus_level, iclr, imap);
}
-static void sbus_irq_trans_init(struct device_node *dp)
+static void __init sbus_irq_trans_init(struct device_node *dp)
{
const struct linux_prom64_registers *regs;
return build_irq(0, iclr, imap);
}
-static void central_irq_trans_init(struct device_node *dp)
+static void __init central_irq_trans_init(struct device_node *dp)
{
dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
dp->irq_trans->irq_build = central_build_irq;
};
#ifdef CONFIG_PCI
-static struct irq_trans pci_irq_trans_table[] = {
+static struct irq_trans __initdata pci_irq_trans_table[] = {
{ "SUNW,sabre", sabre_irq_trans_init },
{ "pci108e,a000", sabre_irq_trans_init },
{ "pci108e,a001", sabre_irq_trans_init },
{ "SUNW,tomatillo", tomatillo_irq_trans_init },
{ "pci108e,a801", tomatillo_irq_trans_init },
{ "SUNW,sun4v-pci", pci_sun4v_irq_trans_init },
+ { "pciex108e,80f0", fire_irq_trans_init },
};
#endif
return sun4v_build_irq(devhandle, devino);
}
-static void sun4v_vdev_irq_trans_init(struct device_node *dp)
+static void __init sun4v_vdev_irq_trans_init(struct device_node *dp)
{
const struct linux_prom64_registers *regs;
((regs->phys_addr >> 32UL) & 0x0fffffff);
}
-static void irq_trans_init(struct device_node *dp)
+static void __init irq_trans_init(struct device_node *dp)
{
#ifdef CONFIG_PCI
const char *model;