static int xenon_sdhci_ofdata_to_platdata(struct udevice *dev) { struct sdhci_host *host = dev_get_priv(dev); struct xenon_sdhci_priv *priv = dev_get_priv(dev); const char *name; host->name = dev->name; host->ioaddr = (void *)devfdt_get_addr(dev); if (device_is_compatible(dev, "marvell,armada-3700-sdhci")) priv->pad_ctrl_reg = (void *)devfdt_get_addr_index(dev, 1); name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "marvell,pad-type", NULL); if (name) { if (0 == strncmp(name, "sd", 2)) { priv->pad_type = SOC_PAD_SD; } else if (0 == strncmp(name, "fixed-1-8v", 10)) { priv->pad_type = SOC_PAD_FIXED_1_8V; } else { printf("Unsupported SOC PHY PAD ctrl type %s\n", name); return -EINVAL; } } return 0; }
int __init device_init(struct dt_device_node *dev, enum device_type type, const void *data) { const struct device_desc *desc; ASSERT(dev != NULL); if ( !dt_device_is_available(dev) ) return -ENODEV; for ( desc = _sdevice; desc != _edevice; desc++ ) { if ( desc->type != type ) continue; if ( device_is_compatible(desc, dev) ) { ASSERT(desc->init != NULL); return desc->init(dev, data); } } return -EBADF; }
static void __devinit apple_kiwi_init(struct pci_dev *pdev) { struct device_node *np = pci_device_to_OF_node(pdev); unsigned int class_rev = 0; unsigned long mmio; u8 conf; if (np == NULL || !device_is_compatible(np, "kiwi-root")) return; pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; if (class_rev >= 0x03) { /* Setup chip magic config stuff (from darwin) */ pci_read_config_byte(pdev, 0x40, &conf); pci_write_config_byte(pdev, 0x40, conf | 0x01); } mmio = (unsigned long)ioremap(pci_resource_start(pdev, 5), pci_resource_len(pdev, 5)); /* Setup some PLL stuffs */ switch (pdev->device) { case PCI_DEVICE_ID_PROMISE_20270: writew(0x0d2b, mmio + 0x1202); mdelay(30); break; case PCI_DEVICE_ID_PROMISE_20271: writew(0x0826, mmio + 0x1202); mdelay(30); break; } iounmap((void *)mmio); }
static void __init mpic_init_IRQ(void) { struct device_node *dn; struct mpic *mpic; unsigned int virq; for (dn = NULL; (dn = of_find_node_by_name(dn, "interrupt-controller"));) { if (!device_is_compatible(dn, "CBEA,platform-open-pic")) continue; /* The MPIC driver will get everything it needs from the * device-tree, just pass 0 to all arguments */ mpic = mpic_alloc(dn, 0, 0, 0, 0, " MPIC "); if (mpic == NULL) continue; mpic_init(mpic); virq = irq_of_parse_and_map(dn, 0); if (virq == NO_IRQ) continue; printk(KERN_INFO "%s : hooking up to IRQ %d\n", dn->full_name, virq); set_irq_data(virq, mpic); set_irq_chained_handler(virq, cell_mpic_cascade); } }
/* * Indicates whether the root node has a given value in its * compatible property. */ int machine_is_compatible(const char *compat) { struct device_node *root; root = find_path_device("/"); if (root == 0) return 0; return device_is_compatible(root, compat); }
/** * vio_match_device: - Tell if a VIO device has a matching * VIO device id structure. * @ids: array of VIO device id structures to search in * @dev: the VIO device structure to match against * * Used by a driver to check whether a VIO device present in the * system is in its list of supported devices. Returns the matching * vio_device_id structure or NULL if there is no match. */ static const struct vio_device_id *vio_match_device( const struct vio_device_id *ids, const struct vio_dev *dev) { while (ids->type[0] != '\0') { if ((strncmp(dev->type, ids->type, strlen(ids->type)) == 0) && device_is_compatible(dev->dev.platform_data, ids->compat)) return ids; ids++; } return NULL; }
static int __init smp_core99_probe(void) { struct device_node *cpus; struct device_node *cc; int ncpus = 0; /* Maybe use systemconfiguration here ? */ if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345); /* Count CPUs in the device-tree */ for (cpus = NULL; (cpus = of_find_node_by_type(cpus, "cpu")) != NULL;) ++ncpus; printk(KERN_INFO "PowerMac SMP probe found %d cpus\n", ncpus); /* Nothing more to do if less than 2 of them */ if (ncpus <= 1) return 1; /* Look for the clock chip */ for (cc = NULL; (cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL;) { struct device_node *p = of_get_parent(cc); u32 *reg; int ok; ok = p && device_is_compatible(p, "uni-n-i2c"); if (!ok) goto next; reg = (u32 *)get_property(cc, "reg", NULL); if (reg == NULL) goto next; switch (*reg) { case 0xd2: pmac_tb_freeze = smp_core99_cypress_tb_freeze; printk(KERN_INFO "Timebase clock is Cypress chip\n"); break; case 0xd4: pmac_tb_freeze = smp_core99_pulsar_tb_freeze; printk(KERN_INFO "Timebase clock is Pulsar chip\n"); break; } if (pmac_tb_freeze != NULL) { pmac_tb_clock_chip_host = p; smp_ops->give_timebase = smp_core99_give_timebase; smp_ops->take_timebase = smp_core99_take_timebase; break; } next: of_node_put(p); } mpic_request_ipis(); return ncpus; }
static int wf_lm75_attach(struct i2c_adapter *adapter) { struct device_node *busnode, *dev; struct pmac_i2c_bus *bus; DBG("wf_lm75: adapter %s detected\n", adapter->name); bus = pmac_i2c_adapter_to_bus(adapter); if (bus == NULL) return -ENODEV; busnode = pmac_i2c_get_bus_node(bus); DBG("wf_lm75: bus found, looking for device...\n"); /* Now look for lm75(s) in there */ for (dev = NULL; (dev = of_get_next_child(busnode, dev)) != NULL;) { const char *loc = get_property(dev, "hwsensor-location", NULL); u8 addr; /* We must re-match the adapter in order to properly check * the channel on multibus setups */ if (!pmac_i2c_match_adapter(dev, adapter)) continue; addr = pmac_i2c_get_dev_addr(dev); if (loc == NULL || addr == 0) continue; /* real lm75 */ if (device_is_compatible(dev, "lm75")) wf_lm75_create(adapter, addr, 0, loc); /* ds1775 (compatible, better resolution */ else if (device_is_compatible(dev, "ds1775")) wf_lm75_create(adapter, addr, 1, loc); } return 0; }
enum device_type device_get_type(const struct dt_device_node *dev) { const struct device_desc *desc; ASSERT(dev != NULL); for ( desc = _sdevice; desc != _edevice; desc++ ) { if ( device_is_compatible(desc, dev) ) return desc->type; } return DEVICE_UNKNOWN; }
/* * Construct and return a list of the device_nodes with a given type * and compatible property. */ struct device_node * find_compatible_devices(const char *type, const char *compat) { struct device_node *head, **prevp, *np; prevp = &head; for (np = allnodes; np != 0; np = np->allnext) { if (type != NULL && !(np->type != 0 && strcasecmp(np->type, type) == 0)) continue; if (device_is_compatible(np, compat)) { *prevp = np; prevp = &np->next; } } *prevp = 0; return head; }
static void __devinit apple_kiwi_init(struct pci_dev *pdev) { struct device_node *np = pci_device_to_OF_node(pdev); unsigned int class_rev = 0; u8 conf; if (np == NULL || !device_is_compatible(np, "kiwi-root")) return; pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; if (class_rev >= 0x03) { /* Setup chip magic config stuff (from darwin) */ pci_read_config_byte (pdev, 0x40, &conf); pci_write_config_byte(pdev, 0x40, (conf | 0x01)); } }
/* XXX this requires an interface change to handle multiple discontiguous * vterms */ int hvc_count(int *start_termno) { struct device_node *vty; int num_found = 0; /* consider only the first vty node. * we should _always_ be able to find one. */ vty = of_find_node_by_name(NULL, "vty"); if (vty && device_is_compatible(vty, "hvterm1")) { u32 *termno = (u32 *)get_property(vty, "reg", NULL); if (termno && start_termno) *start_termno = *termno; num_found = 1; of_node_put(vty); } return num_found; }
/** * of_match_node - Tell if an device_node has a matching of_match structure * @ids: array of of device match structures to search in * @node: the of device structure to match against * * Low level utility function used by device matching. */ const struct of_device_id *of_match_node(const struct of_device_id *matches, const struct device_node *node) { while (matches->name[0] || matches->type[0] || matches->compatible[0]) { int match = 1; if (matches->name[0]) match &= node->name && !strcmp(matches->name, node->name); if (matches->type[0]) match &= node->type && !strcmp(matches->type, node->type); if (matches->compatible[0]) match &= device_is_compatible(node, matches->compatible); if (match) return matches; matches++; } return NULL; }
/** * of_match_device - Tell if an of_device structure has a matching * of_match structure * @ids: array of of device match structures to search in * @dev: the of device structure to match against * * Used by a driver to check whether an of_device present in the * system is in its list of supported devices. */ const struct of_device_id * of_match_device(const struct of_device_id *matches, const struct of_device *dev) { if (!dev->node) return NULL; while (matches->name[0] || matches->type[0] || matches->compatible[0]) { int match = 1; if (matches->name[0]) match &= dev->node->name && !strcmp(matches->name, dev->node->name); if (matches->type[0]) match &= dev->node->type && !strcmp(matches->type, dev->node->type); if (matches->compatible[0]) match &= device_is_compatible(dev->node, matches->compatible); if (match) return matches; matches++; } return NULL; }
/** * of_match_device - Tell if an of_device structure has a matching * of_match structure * @ids: array of of device match structures to search in * @dev: the of device structure to match against * * Used by a driver to check whether an of_device present in the * system is in its list of supported devices. */ const struct of_match * of_match_device(const struct of_match *matches, const struct of_device *dev) { if (!dev->node) return NULL; while (matches->name || matches->type || matches->compatible) { int match = 1; if (matches->name && matches->name != OF_ANY_MATCH) match &= dev->node->name && !strcmp(matches->name, dev->node->name); if (matches->type && matches->type != OF_ANY_MATCH) match &= dev->node->type && !strcmp(matches->type, dev->node->type); if (matches->compatible && matches->compatible != OF_ANY_MATCH) match &= device_is_compatible(dev->node, matches->compatible); if (match) return matches; matches++; } return NULL; }
/* * This is called very early, as part of setup_system() or eventually * setup_arch(), basically before anything else in this file. This function * will try to build a list of all the available 8250-compatible serial ports * in the machine using the Open Firmware device-tree. It currently only deals * with ISA and PCI busses but could be extended. It allows a very early boot * console to be initialized, that list is also used later to provide 8250 with * the machine non-PCI ports and to properly pick the default console port */ void __init find_legacy_serial_ports(void) { struct device_node *np, *stdout = NULL; const char *path; int index; DBG(" -> find_legacy_serial_port()\n"); /* Now find out if one of these is out firmware console */ path = get_property(of_chosen, "linux,stdout-path", NULL); if (path != NULL) { stdout = of_find_node_by_path(path); if (stdout) DBG("stdout is %s\n", stdout->full_name); } else { DBG(" no linux,stdout-path !\n"); } /* First fill our array with SOC ports */ for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16550")) != NULL;) { struct device_node *soc = of_get_parent(np); if (soc && !strcmp(soc->type, "soc")) { index = add_legacy_soc_port(np, np); if (index >= 0 && np == stdout) legacy_serial_console = index; } of_node_put(soc); } /* First fill our array with ISA ports */ for (np = NULL; (np = of_find_node_by_type(np, "serial"));) { struct device_node *isa = of_get_parent(np); if (isa && !strcmp(isa->name, "isa")) { index = add_legacy_isa_port(np, isa); if (index >= 0 && np == stdout) legacy_serial_console = index; } of_node_put(isa); } /* First fill our array with tsi-bridge ports */ for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16550")) != NULL;) { struct device_node *tsi = of_get_parent(np); if (tsi && !strcmp(tsi->type, "tsi-bridge")) { index = add_legacy_soc_port(np, np); if (index >= 0 && np == stdout) legacy_serial_console = index; } of_node_put(tsi); } /* First fill our array with opb bus ports */ for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16750")) != NULL;) { struct device_node *opb = of_get_parent(np); if (opb && !strcmp(opb->type, "opb")) { index = add_legacy_soc_port(np, np); if (index >= 0 && np == stdout) legacy_serial_console = index; } of_node_put(opb); } #ifdef CONFIG_PCI /* Next, try to locate PCI ports */ for (np = NULL; (np = of_find_all_nodes(np));) { struct device_node *pci, *parent = of_get_parent(np); if (parent && !strcmp(parent->name, "isa")) { of_node_put(parent); continue; } if (strcmp(np->name, "serial") && strcmp(np->type, "serial")) { of_node_put(parent); continue; } /* Check for known pciclass, and also check wether we have * a device with child nodes for ports or not */ if (device_is_compatible(np, "pciclass,0700") || device_is_compatible(np, "pciclass,070002")) pci = np; else if (device_is_compatible(parent, "pciclass,0700") || device_is_compatible(parent, "pciclass,070002")) pci = parent; else { of_node_put(parent); continue; } index = add_legacy_pci_port(np, pci); if (index >= 0 && np == stdout) legacy_serial_console = index; of_node_put(parent); } #endif DBG("legacy_serial_console = %d\n", legacy_serial_console); if (legacy_serial_console >= 0) setup_legacy_serial_console(legacy_serial_console); DBG(" <- find_legacy_serial_port()\n"); }
static int __init add_legacy_pci_port(struct device_node *np, struct device_node *pci_dev) { u64 addr, base; const u32 *addrp; 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 * the generic 8250_pci driver later on. The reason is that 8250 * compatible UARTs on PCI need all sort of quirks (port offsets * etc...) that this code doesn't know about */ if (get_property(np, "clock-frequency", NULL) == NULL) return -1; /* Get the PCI address. Assume BAR 0 */ addrp = of_get_pci_address(pci_dev, 0, NULL, &flags); if (addrp == NULL) return -1; /* 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) */ if (iotype == UPIO_MEM) base = addr; else base = addrp[2]; /* Try to guess an index... If we have subdevices of the pci dev, * we get to their "reg" property */ if (np != pci_dev) { const u32 *reg = get_property(np, "reg", NULL); if (reg && (*reg < 4)) index = lindex = *reg; } /* Local index means it's the Nth port in the PCI chip. Unfortunately * the offset to add here is device specific. We know about those * EXAR ports and we default to the most common case. If your UART * doesn't work for these settings, you'll have to add your own special * cases here */ if (device_is_compatible(pci_dev, "pci13a8,152") || device_is_compatible(pci_dev, "pci13a8,154") || device_is_compatible(pci_dev, "pci13a8,158")) { addr += 0x200 * lindex; base += 0x200 * lindex; } else { addr += 8 * lindex; base += 8 * lindex; } /* 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, np != pci_dev); }
static void __init pseries_mpic_init_IRQ(void) { struct device_node *np, *old, *cascade = NULL; unsigned int *addrp; unsigned long intack = 0; unsigned int *opprop; unsigned long openpic_addr = 0; unsigned int cascade_irq; int naddr, n, i, opplen; struct mpic *mpic; np = of_find_node_by_path("/"); naddr = prom_n_addr_cells(np); opprop = (unsigned int *) get_property(np, "platform-open-pic", &opplen); if (opprop != 0) { openpic_addr = of_read_number(opprop, naddr); printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr); } of_node_put(np); BUG_ON(openpic_addr == 0); /* Setup the openpic driver */ mpic = mpic_alloc(pSeries_mpic_node, openpic_addr, MPIC_PRIMARY, 16, 250, /* isu size, irq count */ " MPIC "); BUG_ON(mpic == NULL); /* Add ISUs */ opplen /= sizeof(u32); for (n = 0, i = naddr; i < opplen; i += naddr, n++) { unsigned long isuaddr = of_read_number(opprop + i, naddr); mpic_assign_isu(mpic, n, isuaddr); } /* All ISUs are setup, complete initialization */ mpic_init(mpic); /* Look for cascade */ for_each_node_by_type(np, "interrupt-controller") if (device_is_compatible(np, "chrp,iic")) { cascade = np; break; } if (cascade == NULL) return; cascade_irq = irq_of_parse_and_map(cascade, 0); if (cascade == NO_IRQ) { printk(KERN_ERR "xics: failed to map cascade interrupt"); return; } /* Check ACK type */ for (old = of_node_get(cascade); old != NULL ; old = np) { np = of_get_parent(old); of_node_put(old); if (np == NULL) break; if (strcmp(np->name, "pci") != 0) continue; addrp = (u32 *)get_property(np, "8259-interrupt-acknowledge", NULL); if (addrp == NULL) continue; naddr = prom_n_addr_cells(np); intack = addrp[naddr-1]; if (naddr > 1) intack |= ((unsigned long)addrp[naddr-2]) << 32; } if (intack) printk(KERN_DEBUG "mpic: PCI 8259 intack at 0x%016lx\n", intack); i8259_init(cascade, intack); of_node_put(cascade); set_irq_chained_handler(cascade_irq, pseries_8259_cascade); }
void __init pmac_ide_probe(void) { struct device_node *np; int i; struct device_node *atas; struct device_node *p, **pp, *removables, **rp; unsigned long base; int irq, big_delay; ide_hwif_t *hwif; if (_machine != _MACH_Pmac) return; pp = &atas; rp = &removables; p = find_devices("ATA"); if (p == NULL) p = find_devices("IDE"); if (p == NULL) p = find_type_devices("ide"); if (p == NULL) p = find_type_devices("ata"); /* Move removable devices such as the media-bay CDROM on the PB3400 to the end of the list. */ for (; p != NULL; p = p->next) { if (p->parent && p->parent->type && strcasecmp(p->parent->type, "media-bay") == 0) { *rp = p; rp = &p->next; } else { *pp = p; pp = &p->next; } } *rp = NULL; *pp = removables; big_delay = 0; for (i = 0, np = atas; i < MAX_HWIFS && np != NULL; np = np->next) { struct device_node *tp; int *bidp; int in_bay = 0; /* * If this node is not under a mac-io or dbdma node, * leave it to the generic PCI driver. */ for (tp = np->parent; tp != 0; tp = tp->parent) if (tp->type && (strcmp(tp->type, "mac-io") == 0 || strcmp(tp->type, "dbdma") == 0)) break; if (tp == 0) continue; if (np->n_addrs == 0) { printk(KERN_WARNING "ide: no address for device %s\n", np->full_name); continue; } /* * If this slot is taken (e.g. by ide-pci.c) try the next one. */ while (i < MAX_HWIFS && ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0) ++i; if (i >= MAX_HWIFS) break; base = (unsigned long) ioremap(np->addrs[0].address, 0x200) - _IO_BASE; /* XXX This is bogus. Should be fixed in the registry by checking the kind of host interrupt controller, a bit like gatwick fixes in irq.c */ if (np->n_intrs == 0) { printk(KERN_WARNING "ide: no intrs for device %s, using 13\n", np->full_name); irq = 13; } else { irq = np->intrs[0].line; } pmac_ide[i].regbase = base; pmac_ide[i].irq = irq; pmac_ide[i].node = np; if (device_is_compatible(np, "keylargo-ata")) { if (strcmp(np->name, "ata-4") == 0) pmac_ide[i].kind = controller_kl_ata4; else pmac_ide[i].kind = controller_kl_ata3; } else if (device_is_compatible(np, "heathrow-ata")) pmac_ide[i].kind = controller_heathrow; else pmac_ide[i].kind = controller_ohare; bidp = (int *)get_property(np, "AAPL,bus-id", NULL); pmac_ide[i].aapl_bus_id = bidp ? *bidp : 0; if (np->parent && np->parent->name && strcasecmp(np->parent->name, "media-bay") == 0) { #ifdef CONFIG_PMAC_PBOOK media_bay_set_ide_infos(np->parent,base,irq,i); #endif /* CONFIG_PMAC_PBOOK */ in_bay = 1; } else if (pmac_ide[i].kind == controller_ohare) { /* The code below is having trouble on some ohare machines * (timing related ?). Until I can put my hand on one of these * units, I keep the old way */ feature_set(np, FEATURE_IDE0_enable); } else { /* This is necessary to enable IDE when net-booting */ printk(KERN_INFO "pmac_ide: enabling IDE bus ID %d\n", pmac_ide[i].aapl_bus_id); switch(pmac_ide[i].aapl_bus_id) { case 0: feature_set(np, FEATURE_IDE0_reset); mdelay(10); feature_set(np, FEATURE_IDE0_enable); mdelay(10); feature_clear(np, FEATURE_IDE0_reset); break; case 1: feature_set(np, FEATURE_IDE1_reset); mdelay(10); feature_set(np, FEATURE_IDE1_enable); mdelay(10); feature_clear(np, FEATURE_IDE1_reset); break; case 2: /* This one exists only for KL, I don't know about any enable bit */ feature_set(np, FEATURE_IDE2_reset); mdelay(10); feature_clear(np, FEATURE_IDE2_reset); break; } big_delay = 1; } hwif = &ide_hwifs[i]; pmac_ide_init_hwif_ports(&hwif->hw, base, 0, &hwif->irq); memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); hwif->chipset = ide_pmac; hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET] || in_bay; #ifdef CONFIG_PMAC_PBOOK if (in_bay && check_media_bay_by_base(base, MB_CD) == 0) hwif->noprobe = 0; #endif /* CONFIG_PMAC_PBOOK */ #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC if (np->n_addrs >= 2) { /* has a DBDMA controller channel */ pmac_ide_setup_dma(np, i); } #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ ++i; } pmac_ide_count = i; if (big_delay) mdelay(IDE_WAKEUP_DELAY_MS); #ifdef CONFIG_PMAC_PBOOK pmu_register_sleep_notifier(&idepmac_sleep_notifier); #endif /* CONFIG_PMAC_PBOOK */ }
/* * Setup one port structure after probing, HW is down at this point, * Unlike sunzilog, we don't need to pre-init the spinlock as we don't * register our console before uart_add_one_port() is called */ static int __init pmz_init_port(struct uart_pmac_port *uap) { struct device_node *np = uap->node; const char *conn; const struct slot_names_prop { int count; char name[1]; } *slots; int len; struct resource r_ports, r_rxdma, r_txdma; /* * Request & map chip registers */ if (of_address_to_resource(np, 0, &r_ports)) return -ENODEV; uap->port.mapbase = r_ports.start; uap->port.membase = ioremap(uap->port.mapbase, 0x1000); uap->control_reg = uap->port.membase; uap->data_reg = uap->control_reg + 0x10; /* * Request & map DBDMA registers */ #ifdef HAS_DBDMA if (of_address_to_resource(np, 1, &r_txdma) == 0 && of_address_to_resource(np, 2, &r_rxdma) == 0) uap->flags |= PMACZILOG_FLAG_HAS_DMA; #else memset(&r_txdma, 0, sizeof(struct resource)); memset(&r_rxdma, 0, sizeof(struct resource)); #endif if (ZS_HAS_DMA(uap)) { uap->tx_dma_regs = ioremap(r_txdma.start, 0x100); if (uap->tx_dma_regs == NULL) { uap->flags &= ~PMACZILOG_FLAG_HAS_DMA; goto no_dma; } uap->rx_dma_regs = ioremap(r_rxdma.start, 0x100); if (uap->rx_dma_regs == NULL) { iounmap(uap->tx_dma_regs); uap->tx_dma_regs = NULL; uap->flags &= ~PMACZILOG_FLAG_HAS_DMA; goto no_dma; } uap->tx_dma_irq = irq_of_parse_and_map(np, 1); uap->rx_dma_irq = irq_of_parse_and_map(np, 2); } no_dma: /* * Detect port type */ if (device_is_compatible(np, "cobalt")) uap->flags |= PMACZILOG_FLAG_IS_INTMODEM; conn = get_property(np, "AAPL,connector", &len); if (conn && (strcmp(conn, "infrared") == 0)) uap->flags |= PMACZILOG_FLAG_IS_IRDA; uap->port_type = PMAC_SCC_ASYNC; /* 1999 Powerbook G3 has slot-names property instead */ slots = get_property(np, "slot-names", &len); if (slots && slots->count > 0) { if (strcmp(slots->name, "IrDA") == 0) uap->flags |= PMACZILOG_FLAG_IS_IRDA; else if (strcmp(slots->name, "Modem") == 0) uap->flags |= PMACZILOG_FLAG_IS_INTMODEM; } if (ZS_IS_IRDA(uap)) uap->port_type = PMAC_SCC_IRDA; if (ZS_IS_INTMODEM(uap)) { struct device_node* i2c_modem = find_devices("i2c-modem"); if (i2c_modem) { const char* mid = get_property(i2c_modem, "modem-id", NULL); if (mid) switch(*mid) { case 0x04 : case 0x05 : case 0x07 : case 0x08 : case 0x0b : case 0x0c : uap->port_type = PMAC_SCC_I2S1; } printk(KERN_INFO "pmac_zilog: i2c-modem detected, id: %d\n", mid ? (*mid) : 0); } else { printk(KERN_INFO "pmac_zilog: serial modem detected\n"); } } /* * Init remaining bits of "port" structure */ uap->port.iotype = UPIO_MEM; uap->port.irq = irq_of_parse_and_map(np, 0); uap->port.uartclk = ZS_CLOCK; uap->port.fifosize = 1; uap->port.ops = &pmz_pops; uap->port.type = PORT_PMAC_ZILOG; uap->port.flags = 0; /* Setup some valid baud rate information in the register * shadows so we don't write crap there before baud rate is * first initialized. */ pmz_convert_to_zs(uap, CS8, 0, 9600); return 0; }
static void __init offb_init_fb(const char *name, const char *full_name, int width, int height, int depth, int pitch, unsigned long address, struct device_node *dp) { unsigned long res_size = pitch * height * depth / 8; struct offb_par *par = &default_par; unsigned long res_start = address; struct fb_fix_screeninfo *fix; struct fb_var_screeninfo *var; struct fb_info *info; int size; if (!request_mem_region(res_start, res_size, "offb")) return; printk(KERN_INFO "Using unsupported %dx%d %s at %lx, depth=%d, pitch=%d\n", width, height, name, address, depth, pitch); if (depth != 8 && depth != 16 && depth != 32) { printk(KERN_ERR "%s: can't use depth = %d\n", full_name, depth); release_mem_region(res_start, res_size); return; } size = sizeof(struct fb_info) + sizeof(u32) * 17; info = kmalloc(size, GFP_ATOMIC); if (info == 0) { release_mem_region(res_start, res_size); return; } memset(info, 0, size); fix = &info->fix; var = &info->var; strcpy(fix->id, "OFfb "); strncat(fix->id, name, sizeof(fix->id) - sizeof("OFfb ")); fix->id[sizeof(fix->id) - 1] = '\0'; var->xres = var->xres_virtual = width; var->yres = var->yres_virtual = height; fix->line_length = pitch; fix->smem_start = address; fix->smem_len = pitch * height; fix->type = FB_TYPE_PACKED_PIXELS; fix->type_aux = 0; par->cmap_type = cmap_unknown; if (depth == 8) { /* XXX kludge for ati */ if (dp && !strncmp(name, "ATY,Rage128", 11)) { unsigned long regbase = dp->addrs[2].address; par->cmap_adr = ioremap(regbase, 0x1FFF); par->cmap_type = cmap_r128; } else if (dp && (!strncmp(name, "ATY,RageM3pA", 12) || !strncmp(name, "ATY,RageM3p12A", 14))) { unsigned long regbase = dp->parent->addrs[2].address; par->cmap_adr = ioremap(regbase, 0x1FFF); par->cmap_type = cmap_M3A; } else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) { unsigned long regbase = dp->parent->addrs[2].address; par->cmap_adr = ioremap(regbase, 0x1FFF); par->cmap_type = cmap_M3B; } else if (dp && !strncmp(name, "ATY,Rage6", 9)) { unsigned long regbase = dp->addrs[1].address; par->cmap_adr = ioremap(regbase, 0x1FFF); par->cmap_type = cmap_radeon; } else if (!strncmp(name, "ATY,", 4)) { unsigned long base = address & 0xff000000UL; par->cmap_adr = ioremap(base + 0x7ff000, 0x1000) + 0xcc0; par->cmap_data = par->cmap_adr + 1; par->cmap_type = cmap_m64; } else if (device_is_compatible(dp, "pci1014,b7")) { unsigned long regbase = dp->addrs[0].address; par->cmap_adr = ioremap(regbase + 0x6000, 0x1000); par->cmap_type = cmap_gxt2000; } fix->visual = par->cmap_adr ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_STATIC_PSEUDOCOLOR; } else fix->visual = /* par->cmap_adr ? FB_VISUAL_DIRECTCOLOR : */ FB_VISUAL_TRUECOLOR; var->xoffset = var->yoffset = 0; var->bits_per_pixel = depth; switch (depth) { case 8: var->bits_per_pixel = 8; var->red.offset = 0; var->red.length = 8; var->green.offset = 0; var->green.length = 8; var->blue.offset = 0; var->blue.length = 8; var->transp.offset = 0; var->transp.length = 0; break; case 16: /* RGB 555 */ var->bits_per_pixel = 16; var->red.offset = 10; var->red.length = 5; var->green.offset = 5; var->green.length = 5; var->blue.offset = 0; var->blue.length = 5; var->transp.offset = 0; var->transp.length = 0; break; case 32: /* RGB 888 */ var->bits_per_pixel = 32; var->red.offset = 16; var->red.length = 8; var->green.offset = 8; var->green.length = 8; var->blue.offset = 0; var->blue.length = 8; var->transp.offset = 24; var->transp.length = 8; break; } var->red.msb_right = var->green.msb_right = var->blue.msb_right = var->transp.msb_right = 0; var->grayscale = 0; var->nonstd = 0; var->activate = 0; var->height = var->width = -1; var->pixclock = 10000; var->left_margin = var->right_margin = 16; var->upper_margin = var->lower_margin = 16; var->hsync_len = var->vsync_len = 8; var->sync = 0; var->vmode = FB_VMODE_NONINTERLACED; info->fbops = &offb_ops; info->screen_base = ioremap(address, fix->smem_len); info->par = par; info->pseudo_palette = (void *) (info + 1); info->flags = FBINFO_DEFAULT; fb_alloc_cmap(&info->cmap, 256, 0); if (register_framebuffer(info) < 0) { kfree(info); release_mem_region(res_start, res_size); return; } printk(KERN_INFO "fb%d: Open Firmware frame buffer device on %s\n", info->node, full_name); }
void __init chrp_find_bridges(void) { struct device_node *dev; int *bus_range; int len, index = -1; struct pci_controller *hose; volatile unsigned char *cfg; unsigned int *dma; char *model, *machine; int is_longtrail = 0, is_mot = 0; struct device_node *root = find_path_device("/"); #ifdef CONFIG_POWER3 unsigned int *opprop = (unsigned int *) get_property(root, "platform-open-pic", NULL); int i; #endif /* * The PCI host bridge nodes on some machines don't have * properties to adequately identify them, so we have to * look at what sort of machine this is as well. */ machine = get_property(root, "model", NULL); if (machine != NULL) { is_longtrail = strncmp(machine, "IBM,LongTrail", 13) == 0; is_mot = strncmp(machine, "MOT", 3) == 0; } for (dev = root->child; dev != NULL; dev = dev->sibling) { if (dev->type == NULL || strcmp(dev->type, "pci") != 0) continue; ++index; /* The GG2 bridge on the LongTrail doesn't have an address */ if (dev->n_addrs < 1 && !is_longtrail) { printk(KERN_WARNING "Can't use %s: no address\n", dev->full_name); continue; } bus_range = (int *) get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { printk(KERN_WARNING "Can't get bus-range for %s\n", dev->full_name); continue; } if (bus_range[1] == bus_range[0]) printk(KERN_INFO "PCI bus %d", bus_range[0]); else printk(KERN_INFO "PCI buses %d..%d", bus_range[0], bus_range[1]); printk(" controlled by %s", dev->type); if (dev->n_addrs > 0) printk(" at %x", dev->addrs[0].address); printk("\n"); hose = pcibios_alloc_controller(); if (!hose) { printk("Can't allocate PCI controller structure for %s\n", dev->full_name); continue; } hose->arch_data = dev; hose->first_busno = bus_range[0]; hose->last_busno = bus_range[1]; model = get_property(dev, "model", NULL); if (model == NULL) model = "<none>"; if (device_is_compatible(dev, "IBM,python")) { hose->ops = &python_pci_ops; cfg = ioremap(dev->addrs[0].address + 0xf8000, 0x20); hose->cfg_addr = (volatile unsigned int *) cfg; hose->cfg_data = cfg + 0x10; } else if (is_mot || strncmp(model, "Motorola, Grackle", 17) == 0) { setup_grackle(hose); } else if (is_longtrail) { hose->ops = &gg2_pci_ops; gg2_pci_config_base = (unsigned long) ioremap(GG2_PCI_CONFIG_BASE, 0x80000); } else { printk("No methods for %s (model %s), using RTAS\n", dev->full_name, model); hose->ops = &rtas_pci_ops; } pci_process_bridge_OF_ranges(hose, dev, index == 0); #ifdef CONFIG_POWER3 if (opprop != NULL) { i = prom_n_addr_cells(root) * (index + 2) - 1; openpic_setup_ISU(index, opprop[i]); } #endif /* CONFIG_POWER3 */ /* check the first bridge for a property that we can use to set pci_dram_offset */ dma = (unsigned int *) get_property(dev, "ibm,dma-ranges", &len); if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) { pci_dram_offset = dma[2] - dma[3]; printk("pci_dram_offset = %lx\n", pci_dram_offset); } } ppc_md.pcibios_fixup = chrp_pcibios_fixup; }
__initfunc(void pmac_pic_init(void)) { int i; struct device_node *irqctrler; volatile struct pmac_irq_hw *addr; int second_irq; /* We first try to detect Apple's new Core99 chipset, since mac-io * is quite different on those machines and contains an IBM MPIC2. */ irqctrler = find_type_devices("open-pic"); if (irqctrler != NULL) { printk("PowerMac using OpenPIC irq controller\n"); if (irqctrler->n_addrs > 0) { #ifdef CONFIG_XMON struct device_node* pswitch; #endif /* CONFIG_XMON */ OpenPIC = (volatile struct OpenPIC *) ioremap(irqctrler->addrs[0].address, irqctrler->addrs[0].size); for ( i = 0 ; i < NR_IRQS ; i++ ) { irq_desc[i].ctl = &pmac_open_pic; irq_desc[i].level = 0; } openpic_init(1); has_openpic = 1; #ifdef CONFIG_XMON pswitch = find_devices("programmer-switch"); if (pswitch && pswitch->n_intrs) request_irq(pswitch->intrs[0].line, xmon_irq, 0, "NMI - XMON", 0); #endif /* CONFIG_XMON */ return; } irqctrler = NULL; } /* * G3 powermacs and 1999 G3 PowerBooks have 64 interrupts, * 1998 G3 Series PowerBooks have 128, * other powermacs have 32. * The combo ethernet/modem card for the Powerstar powerbooks * (2400/3400/3500, ohare based) has a second ohare chip * effectively making a total of 64. */ max_irqs = max_real_irqs = 32; irqctrler = find_devices("mac-io"); if (irqctrler) { max_real_irqs = 64; if (irqctrler->next) max_irqs = 128; else max_irqs = 64; } for ( i = 0; i < max_real_irqs ; i++ ) irq_desc[i].ctl = &pmac_pic; /* get addresses of first controller */ if (irqctrler) { if (irqctrler->n_addrs > 0) { addr = ioremap(irqctrler->addrs[0].address, 0x40); addr += 2; for (i = 0; i < 2; ++i, --addr) pmac_irq_hw[i] = addr; } /* get addresses of second controller */ irqctrler = irqctrler->next; if (irqctrler && irqctrler->n_addrs > 0) { addr = ioremap(irqctrler->addrs[0].address, 0x40); addr += 2; for (i = 2; i < 4; ++i, --addr) pmac_irq_hw[i] = addr; } } /* PowerBooks 3400 and 3500 can have a second controller in a second ohare chip, on the combo ethernet/modem card */ if (machine_is_compatible("AAPL,3400/2400") || machine_is_compatible("AAPL,3500")) enable_second_ohare(); /* disable all interrupts in all controllers */ for (i = 0; i * 32 < max_irqs; ++i) out_le32(&pmac_irq_hw[i]->enable, 0); /* get interrupt line of secondary interrupt controller */ if (irqctrler) { second_irq = irqctrler->intrs[0].line; printk(KERN_INFO "irq: secondary controller on irq %d\n", (int)second_irq); if (device_is_compatible(irqctrler, "gatwick")) pmac_fix_gatwick_interrupts(irqctrler, max_real_irqs); request_irq( second_irq, gatwick_action, SA_INTERRUPT, "interrupt cascade", 0 ); } for (i = max_real_irqs; i < max_irqs; i++) irq_desc[i].ctl = &gatwick_pic; printk("System has %d possible interrupts\n", max_irqs); if (max_irqs != max_real_irqs) printk(KERN_DEBUG "%d interrupts on main controller\n", max_real_irqs); #ifdef CONFIG_XMON request_irq(20, xmon_irq, 0, "NMI - XMON", 0); #endif /* CONFIG_XMON */ }
static int wf_lm75_attach(struct i2c_adapter *adapter) { u8 bus_id; struct device_node *smu, *bus, *dev; /* We currently only deal with LM75's hanging off the SMU * i2c busses. If we extend that driver to other/older * machines, we should split this function into SMU-i2c, * keywest-i2c, PMU-i2c, ... */ DBG("wf_lm75: adapter %s detected\n", adapter->name); if (strncmp(adapter->name, "smu-i2c-", 8) != 0) return 0; smu = of_find_node_by_type(NULL, "smu"); if (smu == NULL) return 0; /* Look for the bus in the device-tree */ bus_id = (u8)simple_strtoul(adapter->name + 8, NULL, 16); DBG("wf_lm75: bus ID is %x\n", bus_id); /* Look for sensors subdir */ for (bus = NULL; (bus = of_get_next_child(smu, bus)) != NULL;) { u32 *reg; if (strcmp(bus->name, "i2c")) continue; reg = (u32 *)get_property(bus, "reg", NULL); if (reg == NULL) continue; if (bus_id == *reg) break; } of_node_put(smu); if (bus == NULL) { printk(KERN_WARNING "windfarm: SMU i2c bus 0x%x not found" " in device-tree !\n", bus_id); return 0; } DBG("wf_lm75: bus found, looking for device...\n"); /* Now look for lm75(s) in there */ for (dev = NULL; (dev = of_get_next_child(bus, dev)) != NULL;) { const char *loc = get_property(dev, "hwsensor-location", NULL); u32 *reg = (u32 *)get_property(dev, "reg", NULL); DBG(" dev: %s... (loc: %p, reg: %p)\n", dev->name, loc, reg); if (loc == NULL || reg == NULL) continue; /* real lm75 */ if (device_is_compatible(dev, "lm75")) wf_lm75_create(adapter, *reg, 0, loc); /* ds1775 (compatible, better resolution */ else if (device_is_compatible(dev, "ds1775")) wf_lm75_create(adapter, *reg, 1, loc); } of_node_put(bus); return 0; }
int __init offb_init(void) { struct device_node *dp = NULL, *boot_disp = NULL; #if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32) struct device_node *macos_display = NULL; #endif if (fb_get_options("offb", NULL)) return -ENODEV; #if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32) /* If we're booted from BootX... */ if (boot_infos != 0) { unsigned long addr = (unsigned long) boot_infos->dispDeviceBase; /* find the device node corresponding to the macos display */ while ((dp = of_find_node_by_type(dp, "display"))) { int i; /* * Grrr... It looks like the MacOS ATI driver * munges the assigned-addresses property (but * the AAPL,address value is OK). */ if (strncmp(dp->name, "ATY,", 4) == 0 && dp->n_addrs == 1) { unsigned int *ap = (unsigned int *) get_property(dp, "AAPL,address", NULL); if (ap != NULL) { dp->addrs[0].address = *ap; dp->addrs[0].size = 0x01000000; } } /* * The LTPro on the Lombard powerbook has no addresses * on the display nodes, they are on their parent. */ if (dp->n_addrs == 0 && device_is_compatible(dp, "ATY,264LTPro")) { int na; unsigned int *ap = (unsigned int *) get_property(dp, "AAPL,address", &na); if (ap != 0) for (na /= sizeof(unsigned int); na > 0; --na, ++ap) if (*ap <= addr && addr < *ap + 0x1000000) goto foundit; } /* * See if the display address is in one of the address * ranges for this display. */ for (i = 0; i < dp->n_addrs; ++i) { if (dp->addrs[i].address <= addr && addr < dp->addrs[i].address + dp->addrs[i].size) break; } if (i < dp->n_addrs) { foundit: printk(KERN_INFO "MacOS display is %s\n", dp->full_name); macos_display = dp; break; } } /* initialize it */ offb_init_fb(macos_display ? macos_display-> name : "MacOS display", macos_display ? macos_display-> full_name : "MacOS display", boot_infos->dispDeviceRect[2], boot_infos->dispDeviceRect[3], boot_infos->dispDeviceDepth, boot_infos->dispDeviceRowBytes, addr, NULL); } #endif /* defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32) */ for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) { if (get_property(dp, "linux,opened", NULL) && get_property(dp, "linux,boot-display", NULL)) { boot_disp = dp; offb_init_nodriver(dp); } } for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) { if (get_property(dp, "linux,opened", NULL) && dp != boot_disp) offb_init_nodriver(dp); } return 0; }
void __init chrp_find_bridges(void) { struct device_node *dev; int *bus_range; int len, index = -1; struct pci_controller *hose; unsigned int *dma; char *model, *machine; int is_longtrail = 0, is_mot = 0, is_pegasos = 0; struct device_node *root = find_path_device("/"); /* * The PCI host bridge nodes on some machines don't have * properties to adequately identify them, so we have to * look at what sort of machine this is as well. */ machine = get_property(root, "model", NULL); if (machine != NULL) { is_longtrail = strncmp(machine, "IBM,LongTrail", 13) == 0; is_mot = strncmp(machine, "MOT", 3) == 0; if (strncmp(machine, "Pegasos2", 8) == 0) is_pegasos = 2; else if (strncmp(machine, "Pegasos", 7) == 0) is_pegasos = 1; } for (dev = root->child; dev != NULL; dev = dev->sibling) { if (dev->type == NULL || strcmp(dev->type, "pci") != 0) continue; ++index; /* The GG2 bridge on the LongTrail doesn't have an address */ if (dev->n_addrs < 1 && !is_longtrail) { printk(KERN_WARNING "Can't use %s: no address\n", dev->full_name); continue; } bus_range = (int *) get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { printk(KERN_WARNING "Can't get bus-range for %s\n", dev->full_name); continue; } if (bus_range[1] == bus_range[0]) printk(KERN_INFO "PCI bus %d", bus_range[0]); else printk(KERN_INFO "PCI buses %d..%d", bus_range[0], bus_range[1]); printk(" controlled by %s", dev->type); if (dev->n_addrs > 0) printk(" at %lx", dev->addrs[0].address); printk("\n"); hose = pcibios_alloc_controller(); if (!hose) { printk("Can't allocate PCI controller structure for %s\n", dev->full_name); continue; } hose->arch_data = dev; hose->first_busno = bus_range[0]; hose->last_busno = bus_range[1]; model = get_property(dev, "model", NULL); if (model == NULL) model = "<none>"; if (device_is_compatible(dev, "IBM,python")) { setup_python(hose, dev); } else if (is_mot || strncmp(model, "Motorola, Grackle", 17) == 0) { setup_grackle(hose); } else if (is_longtrail) { void __iomem *p = ioremap(GG2_PCI_CONFIG_BASE, 0x80000); hose->ops = &gg2_pci_ops; hose->cfg_data = p; gg2_pci_config_base = p; } else if (is_pegasos == 1) { setup_indirect_pci(hose, 0xfec00cf8, 0xfee00cfc); } else if (is_pegasos == 2) { setup_peg2(hose, dev); } else { printk("No methods for %s (model %s), using RTAS\n", dev->full_name, model); hose->ops = &rtas_pci_ops; } pci_process_bridge_OF_ranges(hose, dev, index == 0); /* check the first bridge for a property that we can use to set pci_dram_offset */ dma = (unsigned int *) get_property(dev, "ibm,dma-ranges", &len); if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) { pci_dram_offset = dma[2] - dma[3]; printk("pci_dram_offset = %lx\n", pci_dram_offset); } } /* Do not fixup interrupts from OF tree on pegasos */ if (is_pegasos == 0) ppc_md.pcibios_fixup = chrp_pcibios_fixup; }