static int ftr_get_detect(struct gpio_runtime *rt, enum notify_type type) { int gpio, ret, active; switch (type) { case AOA_NOTIFY_HEADPHONE: gpio = headphone_detect_gpio; active = headphone_detect_gpio_activestate; break; case AOA_NOTIFY_LINE_IN: gpio = linein_detect_gpio; active = linein_detect_gpio_activestate; break; case AOA_NOTIFY_LINE_OUT: gpio = lineout_detect_gpio; active = lineout_detect_gpio_activestate; break; default: return -EINVAL; } if (gpio == -1) return -ENODEV; ret = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio, 0); if (ret < 0) return ret; return ((ret >> 1) & 1) == active; }
static int airport_suspend(struct macio_dev *mdev, pm_message_t state) { struct orinoco_private *priv = dev_get_drvdata(&mdev->ofdev.dev); struct net_device *dev = priv->ndev; struct airport *card = priv->card; unsigned long flags; int err; printk(KERN_DEBUG "%s: Airport entering sleep mode\n", dev->name); err = orinoco_lock(priv, &flags); if (err) { printk(KERN_ERR "%s: hw_unavailable on PBOOK_SLEEP_NOW\n", dev->name); return 0; } orinoco_down(priv); orinoco_unlock(priv, &flags); disable_irq(card->irq); pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 0); return 0; }
static int ohci_rbus_resume (struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); int retval = 0; #ifdef CONFIG_PMAC_PBOOK if (_machine == _MACH_Pmac) { struct device_node *of_node; /* Re-enable USB PAD & cell clock */ of_node = pci_device_to_OF_node (to_pci_dev(hcd->self.controller)); if (of_node) pmac_call_feature (PMAC_FTR_USB_ENABLE, of_node, 0, 1); } #endif /* CONFIG_PMAC_PBOOK */ /* resume root hub */ if (time_before (jiffies, ohci->next_statechange)) msleep (100); #ifdef CONFIG_USB_SUSPEND /* get extra cleanup even if remote wakeup isn't in use */ retval = usb_resume_device (hcd->self.root_hub); #else usb_lock_device (hcd->self.root_hub); retval = ohci_hub_resume (hcd); usb_unlock_device (hcd->self.root_hub); #endif return retval; }
static int airport_detach(struct macio_dev *mdev) { struct orinoco_private *priv = dev_get_drvdata(&mdev->ofdev.dev); struct airport *card = priv->card; if (card->ndev_registered) orinoco_if_del(priv); card->ndev_registered = 0; if (card->irq_requested) free_irq(card->irq, priv); card->irq_requested = 0; if (card->vaddr) iounmap(card->vaddr); card->vaddr = NULL; macio_release_resource(mdev, 0); pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 0); ssleep(1); macio_set_drvdata(mdev, NULL); free_orinocodev(priv); return 0; }
static void airport_detach(struct net_device *dev) { struct orinoco_private *priv = dev->priv; struct airport *card = priv->card; #ifdef CONFIG_PMAC_PBOOK pmu_unregister_sleep_notifier(&airport_sleep_notifier); #endif if (card->ndev_registered) unregister_netdev(dev); card->ndev_registered = 0; if (card->irq_requested) free_irq(dev->irq, priv); card->irq_requested = 0; if (card->vaddr) iounmap(card->vaddr); card->vaddr = 0; dev->base_addr = 0; release_OF_resource(card->node, 0); pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 0); current->state = TASK_UNINTERRUPTIBLE; schedule_timeout(HZ); kfree(dev); } /* airport_detach */
static int ohci_rbus_suspend (struct usb_hcd *hcd, pm_message_t message) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); /* suspend root hub, hoping it keeps power during suspend */ if (time_before (jiffies, ohci->next_statechange)) msleep (100); #ifdef CONFIG_USB_SUSPEND (void) usb_suspend_device (hcd->self.root_hub, message); #else usb_lock_device (hcd->self.root_hub); (void) ohci_hub_suspend (hcd); usb_unlock_device (hcd->self.root_hub); #endif /* let things settle down a bit */ msleep (100); #ifdef CONFIG_PMAC_PBOOK if (_machine == _MACH_Pmac) { struct device_node *of_node; /* Disable USB PAD & cell clock */ of_node = pci_device_to_OF_node (to_pci_dev(hcd->self.controller)); if (of_node) pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0); } #endif /* CONFIG_PMAC_PBOOK */ return 0; }
static int airport_suspend(struct macio_dev *mdev, pm_message_t state) { struct net_device *dev = dev_get_drvdata(&mdev->ofdev.dev); struct orinoco_private *priv = netdev_priv(dev); unsigned long flags; int err; printk(KERN_DEBUG "%s: Airport entering sleep mode\n", dev->name); err = orinoco_lock(priv, &flags); if (err) { printk(KERN_ERR "%s: hw_unavailable on PBOOK_SLEEP_NOW\n", dev->name); return 0; } err = __orinoco_down(dev); if (err) printk(KERN_WARNING "%s: PBOOK_SLEEP_NOW: Error %d downing interface\n", dev->name, err); netif_device_detach(dev); priv->hw_unavailable++; orinoco_unlock(priv, &flags); disable_irq(dev->irq); pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 0); return 0; }
void __pmac pmac_show_cpuinfo(struct seq_file *m) { struct device_node *np; char *pp; int plen; char* mbname; int mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_MODEL, 0); unsigned int mbflags = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_FLAGS, 0); if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME, (long)&mbname) != 0) mbname = "Unknown"; /* find motherboard type */ seq_printf(m, "machine\t\t: "); np = find_devices("device-tree"); if (np != NULL) { pp = (char *) get_property(np, "model", NULL); if (pp != NULL) seq_printf(m, "%s\n", pp); else seq_printf(m, "PowerMac\n"); pp = (char *) get_property(np, "compatible", &plen); if (pp != NULL) { seq_printf(m, "motherboard\t:"); while (plen > 0) { int l = strlen(pp) + 1; seq_printf(m, " %s", pp); plen -= l; pp += l; } seq_printf(m, "\n"); } } else seq_printf(m, "PowerMac\n"); /* print parsed model */ seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname); seq_printf(m, "pmac flags\t: %08x\n", mbflags); /* Indicate newworld */ seq_printf(m, "pmac-generation\t: NewWorld\n"); }
static void __init smp_core99_kick_cpu(int nr) { int save_vector, j; unsigned long new_vector; unsigned long flags; volatile unsigned int *vector = ((volatile unsigned int *)(KERNELBASE+0x100)); if (nr < 1 || nr > 3) return; if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346); local_irq_save(flags); local_irq_disable(); /* Save reset vector */ save_vector = *vector; /* Setup fake reset vector that does * b .pmac_secondary_start - KERNELBASE */ switch(nr) { case 1: new_vector = (unsigned long)pmac_secondary_start_1; break; case 2: new_vector = (unsigned long)pmac_secondary_start_2; break; case 3: default: new_vector = (unsigned long)pmac_secondary_start_3; break; } *vector = 0x48000002 + (new_vector - KERNELBASE); /* flush data cache and inval instruction cache */ flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); /* Put some life in our friend */ pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0); paca[nr].cpu_start = 1; /* FIXME: We wait a bit for the CPU to take the exception, I should * instead wait for the entry code to set something for me. Well, * ideally, all that crap will be done in prom.c and the CPU left * in a RAM-based wait loop like CHRP. */ for (j = 1; j < 1000000; j++) mb(); /* Restore our exception vector */ *vector = save_vector; flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); local_irq_restore(flags); if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347); }
static __init void pmac_init_IRQ(void) { struct device_node *irqctrler = NULL; struct device_node *irqctrler2 = NULL; struct device_node *np = NULL; struct mpic *mpic1, *mpic2; /* We first try to detect Apple's new Core99 chipset, since mac-io * is quite different on those machines and contains an IBM MPIC2. */ while ((np = of_find_node_by_type(np, "open-pic")) != NULL) { struct device_node *parent = of_get_parent(np); if (parent && !strcmp(parent->name, "u3")) irqctrler2 = of_node_get(np); else irqctrler = of_node_get(np); of_node_put(parent); } if (irqctrler != NULL && irqctrler->n_addrs > 0) { unsigned char senses[128]; printk(KERN_INFO "PowerMac using OpenPIC irq controller at 0x%08x\n", (unsigned int)irqctrler->addrs[0].address); prom_get_irq_senses(senses, 0, 128); mpic1 = mpic_alloc(irqctrler->addrs[0].address, MPIC_PRIMARY | MPIC_WANTS_RESET, 0, 0, 128, 256, senses, 128, " K2-MPIC "); BUG_ON(mpic1 == NULL); mpic_init(mpic1); if (irqctrler2 != NULL && irqctrler2->n_intrs > 0 && irqctrler2->n_addrs > 0) { printk(KERN_INFO "Slave OpenPIC at 0x%08x hooked on IRQ %d\n", (u32)irqctrler2->addrs[0].address, irqctrler2->intrs[0].line); pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler2, 0, 0); prom_get_irq_senses(senses, 128, 128 + 128); /* We don't need to set MPIC_BROKEN_U3 here since we don't have * hypertransport interrupts routed to it */ mpic2 = mpic_alloc(irqctrler2->addrs[0].address, MPIC_BIG_ENDIAN | MPIC_WANTS_RESET, 0, 128, 128, 0, senses, 128, " U3-MPIC "); BUG_ON(mpic2 == NULL); mpic_init(mpic2); mpic_setup_cascade(irqctrler2->intrs[0].line, pmac_u3_cascade, mpic2); } } of_node_put(irqctrler); of_node_put(irqctrler2); }
/* Turn off the chip's clock */ static void gem_put_cell(struct gem *gp) { BUG_ON(gp->cell_enabled <= 0); gp->cell_enabled--; #ifdef CONFIG_PPC_PMAC if (gp->cell_enabled == 0) { mb(); pmac_call_feature(PMAC_FTR_GMAC_ENABLE, gp->of_node, 0, 0); udelay(10); } #endif /* CONFIG_PPC_PMAC */ }
static int airport_hard_reset(struct orinoco_private *priv) { #if 0 struct airport *card = priv->card; disable_irq(card->irq); pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(card->mdev), 0, 0); ssleep(1); pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(card->mdev), 0, 1); ssleep(1); enable_irq(card->irq); ssleep(1); #endif return 0; }
static void __exit cnxthwusb_cleanup (void) { dbg("%s", __FUNCTION__); usb_deregister(&cnxthwusb_driver); #ifdef CONFIG_PPC_PMAC if(pmacftrmodemenable) { int ret = pmac_call_feature(PMAC_FTR_MODEM_ENABLE, NULL, 0, 0); if(ret) { err("%s: cannot disable internal modem (%d)", __FUNCTION__, ret); return; } } #endif }
static int hcd_pci_suspend_noirq(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); struct usb_hcd *hcd = pci_get_drvdata(pci_dev); int retval; retval = check_root_hub_suspended(dev); if (retval) return retval; pci_save_state(pci_dev); /* If the root hub is HALTed rather than SUSPENDed, * disallow remote wakeup. */ if (hcd->state == HC_STATE_HALT) device_set_wakeup_enable(dev, 0); dev_dbg(dev, "wakeup: %d\n", device_may_wakeup(dev)); /* Possibly enable remote wakeup, * choose the appropriate low-power state, and go to that state. */ retval = pci_prepare_to_sleep(pci_dev); if (retval == -EIO) { /* Low-power not supported */ dev_dbg(dev, "--> PCI D0 legacy\n"); retval = 0; } else if (retval == 0) { dev_dbg(dev, "--> PCI %s\n", pci_power_name(pci_dev->current_state)); } else { suspend_report_result(pci_prepare_to_sleep, retval); return retval; } #ifdef CONFIG_PPC_PMAC /* Disable ASIC clocks for USB */ if (machine_is(powermac)) { struct device_node *of_node; of_node = pci_device_to_OF_node(pci_dev); if (of_node) pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0); } #endif return retval; }
static int hcd_pci_resume_noirq(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); #ifdef CONFIG_PPC_PMAC /* Reenable ASIC clocks for USB */ if (machine_is(powermac)) { struct device_node *of_node; of_node = pci_device_to_OF_node(pci_dev); if (of_node) pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 1); } #endif /* Go back to D0 and disable remote wakeup */ pci_back_from_sleep(pci_dev); return 0; }
static int airport_resume(struct macio_dev *mdev) { struct net_device *dev = dev_get_drvdata(&mdev->ofdev.dev); struct orinoco_private *priv = netdev_priv(dev); unsigned long flags; int err; printk(KERN_DEBUG "%s: Airport waking up\n", dev->name); pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 1); msleep(200); enable_irq(dev->irq); err = orinoco_reinit_firmware(dev); if (err) { printk(KERN_ERR "%s: Error %d re-initializing firmware on PBOOK_WAKE\n", dev->name, err); return 0; } spin_lock_irqsave(&priv->lock, flags); netif_device_attach(dev); priv->hw_unavailable--; if (priv->open && (! priv->hw_unavailable)) { err = __orinoco_up(dev); if (err) printk(KERN_ERR "%s: Error %d restarting card on PBOOK_WAKE\n", dev->name, err); } spin_unlock_irqrestore(&priv->lock, flags); return 0; }
static int __init cnxthwusb_init (void) { int ret; dbg("%s", __FUNCTION__); #ifdef CONFIG_PPC_PMAC if(pmacftrmodemenable) { ret = pmac_call_feature(PMAC_FTR_MODEM_ENABLE, NULL, 0, 1); if(ret) { err("%s: cannot enable internal modem (%d)", __FUNCTION__, ret); return ret; } } #endif ret = usb_register(&cnxthwusb_driver); if(ret) { err("%s: usb_register (%d) failed", __FUNCTION__, ret); } return ret; }
static int airport_resume(struct macio_dev *mdev) { struct orinoco_private *priv = dev_get_drvdata(&mdev->ofdev.dev); struct net_device *dev = priv->ndev; struct airport *card = priv->card; unsigned long flags; int err; printk(KERN_DEBUG "%s: Airport waking up\n", dev->name); pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 1); msleep(200); enable_irq(card->irq); spin_lock_irqsave(&priv->lock, flags); err = orinoco_up(priv); spin_unlock_irqrestore(&priv->lock, flags); return err; }
void __init pmac_setup_arch(void) { /* init to some ~sane value until calibrate_delay() runs */ loops_per_jiffy = 50000000; /* Probe motherboard chipset */ pmac_feature_init(); #if 0 /* Lock-enable the SCC channel used for debug */ if (sccdbg) { np = of_find_node_by_name(NULL, "escc"); if (np) pmac_call_feature(PMAC_FTR_SCC_ENABLE, np, PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1); } #endif /* We can NAP */ powersave_nap = 1; /* Initialize the PMU */ find_via_pmu(); /* Init NVRAM access */ pmac_nvram_init(); /* Setup SMP callback */ #ifdef CONFIG_SMP pmac_setup_smp(); #endif /* Lookup PCI hosts */ pmac_pci_init(); #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; #endif }
static int airport_sleep_notify(struct pmu_sleep_notifier *self, int when) { struct net_device *dev = airport_dev; struct orinoco_private *priv = dev->priv; struct airport *card = priv->card; unsigned long flags; int err; if (! airport_dev) return PBOOK_SLEEP_OK; switch (when) { case PBOOK_SLEEP_NOW: printk(KERN_DEBUG "%s: Airport entering sleep mode\n", dev->name); err = orinoco_lock(priv, &flags); if (err) { printk(KERN_ERR "%s: hw_unavailable on PBOOK_SLEEP_NOW\n", dev->name); break; } err = __orinoco_down(dev); if (err) printk(KERN_WARNING "%s: PBOOK_SLEEP_NOW: Error %d downing interface\n", dev->name, err); netif_device_detach(dev); priv->hw_unavailable = 1; orinoco_unlock(priv, &flags); disable_irq(dev->irq); pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 0); break; case PBOOK_WAKE: printk(KERN_DEBUG "%s: Airport waking up\n", dev->name); pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 1); mdelay(200); enable_irq(dev->irq); err = orinoco_reinit_firmware(dev); if (err) { printk(KERN_ERR "%s: Error %d re-initializing firmware on PBOOK_WAKE\n", dev->name, err); break; } spin_lock_irqsave(&priv->lock, flags); netif_device_attach(dev); if (priv->open) { err = __orinoco_up(dev); if (err) printk(KERN_ERR "%s: Error %d restarting card on PBOOK_WAKE\n", dev->name, err); } priv->hw_unavailable = 0; spin_unlock_irqrestore(&priv->lock, flags); break; } return PBOOK_SLEEP_OK; }
static int swim3_add_device(struct macio_dev *mdev, int index) { struct device_node *swim = mdev->ofdev.dev.of_node; struct floppy_state *fs = &floppy_states[index]; int rc = -EBUSY; /* Check & Request resources */ if (macio_resource_count(mdev) < 2) { printk(KERN_WARNING "ifd%d: no address for %s\n", index, swim->full_name); return -ENXIO; } if (macio_irq_count(mdev) < 2) { printk(KERN_WARNING "fd%d: no intrs for device %s\n", index, swim->full_name); } if (macio_request_resource(mdev, 0, "swim3 (mmio)")) { printk(KERN_ERR "fd%d: can't request mmio resource for %s\n", index, swim->full_name); return -EBUSY; } if (macio_request_resource(mdev, 1, "swim3 (dma)")) { printk(KERN_ERR "fd%d: can't request dma resource for %s\n", index, swim->full_name); macio_release_resource(mdev, 0); return -EBUSY; } dev_set_drvdata(&mdev->ofdev.dev, fs); if (mdev->media_bay == NULL) pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1); memset(fs, 0, sizeof(*fs)); spin_lock_init(&fs->lock); fs->state = idle; fs->swim3 = (struct swim3 __iomem *) ioremap(macio_resource_start(mdev, 0), 0x200); if (fs->swim3 == NULL) { printk("fd%d: couldn't map registers for %s\n", index, swim->full_name); rc = -ENOMEM; goto out_release; } fs->dma = (struct dbdma_regs __iomem *) ioremap(macio_resource_start(mdev, 1), 0x200); if (fs->dma == NULL) { printk("fd%d: couldn't map DMA for %s\n", index, swim->full_name); iounmap(fs->swim3); rc = -ENOMEM; goto out_release; } fs->swim3_intr = macio_irq(mdev, 0); fs->dma_intr = macio_irq(mdev, 1); fs->cur_cyl = -1; fs->cur_sector = -1; fs->secpercyl = 36; fs->secpertrack = 18; fs->total_secs = 2880; fs->mdev = mdev; init_waitqueue_head(&fs->wait); fs->dma_cmd = (struct dbdma_cmd *) DBDMA_ALIGN(fs->dbdma_cmd_space); memset(fs->dma_cmd, 0, 2 * sizeof(struct dbdma_cmd)); st_le16(&fs->dma_cmd[1].command, DBDMA_STOP); if (request_irq(fs->swim3_intr, swim3_interrupt, 0, "SWIM3", fs)) { printk(KERN_ERR "fd%d: couldn't request irq %d for %s\n", index, fs->swim3_intr, swim->full_name); pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0); goto out_unmap; return -EBUSY; } /* if (request_irq(fs->dma_intr, fd_dma_interrupt, 0, "SWIM3-dma", fs)) { printk(KERN_ERR "Couldn't get irq %d for SWIM3 DMA", fs->dma_intr); return -EBUSY; } */ init_timer(&fs->timeout); printk(KERN_INFO "fd%d: SWIM3 floppy controller %s\n", floppy_count, mdev->media_bay ? "in media bay" : ""); return 0; out_unmap: iounmap(fs->dma); iounmap(fs->swim3); out_release: macio_release_resource(mdev, 0); macio_release_resource(mdev, 1); return rc; }
static int ohci_pci_suspend (struct pci_dev *dev, u32 state) { ohci_t *ohci = (ohci_t *) pci_get_drvdata(dev); unsigned long flags; u16 cmd; if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) { dbg ("can't suspend usb-%s (state is %s)", dev->slot_name, hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS)); return -EIO; } /* act as if usb suspend can always be used */ info ("USB suspend: usb-%s", dev->slot_name); ohci->sleeping = 1; /* First stop processing */ spin_lock_irqsave (&usb_ed_lock, flags); ohci->hc_control &= ~(OHCI_CTRL_PLE|OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_IE); writel (ohci->hc_control, &ohci->regs->control); writel (OHCI_INTR_SF, &ohci->regs->intrstatus); (void) readl (&ohci->regs->intrstatus); spin_unlock_irqrestore (&usb_ed_lock, flags); /* Wait a frame or two */ mdelay(1); if (!readl (&ohci->regs->intrstatus) & OHCI_INTR_SF) mdelay (1); #ifdef CONFIG_PMAC_PBOOK if (_machine == _MACH_Pmac) disable_irq (ohci->irq); /* else, 2.4 assumes shared irqs -- don't disable */ #endif /* Enable remote wakeup */ writel (readl(&ohci->regs->intrenable) | OHCI_INTR_RD, &ohci->regs->intrenable); /* Suspend chip and let things settle down a bit */ ohci->hc_control = OHCI_USB_SUSPEND; writel (ohci->hc_control, &ohci->regs->control); (void) readl (&ohci->regs->control); mdelay (500); /* No schedule here ! */ switch (readl (&ohci->regs->control) & OHCI_CTRL_HCFS) { case OHCI_USB_RESET: dbg("Bus in reset phase ???"); break; case OHCI_USB_RESUME: dbg("Bus in resume phase ???"); break; case OHCI_USB_OPER: dbg("Bus in operational phase ???"); break; case OHCI_USB_SUSPEND: dbg("Bus suspended"); break; } /* In some rare situations, Apple's OHCI have happily trashed * memory during sleep. We disable it's bus master bit during * suspend */ pci_read_config_word (dev, PCI_COMMAND, &cmd); cmd &= ~PCI_COMMAND_MASTER; pci_write_config_word (dev, PCI_COMMAND, cmd); #ifdef CONFIG_PMAC_PBOOK { struct device_node *of_node; /* Disable USB PAD & cell clock */ of_node = pci_device_to_OF_node (ohci->ohci_dev); if (of_node) pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0); } #endif return 0; }
static int airport_attach(struct macio_dev *mdev, const struct of_device_id *match) { struct orinoco_private *priv; struct net_device *dev; struct airport *card; unsigned long phys_addr; hermes_t *hw; if (macio_resource_count(mdev) < 1 || macio_irq_count(mdev) < 1) { printk(KERN_ERR PFX "Wrong interrupt/addresses in OF tree\n"); return -ENODEV; } /* Allocate space for private device-specific data */ dev = alloc_orinocodev(sizeof(*card), airport_hard_reset); if (! dev) { printk(KERN_ERR PFX "Cannot allocate network device\n"); return -ENODEV; } priv = netdev_priv(dev); card = priv->card; hw = &priv->hw; card->mdev = mdev; if (macio_request_resource(mdev, 0, "airport")) { printk(KERN_ERR PFX "can't request IO resource !\n"); free_orinocodev(dev); return -EBUSY; } SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &mdev->ofdev.dev); macio_set_drvdata(mdev, dev); /* Setup interrupts & base address */ dev->irq = macio_irq(mdev, 0); phys_addr = macio_resource_start(mdev, 0); /* Physical address */ printk(KERN_DEBUG PFX "Physical address %lx\n", phys_addr); dev->base_addr = phys_addr; card->vaddr = ioremap(phys_addr, AIRPORT_IO_LEN); if (!card->vaddr) { printk(KERN_ERR PFX "ioremap() failed\n"); goto failed; } hermes_struct_init(hw, card->vaddr, HERMES_16BIT_REGSPACING); /* Power up card */ pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 1); ssleep(1); /* Reset it before we get the interrupt */ hermes_init(hw); if (request_irq(dev->irq, orinoco_interrupt, 0, dev->name, dev)) { printk(KERN_ERR PFX "Couldn't get IRQ %d\n", dev->irq); goto failed; } card->irq_requested = 1; /* Tell the stack we exist */ if (register_netdev(dev) != 0) { printk(KERN_ERR PFX "register_netdev() failed\n"); goto failed; } printk(KERN_DEBUG PFX "Card registered for interface %s\n", dev->name); card->ndev_registered = 1; return 0; failed: airport_detach(mdev); return -ENODEV; } /* airport_attach */
/** * usb_hcd_pci_resume - power management resume of a PCI-based HCD * @dev: USB Host Controller being resumed * * Store this function in the HCD's struct pci_driver as resume(). */ int usb_hcd_pci_resume (struct pci_dev *dev) { struct usb_hcd *hcd; int retval; hcd = pci_get_drvdata(dev); if (hcd->state != HC_STATE_SUSPENDED) { dev_dbg (hcd->self.controller, "can't resume, not suspended!\n"); return 0; } #ifdef CONFIG_PPC_PMAC /* Reenable ASIC clocks for USB */ if (machine_is(powermac)) { struct device_node *of_node; of_node = pci_device_to_OF_node (dev); if (of_node) pmac_call_feature (PMAC_FTR_USB_ENABLE, of_node, 0, 1); } #endif /* NOTE: chip docs cover clean "real suspend" cases (what Linux * calls "standby", "suspend to RAM", and so on). There are also * dirty cases when swsusp fakes a suspend in "shutdown" mode. */ if (dev->current_state != PCI_D0) { #ifdef DEBUG int pci_pm; u16 pmcr; pci_pm = pci_find_capability(dev, PCI_CAP_ID_PM); pci_read_config_word(dev, pci_pm + PCI_PM_CTRL, &pmcr); pmcr &= PCI_PM_CTRL_STATE_MASK; if (pmcr) { /* Clean case: power to USB and to HC registers was * maintained; remote wakeup is easy. */ dev_dbg(hcd->self.controller, "resume from PCI D%d\n", pmcr); } else { /* Clean: HC lost Vcc power, D0 uninitialized * + Vaux may have preserved port and transceiver * state ... for remote wakeup from D3cold * + or not; HCD must reinit + re-enumerate * * Dirty: D0 semi-initialized cases with swsusp * + after BIOS init * + after Linux init (HCD statically linked) */ dev_dbg(hcd->self.controller, "PCI D0, from previous PCI D%d\n", dev->current_state); } #endif /* yes, ignore these results too... */ (void) pci_enable_wake (dev, dev->current_state, 0); (void) pci_enable_wake (dev, PCI_D3cold, 0); } else { /* Same basic cases: clean (powered/not), dirty */ dev_dbg(hcd->self.controller, "PCI legacy resume\n"); } /* NOTE: the PCI API itself is asymmetric here. We don't need to * pci_set_power_state(PCI_D0) since that's part of re-enabling; * but that won't re-enable bus mastering. Yet pci_disable_device() * explicitly disables bus mastering... */ retval = pci_enable_device (dev); if (retval < 0) { dev_err (hcd->self.controller, "can't re-enable after resume, %d!\n", retval); return retval; } pci_set_master (dev); pci_restore_state (dev); dev->dev.power.power_state = PMSG_ON; clear_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); if (hcd->driver->resume) { retval = hcd->driver->resume(hcd); if (retval) { dev_err (hcd->self.controller, "PCI post-resume error %d!\n", retval); usb_hc_died (hcd); } } return retval; }
static int ohci_pci_resume (struct pci_dev *dev) { ohci_t *ohci = (ohci_t *) pci_get_drvdata(dev); int temp; unsigned long flags; /* guard against multiple resumes */ atomic_inc (&ohci->resume_count); if (atomic_read (&ohci->resume_count) != 1) { err ("concurrent PCI resumes for usb-%s", dev->slot_name); atomic_dec (&ohci->resume_count); return 0; } #ifdef CONFIG_PMAC_PBOOK { struct device_node *of_node; /* Re-enable USB PAD & cell clock */ of_node = pci_device_to_OF_node (ohci->ohci_dev); if (of_node) pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 1); } #endif /* did we suspend, or were we powered off? */ ohci->hc_control = readl (&ohci->regs->control); temp = ohci->hc_control & OHCI_CTRL_HCFS; #ifdef DEBUG /* the registers may look crazy here */ ohci_dump_status (ohci); #endif /* Re-enable bus mastering */ pci_set_master(ohci->ohci_dev); switch (temp) { case OHCI_USB_RESET: // lost power info ("USB restart: usb-%s", dev->slot_name); hc_restart (ohci); break; case OHCI_USB_SUSPEND: // host wakeup case OHCI_USB_RESUME: // remote wakeup info ("USB continue: usb-%s from %s wakeup", dev->slot_name, (temp == OHCI_USB_SUSPEND) ? "host" : "remote"); ohci->hc_control = OHCI_USB_RESUME; writel (ohci->hc_control, &ohci->regs->control); (void) readl (&ohci->regs->control); mdelay (20); /* no schedule here ! */ /* Some controllers (lucent) need a longer delay here */ mdelay (15); temp = readl (&ohci->regs->control); temp = ohci->hc_control & OHCI_CTRL_HCFS; if (temp != OHCI_USB_RESUME) { err ("controller usb-%s won't resume", dev->slot_name); ohci->disabled = 1; return -EIO; } /* Some chips likes being resumed first */ writel (OHCI_USB_OPER, &ohci->regs->control); (void) readl (&ohci->regs->control); mdelay (3); /* Then re-enable operations */ spin_lock_irqsave (&usb_ed_lock, flags); ohci->disabled = 0; ohci->sleeping = 0; ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER; if (!ohci->ed_rm_list[0] && !ohci->ed_rm_list[1]) { if (ohci->ed_controltail) ohci->hc_control |= OHCI_CTRL_CLE; if (ohci->ed_bulktail) ohci->hc_control |= OHCI_CTRL_BLE; } writel (ohci->hc_control, &ohci->regs->control); writel (OHCI_INTR_SF, &ohci->regs->intrstatus); writel (OHCI_INTR_SF, &ohci->regs->intrenable); /* Check for a pending done list */ writel (OHCI_INTR_WDH, &ohci->regs->intrdisable); (void) readl (&ohci->regs->intrdisable); spin_unlock_irqrestore (&usb_ed_lock, flags); #ifdef CONFIG_PMAC_PBOOK if (_machine == _MACH_Pmac) enable_irq (ohci->irq); #endif if (ohci->hcca->done_head) dl_done_list (ohci, dl_reverse_done_list (ohci)); writel (OHCI_INTR_WDH, &ohci->regs->intrenable); writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */ writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */ break; default: warn ("odd PCI resume for usb-%s", dev->slot_name); } /* controller is operational, extra resumes are harmless */ atomic_dec (&ohci->resume_count); return 0; }
/** * usb_hcd_pci_suspend - power management suspend of a PCI-based HCD * @dev: USB Host Controller being suspended * @message: semantics in flux * * Store this function in the HCD's struct pci_driver as suspend(). */ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) { struct usb_hcd *hcd; int retval = 0; int has_pci_pm; hcd = pci_get_drvdata(dev); /* Root hub suspend should have stopped all downstream traffic, * and all bus master traffic. And done so for both the interface * and the stub usb_device (which we check here). But maybe it * didn't; writing sysfs power/state files ignores such rules... * * We must ignore the FREEZE vs SUSPEND distinction here, because * otherwise the swsusp will save (and restore) garbage state. */ if (!(hcd->state == HC_STATE_SUSPENDED || hcd->state == HC_STATE_HALT)) return -EBUSY; if (hcd->driver->suspend) { retval = hcd->driver->suspend(hcd, message); suspend_report_result(hcd->driver->suspend, retval); if (retval) goto done; } synchronize_irq(dev->irq); /* FIXME until the generic PM interfaces change a lot more, this * can't use PCI D1 and D2 states. For example, the confusion * between messages and states will need to vanish, and messages * will need to provide a target system state again. * * It'll be important to learn characteristics of the target state, * especially on embedded hardware where the HCD will often be in * charge of an external VBUS power supply and one or more clocks. * Some target system states will leave them active; others won't. * (With PCI, that's often handled by platform BIOS code.) */ /* even when the PCI layer rejects some of the PCI calls * below, HCs can try global suspend and reduce DMA traffic. * PM-sensitive HCDs may already have done this. */ has_pci_pm = pci_find_capability(dev, PCI_CAP_ID_PM); /* Downstream ports from this root hub should already be quiesced, so * there will be no DMA activity. Now we can shut down the upstream * link (except maybe for PME# resume signaling) and enter some PCI * low power state, if the hardware allows. */ if (hcd->state == HC_STATE_SUSPENDED) { /* no DMA or IRQs except when HC is active */ if (dev->current_state == PCI_D0) { pci_save_state (dev); pci_disable_device (dev); } if (!has_pci_pm) { dev_dbg (hcd->self.controller, "--> PCI D0/legacy\n"); goto done; } /* NOTE: dev->current_state becomes nonzero only here, and * only for devices that support PCI PM. Also, exiting * PCI_D3 (but not PCI_D1 or PCI_D2) is allowed to reset * some device state (e.g. as part of clock reinit). */ retval = pci_set_power_state (dev, PCI_D3hot); suspend_report_result(pci_set_power_state, retval); if (retval == 0) { int wake = device_can_wakeup(&hcd->self.root_hub->dev); wake = wake && device_may_wakeup(hcd->self.controller); dev_dbg (hcd->self.controller, "--> PCI D3%s\n", wake ? "/wakeup" : ""); /* Ignore these return values. We rely on pci code to * reject requests the hardware can't implement, rather * than coding the same thing. */ (void) pci_enable_wake (dev, PCI_D3hot, wake); (void) pci_enable_wake (dev, PCI_D3cold, wake); } else { dev_dbg (&dev->dev, "PCI D3 suspend fail, %d\n", retval); (void) usb_hcd_pci_resume (dev); } } else if (hcd->state != HC_STATE_HALT) { dev_dbg (hcd->self.controller, "hcd state %d; not suspended\n", hcd->state); WARN_ON(1); retval = -EINVAL; } done: if (retval == 0) { dev->dev.power.power_state = PMSG_SUSPEND; #ifdef CONFIG_PPC_PMAC /* Disable ASIC clocks for USB */ if (machine_is(powermac)) { struct device_node *of_node; of_node = pci_device_to_OF_node (dev); if (of_node) pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0); } #endif } return retval; }
void udbg_scc_init(int force_scc) { const u32 *reg; unsigned long addr; struct device_node *stdout = NULL, *escc = NULL, *macio = NULL; struct device_node *ch, *ch_def = NULL, *ch_a = NULL; const char *path; int i, x; escc = of_find_node_by_name(NULL, "escc"); if (escc == NULL) goto bail; macio = of_get_parent(escc); if (macio == NULL) goto bail; path = of_get_property(of_chosen, "linux,stdout-path", NULL); if (path != NULL) stdout = of_find_node_by_path(path); for (ch = NULL; (ch = of_get_next_child(escc, ch)) != NULL;) { if (ch == stdout) ch_def = of_node_get(ch); if (strcmp(ch->name, "ch-a") == 0) ch_a = of_node_get(ch); } if (ch_def == NULL && !force_scc) goto bail; ch = ch_def ? ch_def : ch_a; /* Get address within mac-io ASIC */ reg = of_get_property(escc, "reg", NULL); if (reg == NULL) goto bail; addr = reg[0]; /* Get address of mac-io PCI itself */ reg = of_get_property(macio, "assigned-addresses", NULL); if (reg == NULL) goto bail; addr += reg[2]; /* Lock the serial port */ pmac_call_feature(PMAC_FTR_SCC_ENABLE, ch, PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1); if (ch == ch_a) addr += 0x20; sccc = ioremap(addr & PAGE_MASK, PAGE_SIZE) ; sccc += addr & ~PAGE_MASK; sccd = sccc + 0x10; mb(); for (i = 20000; i != 0; --i) x = in_8(sccc); out_8(sccc, 0x09); /* reset A or B side */ out_8(sccc, 0xc0); /* If SCC was the OF output port, read the BRG value, else * Setup for 38400 or 57600 8N1 depending on the machine */ if (ch_def != NULL) { out_8(sccc, 13); scc_inittab[1] = in_8(sccc); out_8(sccc, 12); scc_inittab[3] = in_8(sccc); } else if (machine_is_compatible("RackMac1,1") || machine_is_compatible("RackMac1,2") || machine_is_compatible("MacRISC4")) { /* Xserves and G5s default to 57600 */ scc_inittab[1] = 0; scc_inittab[3] = 0; } else { /* Others default to 38400 */ scc_inittab[1] = 0; scc_inittab[3] = 1; } for (i = 0; i < sizeof(scc_inittab); ++i) out_8(sccc, scc_inittab[i]); udbg_putc = udbg_scc_putc; udbg_getc = udbg_scc_getc; udbg_getc_poll = udbg_scc_getc_poll; udbg_puts("Hello World !\n"); bail: of_node_put(macio); of_node_put(escc); of_node_put(stdout); of_node_put(ch_def); of_node_put(ch_a); }
static int airport_attach(struct macio_dev *mdev, const struct of_device_id *match) { struct orinoco_private *priv; struct airport *card; unsigned long phys_addr; hermes_t *hw; if (macio_resource_count(mdev) < 1 || macio_irq_count(mdev) < 1) { printk(KERN_ERR PFX "Wrong interrupt/addresses in OF tree\n"); return -ENODEV; } /* Allocate space for private device-specific data */ priv = alloc_orinocodev(sizeof(*card), &mdev->ofdev.dev, airport_hard_reset, NULL); if (!priv) { printk(KERN_ERR PFX "Cannot allocate network device\n"); return -ENODEV; } card = priv->card; hw = &priv->hw; card->mdev = mdev; if (macio_request_resource(mdev, 0, DRIVER_NAME)) { printk(KERN_ERR PFX "can't request IO resource !\n"); free_orinocodev(priv); return -EBUSY; } macio_set_drvdata(mdev, priv); /* Setup interrupts & base address */ card->irq = macio_irq(mdev, 0); phys_addr = macio_resource_start(mdev, 0); /* Physical address */ printk(KERN_DEBUG PFX "Physical address %lx\n", phys_addr); card->vaddr = ioremap(phys_addr, AIRPORT_IO_LEN); if (!card->vaddr) { printk(KERN_ERR PFX "ioremap() failed\n"); goto failed; } hermes_struct_init(hw, card->vaddr, HERMES_16BIT_REGSPACING); /* Power up card */ pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 1); ssleep(1); /* Reset it before we get the interrupt */ hermes_init(hw); if (request_irq(card->irq, orinoco_interrupt, 0, DRIVER_NAME, priv)) { printk(KERN_ERR PFX "Couldn't get IRQ %d\n", card->irq); goto failed; } card->irq_requested = 1; /* Initialise the main driver */ if (orinoco_init(priv) != 0) { printk(KERN_ERR PFX "orinoco_init() failed\n"); goto failed; } /* Register an interface with the stack */ if (orinoco_if_add(priv, phys_addr, card->irq) != 0) { printk(KERN_ERR PFX "orinoco_if_add() failed\n"); goto failed; } card->ndev_registered = 1; return 0; failed: airport_detach(mdev); return -ENODEV; } /* airport_attach */
int __pmac pmac_show_cpuinfo(struct seq_file *m) { struct device_node *np; char *pp; int plen; int mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_MODEL, 0); unsigned int mbflags = (unsigned int)pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_FLAGS, 0); char* mbname; if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME, (int)&mbname) != 0) mbname = "Unknown"; /* find motherboard type */ seq_printf(m, "machine\t\t: "); np = find_devices("device-tree"); if (np != NULL) { pp = (char *) get_property(np, "model", NULL); if (pp != NULL) seq_printf(m, "%s\n", pp); else seq_printf(m, "PowerMac\n"); pp = (char *) get_property(np, "compatible", &plen); if (pp != NULL) { seq_printf(m, "motherboard\t:"); while (plen > 0) { int l = strlen(pp) + 1; seq_printf(m, " %s", pp); plen -= l; pp += l; } seq_printf(m, "\n"); } } else seq_printf(m, "PowerMac\n"); /* print parsed model */ seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname); seq_printf(m, "pmac flags\t: %08x\n", mbflags); /* find l2 cache info */ np = find_devices("l2-cache"); if (np == 0) np = find_type_devices("cache"); if (np != 0) { unsigned int *ic = (unsigned int *) get_property(np, "i-cache-size", NULL); unsigned int *dc = (unsigned int *) get_property(np, "d-cache-size", NULL); seq_printf(m, "L2 cache\t:"); has_l2cache = 1; if (get_property(np, "cache-unified", NULL) != 0 && dc) { seq_printf(m, " %dK unified", *dc / 1024); } else { if (ic) seq_printf(m, " %dK instruction", *ic / 1024); if (dc) seq_printf(m, "%s %dK data", (ic? " +": ""), *dc / 1024); } pp = get_property(np, "ram-type", NULL); if (pp) seq_printf(m, " %s", pp); seq_printf(m, "\n"); } /* find ram info */ np = find_devices("memory"); if (np != 0) { int n; struct reg_property *reg = (struct reg_property *) get_property(np, "reg", &n); if (reg != 0) { unsigned long total = 0; for (n /= sizeof(struct reg_property); n > 0; --n) total += (reg++)->size; seq_printf(m, "memory\t\t: %luMB\n", total >> 20); }
static int swim3_add_device(struct macio_dev *mdev, int index) { struct device_node *swim = mdev->ofdev.dev.of_node; struct floppy_state *fs = &floppy_states[index]; int rc = -EBUSY; /* Do this first for message macros */ memset(fs, 0, sizeof(*fs)); fs->mdev = mdev; fs->index = index; /* Check & Request resources */ if (macio_resource_count(mdev) < 2) { swim3_err("%s", "No address in device-tree\n"); return -ENXIO; } if (macio_irq_count(mdev) < 1) { swim3_err("%s", "No interrupt in device-tree\n"); return -ENXIO; } if (macio_request_resource(mdev, 0, "swim3 (mmio)")) { swim3_err("%s", "Can't request mmio resource\n"); return -EBUSY; } if (macio_request_resource(mdev, 1, "swim3 (dma)")) { swim3_err("%s", "Can't request dma resource\n"); macio_release_resource(mdev, 0); return -EBUSY; } dev_set_drvdata(&mdev->ofdev.dev, fs); if (mdev->media_bay == NULL) pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1); fs->state = idle; fs->swim3 = (struct swim3 __iomem *) ioremap(macio_resource_start(mdev, 0), 0x200); if (fs->swim3 == NULL) { swim3_err("%s", "Couldn't map mmio registers\n"); rc = -ENOMEM; goto out_release; } fs->dma = (struct dbdma_regs __iomem *) ioremap(macio_resource_start(mdev, 1), 0x200); if (fs->dma == NULL) { swim3_err("%s", "Couldn't map dma registers\n"); iounmap(fs->swim3); rc = -ENOMEM; goto out_release; } fs->swim3_intr = macio_irq(mdev, 0); fs->dma_intr = macio_irq(mdev, 1); fs->cur_cyl = -1; fs->cur_sector = -1; fs->secpercyl = 36; fs->secpertrack = 18; fs->total_secs = 2880; init_waitqueue_head(&fs->wait); fs->dma_cmd = (struct dbdma_cmd *) DBDMA_ALIGN(fs->dbdma_cmd_space); memset(fs->dma_cmd, 0, 2 * sizeof(struct dbdma_cmd)); fs->dma_cmd[1].command = cpu_to_le16(DBDMA_STOP); if (mdev->media_bay == NULL || check_media_bay(mdev->media_bay) == MB_FD) swim3_mb_event(mdev, MB_FD); if (request_irq(fs->swim3_intr, swim3_interrupt, 0, "SWIM3", fs)) { swim3_err("%s", "Couldn't request interrupt\n"); pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0); goto out_unmap; return -EBUSY; } timer_setup(&fs->timeout, NULL, 0); swim3_info("SWIM3 floppy controller %s\n", mdev->media_bay ? "in media bay" : ""); return 0; out_unmap: iounmap(fs->dma); iounmap(fs->swim3); out_release: macio_release_resource(mdev, 0); macio_release_resource(mdev, 1); return rc; }