int __init wax_init_chip(struct parisc_device *dev) { struct gsc_asic *wax; struct parisc_device *parent; struct gsc_irq gsc_irq; int ret; wax = kzalloc(sizeof(*wax), GFP_KERNEL); if (!wax) return -ENOMEM; wax->name = "wax"; wax->hpa = dev->hpa.start; wax->version = 0; /* gsc_readb(wax->hpa+WAX_VER); */ printk(KERN_INFO "%s at 0x%lx found.\n", wax->name, wax->hpa); /* Stop wax hissing for a bit */ wax_init_irq(wax); /* the IRQ wax should use */ dev->irq = gsc_claim_irq(&gsc_irq, WAX_GSC_IRQ); if (dev->irq < 0) { printk(KERN_ERR "%s(): cannot get GSC irq\n", __func__); kfree(wax); return -EBUSY; } wax->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data; ret = request_irq(gsc_irq.irq, gsc_asic_intr, 0, "wax", wax); if (ret < 0) { kfree(wax); return ret; } /* enable IRQ's for devices below WAX */ gsc_writel(wax->eim, wax->hpa + OFFSET_IAR); /* Done init'ing, register this driver */ ret = gsc_common_setup(dev, wax); if (ret) { kfree(wax); return ret; } gsc_fixup_irqs(dev, wax, wax_choose_irq); /* On 715-class machines, Wax EISA is a sibling of Wax, not a child. */ parent = parisc_parent(dev); if (parent->id.hw_type != HPHW_IOA) { gsc_fixup_irqs(parent, wax, wax_choose_irq); } return ret; }
int __init asp_init_chip(struct parisc_device *dev) { struct gsc_asic *asp; struct gsc_irq gsc_irq; int ret; asp = kmalloc(sizeof(*asp), GFP_KERNEL); if(!asp) return -ENOMEM; asp->version = gsc_readb(dev->hpa + ASP_VER_OFFSET) & 0xf; asp->name = (asp->version == 1) ? "Asp" : "Cutoff"; asp->hpa = ASP_INTERRUPT_ADDR; printk(KERN_INFO "%s version %d at 0x%lx found.\n", asp->name, asp->version, dev->hpa); /* the IRQ ASP should use */ ret = -EBUSY; dev->irq = gsc_claim_irq(&gsc_irq, ASP_GSC_IRQ); if (dev->irq < 0) { printk(KERN_ERR "%s(): cannot get GSC irq\n", __FUNCTION__); goto out; } asp->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data; ret = request_irq(gsc_irq.irq, gsc_asic_intr, 0, "asp", asp); if (ret < 0) goto out; /* Program VIPER to interrupt on the ASP irq */ gsc_writel((1 << (31 - ASP_GSC_IRQ)),VIPER_INT_WORD); /* Done init'ing, register this driver */ ret = gsc_common_setup(dev, asp); if (ret) goto out; gsc_fixup_irqs(dev, asp, asp_choose_irq); /* Mongoose is a sibling of Asp, not a child... */ gsc_fixup_irqs(parisc_parent(dev), asp, asp_choose_irq); /* initialize the chassis LEDs */ #ifdef CONFIG_CHASSIS_LCD_LED register_led_driver(DISPLAY_MODEL_OLD_ASP, LED_CMD_REG_NONE, ASP_LED_ADDR); #endif return 0; out: kfree(asp); return ret; }
static int __init wax_init_chip(struct parisc_device *dev) { struct gsc_asic *wax; struct parisc_device *parent; struct gsc_irq gsc_irq; int ret; wax = kzalloc(sizeof(*wax), GFP_KERNEL); if (!wax) return -ENOMEM; wax->name = "wax"; wax->hpa = dev->hpa.start; wax->version = 0; /* */ printk(KERN_INFO "%s at 0x%lx found.\n", wax->name, wax->hpa); /* */ wax_init_irq(wax); /* */ dev->irq = gsc_claim_irq(&gsc_irq, WAX_GSC_IRQ); if (dev->irq < 0) { printk(KERN_ERR "%s(): cannot get GSC irq\n", __func__); kfree(wax); return -EBUSY; } wax->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data; ret = request_irq(gsc_irq.irq, gsc_asic_intr, 0, "wax", wax); if (ret < 0) { kfree(wax); return ret; } /* */ gsc_writel(wax->eim, wax->hpa + OFFSET_IAR); /* */ ret = gsc_common_setup(dev, wax); if (ret) { kfree(wax); return ret; } gsc_fixup_irqs(dev, wax, wax_choose_irq); /* */ parent = parisc_parent(dev); if (parent->id.hw_type != HPHW_IOA) { gsc_fixup_irqs(parent, wax, wax_choose_irq); } return ret; }
static int __init asp_init_chip(struct parisc_device *dev) { struct gsc_irq gsc_irq; int ret; asp.version = gsc_readb(dev->hpa.start + ASP_VER_OFFSET) & 0xf; asp.name = (asp.version == 1) ? "Asp" : "Cutoff"; asp.hpa = ASP_INTERRUPT_ADDR; #ifdef CONFIG_DEBUG_PRINTK printk(KERN_INFO "%s version %d at 0x%lx found.\n", asp.name, asp.version, (unsigned long)dev->hpa.start); #else ; #endif /* the IRQ ASP should use */ ret = -EBUSY; dev->irq = gsc_claim_irq(&gsc_irq, ASP_GSC_IRQ); if (dev->irq < 0) { printk(KERN_ERR "%s(): cannot get GSC irq\n", __func__); goto out; } asp.eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data; ret = request_irq(gsc_irq.irq, gsc_asic_intr, 0, "asp", &asp); if (ret < 0) goto out; /* Program VIPER to interrupt on the ASP irq */ gsc_writel((1 << (31 - ASP_GSC_IRQ)),VIPER_INT_WORD); /* Done init'ing, register this driver */ ret = gsc_common_setup(dev, &asp); if (ret) goto out; gsc_fixup_irqs(dev, &asp, asp_choose_irq); /* Mongoose is a sibling of Asp, not a child... */ gsc_fixup_irqs(parisc_parent(dev), &asp, asp_choose_irq); /* initialize the chassis LEDs */ #ifdef CONFIG_CHASSIS_LCD_LED register_led_driver(DISPLAY_MODEL_OLD_ASP, LED_CMD_REG_NONE, ASP_LED_ADDR); #endif out: return ret; }
static int __init lasi_init_chip(struct parisc_device *dev) { extern void (*chassis_power_off)(void); struct gsc_asic *lasi; struct gsc_irq gsc_irq; int ret; lasi = kzalloc(sizeof(*lasi), GFP_KERNEL); if (!lasi) return -ENOMEM; lasi->name = "Lasi"; lasi->hpa = dev->hpa.start; lasi->version = gsc_readl(lasi->hpa + LASI_VER) & 0xf; printk(KERN_INFO "%s version %d at 0x%lx found.\n", lasi->name, lasi->version, lasi->hpa); lasi_led_init(lasi->hpa); lasi_init_irq(lasi); dev->irq = gsc_alloc_irq(&gsc_irq); if (dev->irq < 0) { printk(KERN_ERR "%s(): cannot get GSC irq\n", __func__); kfree(lasi); return -EBUSY; } lasi->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data; ret = request_irq(gsc_irq.irq, gsc_asic_intr, 0, "lasi", lasi); if (ret < 0) { kfree(lasi); return ret; } gsc_writel(lasi->eim, lasi->hpa + OFFSET_IAR); ret = gsc_common_setup(dev, lasi); if (ret) { kfree(lasi); return ret; } gsc_fixup_irqs(dev, lasi, lasi_choose_irq); lasi_power_off_hpa = lasi->hpa; chassis_power_off = lasi_power_off; return ret; }
static int __init lasi_init_chip(struct parisc_device *dev) { extern void (*chassis_power_off)(void); struct gsc_asic *lasi; struct gsc_irq gsc_irq; int ret; lasi = kzalloc(sizeof(*lasi), GFP_KERNEL); if (!lasi) return -ENOMEM; lasi->name = "Lasi"; lasi->hpa = dev->hpa.start; /* Check the 4-bit (yes, only 4) version register */ lasi->version = gsc_readl(lasi->hpa + LASI_VER) & 0xf; printk(KERN_INFO "%s version %d at 0x%lx found.\n", lasi->name, lasi->version, lasi->hpa); /* initialize the chassis LEDs really early */ lasi_led_init(lasi->hpa); /* Stop LASI barking for a bit */ lasi_init_irq(lasi); /* the IRQ lasi should use */ dev->irq = gsc_alloc_irq(&gsc_irq); if (dev->irq < 0) { printk(KERN_ERR "%s(): cannot get GSC irq\n", __func__); kfree(lasi); return -EBUSY; } lasi->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data; ret = request_irq(gsc_irq.irq, gsc_asic_intr, 0, "lasi", lasi); if (ret < 0) { kfree(lasi); return ret; } /* enable IRQ's for devices below LASI */ gsc_writel(lasi->eim, lasi->hpa + OFFSET_IAR); /* Done init'ing, register this driver */ ret = gsc_common_setup(dev, lasi); if (ret) { kfree(lasi); return ret; } gsc_fixup_irqs(dev, lasi, lasi_choose_irq); /* initialize the power off function */ lasi_power_off_hpa = lasi->hpa; chassis_power_off = lasi_power_off; return ret; }
static int __init asp_init_chip(struct parisc_device *dev) { struct gsc_irq gsc_irq; int ret; asp.version = gsc_readb(dev->hpa.start + ASP_VER_OFFSET) & 0xf; asp.name = (asp.version == 1) ? "Asp" : "Cutoff"; asp.hpa = ASP_INTERRUPT_ADDR; printk(KERN_INFO "%s version %d at 0x%lx found.\n", asp.name, asp.version, (unsigned long)dev->hpa.start); ret = -EBUSY; dev->irq = gsc_claim_irq(&gsc_irq, ASP_GSC_IRQ); if (dev->irq < 0) { printk(KERN_ERR "%s(): cannot get GSC irq\n", __func__); goto out; } asp.eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data; ret = request_irq(gsc_irq.irq, gsc_asic_intr, 0, "asp", &asp); if (ret < 0) goto out; gsc_writel((1 << (31 - ASP_GSC_IRQ)),VIPER_INT_WORD); ret = gsc_common_setup(dev, &asp); if (ret) goto out; gsc_fixup_irqs(dev, &asp, asp_choose_irq); gsc_fixup_irqs(parisc_parent(dev), &asp, asp_choose_irq); #ifdef CONFIG_CHASSIS_LCD_LED register_led_driver(DISPLAY_MODEL_OLD_ASP, LED_CMD_REG_NONE, ASP_LED_ADDR); #endif out: return ret; }
static int gsc_fixup_irqs_callback(struct device *dev, void *data) { struct parisc_device *padev = to_parisc_device(dev); struct gsc_fixup_struct *gf = data; if (padev->id.hw_type == HPHW_FAULTY) gsc_fixup_irqs(padev, gf->ctrl, gf->choose_irq); gf->choose_irq(padev, gf->ctrl); return 0; }
static int gsc_fixup_irqs_callback(struct device *dev, void *data) { struct parisc_device *padev = to_parisc_device(dev); struct gsc_fixup_struct *gf = data; /* work-around for 715/64 and others which have parent at path [5] and children at path [5/0/x] */ if (padev->id.hw_type == HPHW_FAULTY) gsc_fixup_irqs(padev, gf->ctrl, gf->choose_irq); gf->choose_irq(padev, gf->ctrl); return 0; }
void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl, void (*choose_irq)(struct parisc_device *, void *)) { struct device *dev; struct klist_iter i; klist_iter_init(&parent->dev.klist_children, &i); while ((dev = next_device(&i))) { struct parisc_device *padev = to_parisc_device(dev); /* work-around for 715/64 and others which have parent at path [5] and children at path [5/0/x] */ if (padev->id.hw_type == HPHW_FAULTY) return gsc_fixup_irqs(padev, ctrl, choose_irq); choose_irq(padev, ctrl); } klist_iter_exit(&i); }