static int sis5595_setup(struct pci_dev *SIS5595_dev) { u16 a; u8 val; int *i; int retval = -ENODEV; /* Look for imposters */ for (i = blacklist; *i != 0; i++) { struct pci_dev *dev; dev = pci_get_device(PCI_VENDOR_ID_SI, *i, NULL); if (dev) { dev_err(&SIS5595_dev->dev, "Looked for SIS5595 but found unsupported device %.4x\n", *i); pci_dev_put(dev); return -ENODEV; } } /* Determine the address of the SMBus areas */ pci_read_config_word(SIS5595_dev, ACPI_BASE, &sis5595_base); if (sis5595_base == 0 && force_addr == 0) { dev_err(&SIS5595_dev->dev, "ACPI base address uninitialized - upgrade BIOS or use force_addr=0xaddr\n"); return -ENODEV; } if (force_addr) sis5595_base = force_addr & ~(SIS5595_EXTENT - 1); dev_dbg(&SIS5595_dev->dev, "ACPI Base address: %04x\n", sis5595_base); /* NB: We grab just the two SMBus registers here, but this may still * interfere with ACPI :-( */ if (!request_region(sis5595_base + SMB_INDEX, 2, "sis5595-smbus")) { dev_err(&SIS5595_dev->dev, "SMBus registers 0x%04x-0x%04x already in use!\n", sis5595_base + SMB_INDEX, sis5595_base + SMB_INDEX + 1); return -ENODEV; } if (force_addr) { dev_info(&SIS5595_dev->dev, "forcing ISA address 0x%04X\n", sis5595_base); if (!pci_write_config_word(SIS5595_dev, ACPI_BASE, sis5595_base)) goto error; if (!pci_read_config_word(SIS5595_dev, ACPI_BASE, &a)) goto error; if ((a & ~(SIS5595_EXTENT - 1)) != sis5595_base) { /* doesn't work for some chips! */ dev_err(&SIS5595_dev->dev, "force address failed - not supported?\n"); goto error; } } if (!pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val)) goto error; if ((val & 0x80) == 0) { dev_info(&SIS5595_dev->dev, "enabling ACPI\n"); if (!pci_write_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, val | 0x80)) goto error; if (!pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val)) goto error; if ((val & 0x80) == 0) { /* doesn't work for some chips? */ dev_err(&SIS5595_dev->dev, "ACPI enable failed - not supported?\n"); goto error; } } /* Everything is happy */ return 0; error: release_region(sis5595_base + SMB_INDEX, 2); return retval; }
static int __init mod_init(void) { int err = -ENODEV; int i; struct pci_dev *dev = NULL; void __iomem *mem = mem; u8 hw_status; struct intel_rng_hw *intel_rng_hw; for (i = 0; !dev && pci_tbl[i].vendor; ++i) dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device, NULL); if (!dev) goto out; if (no_fwh_detect < 0) { pci_dev_put(dev); goto fwh_done; } intel_rng_hw = kmalloc(sizeof(*intel_rng_hw), GFP_KERNEL); if (!intel_rng_hw) { pci_dev_put(dev); goto out; } err = intel_init_hw_struct(intel_rng_hw, dev); if (err) { pci_dev_put(dev); kfree(intel_rng_hw); if (err == -ENODEV) goto fwh_done; goto out; } err = stop_machine(intel_rng_hw_init, intel_rng_hw, NULL); pci_dev_put(dev); iounmap(intel_rng_hw->mem); kfree(intel_rng_hw); if (err) goto out; fwh_done: err = -ENOMEM; mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN); if (!mem) goto out; intel_rng.priv = (unsigned long)mem; err = -ENODEV; hw_status = hwstatus_get(mem); if ((hw_status & INTEL_RNG_PRESENT) == 0) { iounmap(mem); goto out; } printk(KERN_INFO "Intel 82802 RNG detected\n"); err = hwrng_register(&intel_rng); if (err) { printk(KERN_ERR PFX "RNG registering failed (%d)\n", err); iounmap(mem); } out: return err; }
/* Get framebuffer memory from Hyper-V video pci space */ static int hvfb_getmem(struct fb_info *info) { struct hvfb_par *par = info->par; struct pci_dev *pdev = NULL; void __iomem *fb_virt; int gen2vm = efi_enabled(EFI_BOOT); int ret; par->mem.name = KBUILD_MODNAME; par->mem.flags = IORESOURCE_MEM | IORESOURCE_BUSY; if (gen2vm) { ret = allocate_resource(&hyperv_mmio, &par->mem, screen_fb_size, 0, -1, screen_fb_size, NULL, NULL); if (ret != 0) { pr_err("Unable to allocate framebuffer memory\n"); return -ENODEV; } } else { pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT, PCI_DEVICE_ID_HYPERV_VIDEO, NULL); if (!pdev) { pr_err("Unable to find PCI Hyper-V video\n"); return -ENODEV; } if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM) || pci_resource_len(pdev, 0) < screen_fb_size) goto err1; par->mem.end = pci_resource_end(pdev, 0); par->mem.start = par->mem.end - screen_fb_size + 1; ret = request_resource(&pdev->resource[0], &par->mem); if (ret != 0) { pr_err("Unable to request framebuffer memory\n"); goto err1; } } fb_virt = ioremap(par->mem.start, screen_fb_size); if (!fb_virt) goto err2; info->apertures = alloc_apertures(1); if (!info->apertures) goto err3; if (gen2vm) { info->apertures->ranges[0].base = screen_info.lfb_base; info->apertures->ranges[0].size = screen_info.lfb_size; remove_conflicting_framebuffers(info->apertures, KBUILD_MODNAME, false); } else { info->apertures->ranges[0].base = pci_resource_start(pdev, 0); info->apertures->ranges[0].size = pci_resource_len(pdev, 0); } info->fix.smem_start = par->mem.start; info->fix.smem_len = screen_fb_size; info->screen_base = fb_virt; info->screen_size = screen_fb_size; if (!gen2vm) pci_dev_put(pdev); return 0; err3: iounmap(fb_virt); err2: release_resource(&par->mem); err1: if (!gen2vm) pci_dev_put(pdev); return -ENOMEM; }
int acpi_pci_bind(struct acpi_device *device) { int result = 0; acpi_status status; struct acpi_pci_data *data; struct acpi_pci_data *pdata; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; acpi_handle handle; if (!device || !device->parent) return -EINVAL; data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); if (!data) return -ENOMEM; status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); if (ACPI_FAILURE(status)) { kfree(data); return -ENODEV; } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI device [%s]...\n", (char *)buffer.pointer)); /* * Segment & Bus * ------------- * These are obtained via the parent device's ACPI-PCI context. */ status = acpi_get_data(device->parent->handle, acpi_pci_data_handler, (void **)&pdata); if (ACPI_FAILURE(status) || !pdata || !pdata->bus) { ACPI_EXCEPTION((AE_INFO, status, "Invalid ACPI-PCI context for parent device %s", acpi_device_bid(device->parent))); result = -ENODEV; goto end; } data->id.segment = pdata->id.segment; data->id.bus = pdata->bus->number; /* * Device & Function * ----------------- * These are simply obtained from the device's _ADR method. Note * that a value of zero is valid. */ data->id.device = device->pnp.bus_address >> 16; data->id.function = device->pnp.bus_address & 0xFFFF; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "...to %04x:%02x:%02x.%d\n", data->id.segment, data->id.bus, data->id.device, data->id.function)); /* * TBD: Support slot devices (e.g. function=0xFFFF). */ /* * Locate PCI Device * ----------------- * Locate matching device in PCI namespace. If it doesn't exist * this typically means that the device isn't currently inserted * (e.g. docking station, port replicator, etc.). */ data->dev = pci_get_slot(pdata->bus, PCI_DEVFN(data->id.device, data->id.function)); if (!data->dev) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %04x:%02x:%02x.%d not present in PCI namespace\n", data->id.segment, data->id.bus, data->id.device, data->id.function)); result = -ENODEV; goto end; } if (!data->dev->bus) { printk(KERN_ERR PREFIX "Device %04x:%02x:%02x.%d has invalid 'bus' field\n", data->id.segment, data->id.bus, data->id.device, data->id.function); result = -ENODEV; goto end; } /* * PCI Bridge? * ----------- * If so, set the 'bus' field and install the 'bind' function to * facilitate callbacks for all of its children. */ if (data->dev->subordinate) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %04x:%02x:%02x.%d is a PCI bridge\n", data->id.segment, data->id.bus, data->id.device, data->id.function)); data->bus = data->dev->subordinate; device->ops.bind = acpi_pci_bind; device->ops.unbind = acpi_pci_unbind; } /* * Attach ACPI-PCI Context * ----------------------- * Thus binding the ACPI and PCI devices. */ status = acpi_attach_data(device->handle, acpi_pci_data_handler, data); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Unable to attach ACPI-PCI context to device %s", acpi_device_bid(device))); result = -ENODEV; goto end; } /* * PCI Routing Table * ----------------- * Evaluate and parse _PRT, if exists. This code is independent of * PCI bridges (above) to allow parsing of _PRT objects within the * scope of non-bridge devices. Note that _PRTs within the scope of * a PCI bridge assume the bridge's subordinate bus number. * * TBD: Can _PRTs exist within the scope of non-bridge PCI devices? */ status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); if (ACPI_SUCCESS(status)) { if (data->bus) /* PCI-PCI bridge */ acpi_pci_irq_add_prt(device->handle, data->id.segment, data->bus->number); else /* non-bridge PCI device */ acpi_pci_irq_add_prt(device->handle, data->id.segment, data->id.bus); } end: kfree(buffer.pointer); if (result) { pci_dev_put(data->dev); kfree(data); } return result; }
int mthca_reset(struct mthca_dev *mdev) { int i; int err = 0; u32 *hca_header = NULL; u32 *bridge_header = NULL; struct pci_dev *bridge = NULL; int bridge_pcix_cap = 0; int hca_pcie_cap = 0; int hca_pcix_cap = 0; u16 devctl; u16 linkctl; #define MTHCA_RESET_OFFSET 0xf0010 #define MTHCA_RESET_VALUE swab32(1) /* * Reset the chip. This is somewhat ugly because we have to * save off the PCI header before reset and then restore it * after the chip reboots. We skip config space offsets 22 * and 23 since those have a special meaning. * * To make matters worse, for Tavor (PCI-X HCA) we have to * find the associated bridge device and save off its PCI * header as well. */ if (!(mdev->mthca_flags & MTHCA_FLAG_PCIE)) { /* Look for the bridge -- its device ID will be 2 more than HCA's device ID. */ #ifdef __linux__ while ((bridge = pci_get_device(mdev->pdev->vendor, mdev->pdev->device + 2, bridge)) != NULL) { if (bridge->hdr_type == PCI_HEADER_TYPE_BRIDGE && bridge->subordinate == mdev->pdev->bus) { mthca_dbg(mdev, "Found bridge: %s\n", pci_name(bridge)); break; } } if (!bridge) { /* * Didn't find a bridge for a Tavor device -- * assume we're in no-bridge mode and hope for * the best. */ mthca_warn(mdev, "No bridge found for %s\n", pci_name(mdev->pdev)); } #else mthca_warn(mdev, "Reset on PCI-X is not supported.\n"); goto out; #endif } /* For Arbel do we need to save off the full 4K PCI Express header?? */ hca_header = kmalloc(256, GFP_KERNEL); if (!hca_header) { err = -ENOMEM; mthca_err(mdev, "Couldn't allocate memory to save HCA " "PCI header, aborting.\n"); goto out; } for (i = 0; i < 64; ++i) { if (i == 22 || i == 23) continue; if (pci_read_config_dword(mdev->pdev, i * 4, hca_header + i)) { err = -ENODEV; mthca_err(mdev, "Couldn't save HCA " "PCI header, aborting.\n"); goto out; } } hca_pcix_cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_PCIX); hca_pcie_cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_EXP); #ifdef __linux__ if (bridge) { bridge_header = kmalloc(256, GFP_KERNEL); if (!bridge_header) { err = -ENOMEM; mthca_err(mdev, "Couldn't allocate memory to save HCA " "bridge PCI header, aborting.\n"); goto out; } for (i = 0; i < 64; ++i) { if (i == 22 || i == 23) continue; if (pci_read_config_dword(bridge, i * 4, bridge_header + i)) { err = -ENODEV; mthca_err(mdev, "Couldn't save HCA bridge " "PCI header, aborting.\n"); goto out; } } bridge_pcix_cap = pci_find_capability(bridge, PCI_CAP_ID_PCIX); if (!bridge_pcix_cap) { err = -ENODEV; mthca_err(mdev, "Couldn't locate HCA bridge " "PCI-X capability, aborting.\n"); goto out; } } #endif /* actually hit reset */ { void __iomem *reset = ioremap(pci_resource_start(mdev->pdev, 0) + MTHCA_RESET_OFFSET, 4); if (!reset) { err = -ENOMEM; mthca_err(mdev, "Couldn't map HCA reset register, " "aborting.\n"); goto out; } writel(MTHCA_RESET_VALUE, reset); iounmap(reset); } /* Docs say to wait one second before accessing device */ msleep(1000); /* Now wait for PCI device to start responding again */ { u32 v; int c = 0; for (c = 0; c < 100; ++c) { if (pci_read_config_dword(bridge ? bridge : mdev->pdev, 0, &v)) { err = -ENODEV; mthca_err(mdev, "Couldn't access HCA after reset, " "aborting.\n"); goto out; } if (v != 0xffffffff) goto good; msleep(100); } err = -ENODEV; mthca_err(mdev, "PCI device did not come back after reset, " "aborting.\n"); goto out; } good: /* Now restore the PCI headers */ if (bridge) { if (pci_write_config_dword(bridge, bridge_pcix_cap + 0x8, bridge_header[(bridge_pcix_cap + 0x8) / 4])) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA bridge Upstream " "split transaction control, aborting.\n"); goto out; } if (pci_write_config_dword(bridge, bridge_pcix_cap + 0xc, bridge_header[(bridge_pcix_cap + 0xc) / 4])) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA bridge Downstream " "split transaction control, aborting.\n"); goto out; } /* * Bridge control register is at 0x3e, so we'll * naturally restore it last in this loop. */ for (i = 0; i < 16; ++i) { if (i * 4 == PCI_COMMAND) continue; if (pci_write_config_dword(bridge, i * 4, bridge_header[i])) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA bridge reg %x, " "aborting.\n", i); goto out; } } if (pci_write_config_dword(bridge, PCI_COMMAND, bridge_header[PCI_COMMAND / 4])) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA bridge COMMAND, " "aborting.\n"); goto out; } } if (hca_pcix_cap) { if (pci_write_config_dword(mdev->pdev, hca_pcix_cap, hca_header[hca_pcix_cap / 4])) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA PCI-X " "command register, aborting.\n"); goto out; } } if (hca_pcie_cap) { devctl = hca_header[(hca_pcie_cap + PCI_EXP_DEVCTL) / 4]; if (pci_write_config_word(mdev->pdev, hca_pcie_cap + PCI_EXP_DEVCTL, devctl)) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA PCI Express " "Device Control register, aborting.\n"); goto out; } linkctl = hca_header[(hca_pcie_cap + PCI_EXP_LNKCTL) / 4]; if (pci_write_config_word(mdev->pdev, hca_pcie_cap + PCI_EXP_LNKCTL, linkctl)) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA PCI Express " "Link control register, aborting.\n"); goto out; } } for (i = 0; i < 16; ++i) { if (i * 4 == PCI_COMMAND) continue; if (pci_write_config_dword(mdev->pdev, i * 4, hca_header[i])) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA reg %x, " "aborting.\n", i); goto out; } } if (pci_write_config_dword(mdev->pdev, PCI_COMMAND, hca_header[PCI_COMMAND / 4])) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA COMMAND, " "aborting.\n"); goto out; } out: #ifdef __linux__ if (bridge) pci_dev_put(bridge); #endif kfree(bridge_header); kfree(hca_header); return err; }
static int zt5550_hc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { int status; status = zt5550_hc_config(pdev); if (status != 0) return status; dbg("returned from zt5550_hc_config"); memset(&zt5550_hpc, 0, sizeof(struct cpci_hp_controller)); zt5550_hpc_ops.query_enum = zt5550_hc_query_enum; zt5550_hpc.ops = &zt5550_hpc_ops; if (!poll) { zt5550_hpc.irq = hc_dev->irq; zt5550_hpc.irq_flags = IRQF_SHARED; zt5550_hpc.dev_id = hc_dev; zt5550_hpc_ops.enable_irq = zt5550_hc_enable_irq; zt5550_hpc_ops.disable_irq = zt5550_hc_disable_irq; zt5550_hpc_ops.check_irq = zt5550_hc_check_irq; } else { info("using ENUM# polling mode"); } status = cpci_hp_register_controller(&zt5550_hpc); if (status != 0) { err("could not register cPCI hotplug controller"); goto init_hc_error; } dbg("registered controller"); /* Look for first device matching cPCI bus's bridge vendor and device IDs */ bus0_dev = pci_get_device(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21154, NULL); if (!bus0_dev) { status = -ENODEV; goto init_register_error; } bus0 = bus0_dev->subordinate; pci_dev_put(bus0_dev); status = cpci_hp_register_bus(bus0, 0x0a, 0x0f); if (status != 0) { err("could not register cPCI hotplug bus"); goto init_register_error; } dbg("registered bus"); status = cpci_hp_start(); if (status != 0) { err("could not started cPCI hotplug system"); cpci_hp_unregister_bus(bus0); goto init_register_error; } dbg("started cpci hp system"); return 0; init_register_error: cpci_hp_unregister_controller(&zt5550_hpc); init_hc_error: err("status = %d", status); zt5550_hc_cleanup(); return status; }
static int __devinit pasemi_nand_probe(struct platform_device *ofdev, const struct of_device_id *match) { struct pci_dev *pdev; struct device_node *np = ofdev->dev.of_node; struct resource res; struct nand_chip *chip; int err = 0; err = of_address_to_resource(np, 0, &res); if (err) return -EINVAL; /* We only support one device at the moment */ if (pasemi_nand_mtd) return -ENODEV; pr_debug("pasemi_nand at %llx-%llx\n", res.start, res.end); /* Allocate memory for MTD device structure and private data */ pasemi_nand_mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); if (!pasemi_nand_mtd) { printk(KERN_WARNING "Unable to allocate PASEMI NAND MTD device structure\n"); err = -ENOMEM; goto out; } /* Get pointer to private data */ chip = (struct nand_chip *)&pasemi_nand_mtd[1]; /* Link the private data with the MTD structure */ pasemi_nand_mtd->priv = chip; pasemi_nand_mtd->owner = THIS_MODULE; chip->IO_ADDR_R = of_iomap(np, 0); chip->IO_ADDR_W = chip->IO_ADDR_R; if (!chip->IO_ADDR_R) { err = -EIO; goto out_mtd; } pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa008, NULL); if (!pdev) { err = -ENODEV; goto out_ior; } lpcctl = pci_resource_start(pdev, 0); pci_dev_put(pdev); if (!request_region(lpcctl, 4, driver_name)) { err = -EBUSY; goto out_ior; } chip->cmd_ctrl = pasemi_hwcontrol; chip->dev_ready = pasemi_device_ready; chip->read_buf = pasemi_read_buf; chip->write_buf = pasemi_write_buf; chip->chip_delay = 0; chip->ecc.mode = NAND_ECC_SOFT; /* Enable the following for a flash based bad block table */ chip->options = NAND_NO_AUTOINCR; chip->bbt_options = NAND_BBT_USE_FLASH; /* Scan to find existance of the device */ if (nand_scan(pasemi_nand_mtd, 1)) { err = -ENXIO; goto out_lpc; } if (add_mtd_device(pasemi_nand_mtd)) { printk(KERN_ERR "pasemi_nand: Unable to register MTD device\n"); err = -ENODEV; goto out_lpc; } printk(KERN_INFO "PA Semi NAND flash at %08llx, control at I/O %x\n", res.start, lpcctl); return 0; out_lpc: release_region(lpcctl, 4); out_ior: iounmap(chip->IO_ADDR_R); out_mtd: kfree(pasemi_nand_mtd); out: return err; }
/* PCI probe function */ static int ps_hdmi_hpd_probe(struct pci_dev *pdev, const struct pci_device_id *id) { int result = 0; hdmi_context_t *ctx = g_context; if (pdev == NULL || ctx == NULL) { pr_err("%s: called with NULL device or context\n", __func__); result = -EINVAL; return result; } /* Verify probe is called for the intended device */ if (pdev->device != PS_MSIC_PCI_DEVICE_ID) { pr_err("%s: called for wrong device id = 0x%x\n", __func__, pdev->device); result = -EINVAL; goto exit; } pr_debug("pci_enable_device for 0x%x\n", PS_MSIC_PCI_DEVICE_ID); result = pci_enable_device(pdev); if (result) { pr_err("%s: Failed to enable MSIC PCI device = 0x%x\n", __func__, PS_MSIC_PCI_DEVICE_ID); goto exit; } /* Perform the GPIO configuration */ result = gpio_request(ctx->gpio_hpd_pin, "ctp_hdmi_ti_hpd"); if (result) { pr_debug("%s: Failed to request GPIO %d for kbd IRQ\n", __func__, ctx->gpio_hpd_pin); goto exit2; } result = gpio_direction_input(ctx->gpio_hpd_pin); if (result) { pr_debug("%s: Failed to set GPIO %d as input\n", __func__, ctx->gpio_hpd_pin); goto exit3; } ctx->irq_number = gpio_to_irq(ctx->gpio_hpd_pin); pr_debug("%s: IRQ number assigned = %d\n", __func__, ctx->irq_number); result = irq_set_irq_type(ctx->irq_number, IRQ_TYPE_EDGE_BOTH); if (result) { pr_debug("%s: Failed to set HDMI HPD IRQ type for IRQ %d\n", __func__, ctx->irq_number); goto exit3; } /* This is unused on CTP platform, since we use GPIO */ ctx->dev.irq_io_address = 0; result = request_threaded_irq(ctx->irq_number, ps_hdmi_irq_handler, ctx->hpd_callback, IRQF_SHARED, PS_HDMI_HPD_PCI_DRIVER_NAME, ctx->hpd_data); if (result) { pr_debug("%s: Register irq interrupt %d failed\n", __func__, ctx->irq_number); goto exit3; } irq_set_irq_wake(ctx->irq_number, 1); return result; exit3: gpio_free(ctx->gpio_hpd_pin); exit2: pci_disable_device(pdev); exit: pci_dev_put(pdev); return result; }
static int __devinit sis_find_family(struct pci_dev *dev) { struct pci_dev *host; int i = 0; chipset_family = 0; for (i = 0; i < ARRAY_SIZE(SiSHostChipInfo) && !chipset_family; i++) { host = pci_get_device(PCI_VENDOR_ID_SI, SiSHostChipInfo[i].host_id, NULL); if (!host) continue; chipset_family = SiSHostChipInfo[i].chipset_family; /* Special case for SiS630 : 630S/ET is ATA_100a */ if (SiSHostChipInfo[i].host_id == PCI_DEVICE_ID_SI_630) { if (host->revision >= 0x30) chipset_family = ATA_100a; } pci_dev_put(host); printk(KERN_INFO DRV_NAME " %s: %s %s controller\n", pci_name(dev), SiSHostChipInfo[i].name, chipset_capability[chipset_family]); } if (!chipset_family) { /* Belongs to pci-quirks */ u32 idemisc; u16 trueid; /* Disable ID masking and register remapping */ pci_read_config_dword(dev, 0x54, &idemisc); pci_write_config_dword(dev, 0x54, (idemisc & 0x7fffffff)); pci_read_config_word(dev, PCI_DEVICE_ID, &trueid); pci_write_config_dword(dev, 0x54, idemisc); if (trueid == 0x5518) { printk(KERN_INFO DRV_NAME " %s: SiS 962/963 MuTIOL IDE UDMA133 controller\n", pci_name(dev)); chipset_family = ATA_133; /* Check for 5513 compability mapping * We must use this, else the port enabled code will fail, * as it expects the enablebits at 0x4a. */ if ((idemisc & 0x40000000) == 0) { pci_write_config_dword(dev, 0x54, idemisc | 0x40000000); printk(KERN_INFO DRV_NAME " %s: Switching to 5513 register mapping\n", pci_name(dev)); } } } if (!chipset_family) { /* Belongs to pci-quirks */ struct pci_dev *lpc_bridge; u16 trueid; u8 prefctl; u8 idecfg; pci_read_config_byte(dev, 0x4a, &idecfg); pci_write_config_byte(dev, 0x4a, idecfg | 0x10); pci_read_config_word(dev, PCI_DEVICE_ID, &trueid); pci_write_config_byte(dev, 0x4a, idecfg); if (trueid == 0x5517) { /* SiS 961/961B */ lpc_bridge = pci_get_slot(dev->bus, 0x10); /* Bus 0, Dev 2, Fn 0 */ pci_read_config_byte(dev, 0x49, &prefctl); pci_dev_put(lpc_bridge); if (lpc_bridge->revision == 0x10 && (prefctl & 0x80)) { printk(KERN_INFO DRV_NAME " %s: SiS 961B MuTIOL IDE UDMA133 controller\n", pci_name(dev)); chipset_family = ATA_133a; } else { printk(KERN_INFO DRV_NAME " %s: SiS 961 MuTIOL IDE UDMA100 controller\n", pci_name(dev)); chipset_family = ATA_100; } } } return chipset_family; }
static int falcon_probe_nic(struct efx_nic *efx) { struct falcon_nic_data *nic_data; struct falcon_board *board; int rc; /* Allocate storage for hardware specific data */ nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL); if (!nic_data) return -ENOMEM; efx->nic_data = nic_data; rc = -ENODEV; if (efx_nic_fpga_ver(efx) != 0) { EFX_ERR(efx, "Falcon FPGA not supported\n"); goto fail1; } if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1) { efx_oword_t nic_stat; struct pci_dev *dev; u8 pci_rev = efx->pci_dev->revision; if ((pci_rev == 0xff) || (pci_rev == 0)) { EFX_ERR(efx, "Falcon rev A0 not supported\n"); goto fail1; } efx_reado(efx, &nic_stat, FR_AB_NIC_STAT); if (EFX_OWORD_FIELD(nic_stat, FRF_AB_STRAP_10G) == 0) { EFX_ERR(efx, "Falcon rev A1 1G not supported\n"); goto fail1; } if (EFX_OWORD_FIELD(nic_stat, FRF_AA_STRAP_PCIE) == 0) { EFX_ERR(efx, "Falcon rev A1 PCI-X not supported\n"); goto fail1; } dev = pci_dev_get(efx->pci_dev); while ((dev = pci_get_device(EFX_VENDID_SFC, FALCON_A_S_DEVID, dev))) { if (dev->bus == efx->pci_dev->bus && dev->devfn == efx->pci_dev->devfn + 1) { nic_data->pci_dev2 = dev; break; } } if (!nic_data->pci_dev2) { EFX_ERR(efx, "failed to find secondary function\n"); rc = -ENODEV; goto fail2; } } /* Now we can reset the NIC */ rc = falcon_reset_hw(efx, RESET_TYPE_ALL); if (rc) { EFX_ERR(efx, "failed to reset NIC\n"); goto fail3; } /* Allocate memory for INT_KER */ rc = efx_nic_alloc_buffer(efx, &efx->irq_status, sizeof(efx_oword_t)); if (rc) goto fail4; BUG_ON(efx->irq_status.dma_addr & 0x0f); EFX_LOG(efx, "INT_KER at %llx (virt %p phys %llx)\n", (u64)efx->irq_status.dma_addr, efx->irq_status.addr, (u64)virt_to_phys(efx->irq_status.addr)); falcon_probe_spi_devices(efx); /* Read in the non-volatile configuration */ rc = falcon_probe_nvconfig(efx); if (rc) goto fail5; /* Initialise I2C adapter */ board = falcon_board(efx); board->i2c_adap.owner = THIS_MODULE; board->i2c_data = falcon_i2c_bit_operations; board->i2c_data.data = efx; board->i2c_adap.algo_data = &board->i2c_data; board->i2c_adap.dev.parent = &efx->pci_dev->dev; strlcpy(board->i2c_adap.name, "SFC4000 GPIO", sizeof(board->i2c_adap.name)); rc = i2c_bit_add_bus(&board->i2c_adap); if (rc) goto fail5; rc = falcon_board(efx)->type->init(efx); if (rc) { EFX_ERR(efx, "failed to initialise board\n"); goto fail6; } nic_data->stats_disable_count = 1; setup_timer(&nic_data->stats_timer, &falcon_stats_timer_func, (unsigned long)efx); return 0; fail6: BUG_ON(i2c_del_adapter(&board->i2c_adap)); memset(&board->i2c_adap, 0, sizeof(board->i2c_adap)); fail5: falcon_remove_spi_devices(efx); efx_nic_free_buffer(efx, &efx->irq_status); fail4: fail3: if (nic_data->pci_dev2) { pci_dev_put(nic_data->pci_dev2); nic_data->pci_dev2 = NULL; } fail2: fail1: kfree(efx->nic_data); return rc; }
static int jmicron_probe(struct sdhci_pci_chip *chip) { int ret; u16 mmcdev = 0; if (chip->pdev->revision == 0) { chip->quirks |= SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_32BIT_DMA_SIZE | SDHCI_QUIRK_32BIT_ADMA_SIZE | SDHCI_QUIRK_RESET_AFTER_REQUEST | SDHCI_QUIRK_BROKEN_SMALL_PIO; } /* * JMicron chips can have two interfaces to the same hardware * in order to work around limitations in Microsoft's driver. * We need to make sure we only bind to one of them. * * This code assumes two things: * * 1. The PCI code adds subfunctions in order. * * 2. The MMC interface has a lower subfunction number * than the SD interface. */ if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_SD) mmcdev = PCI_DEVICE_ID_JMICRON_JMB38X_MMC; else if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_SD) mmcdev = PCI_DEVICE_ID_JMICRON_JMB388_ESD; if (mmcdev) { struct pci_dev *sd_dev; sd_dev = NULL; while ((sd_dev = pci_get_device(PCI_VENDOR_ID_JMICRON, mmcdev, sd_dev)) != NULL) { if ((PCI_SLOT(chip->pdev->devfn) == PCI_SLOT(sd_dev->devfn)) && (chip->pdev->bus == sd_dev->bus)) break; } if (sd_dev) { pci_dev_put(sd_dev); dev_info(&chip->pdev->dev, "Refusing to bind to " "secondary interface.\n"); return -ENODEV; } } /* * JMicron chips need a bit of a nudge to enable the power * output pins. */ ret = jmicron_pmos(chip, 1); if (ret) { dev_err(&chip->pdev->dev, "Failure enabling card power\n"); return ret; } /* quirk for unsable RO-detection on JM388 chips */ if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_SD || chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD) chip->quirks |= SDHCI_QUIRK_UNSTABLE_RO_DETECT; return 0; }
static unsigned int init_chipset_ali15x3(struct pci_dev *dev) { unsigned long flags; u8 tmpbyte; struct pci_dev *north = pci_get_slot(dev->bus, PCI_DEVFN(0,0)); m5229_revision = dev->revision; isa_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); local_irq_save(flags); if (m5229_revision < 0xC2) { /* * revision 0x20 (1543-E, 1543-F) * revision 0xC0, 0xC1 (1543C-C, 1543C-D, 1543C-E) * clear CD-ROM DMA write bit, m5229, 0x4b, bit 7 */ pci_read_config_byte(dev, 0x4b, &tmpbyte); /* * clear bit 7 */ pci_write_config_byte(dev, 0x4b, tmpbyte & 0x7F); /* * check m1533, 0x5e, bit 1~4 == 1001 => & 00011110 = 00010010 */ if (m5229_revision >= 0x20 && isa_dev) { pci_read_config_byte(isa_dev, 0x5e, &tmpbyte); chip_is_1543c_e = ((tmpbyte & 0x1e) == 0x12) ? 1: 0; } goto out; } /* * 1543C-B?, 1535, 1535D, 1553 * Note 1: not all "motherboard" support this detection * Note 2: if no udma 66 device, the detection may "error". * but in this case, we will not set the device to * ultra 66, the detection result is not important */ /* * enable "Cable Detection", m5229, 0x4b, bit3 */ pci_read_config_byte(dev, 0x4b, &tmpbyte); pci_write_config_byte(dev, 0x4b, tmpbyte | 0x08); /* * We should only tune the 1533 enable if we are using an ALi * North bridge. We might have no north found on some zany * box without a device at 0:0.0. The ALi bridge will be at * 0:0.0 so if we didn't find one we know what is cooking. */ if (north && north->vendor != PCI_VENDOR_ID_AL) goto out; if (m5229_revision < 0xC5 && isa_dev) { /* * set south-bridge's enable bit, m1533, 0x79 */ pci_read_config_byte(isa_dev, 0x79, &tmpbyte); if (m5229_revision == 0xC2) { /* * 1543C-B0 (m1533, 0x79, bit 2) */ pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x04); } else if (m5229_revision >= 0xC3) { /* * 1553/1535 (m1533, 0x79, bit 1) */ pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x02); } } out: /* * CD_ROM DMA on (m5229, 0x53, bit0) * Enable this bit even if we want to use PIO. * PIO FIFO off (m5229, 0x53, bit1) * The hardware will use 0x54h and 0x55h to control PIO FIFO. * (Not on later devices it seems) * * 0x53 changes meaning on later revs - we must no touch * bit 1 on them. Need to check if 0x20 is the right break. */ if (m5229_revision >= 0x20) { pci_read_config_byte(dev, 0x53, &tmpbyte); if (m5229_revision <= 0x20) tmpbyte = (tmpbyte & (~0x02)) | 0x01; else if (m5229_revision == 0xc7 || m5229_revision == 0xc8) tmpbyte |= 0x03; else tmpbyte |= 0x01; pci_write_config_byte(dev, 0x53, tmpbyte); } pci_dev_put(north); pci_dev_put(isa_dev); local_irq_restore(flags); return 0; }
static int pcifront_detach_devices(struct pcifront_device *pdev) { int err = 0; int i, num_devs; unsigned int domain, bus, slot, func; struct pci_bus *pci_bus; struct pci_dev *pci_dev; char str[64]; spin_lock(&pdev->dev_lock); if (xenbus_read_driver_state(pdev->xdev->nodename) != XenbusStateConnected) goto out; err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, "num_devs", "%d", &num_devs); if (err != 1) { if (err >= 0) err = -EINVAL; xenbus_dev_fatal(pdev->xdev, err, "Error reading number of PCI devices"); goto out; } /* Find devices being detached and remove them. */ for (i = 0; i < num_devs; i++) { int l, state; l = snprintf(str, sizeof(str), "state-%d", i); if (unlikely(l >= (sizeof(str) - 1))) { err = -ENOMEM; goto out; } err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, str, "%d", &state); if (err != 1) state = XenbusStateUnknown; if (state != XenbusStateClosing) continue; /* Remove device. */ l = snprintf(str, sizeof(str), "vdev-%d", i); if (unlikely(l >= (sizeof(str) - 1))) { err = -ENOMEM; goto out; } err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, str, "%x:%x:%x.%x", &domain, &bus, &slot, &func); if (err != 4) { if (err >= 0) err = -EINVAL; xenbus_dev_fatal(pdev->xdev, err, "Error reading PCI device %d", i); goto out; } pci_bus = pci_find_bus(domain, bus); if(!pci_bus) { dev_dbg(&pdev->xdev->dev, "Cannot get bus %04x:%02x\n", domain, bus); continue; } pci_dev = pci_get_slot(pci_bus, PCI_DEVFN(slot, func)); if(!pci_dev) { dev_dbg(&pdev->xdev->dev, "Cannot get PCI device %04x:%02x:%02x.%02x\n", domain, bus, slot, func); continue; } pci_remove_bus_device(pci_dev); pci_dev_put(pci_dev); dev_dbg(&pdev->xdev->dev, "PCI device %04x:%02x:%02x.%02x removed.\n", domain, bus, slot, func); } err = xenbus_switch_state(pdev->xdev, XenbusStateReconfiguring); out: spin_unlock(&pdev->dev_lock); return err; }
/* * Helper function for ibft_register_kobjects. */ static int __init ibft_create_kobject(struct acpi_table_ibft *header, struct ibft_hdr *hdr) { struct iscsi_boot_kobj *boot_kobj = NULL; struct ibft_kobject *ibft_kobj = NULL; struct ibft_nic *nic = (struct ibft_nic *)hdr; struct pci_dev *pci_dev; int rc = 0; ibft_kobj = kzalloc(sizeof(*ibft_kobj), GFP_KERNEL); if (!ibft_kobj) return -ENOMEM; ibft_kobj->header = header; ibft_kobj->hdr = hdr; switch (hdr->id) { case id_initiator: rc = ibft_verify_hdr("initiator", hdr, id_initiator, sizeof(*ibft_kobj->initiator)); if (rc) break; boot_kobj = iscsi_boot_create_initiator(boot_kset, hdr->index, ibft_kobj, ibft_attr_show_initiator, ibft_check_initiator_for, ibft_kobj_release); if (!boot_kobj) { rc = -ENOMEM; goto free_ibft_obj; } break; case id_nic: rc = ibft_verify_hdr("ethernet", hdr, id_nic, sizeof(*ibft_kobj->nic)); if (rc) break; boot_kobj = iscsi_boot_create_ethernet(boot_kset, hdr->index, ibft_kobj, ibft_attr_show_nic, ibft_check_nic_for, ibft_kobj_release); if (!boot_kobj) { rc = -ENOMEM; goto free_ibft_obj; } break; case id_target: rc = ibft_verify_hdr("target", hdr, id_target, sizeof(*ibft_kobj->tgt)); if (rc) break; boot_kobj = iscsi_boot_create_target(boot_kset, hdr->index, ibft_kobj, ibft_attr_show_target, ibft_check_tgt_for, ibft_kobj_release); if (!boot_kobj) { rc = -ENOMEM; goto free_ibft_obj; } break; case id_reserved: case id_control: case id_extensions: /* Fields which we don't support. Ignore them */ rc = 1; break; default: printk(KERN_ERR "iBFT has unknown structure type (%d). " \ "Report this bug to %.6s!\n", hdr->id, header->header.oem_id); rc = 1; break; } if (rc) { /* Skip adding this kobject, but exit with non-fatal error. */ rc = 0; goto free_ibft_obj; } if (hdr->id == id_nic) { /* * We don't search for the device in other domains than * zero. This is because on x86 platforms the BIOS * executes only devices which are in domain 0. Furthermore, the * iBFT spec doesn't have a domain id field :-( */ pci_dev = pci_get_bus_and_slot((nic->pci_bdf & 0xff00) >> 8, (nic->pci_bdf & 0xff)); if (pci_dev) { rc = sysfs_create_link(&boot_kobj->kobj, &pci_dev->dev.kobj, "device"); pci_dev_put(pci_dev); } }
void intel_detect_pch(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct pci_dev *pch = NULL; /* In all current cases, num_pipes is equivalent to the PCH_NOP setting * (which really amounts to a PCH but no South Display). */ if (INTEL_INFO(dev)->num_pipes == 0) { dev_priv->pch_type = PCH_NOP; return; } /* * The reason to probe ISA bridge instead of Dev31:Fun0 is to * make graphics device passthrough work easy for VMM, that only * need to expose ISA bridge to let driver know the real hardware * underneath. This is a requirement from virtualization team. * * In some virtualized environments (e.g. XEN), there is irrelevant * ISA bridge in the system. To work reliably, we should scan trhough * all the ISA bridge devices and check for the first match, instead * of only checking the first one. */ while ((pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, pch))) { if (pch->vendor == PCI_VENDOR_ID_INTEL) { unsigned short id = pch->device & INTEL_PCH_DEVICE_ID_MASK; dev_priv->pch_id = id; if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) { dev_priv->pch_type = PCH_IBX; DRM_DEBUG_KMS("Found Ibex Peak PCH\n"); WARN_ON(!IS_GEN5(dev)); } else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) { dev_priv->pch_type = PCH_CPT; DRM_DEBUG_KMS("Found CougarPoint PCH\n"); WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev))); } else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) { /* PantherPoint is CPT compatible */ dev_priv->pch_type = PCH_CPT; DRM_DEBUG_KMS("Found PantherPoint PCH\n"); WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev))); } else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) { dev_priv->pch_type = PCH_LPT; DRM_DEBUG_KMS("Found LynxPoint PCH\n"); WARN_ON(!IS_HASWELL(dev) && !IS_BROADWELL(dev)); WARN_ON(IS_HSW_ULT(dev) || IS_BDW_ULT(dev)); } else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) { dev_priv->pch_type = PCH_LPT; DRM_DEBUG_KMS("Found LynxPoint LP PCH\n"); WARN_ON(!IS_HASWELL(dev) && !IS_BROADWELL(dev)); WARN_ON(!IS_HSW_ULT(dev) && !IS_BDW_ULT(dev)); } else if (id == INTEL_PCH_SPT_DEVICE_ID_TYPE) { dev_priv->pch_type = PCH_SPT; DRM_DEBUG_KMS("Found SunrisePoint PCH\n"); WARN_ON(!IS_SKYLAKE(dev) && !IS_KABYLAKE(dev)); } else if (id == INTEL_PCH_SPT_LP_DEVICE_ID_TYPE) { dev_priv->pch_type = PCH_SPT; DRM_DEBUG_KMS("Found SunrisePoint LP PCH\n"); WARN_ON(!IS_SKYLAKE(dev) && !IS_KABYLAKE(dev)); } else if ((id == INTEL_PCH_P2X_DEVICE_ID_TYPE) || (id == INTEL_PCH_QEMU_DEVICE_ID_TYPE)) { dev_priv->pch_type = intel_virt_detect_pch(dev); } else continue; break; } } if (!pch) DRM_DEBUG_KMS("No PCH found.\n"); pci_dev_put(pch); }
/* pasemi_dma_init - Initialize the PA Semi DMA library * * This function initializes the DMA library. It must be called before * any other function in the library. * * Returns 0 on success, errno on failure. */ int pasemi_dma_init(void) { static DEFINE_SPINLOCK(init_lock); struct pci_dev *iob_pdev; struct pci_dev *pdev; struct resource res; struct device_node *dn; int i, intf, err = 0; unsigned long timeout; u32 tmp; if (!machine_is(pasemi)) return -ENODEV; spin_lock(&init_lock); /* Make sure we haven't already initialized */ if (dma_pdev) goto out; iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL); if (!iob_pdev) { BUG(); pr_warn("Can't find I/O Bridge\n"); err = -ENODEV; goto out; } iob_regs = map_onedev(iob_pdev, 0); dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL); if (!dma_pdev) { BUG(); pr_warn("Can't find DMA controller\n"); err = -ENODEV; goto out; } dma_regs = map_onedev(dma_pdev, 0); base_hw_irq = virq_to_hw(dma_pdev->irq); pci_read_config_dword(dma_pdev, PAS_DMA_CAP_TXCH, &tmp); num_txch = (tmp & PAS_DMA_CAP_TXCH_TCHN_M) >> PAS_DMA_CAP_TXCH_TCHN_S; pci_read_config_dword(dma_pdev, PAS_DMA_CAP_RXCH, &tmp); num_rxch = (tmp & PAS_DMA_CAP_RXCH_RCHN_M) >> PAS_DMA_CAP_RXCH_RCHN_S; intf = 0; for (pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa006, NULL); pdev; pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa006, pdev)) mac_regs[intf++] = map_onedev(pdev, 0); pci_dev_put(pdev); for (pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa005, NULL); pdev; pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa005, pdev)) mac_regs[intf++] = map_onedev(pdev, 0); pci_dev_put(pdev); dn = pci_device_to_OF_node(iob_pdev); if (dn) err = of_address_to_resource(dn, 1, &res); if (!dn || err) { /* Fallback for old firmware */ res.start = 0xfd800000; res.end = res.start + 0x1000; } dma_status = ioremap_cache(res.start, resource_size(&res)); pci_dev_put(iob_pdev); for (i = 0; i < MAX_TXCH; i++) __set_bit(i, txch_free); for (i = 0; i < MAX_RXCH; i++) __set_bit(i, rxch_free); timeout = jiffies + HZ; pasemi_write_dma_reg(PAS_DMA_COM_RXCMD, 0); while (pasemi_read_dma_reg(PAS_DMA_COM_RXSTA) & 1) { if (time_after(jiffies, timeout)) { pr_warn("Warning: Could not disable RX section\n"); break; } } timeout = jiffies + HZ; pasemi_write_dma_reg(PAS_DMA_COM_TXCMD, 0); while (pasemi_read_dma_reg(PAS_DMA_COM_TXSTA) & 1) { if (time_after(jiffies, timeout)) { pr_warn("Warning: Could not disable TX section\n"); break; } } /* setup resource allocations for the different DMA sections */ tmp = pasemi_read_dma_reg(PAS_DMA_COM_CFG); pasemi_write_dma_reg(PAS_DMA_COM_CFG, tmp | 0x18000000); /* enable tx section */ pasemi_write_dma_reg(PAS_DMA_COM_TXCMD, PAS_DMA_COM_TXCMD_EN); /* enable rx section */ pasemi_write_dma_reg(PAS_DMA_COM_RXCMD, PAS_DMA_COM_RXCMD_EN); for (i = 0; i < MAX_FLAGS; i++) __set_bit(i, flags_free); for (i = 0; i < MAX_FUN; i++) __set_bit(i, fun_free); /* clear all status flags */ pasemi_write_dma_reg(PAS_DMA_TXF_CFLG0, 0xffffffff); pasemi_write_dma_reg(PAS_DMA_TXF_CFLG1, 0xffffffff); pr_info("PA Semi PWRficient DMA library initialized " "(%d tx, %d rx channels)\n", num_txch, num_rxch); out: spin_unlock(&init_lock); return err; }
static int __devinit agp_amdk7_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct agp_bridge_data *bridge; u8 cap_ptr; int j; cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); if (!cap_ptr) return -ENODEV; j = ent - agp_amdk7_pci_table; dev_info(&pdev->dev, "AMD %s chipset\n", amd_agp_device_ids[j].chipset_name); bridge = agp_alloc_bridge(); if (!bridge) return -ENOMEM; bridge->driver = &amd_irongate_driver; bridge->dev_private_data = &amd_irongate_private, bridge->dev = pdev; bridge->capndx = cap_ptr; /* 751 Errata (22564_B-1.PDF) erratum 20: strobe glitch with Nvidia NV10 GeForce cards. system controller may experience noise due to strong drive strengths */ if (agp_bridge->dev->device == PCI_DEVICE_ID_AMD_FE_GATE_7006) { struct pci_dev *gfxcard=NULL; cap_ptr = 0; while (!cap_ptr) { gfxcard = pci_get_class(PCI_CLASS_DISPLAY_VGA<<8, gfxcard); if (!gfxcard) { dev_info(&pdev->dev, "no AGP VGA controller\n"); return -ENODEV; } cap_ptr = pci_find_capability(gfxcard, PCI_CAP_ID_AGP); } /* With so many variants of NVidia cards, it's simpler just to blacklist them all, and then whitelist them as needed (if necessary at all). */ if (gfxcard->vendor == PCI_VENDOR_ID_NVIDIA) { agp_bridge->flags |= AGP_ERRATA_1X; dev_info(&pdev->dev, "AMD 751 chipset with NVidia GeForce; forcing 1X due to errata\n"); } pci_dev_put(gfxcard); } /* 761 Errata (23613_F.pdf) * Revisions B0/B1 were a disaster. * erratum 44: SYSCLK/AGPCLK skew causes 2X failures -- Force mode to 1X * erratum 45: Timing problem prevents fast writes -- Disable fast write. * erratum 46: Setup violation on AGP SBA pins - Disable side band addressing. * With this lot disabled, we should prevent lockups. */ if (agp_bridge->dev->device == PCI_DEVICE_ID_AMD_FE_GATE_700E) { if (pdev->revision == 0x10 || pdev->revision == 0x11) { agp_bridge->flags = AGP_ERRATA_FASTWRITES; agp_bridge->flags |= AGP_ERRATA_SBA; agp_bridge->flags |= AGP_ERRATA_1X; dev_info(&pdev->dev, "AMD 761 chipset with errata; disabling AGP fast writes & SBA and forcing to 1X\n"); } } /* Fill in the mode register */ pci_read_config_dword(pdev, bridge->capndx+PCI_AGP_STATUS, &bridge->mode); pci_set_drvdata(pdev, bridge); return agp_add_bridge(bridge); }
static int acpi_processor_errata_piix4(struct pci_dev *dev) { u8 value1 = 0; u8 value2 = 0; if (!dev) return -EINVAL; /* * Note that 'dev' references the PIIX4 ACPI Controller. */ switch (dev->revision) { case 0: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 A-step\n")); break; case 1: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 B-step\n")); break; case 2: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4E\n")); break; case 3: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4M\n")); break; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unknown PIIX4\n")); break; } switch (dev->revision) { case 0: /* PIIX4 A-step */ case 1: /* PIIX4 B-step */ /* * See specification changes #13 ("Manual Throttle Duty Cycle") * and #14 ("Enabling and Disabling Manual Throttle"), plus * erratum #5 ("STPCLK# Deassertion Time") from the January * 2002 PIIX4 specification update. Applies to only older * PIIX4 models. */ errata.piix4.throttle = 1; case 2: /* PIIX4E */ case 3: /* PIIX4M */ /* * See erratum #18 ("C3 Power State/BMIDE and Type-F DMA * Livelock") from the January 2002 PIIX4 specification update. * Applies to all PIIX4 models. */ /* * BM-IDE * ------ * Find the PIIX4 IDE Controller and get the Bus Master IDE * Status register address. We'll use this later to read * each IDE controller's DMA status to make sure we catch all * DMA activity. */ dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB, PCI_ANY_ID, PCI_ANY_ID, NULL); if (dev) { errata.piix4.bmisx = pci_resource_start(dev, 4); pci_dev_put(dev); } /* * Type-F DMA * ---------- * Find the PIIX4 ISA Controller and read the Motherboard * DMA controller's status to see if Type-F (Fast) DMA mode * is enabled (bit 7) on either channel. Note that we'll * disable C3 support if this is enabled, as some legacy * devices won't operate well if fast DMA is disabled. */ dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, PCI_ANY_ID, PCI_ANY_ID, NULL); if (dev) { pci_read_config_byte(dev, 0x76, &value1); pci_read_config_byte(dev, 0x77, &value2); if ((value1 & 0x80) || (value2 & 0x80)) errata.piix4.fdma = 1; pci_dev_put(dev); } break; } if (errata.piix4.bmisx) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Bus master activity detection (BM-IDE) erratum enabled\n")); if (errata.piix4.fdma) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Type-F DMA livelock erratum (C3 disabled)\n")); return 0; }
void __init ebus_init(void) { struct pci_pbm_info *pbm; struct linux_ebus_device *dev; struct linux_ebus *ebus; struct pci_dev *pdev; struct pcidev_cookie *cookie; struct device_node *dp; int is_rio; int num_ebus = 0; pdev = find_next_ebus(NULL, &is_rio); if (!pdev) { printk("ebus: No EBus's found.\n"); return; } cookie = pdev->sysdata; dp = cookie->prom_node; ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus)); ebus->next = NULL; ebus->is_rio = is_rio; while (dp) { struct device_node *child; /* SUNW,pci-qfe uses four empty ebuses on it. I think we should not consider them here, as they have half of the properties this code expects and once we do PCI hot-plug, we'd have to tweak with the ebus_chain in the runtime after initialization. -jj */ if (!dp->child) { pdev = find_next_ebus(pdev, &is_rio); if (!pdev) { if (ebus == ebus_chain) { ebus_chain = NULL; printk("ebus: No EBus's found.\n"); return; } break; } ebus->is_rio = is_rio; cookie = pdev->sysdata; dp = cookie->prom_node; continue; } printk("ebus%d:", num_ebus); ebus->index = num_ebus; ebus->prom_node = dp; ebus->self = pdev; ebus->parent = pbm = cookie->pbm; ebus->ofdev.node = dp; ebus->ofdev.dev.parent = &pdev->dev; ebus->ofdev.dev.bus = &ebus_bus_type; strcpy(ebus->ofdev.dev.bus_id, dp->path_component_name); /* Register with core */ if (of_device_register(&ebus->ofdev) != 0) printk(KERN_DEBUG "ebus: device registration error for %s!\n", ebus->ofdev.dev.bus_id); child = dp->child; if (!child) goto next_ebus; ebus->devices = ebus_alloc(sizeof(struct linux_ebus_device)); dev = ebus->devices; dev->next = NULL; dev->children = NULL; dev->bus = ebus; fill_ebus_device(child, dev); while ((child = child->sibling) != NULL) { dev->next = ebus_alloc(sizeof(struct linux_ebus_device)); dev = dev->next; dev->next = NULL; dev->children = NULL; dev->bus = ebus; fill_ebus_device(child, dev); } next_ebus: printk("\n"); pdev = find_next_ebus(pdev, &is_rio); if (!pdev) break; cookie = pdev->sysdata; dp = cookie->prom_node; ebus->next = ebus_alloc(sizeof(struct linux_ebus)); ebus = ebus->next; ebus->next = NULL; ebus->is_rio = is_rio; ++num_ebus; } pci_dev_put(pdev); /* XXX for the case, when ebusnd is 0, is it OK? */ }
static int __init samsung_init(void) { struct device *parent=NULL; if (use_sabi && !dmi_check_system(samsung_sabi_dmi_table) && !force){ printk(KERN_ERR "Samsung-backlight is intended to work only with Samsung laptops.\n"); return -ENODEV; } if (!use_sabi && !dmi_check_system(samsung_dmi_table) && !force){ printk(KERN_ERR "Sorry, your laptop is not supported. Try use_sabi=1\n"); return -ENODEV; } if(use_sabi){ const char *test_str = "SwSmi@"; int pos; int index = 0; void __iomem *base; unsigned int ifaceP; mutex_init(&sabi_mutex); f0000_segment = ioremap(0xf0000, 0xffff); if (!f0000_segment) { printk(KERN_ERR "Samsung-backlight: Can't map the segment at 0xf0000\n"); return -EINVAL; } printk(KERN_INFO "Samsung-backlight: checking for SABI support.\n"); /* Try to find the signature "SwSmi@" in memory to find the header */ base = f0000_segment; for (pos = 0; pos < 0xffff; ++pos) { char temp = readb(base + pos); if (temp == test_str[index]) { if (5 == index++) break; } else { index = 0; } } if (pos == 0xffff) { printk(KERN_INFO "Samsung-backlight: SABI is not supported\n"); iounmap(f0000_segment); return -EINVAL; } sabi = (struct sabi_header __iomem *)(base + pos + 1); printk(KERN_INFO "Samsung-backlight: SABI is supported (%x)\n", pos + 0xf0000 - 6); if (debug) { printk(KERN_DEBUG "SABI header:\n"); printk(KERN_DEBUG " SMI Port Number = 0x%04x\n", readw(&sabi->port)); printk(KERN_DEBUG " SMI Interface Function = 0x%02x\n", readb(&sabi->iface_func)); printk(KERN_DEBUG " SMI enable memory buffer = 0x%02x\n", readb(&sabi->en_mem)); printk(KERN_DEBUG " SMI restore memory buffer = 0x%02x\n", readb(&sabi->re_mem)); printk(KERN_DEBUG " SABI data offset = 0x%04x\n", readw(&sabi->data_offset)); printk(KERN_DEBUG " SABI data segment = 0x%04x\n", readw(&sabi->data_segment)); printk(KERN_DEBUG " BIOS interface version = 0x%02x\n", readb(&sabi->bios_ifver)); printk(KERN_DEBUG " KBD Launcher string = 0x%02x\n", readb(&sabi->launcher_string)); } /* Get a pointer to the SABI Interface */ ifaceP = (readw(&sabi->data_segment) & 0x0ffff) << 4; ifaceP += readw(&sabi->data_offset) & 0x0ffff; sabi_iface = (struct sabi_interface __iomem *)ioremap(ifaceP, 16); if (!sabi_iface) { printk(KERN_ERR "Samsung-backlight: Can't remap %x\n", ifaceP); iounmap(f0000_segment); return -EINVAL; } if (debug) { printk(KERN_DEBUG "Samsung-backlight: SABI Interface = %p\n", sabi_iface); } }else{ /* * The Samsung N120, N130, and NC10 use pci device id 0x27ae, while the * NP-Q45 uses 0x2a02. Odds are we might need to add more to the * list over time... */ int pcidevids[]={0x27ae,0x2a02,0x2a42,0xa011,0}; int i; for(i=0, pci_device=NULL;pcidevids[i]>0 && pci_device==NULL;++i) pci_device = pci_get_device(PCI_VENDOR_ID_INTEL, pcidevids[i], NULL); if (!pci_device) return -ENODEV; parent=&pci_device->dev; } /* create a backlight device to talk to this one */ #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) backlight_device = backlight_device_register("samsung", parent, NULL, &backlight_ops,NULL); #else backlight_device = backlight_device_register("samsung", parent, NULL, &backlight_ops); #endif if (IS_ERR(backlight_device)) { if(pci_device) pci_dev_put(pci_device); return PTR_ERR(backlight_device); } backlight_device->props.max_brightness = use_sabi ? SABI_MAX_BRIGHT : MAX_BRIGHT; backlight_device->props.brightness = read_brightness(); backlight_device->props.power = FB_BLANK_UNBLANK; backlight_update_status(backlight_device); return 0; }
static int __init init_l440gx(void) { struct pci_dev *dev, *pm_dev; struct resource *pm_iobase; __u16 word; dev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, NULL); pm_dev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, NULL); pci_dev_put(dev); if (!dev || !pm_dev) { #ifdef CONFIG_DEBUG_PRINTK printk(KERN_NOTICE "L440GX flash mapping: failed to find PIIX4 ISA bridge, cannot continue\n"); #else ; #endif pci_dev_put(pm_dev); return -ENODEV; } l440gx_map.virt = ioremap_nocache(WINDOW_ADDR, WINDOW_SIZE); if (!l440gx_map.virt) { #ifdef CONFIG_DEBUG_PRINTK printk(KERN_WARNING "Failed to ioremap L440GX flash region\n"); #else ; #endif pci_dev_put(pm_dev); return -ENOMEM; } simple_map_init(&l440gx_map); #ifdef CONFIG_DEBUG_PRINTK printk(KERN_NOTICE "window_addr = 0x%08lx\n", (unsigned long)l440gx_map.virt); #else ; #endif /* Setup the pm iobase resource * This code should move into some kind of generic bridge * driver but for the moment I'm content with getting the * allocation correct. */ pm_iobase = &pm_dev->resource[PIIXE_IOBASE_RESOURCE]; if (!(pm_iobase->flags & IORESOURCE_IO)) { pm_iobase->name = "pm iobase"; pm_iobase->start = 0; pm_iobase->end = 63; pm_iobase->flags = IORESOURCE_IO; /* Put the current value in the resource */ pci_read_config_dword(pm_dev, 0x40, &iobase); iobase &= ~1; pm_iobase->start += iobase & ~1; pm_iobase->end += iobase & ~1; pci_dev_put(pm_dev); /* Allocate the resource region */ if (pci_assign_resource(pm_dev, PIIXE_IOBASE_RESOURCE) != 0) { pci_dev_put(dev); pci_dev_put(pm_dev); #ifdef CONFIG_DEBUG_PRINTK printk(KERN_WARNING "Could not allocate pm iobase resource\n"); #else ; #endif iounmap(l440gx_map.virt); return -ENXIO; } } /* Set the iobase */ iobase = pm_iobase->start; pci_write_config_dword(pm_dev, 0x40, iobase | 1); /* Set XBCS# */ pci_read_config_word(dev, 0x4e, &word); word |= 0x4; pci_write_config_word(dev, 0x4e, word); /* Supply write voltage to the chip */ l440gx_set_vpp(&l440gx_map, 1); /* Enable the gate on the WE line */ outb(inb(TRIBUF_PORT) & ~1, TRIBUF_PORT); #ifdef CONFIG_DEBUG_PRINTK printk(KERN_NOTICE "Enabled WE line to L440GX BIOS flash chip.\n"); #else ; #endif mymtd = do_map_probe("jedec_probe", &l440gx_map); if (!mymtd) { #ifdef CONFIG_DEBUG_PRINTK printk(KERN_NOTICE "JEDEC probe on BIOS chip failed. Using ROM\n"); #else ; #endif mymtd = do_map_probe("map_rom", &l440gx_map); } if (mymtd) { mymtd->owner = THIS_MODULE; mtd_device_register(mymtd, NULL, 0); return 0; } iounmap(l440gx_map.virt); return -ENXIO; }
static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; static const struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 1, .identity = "ALiM7101", }; switch (cmd) { case WDIOC_GETSUPPORT: return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0, p); case WDIOC_SETOPTIONS: { int new_options, retval = -EINVAL; if (get_user(new_options, p)) return -EFAULT; if (new_options & WDIOS_DISABLECARD) { wdt_turnoff(); retval = 0; } if (new_options & WDIOS_ENABLECARD) { wdt_startup(); retval = 0; } return retval; } case WDIOC_KEEPALIVE: wdt_keepalive(); return 0; case WDIOC_SETTIMEOUT: { int new_timeout; if (get_user(new_timeout, p)) return -EFAULT; /* arbitrary upper limit */ if (new_timeout < 1 || new_timeout > 3600) return -EINVAL; timeout = new_timeout; wdt_keepalive(); /* Fall through */ } case WDIOC_GETTIMEOUT: return put_user(timeout, p); default: return -ENOTTY; } } static const struct file_operations wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = fop_write, .open = fop_open, .release = fop_close, .unlocked_ioctl = fop_ioctl, }; static struct miscdevice wdt_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &wdt_fops, }; /* * Notifier for system down */ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { if (code == SYS_DOWN || code == SYS_HALT) wdt_turnoff(); if (code == SYS_RESTART) { /* * Cobalt devices have no way of rebooting themselves other * than getting the watchdog to pull reset, so we restart the * watchdog on reboot with no heartbeat */ wdt_change(WDT_ENABLE); printk(KERN_INFO PFX "Watchdog timer is now enabled " "with no heartbeat - should reboot in ~1 second.\n"); } return NOTIFY_DONE; } /* * The WDT needs to learn about soft shutdowns in order to * turn the timebomb registers off. */ static struct notifier_block wdt_notifier = { .notifier_call = wdt_notify_sys, }; static void __exit alim7101_wdt_unload(void) { wdt_turnoff(); /* Deregister */ misc_deregister(&wdt_miscdev); unregister_reboot_notifier(&wdt_notifier); pci_dev_put(alim7101_pmu); } static int __init alim7101_wdt_init(void) { int rc = -EBUSY; struct pci_dev *ali1543_south; char tmp; printk(KERN_INFO PFX "Steve Hill <*****@*****.**>.\n"); alim7101_pmu = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, NULL); if (!alim7101_pmu) { printk(KERN_INFO PFX "ALi M7101 PMU not present - WDT not set\n"); return -EBUSY; } /* Set the WDT in the PMU to 1 second */ pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, 0x02); ali1543_south = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); if (!ali1543_south) { printk(KERN_INFO PFX "ALi 1543 South-Bridge not present - WDT not set\n"); goto err_out; } pci_read_config_byte(ali1543_south, 0x5e, &tmp); pci_dev_put(ali1543_south); if ((tmp & 0x1e) == 0x00) { if (!use_gpio) { printk(KERN_INFO PFX "Detected old alim7101 revision 'a1d'. " "If this is a cobalt board, set the 'use_gpio' " "module parameter.\n"); goto err_out; } nowayout = 1; } else if ((tmp & 0x1e) != 0x12 && (tmp & 0x1e) != 0x00) { printk(KERN_INFO PFX "ALi 1543 South-Bridge does not have the correct " "revision number (???1001?) - WDT not set\n"); goto err_out; } if (timeout < 1 || timeout > 3600) { /* arbitrary upper limit */ timeout = WATCHDOG_TIMEOUT; printk(KERN_INFO PFX "timeout value must be 1 <= x <= 3600, using %d\n", timeout); } rc = register_reboot_notifier(&wdt_notifier); if (rc) { printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", rc); goto err_out; } rc = misc_register(&wdt_miscdev); if (rc) { printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", wdt_miscdev.minor, rc); goto err_out_reboot; } if (nowayout) __module_get(THIS_MODULE); printk(KERN_INFO PFX "WDT driver for ALi M7101 initialised. " "timeout=%d sec (nowayout=%d)\n", timeout, nowayout); return 0; err_out_reboot: unregister_reboot_notifier(&wdt_notifier); err_out: pci_dev_put(alim7101_pmu); return rc; }
static int cs5530_init_chip(void) { struct pci_dev *master_0 = NULL, *cs5530_0 = NULL, *dev = NULL; while ((dev = pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) { switch (dev->device) { case PCI_DEVICE_ID_CYRIX_PCI_MASTER: master_0 = pci_dev_get(dev); break; case PCI_DEVICE_ID_CYRIX_5530_LEGACY: cs5530_0 = pci_dev_get(dev); break; } } if (!master_0) { printk(KERN_ERR DRV_NAME ": unable to locate PCI MASTER function\n"); goto fail_put; } if (!cs5530_0) { printk(KERN_ERR DRV_NAME ": unable to locate CS5530 LEGACY function\n"); goto fail_put; } pci_set_master(cs5530_0); pci_try_set_mwi(cs5530_0); /* * Set PCI CacheLineSize to 16-bytes: * --> Write 0x04 into 8-bit PCI CACHELINESIZE reg of function 0 of the cs5530 * * Note: This value is constant because the 5530 is only a Geode companion */ pci_write_config_byte(cs5530_0, PCI_CACHE_LINE_SIZE, 0x04); /* * Disable trapping of UDMA register accesses (Win98 hack): * --> Write 0x5006 into 16-bit reg at offset 0xd0 of function 0 of the cs5530 */ pci_write_config_word(cs5530_0, 0xd0, 0x5006); /* * Bit-1 at 0x40 enables MemoryWriteAndInvalidate on internal X-bus: * The other settings are what is necessary to get the register * into a sane state for IDE DMA operation. */ pci_write_config_byte(master_0, 0x40, 0x1e); /* * Set max PCI burst size (16-bytes seems to work best): * 16bytes: set bit-1 at 0x41 (reg value of 0x16) * all others: clear bit-1 at 0x41, and do: * 128bytes: OR 0x00 at 0x41 * 256bytes: OR 0x04 at 0x41 * 512bytes: OR 0x08 at 0x41 * 1024bytes: OR 0x0c at 0x41 */ pci_write_config_byte(master_0, 0x41, 0x14); /* * These settings are necessary to get the chip * into a sane state for IDE DMA operation. */ pci_write_config_byte(master_0, 0x42, 0x00); pci_write_config_byte(master_0, 0x43, 0xc1); pci_dev_put(master_0); pci_dev_put(cs5530_0); return 0; fail_put: if (master_0) pci_dev_put(master_0); if (cs5530_0) pci_dev_put(cs5530_0); return -ENODEV; }
/* called during probe() after chip reset completes */ static int ehci_pci_setup(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); struct pci_dev *pdev = to_pci_dev(hcd->self.controller); struct pci_dev *p_smbus; u8 rev; u32 temp; int retval; switch (pdev->vendor) { case PCI_VENDOR_ID_TOSHIBA_2: /* celleb's companion chip */ if (pdev->device == 0x01b5) { #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO ehci->big_endian_mmio = 1; #else ehci_warn(ehci, "unsupported big endian Toshiba quirk\n"); #endif } break; } ehci->caps = hcd->regs; ehci->regs = hcd->regs + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); /* ehci_init() causes memory for DMA transfers to be * allocated. Thus, any vendor-specific workarounds based on * limiting the type of memory used for DMA transfers must * happen before ehci_init() is called. */ switch (pdev->vendor) { case PCI_VENDOR_ID_NVIDIA: /* NVidia reports that certain chips don't handle * QH, ITD, or SITD addresses above 2GB. (But TD, * data buffer, and periodic schedule are normal.) */ switch (pdev->device) { case 0x003c: /* MCP04 */ case 0x005b: /* CK804 */ case 0x00d8: /* CK8 */ case 0x00e8: /* CK8S */ if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(31)) < 0) ehci_warn(ehci, "can't enable NVidia " "workaround for >2GB RAM\n"); break; } break; } /* cache this readonly data; minimize chip reads */ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); retval = ehci_halt(ehci); if (retval) return retval; if ((pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == 0x7808) || (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->device == 0x4396)) { /* EHCI controller on AMD SB700/SB800/Hudson-2/3 platforms may * read/write memory space which does not belong to it when * there is NULL pointer with T-bit set to 1 in the frame list * table. To avoid the issue, the frame list link pointer * should always contain a valid pointer to a inactive qh. */ ehci->use_dummy_qh = 1; ehci_info(ehci, "applying AMD SB700/SB800/Hudson-2/3 EHCI " "dummy qh workaround\n"); } /* data structure init */ retval = ehci_init(hcd); if (retval) return retval; switch (pdev->vendor) { case PCI_VENDOR_ID_NEC: ehci->need_io_watchdog = 0; break; case PCI_VENDOR_ID_INTEL: ehci->need_io_watchdog = 0; ehci->fs_i_thresh = 1; if (pdev->device == 0x27cc) { ehci->broken_periodic = 1; ehci_info(ehci, "using broken periodic workaround\n"); } if (pdev->device == 0x0806 || pdev->device == 0x0811 || pdev->device == 0x0829) { ehci_info(ehci, "disable lpm for langwell/penwell\n"); ehci->has_lpm = 0; } if (pdev->device == PCI_DEVICE_ID_INTEL_CE4100_USB) { hcd->has_tt = 1; tdi_reset(ehci); } break; case PCI_VENDOR_ID_TDI: if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { hcd->has_tt = 1; tdi_reset(ehci); } break; case PCI_VENDOR_ID_AMD: /* AMD PLL quirk */ if (usb_amd_find_chipset_info()) ehci->amd_pll_fix = 1; /* AMD8111 EHCI doesn't work, according to AMD errata */ if (pdev->device == 0x7463) { ehci_info(ehci, "ignoring AMD8111 (errata)\n"); retval = -EIO; goto done; } break; case PCI_VENDOR_ID_NVIDIA: switch (pdev->device) { /* Some NForce2 chips have problems with selective suspend; * fixed in newer silicon. */ case 0x0068: if (pdev->revision < 0xa4) ehci->no_selective_suspend = 1; break; /* MCP89 chips on the MacBookAir3,1 give EPROTO when * fetching device descriptors unless LPM is disabled. * There are also intermittent problems enumerating * devices with PPCD enabled. */ case 0x0d9d: ehci_info(ehci, "disable lpm/ppcd for nvidia mcp89"); ehci->has_lpm = 0; ehci->has_ppcd = 0; ehci->command &= ~CMD_PPCEE; break; } break; case PCI_VENDOR_ID_VIA: if (pdev->device == 0x3104 && (pdev->revision & 0xf0) == 0x60) { u8 tmp; /* The VT6212 defaults to a 1 usec EHCI sleep time which * hogs the PCI bus *badly*. Setting bit 5 of 0x4B makes * that sleep time use the conventional 10 usec. */ pci_read_config_byte(pdev, 0x4b, &tmp); if (tmp & 0x20) break; pci_write_config_byte(pdev, 0x4b, tmp | 0x20); } break; case PCI_VENDOR_ID_ATI: /* AMD PLL quirk */ if (usb_amd_find_chipset_info()) ehci->amd_pll_fix = 1; /* SB600 and old version of SB700 have a bug in EHCI controller, * which causes usb devices lose response in some cases. */ if ((pdev->device == 0x4386) || (pdev->device == 0x4396)) { p_smbus = pci_get_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL); if (!p_smbus) break; rev = p_smbus->revision; if ((pdev->device == 0x4386) || (rev == 0x3a) || (rev == 0x3b)) { u8 tmp; ehci_info(ehci, "applying AMD SB600/SB700 USB " "freeze workaround\n"); pci_read_config_byte(pdev, 0x53, &tmp); pci_write_config_byte(pdev, 0x53, tmp | (1<<3)); } pci_dev_put(p_smbus); } break; case PCI_VENDOR_ID_NETMOS: /* MosChip frame-index-register bug */ ehci_info(ehci, "applying MosChip frame-index workaround\n"); ehci->frame_index_bug = 1; break; } /* optional debug port, normally in the first BAR */ temp = pci_find_capability(pdev, 0x0a); if (temp) { pci_read_config_dword(pdev, temp, &temp); temp >>= 16; if ((temp & (3 << 13)) == (1 << 13)) { temp &= 0x1fff; ehci->debug = ehci_to_hcd(ehci)->regs + temp; temp = ehci_readl(ehci, &ehci->debug->control); ehci_info(ehci, "debug port %d%s\n", HCS_DEBUG_PORT(ehci->hcs_params), (temp & DBGP_ENABLED) ? " IN USE" : ""); if (!(temp & DBGP_ENABLED)) ehci->debug = NULL; } } ehci_reset(ehci); /* at least the Genesys GL880S needs fixup here */ temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params); temp &= 0x0f; if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) { ehci_dbg(ehci, "bogus port configuration: " "cc=%d x pcc=%d < ports=%d\n", HCS_N_CC(ehci->hcs_params), HCS_N_PCC(ehci->hcs_params), HCS_N_PORTS(ehci->hcs_params)); switch (pdev->vendor) { case 0x17a0: /* GENESYS */ /* GL880S: should be PORTS=2 */ temp |= (ehci->hcs_params & ~0xf); ehci->hcs_params = temp; break; case PCI_VENDOR_ID_NVIDIA: /* NF4: should be PCC=10 */ break; } } /* Serial Bus Release Number is at PCI 0x60 offset */ pci_read_config_byte(pdev, 0x60, &ehci->sbrn); if (pdev->vendor == PCI_VENDOR_ID_STMICRO && pdev->device == PCI_DEVICE_ID_STMICRO_USB_HOST) ehci->sbrn = 0x20; /* ConneXT has no sbrn register */ /* Keep this around for a while just in case some EHCI * implementation uses legacy PCI PM support. This test * can be removed on 17 Dec 2009 if the dev_warn() hasn't * been triggered by then. */ if (!device_can_wakeup(&pdev->dev)) { u16 port_wake; pci_read_config_word(pdev, 0x62, &port_wake); if (port_wake & 0x0001) { dev_warn(&pdev->dev, "Enabling legacy PCI PM\n"); device_set_wakeup_capable(&pdev->dev, 1); } } #ifdef CONFIG_USB_SUSPEND /* REVISIT: the controller works fine for wakeup iff the root hub * itself is "globally" suspended, but usbcore currently doesn't * understand such things. * * System suspend currently expects to be able to suspend the entire * device tree, device-at-a-time. If we failed selective suspend * reports, system suspend would fail; so the root hub code must claim * success. That's lying to usbcore, and it matters for runtime * PM scenarios with selective suspend and remote wakeup... */ if (ehci->no_selective_suspend && device_can_wakeup(&pdev->dev)) ehci_warn(ehci, "selective suspend/wakeup unavailable\n"); #endif ehci_port_power(ehci, 1); retval = ehci_pci_reinit(ehci, pdev); done: return retval; }
static int __devinit i5100_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { int rc; struct mem_ctl_info *mci; struct i5100_priv *priv; struct pci_dev *ch0mm, *ch1mm; int ret = 0; u32 dw; int ranksperch; if (PCI_FUNC(pdev->devfn) != 1) return -ENODEV; rc = pci_enable_device(pdev); if (rc < 0) { ret = rc; goto bail; } /* ECC enabled? */ pci_read_config_dword(pdev, I5100_MC, &dw); if (!i5100_mc_errdeten(dw)) { printk(KERN_INFO "i5100_edac: ECC not enabled.\n"); ret = -ENODEV; goto bail_pdev; } /* figure out how many ranks, from strapped state of 48GB_Mode input */ pci_read_config_dword(pdev, I5100_MS, &dw); ranksperch = !!(dw & (1 << 8)) * 2 + 4; /* enable error reporting... */ pci_read_config_dword(pdev, I5100_EMASK_MEM, &dw); dw &= ~I5100_FERR_NF_MEM_ANY_MASK; pci_write_config_dword(pdev, I5100_EMASK_MEM, dw); /* device 21, func 0, Channel 0 Memory Map, Error Flag/Mask, etc... */ ch0mm = pci_get_device_func(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5100_21, 0); if (!ch0mm) { ret = -ENODEV; goto bail_pdev; } rc = pci_enable_device(ch0mm); if (rc < 0) { ret = rc; goto bail_ch0; } /* device 22, func 0, Channel 1 Memory Map, Error Flag/Mask, etc... */ ch1mm = pci_get_device_func(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5100_22, 0); if (!ch1mm) { ret = -ENODEV; goto bail_disable_ch0; } rc = pci_enable_device(ch1mm); if (rc < 0) { ret = rc; goto bail_ch1; } mci = edac_mc_alloc(sizeof(*priv), ranksperch * 2, 1, 0); if (!mci) { ret = -ENOMEM; goto bail_disable_ch1; } mci->dev = &pdev->dev; priv = mci->pvt_info; priv->ranksperchan = ranksperch; priv->mc = pdev; priv->ch0mm = ch0mm; priv->ch1mm = ch1mm; INIT_DELAYED_WORK(&(priv->i5100_scrubbing), i5100_refresh_scrubbing); /* If scrubbing was already enabled by the bios, start maintaining it */ pci_read_config_dword(pdev, I5100_MC, &dw); if (i5100_mc_scrben(dw)) { priv->scrub_enable = 1; schedule_delayed_work(&(priv->i5100_scrubbing), I5100_SCRUB_REFRESH_RATE); } i5100_init_dimm_layout(pdev, mci); i5100_init_interleaving(pdev, mci); mci->mtype_cap = MEM_FLAG_FB_DDR2; mci->edac_ctl_cap = EDAC_FLAG_SECDED; mci->edac_cap = EDAC_FLAG_SECDED; mci->mod_name = "i5100_edac.c"; mci->mod_ver = "not versioned"; mci->ctl_name = "i5100"; mci->dev_name = pci_name(pdev); mci->ctl_page_to_phys = NULL; mci->edac_check = i5100_check_error; mci->set_sdram_scrub_rate = i5100_set_scrub_rate; mci->get_sdram_scrub_rate = i5100_get_scrub_rate; i5100_init_csrows(mci); /* this strange construction seems to be in every driver, dunno why */ switch (edac_op_state) { case EDAC_OPSTATE_POLL: case EDAC_OPSTATE_NMI: break; default: edac_op_state = EDAC_OPSTATE_POLL; break; } if (edac_mc_add_mc(mci)) { ret = -ENODEV; goto bail_scrub; } return ret; bail_scrub: priv->scrub_enable = 0; cancel_delayed_work_sync(&(priv->i5100_scrubbing)); edac_mc_free(mci); bail_disable_ch1: pci_disable_device(ch1mm); bail_ch1: pci_dev_put(ch1mm); bail_disable_ch0: pci_disable_device(ch0mm); bail_ch0: pci_dev_put(ch0mm); bail_pdev: pci_disable_device(pdev); bail: return ret; }