diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/bus.c | 4 | ||||
-rw-r--r-- | drivers/pci/hotplug/fakephp.c | 2 | ||||
-rw-r--r-- | drivers/pci/pci-sysfs.c | 5 | ||||
-rw-r--r-- | drivers/pci/pci.c | 47 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 85 | ||||
-rw-r--r-- | drivers/pci/slot.c | 2 |
6 files changed, 139 insertions, 6 deletions
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 712250f5874a..26301cb25e7f 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -288,9 +288,9 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), | |||
288 | next = dev->bus_list.next; | 288 | next = dev->bus_list.next; |
289 | 289 | ||
290 | /* Run device routines with the device locked */ | 290 | /* Run device routines with the device locked */ |
291 | down(&dev->dev.sem); | 291 | device_lock(&dev->dev); |
292 | retval = cb(dev, userdata); | 292 | retval = cb(dev, userdata); |
293 | up(&dev->dev.sem); | 293 | device_unlock(&dev->dev); |
294 | if (retval) | 294 | if (retval) |
295 | break; | 295 | break; |
296 | } | 296 | } |
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c index 6151389fd903..0a894efd4b9b 100644 --- a/drivers/pci/hotplug/fakephp.c +++ b/drivers/pci/hotplug/fakephp.c | |||
@@ -73,7 +73,7 @@ static void legacy_release(struct kobject *kobj) | |||
73 | } | 73 | } |
74 | 74 | ||
75 | static struct kobj_type legacy_ktype = { | 75 | static struct kobj_type legacy_ktype = { |
76 | .sysfs_ops = &(struct sysfs_ops){ | 76 | .sysfs_ops = &(const struct sysfs_ops){ |
77 | .store = legacy_store, .show = legacy_show | 77 | .store = legacy_store, .show = legacy_show |
78 | }, | 78 | }, |
79 | .release = &legacy_release, | 79 | .release = &legacy_release, |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 807224ec8351..de296452c957 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -642,6 +642,7 @@ void pci_create_legacy_files(struct pci_bus *b) | |||
642 | if (!b->legacy_io) | 642 | if (!b->legacy_io) |
643 | goto kzalloc_err; | 643 | goto kzalloc_err; |
644 | 644 | ||
645 | sysfs_bin_attr_init(b->legacy_io); | ||
645 | b->legacy_io->attr.name = "legacy_io"; | 646 | b->legacy_io->attr.name = "legacy_io"; |
646 | b->legacy_io->size = 0xffff; | 647 | b->legacy_io->size = 0xffff; |
647 | b->legacy_io->attr.mode = S_IRUSR | S_IWUSR; | 648 | b->legacy_io->attr.mode = S_IRUSR | S_IWUSR; |
@@ -654,6 +655,7 @@ void pci_create_legacy_files(struct pci_bus *b) | |||
654 | goto legacy_io_err; | 655 | goto legacy_io_err; |
655 | 656 | ||
656 | /* Allocated above after the legacy_io struct */ | 657 | /* Allocated above after the legacy_io struct */ |
658 | sysfs_bin_attr_init(b->legacy_mem); | ||
657 | b->legacy_mem = b->legacy_io + 1; | 659 | b->legacy_mem = b->legacy_io + 1; |
658 | b->legacy_mem->attr.name = "legacy_mem"; | 660 | b->legacy_mem->attr.name = "legacy_mem"; |
659 | b->legacy_mem->size = 1024*1024; | 661 | b->legacy_mem->size = 1024*1024; |
@@ -800,6 +802,7 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine) | |||
800 | if (res_attr) { | 802 | if (res_attr) { |
801 | char *res_attr_name = (char *)(res_attr + 1); | 803 | char *res_attr_name = (char *)(res_attr + 1); |
802 | 804 | ||
805 | sysfs_bin_attr_init(res_attr); | ||
803 | if (write_combine) { | 806 | if (write_combine) { |
804 | pdev->res_attr_wc[num] = res_attr; | 807 | pdev->res_attr_wc[num] = res_attr; |
805 | sprintf(res_attr_name, "resource%d_wc", num); | 808 | sprintf(res_attr_name, "resource%d_wc", num); |
@@ -972,6 +975,7 @@ static int pci_create_capabilities_sysfs(struct pci_dev *dev) | |||
972 | if (!attr) | 975 | if (!attr) |
973 | return -ENOMEM; | 976 | return -ENOMEM; |
974 | 977 | ||
978 | sysfs_bin_attr_init(attr); | ||
975 | attr->size = dev->vpd->len; | 979 | attr->size = dev->vpd->len; |
976 | attr->attr.name = "vpd"; | 980 | attr->attr.name = "vpd"; |
977 | attr->attr.mode = S_IRUSR | S_IWUSR; | 981 | attr->attr.mode = S_IRUSR | S_IWUSR; |
@@ -1038,6 +1042,7 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) | |||
1038 | retval = -ENOMEM; | 1042 | retval = -ENOMEM; |
1039 | goto err_resource_files; | 1043 | goto err_resource_files; |
1040 | } | 1044 | } |
1045 | sysfs_bin_attr_init(attr); | ||
1041 | attr->size = rom_size; | 1046 | attr->size = rom_size; |
1042 | attr->attr.name = "rom"; | 1047 | attr->attr.name = "rom"; |
1043 | attr->attr.mode = S_IRUSR; | 1048 | attr->attr.mode = S_IRUSR; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 6e100ae7f5b5..fdcf01af6762 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -303,6 +303,49 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap) | |||
303 | } | 303 | } |
304 | EXPORT_SYMBOL_GPL(pci_find_ext_capability); | 304 | EXPORT_SYMBOL_GPL(pci_find_ext_capability); |
305 | 305 | ||
306 | /** | ||
307 | * pci_bus_find_ext_capability - find an extended capability | ||
308 | * @bus: the PCI bus to query | ||
309 | * @devfn: PCI device to query | ||
310 | * @cap: capability code | ||
311 | * | ||
312 | * Like pci_find_ext_capability() but works for pci devices that do not have a | ||
313 | * pci_dev structure set up yet. | ||
314 | * | ||
315 | * Returns the address of the requested capability structure within the | ||
316 | * device's PCI configuration space or 0 in case the device does not | ||
317 | * support it. | ||
318 | */ | ||
319 | int pci_bus_find_ext_capability(struct pci_bus *bus, unsigned int devfn, | ||
320 | int cap) | ||
321 | { | ||
322 | u32 header; | ||
323 | int ttl; | ||
324 | int pos = PCI_CFG_SPACE_SIZE; | ||
325 | |||
326 | /* minimum 8 bytes per capability */ | ||
327 | ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8; | ||
328 | |||
329 | if (!pci_bus_read_config_dword(bus, devfn, pos, &header)) | ||
330 | return 0; | ||
331 | if (header == 0xffffffff || header == 0) | ||
332 | return 0; | ||
333 | |||
334 | while (ttl-- > 0) { | ||
335 | if (PCI_EXT_CAP_ID(header) == cap) | ||
336 | return pos; | ||
337 | |||
338 | pos = PCI_EXT_CAP_NEXT(header); | ||
339 | if (pos < PCI_CFG_SPACE_SIZE) | ||
340 | break; | ||
341 | |||
342 | if (!pci_bus_read_config_dword(bus, devfn, pos, &header)) | ||
343 | break; | ||
344 | } | ||
345 | |||
346 | return 0; | ||
347 | } | ||
348 | |||
306 | static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap) | 349 | static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap) |
307 | { | 350 | { |
308 | int rc, ttl = PCI_FIND_CAP_TTL; | 351 | int rc, ttl = PCI_FIND_CAP_TTL; |
@@ -2445,7 +2488,7 @@ static int pci_dev_reset(struct pci_dev *dev, int probe) | |||
2445 | if (!probe) { | 2488 | if (!probe) { |
2446 | pci_block_user_cfg_access(dev); | 2489 | pci_block_user_cfg_access(dev); |
2447 | /* block PM suspend, driver probe, etc. */ | 2490 | /* block PM suspend, driver probe, etc. */ |
2448 | down(&dev->dev.sem); | 2491 | device_lock(&dev->dev); |
2449 | } | 2492 | } |
2450 | 2493 | ||
2451 | rc = pci_dev_specific_reset(dev, probe); | 2494 | rc = pci_dev_specific_reset(dev, probe); |
@@ -2467,7 +2510,7 @@ static int pci_dev_reset(struct pci_dev *dev, int probe) | |||
2467 | rc = pci_parent_bus_reset(dev, probe); | 2510 | rc = pci_parent_bus_reset(dev, probe); |
2468 | done: | 2511 | done: |
2469 | if (!probe) { | 2512 | if (!probe) { |
2470 | up(&dev->dev.sem); | 2513 | device_unlock(&dev->dev); |
2471 | pci_unblock_user_cfg_access(dev); | 2514 | pci_unblock_user_cfg_access(dev); |
2472 | } | 2515 | } |
2473 | 2516 | ||
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 039e87b71442..81d19d5683ac 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -2533,6 +2533,91 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1518, quirk_i82576_sriov); | |||
2533 | 2533 | ||
2534 | #endif /* CONFIG_PCI_IOV */ | 2534 | #endif /* CONFIG_PCI_IOV */ |
2535 | 2535 | ||
2536 | /* | ||
2537 | * This is a quirk for the Ricoh MMC controller found as a part of | ||
2538 | * some mulifunction chips. | ||
2539 | |||
2540 | * This is very similiar and based on the ricoh_mmc driver written by | ||
2541 | * Philip Langdale. Thank you for these magic sequences. | ||
2542 | * | ||
2543 | * These chips implement the four main memory card controllers (SD, MMC, MS, xD) | ||
2544 | * and one or both of cardbus or firewire. | ||
2545 | * | ||
2546 | * It happens that they implement SD and MMC | ||
2547 | * support as separate controllers (and PCI functions). The linux SDHCI | ||
2548 | * driver supports MMC cards but the chip detects MMC cards in hardware | ||
2549 | * and directs them to the MMC controller - so the SDHCI driver never sees | ||
2550 | * them. | ||
2551 | * | ||
2552 | * To get around this, we must disable the useless MMC controller. | ||
2553 | * At that point, the SDHCI controller will start seeing them | ||
2554 | * It seems to be the case that the relevant PCI registers to deactivate the | ||
2555 | * MMC controller live on PCI function 0, which might be the cardbus controller | ||
2556 | * or the firewire controller, depending on the particular chip in question | ||
2557 | * | ||
2558 | * This has to be done early, because as soon as we disable the MMC controller | ||
2559 | * other pci functions shift up one level, e.g. function #2 becomes function | ||
2560 | * #1, and this will confuse the pci core. | ||
2561 | */ | ||
2562 | |||
2563 | #ifdef CONFIG_MMC_RICOH_MMC | ||
2564 | static void ricoh_mmc_fixup_rl5c476(struct pci_dev *dev) | ||
2565 | { | ||
2566 | /* disable via cardbus interface */ | ||
2567 | u8 write_enable; | ||
2568 | u8 write_target; | ||
2569 | u8 disable; | ||
2570 | |||
2571 | /* disable must be done via function #0 */ | ||
2572 | if (PCI_FUNC(dev->devfn)) | ||
2573 | return; | ||
2574 | |||
2575 | pci_read_config_byte(dev, 0xB7, &disable); | ||
2576 | if (disable & 0x02) | ||
2577 | return; | ||
2578 | |||
2579 | pci_read_config_byte(dev, 0x8E, &write_enable); | ||
2580 | pci_write_config_byte(dev, 0x8E, 0xAA); | ||
2581 | pci_read_config_byte(dev, 0x8D, &write_target); | ||
2582 | pci_write_config_byte(dev, 0x8D, 0xB7); | ||
2583 | pci_write_config_byte(dev, 0xB7, disable | 0x02); | ||
2584 | pci_write_config_byte(dev, 0x8E, write_enable); | ||
2585 | pci_write_config_byte(dev, 0x8D, write_target); | ||
2586 | |||
2587 | dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via cardbus function)\n"); | ||
2588 | dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n"); | ||
2589 | } | ||
2590 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, ricoh_mmc_fixup_rl5c476); | ||
2591 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, ricoh_mmc_fixup_rl5c476); | ||
2592 | |||
2593 | static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev) | ||
2594 | { | ||
2595 | /* disable via firewire interface */ | ||
2596 | u8 write_enable; | ||
2597 | u8 disable; | ||
2598 | |||
2599 | /* disable must be done via function #0 */ | ||
2600 | if (PCI_FUNC(dev->devfn)) | ||
2601 | return; | ||
2602 | |||
2603 | pci_read_config_byte(dev, 0xCB, &disable); | ||
2604 | |||
2605 | if (disable & 0x02) | ||
2606 | return; | ||
2607 | |||
2608 | pci_read_config_byte(dev, 0xCA, &write_enable); | ||
2609 | pci_write_config_byte(dev, 0xCA, 0x57); | ||
2610 | pci_write_config_byte(dev, 0xCB, disable | 0x02); | ||
2611 | pci_write_config_byte(dev, 0xCA, write_enable); | ||
2612 | |||
2613 | dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via firewire function)\n"); | ||
2614 | dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n"); | ||
2615 | } | ||
2616 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); | ||
2617 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); | ||
2618 | #endif /*CONFIG_MMC_RICOH_MMC*/ | ||
2619 | |||
2620 | |||
2536 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, | 2621 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, |
2537 | struct pci_fixup *end) | 2622 | struct pci_fixup *end) |
2538 | { | 2623 | { |
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index 49c9e6c9779a..f75a44d37fbe 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c | |||
@@ -29,7 +29,7 @@ static ssize_t pci_slot_attr_store(struct kobject *kobj, | |||
29 | return attribute->store ? attribute->store(slot, buf, len) : -EIO; | 29 | return attribute->store ? attribute->store(slot, buf, len) : -EIO; |
30 | } | 30 | } |
31 | 31 | ||
32 | static struct sysfs_ops pci_slot_sysfs_ops = { | 32 | static const struct sysfs_ops pci_slot_sysfs_ops = { |
33 | .show = pci_slot_attr_show, | 33 | .show = pci_slot_attr_show, |
34 | .store = pci_slot_attr_store, | 34 | .store = pci_slot_attr_store, |
35 | }; | 35 | }; |