aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r--drivers/pci/hotplug/Kconfig24
-rw-r--r--drivers/pci/hotplug/Makefile3
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c99
-rw-r--r--drivers/pci/hotplug/cpcihp_generic.c8
-rw-r--r--drivers/pci/hotplug/cpqphp_ctrl.c21
-rw-r--r--drivers/pci/hotplug/fakephp.c164
-rw-r--r--drivers/pci/hotplug/pciehp_acpi.c6
-rw-r--r--drivers/pci/hotplug/pciehp_core.c28
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c12
-rw-r--r--drivers/pci/hotplug/pcihp_slot.c20
10 files changed, 67 insertions, 318 deletions
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig
index 66f29bc00be4..b0e46dede1a9 100644
--- a/drivers/pci/hotplug/Kconfig
+++ b/drivers/pci/hotplug/Kconfig
@@ -17,28 +17,6 @@ menuconfig HOTPLUG_PCI
17 17
18if HOTPLUG_PCI 18if HOTPLUG_PCI
19 19
20config HOTPLUG_PCI_FAKE
21 tristate "Fake PCI Hotplug driver"
22 help
23 Say Y here if you want to use the fake PCI hotplug driver. It can
24 be used to simulate PCI hotplug events if even if your system is
25 not PCI hotplug capable.
26
27 This driver will "emulate" removing PCI devices from the system.
28 If the "power" file is written to with "0" then the specified PCI
29 device will be completely removed from the kernel.
30
31 WARNING, this does NOT turn off the power to the PCI device.
32 This is a "logical" removal, not a physical or electrical
33 removal.
34
35 Use this module at your own risk. You have been warned!
36
37 To compile this driver as a module, choose M here: the
38 module will be called fakephp.
39
40 When in doubt, say N.
41
42config HOTPLUG_PCI_COMPAQ 20config HOTPLUG_PCI_COMPAQ
43 tristate "Compaq PCI Hotplug driver" 21 tristate "Compaq PCI Hotplug driver"
44 depends on X86 && PCI_BIOS 22 depends on X86 && PCI_BIOS
@@ -143,7 +121,7 @@ config HOTPLUG_PCI_SHPC
143 121
144config HOTPLUG_PCI_RPA 122config HOTPLUG_PCI_RPA
145 tristate "RPA PCI Hotplug driver" 123 tristate "RPA PCI Hotplug driver"
146 depends on PPC_PSERIES && EEH && !HOTPLUG_PCI_FAKE 124 depends on PPC_PSERIES && EEH
147 help 125 help
148 Say Y here if you have a RPA system that supports PCI Hotplug. 126 Say Y here if you have a RPA system that supports PCI Hotplug.
149 127
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile
index 6cd9f3c9887d..c459cd4e39c2 100644
--- a/drivers/pci/hotplug/Makefile
+++ b/drivers/pci/hotplug/Makefile
@@ -23,9 +23,6 @@ obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o
23 23
24obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o 24obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o
25 25
26# Link this last so it doesn't claim devices that have a real hotplug driver
27obj-$(CONFIG_HOTPLUG_PCI_FAKE) += fakephp.o
28
29pci_hotplug-objs := pci_hotplug_core.o pcihp_slot.o 26pci_hotplug-objs := pci_hotplug_core.o pcihp_slot.o
30 27
31ifdef CONFIG_HOTPLUG_PCI_CPCI 28ifdef CONFIG_HOTPLUG_PCI_CPCI
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index ad6fd6695495..3d6d4fd1e3c5 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -115,6 +115,35 @@ static const struct acpi_dock_ops acpiphp_dock_ops = {
115 .handler = handle_hotplug_event_func, 115 .handler = handle_hotplug_event_func,
116}; 116};
117 117
118/* Check whether the PCI device is managed by native PCIe hotplug driver */
119static bool device_is_managed_by_native_pciehp(struct pci_dev *pdev)
120{
121 u32 reg32;
122 acpi_handle tmp;
123 struct acpi_pci_root *root;
124
125 /* Check whether the PCIe port supports native PCIe hotplug */
126 if (pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &reg32))
127 return false;
128 if (!(reg32 & PCI_EXP_SLTCAP_HPC))
129 return false;
130
131 /*
132 * Check whether native PCIe hotplug has been enabled for
133 * this PCIe hierarchy.
134 */
135 tmp = acpi_find_root_bridge_handle(pdev);
136 if (!tmp)
137 return false;
138 root = acpi_pci_find_root(tmp);
139 if (!root)
140 return false;
141 if (!(root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL))
142 return false;
143
144 return true;
145}
146
118/* callback routine to register each ACPI PCI slot object */ 147/* callback routine to register each ACPI PCI slot object */
119static acpi_status 148static acpi_status
120register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) 149register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
@@ -142,16 +171,8 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
142 function = adr & 0xffff; 171 function = adr & 0xffff;
143 172
144 pdev = pbus->self; 173 pdev = pbus->self;
145 if (pdev && pci_is_pcie(pdev)) { 174 if (pdev && device_is_managed_by_native_pciehp(pdev))
146 tmp = acpi_find_root_bridge_handle(pdev); 175 return AE_OK;
147 if (tmp) {
148 struct acpi_pci_root *root = acpi_pci_find_root(tmp);
149
150 if (root && (root->osc_control_set &
151 OSC_PCI_EXPRESS_NATIVE_HP_CONTROL))
152 return AE_OK;
153 }
154 }
155 176
156 newfunc = kzalloc(sizeof(struct acpiphp_func), GFP_KERNEL); 177 newfunc = kzalloc(sizeof(struct acpiphp_func), GFP_KERNEL);
157 if (!newfunc) 178 if (!newfunc)
@@ -382,10 +403,10 @@ static inline void config_p2p_bridge_flags(struct acpiphp_bridge *bridge)
382 403
383 404
384/* allocate and initialize host bridge data structure */ 405/* allocate and initialize host bridge data structure */
385static void add_host_bridge(acpi_handle *handle) 406static void add_host_bridge(struct acpi_pci_root *root)
386{ 407{
387 struct acpiphp_bridge *bridge; 408 struct acpiphp_bridge *bridge;
388 struct acpi_pci_root *root = acpi_pci_find_root(handle); 409 acpi_handle handle = root->device->handle;
389 410
390 bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); 411 bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
391 if (bridge == NULL) 412 if (bridge == NULL)
@@ -468,11 +489,12 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
468 489
469 490
470/* find hot-pluggable slots, and then find P2P bridge */ 491/* find hot-pluggable slots, and then find P2P bridge */
471static int add_bridge(acpi_handle handle) 492static int add_bridge(struct acpi_pci_root *root)
472{ 493{
473 acpi_status status; 494 acpi_status status;
474 unsigned long long tmp; 495 unsigned long long tmp;
475 acpi_handle dummy_handle; 496 acpi_handle dummy_handle;
497 acpi_handle handle = root->device->handle;
476 498
477 /* if the bridge doesn't have _STA, we assume it is always there */ 499 /* if the bridge doesn't have _STA, we assume it is always there */
478 status = acpi_get_handle(handle, "_STA", &dummy_handle); 500 status = acpi_get_handle(handle, "_STA", &dummy_handle);
@@ -490,7 +512,7 @@ static int add_bridge(acpi_handle handle)
490 /* check if this bridge has ejectable slots */ 512 /* check if this bridge has ejectable slots */
491 if (detect_ejectable_slots(handle) > 0) { 513 if (detect_ejectable_slots(handle) > 0) {
492 dbg("found PCI host-bus bridge with hot-pluggable slots\n"); 514 dbg("found PCI host-bus bridge with hot-pluggable slots\n");
493 add_host_bridge(handle); 515 add_host_bridge(root);
494 } 516 }
495 517
496 /* search P2P bridges under this host bridge */ 518 /* search P2P bridges under this host bridge */
@@ -588,9 +610,10 @@ cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
588 return AE_OK; 610 return AE_OK;
589} 611}
590 612
591static void remove_bridge(acpi_handle handle) 613static void remove_bridge(struct acpi_pci_root *root)
592{ 614{
593 struct acpiphp_bridge *bridge; 615 struct acpiphp_bridge *bridge;
616 acpi_handle handle = root->device->handle;
594 617
595 /* cleanup p2p bridges under this host bridge 618 /* cleanup p2p bridges under this host bridge
596 in a depth-first manner */ 619 in a depth-first manner */
@@ -869,17 +892,6 @@ static int __ref enable_device(struct acpiphp_slot *slot)
869 return retval; 892 return retval;
870} 893}
871 894
872static void disable_bridges(struct pci_bus *bus)
873{
874 struct pci_dev *dev;
875 list_for_each_entry(dev, &bus->devices, bus_list) {
876 if (dev->subordinate) {
877 disable_bridges(dev->subordinate);
878 pci_disable_device(dev);
879 }
880 }
881}
882
883/* return first device in slot, acquiring a reference on it */ 895/* return first device in slot, acquiring a reference on it */
884static struct pci_dev *dev_in_slot(struct acpiphp_slot *slot) 896static struct pci_dev *dev_in_slot(struct acpiphp_slot *slot)
885{ 897{
@@ -931,12 +943,7 @@ static int disable_device(struct acpiphp_slot *slot)
931 * here. 943 * here.
932 */ 944 */
933 while ((pdev = dev_in_slot(slot))) { 945 while ((pdev = dev_in_slot(slot))) {
934 pci_stop_bus_device(pdev); 946 pci_stop_and_remove_bus_device(pdev);
935 if (pdev->subordinate) {
936 disable_bridges(pdev->subordinate);
937 pci_disable_device(pdev);
938 }
939 __pci_remove_bus_device(pdev);
940 pci_dev_put(pdev); 947 pci_dev_put(pdev);
941 } 948 }
942 949
@@ -1477,34 +1484,6 @@ int __init acpiphp_get_num_slots(void)
1477} 1484}
1478 1485
1479 1486
1480#if 0
1481/**
1482 * acpiphp_for_each_slot - call function for each slot
1483 * @fn: callback function
1484 * @data: context to be passed to callback function
1485 */
1486static int acpiphp_for_each_slot(acpiphp_callback fn, void *data)
1487{
1488 struct list_head *node;
1489 struct acpiphp_bridge *bridge;
1490 struct acpiphp_slot *slot;
1491 int retval = 0;
1492
1493 list_for_each (node, &bridge_list) {
1494 bridge = (struct acpiphp_bridge *)node;
1495 for (slot = bridge->slots; slot; slot = slot->next) {
1496 retval = fn(slot, data);
1497 if (!retval)
1498 goto err_exit;
1499 }
1500 }
1501
1502 err_exit:
1503 return retval;
1504}
1505#endif
1506
1507
1508/** 1487/**
1509 * acpiphp_enable_slot - power on slot 1488 * acpiphp_enable_slot - power on slot
1510 * @slot: ACPI PHP slot 1489 * @slot: ACPI PHP slot
diff --git a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c
index 81af764c629b..a6a71c41cdf8 100644
--- a/drivers/pci/hotplug/cpcihp_generic.c
+++ b/drivers/pci/hotplug/cpcihp_generic.c
@@ -154,12 +154,8 @@ static int __init cpcihp_generic_init(void)
154 if(!r) 154 if(!r)
155 return -EBUSY; 155 return -EBUSY;
156 156
157 bus = pci_find_bus(0, bridge_busnr); 157 dev = pci_get_domain_bus_and_slot(0, bridge_busnr,
158 if (!bus) { 158 PCI_DEVFN(bridge_slot, 0));
159 err("Invalid bus number %d", bridge_busnr);
160 return -EINVAL;
161 }
162 dev = pci_get_slot(bus, PCI_DEVFN(bridge_slot, 0));
163 if(!dev || dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { 159 if(!dev || dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
164 err("Invalid bridge device %s", bridge); 160 err("Invalid bridge device %s", bridge);
165 pci_dev_put(dev); 161 pci_dev_put(dev);
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c
index e43908d9b5df..36112fe212d3 100644
--- a/drivers/pci/hotplug/cpqphp_ctrl.c
+++ b/drivers/pci/hotplug/cpqphp_ctrl.c
@@ -2890,27 +2890,8 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
2890 func->mem_head = mem_node; 2890 func->mem_head = mem_node;
2891 } else 2891 } else
2892 return -ENOMEM; 2892 return -ENOMEM;
2893 } else if ((temp_register & 0x0BL) == 0x04) {
2894 /* Map memory */
2895 base = temp_register & 0xFFFFFFF0;
2896 base = ~base + 1;
2897
2898 dbg("CND: length = 0x%x\n", base);
2899 mem_node = get_resource(&(resources->mem_head), base);
2900
2901 /* allocate the resource to the board */
2902 if (mem_node) {
2903 base = mem_node->base;
2904
2905 mem_node->next = func->mem_head;
2906 func->mem_head = mem_node;
2907 } else
2908 return -ENOMEM;
2909 } else if ((temp_register & 0x0BL) == 0x06) {
2910 /* Those bits are reserved, we can't handle this */
2911 return 1;
2912 } else { 2893 } else {
2913 /* Requesting space below 1M */ 2894 /* Reserved bits or requesting space below 1M */
2914 return NOT_ENOUGH_RESOURCES; 2895 return NOT_ENOUGH_RESOURCES;
2915 } 2896 }
2916 2897
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
deleted file mode 100644
index a019c9a712be..000000000000
--- a/drivers/pci/hotplug/fakephp.c
+++ /dev/null
@@ -1,164 +0,0 @@
1/* Works like the fakephp driver used to, except a little better.
2 *
3 * - It's possible to remove devices with subordinate busses.
4 * - New PCI devices that appear via any method, not just a fakephp triggered
5 * rescan, will be noticed.
6 * - Devices that are removed via any method, not just a fakephp triggered
7 * removal, will also be noticed.
8 *
9 * Uses nothing from the pci-hotplug subsystem.
10 *
11 */
12
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/types.h>
16#include <linux/list.h>
17#include <linux/kobject.h>
18#include <linux/sysfs.h>
19#include <linux/init.h>
20#include <linux/pci.h>
21#include <linux/device.h>
22#include <linux/slab.h>
23#include "../pci.h"
24
25struct legacy_slot {
26 struct kobject kobj;
27 struct pci_dev *dev;
28 struct list_head list;
29};
30
31static LIST_HEAD(legacy_list);
32
33static ssize_t legacy_show(struct kobject *kobj, struct attribute *attr,
34 char *buf)
35{
36 struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj);
37 strcpy(buf, "1\n");
38 return 2;
39}
40
41static void remove_callback(void *data)
42{
43 pci_stop_and_remove_bus_device((struct pci_dev *)data);
44}
45
46static ssize_t legacy_store(struct kobject *kobj, struct attribute *attr,
47 const char *buf, size_t len)
48{
49 struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj);
50 unsigned long val;
51
52 if (strict_strtoul(buf, 0, &val) < 0)
53 return -EINVAL;
54
55 if (val)
56 pci_rescan_bus(slot->dev->bus);
57 else
58 sysfs_schedule_callback(&slot->dev->dev.kobj, remove_callback,
59 slot->dev, THIS_MODULE);
60 return len;
61}
62
63static struct attribute *legacy_attrs[] = {
64 &(struct attribute){ .name = "power", .mode = 0644 },
65 NULL,
66};
67
68static void legacy_release(struct kobject *kobj)
69{
70 struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj);
71
72 pci_dev_put(slot->dev);
73 kfree(slot);
74}
75
76static struct kobj_type legacy_ktype = {
77 .sysfs_ops = &(const struct sysfs_ops){
78 .store = legacy_store, .show = legacy_show
79 },
80 .release = &legacy_release,
81 .default_attrs = legacy_attrs,
82};
83
84static int legacy_add_slot(struct pci_dev *pdev)
85{
86 struct legacy_slot *slot = kzalloc(sizeof(*slot), GFP_KERNEL);
87
88 if (!slot)
89 return -ENOMEM;
90
91 if (kobject_init_and_add(&slot->kobj, &legacy_ktype,
92 &pci_slots_kset->kobj, "%s",
93 dev_name(&pdev->dev))) {
94 dev_warn(&pdev->dev, "Failed to created legacy fake slot\n");
95 return -EINVAL;
96 }
97 slot->dev = pci_dev_get(pdev);
98
99 list_add(&slot->list, &legacy_list);
100
101 return 0;
102}
103
104static int legacy_notify(struct notifier_block *nb,
105 unsigned long action, void *data)
106{
107 struct pci_dev *pdev = to_pci_dev(data);
108
109 if (action == BUS_NOTIFY_ADD_DEVICE) {
110 legacy_add_slot(pdev);
111 } else if (action == BUS_NOTIFY_DEL_DEVICE) {
112 struct legacy_slot *slot;
113
114 list_for_each_entry(slot, &legacy_list, list)
115 if (slot->dev == pdev)
116 goto found;
117
118 dev_warn(&pdev->dev, "Missing legacy fake slot?");
119 return -ENODEV;
120found:
121 kobject_del(&slot->kobj);
122 list_del(&slot->list);
123 kobject_put(&slot->kobj);
124 }
125
126 return 0;
127}
128
129static struct notifier_block legacy_notifier = {
130 .notifier_call = legacy_notify
131};
132
133static int __init init_legacy(void)
134{
135 struct pci_dev *pdev = NULL;
136
137 /* Add existing devices */
138 for_each_pci_dev(pdev)
139 legacy_add_slot(pdev);
140
141 /* Be alerted of any new ones */
142 bus_register_notifier(&pci_bus_type, &legacy_notifier);
143 return 0;
144}
145module_init(init_legacy);
146
147static void __exit remove_legacy(void)
148{
149 struct legacy_slot *slot, *tmp;
150
151 bus_unregister_notifier(&pci_bus_type, &legacy_notifier);
152
153 list_for_each_entry_safe(slot, tmp, &legacy_list, list) {
154 list_del(&slot->list);
155 kobject_del(&slot->kobj);
156 kobject_put(&slot->kobj);
157 }
158}
159module_exit(remove_legacy);
160
161
162MODULE_AUTHOR("Trent Piepho <xyzzy@speakeasy.org>");
163MODULE_DESCRIPTION("Legacy version of the fakephp interface");
164MODULE_LICENSE("GPL");
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c
index 376d70d17176..24d709b7388c 100644
--- a/drivers/pci/hotplug/pciehp_acpi.c
+++ b/drivers/pci/hotplug/pciehp_acpi.c
@@ -81,16 +81,12 @@ static struct list_head __initdata dummy_slots = LIST_HEAD_INIT(dummy_slots);
81/* Dummy driver for dumplicate name detection */ 81/* Dummy driver for dumplicate name detection */
82static int __init dummy_probe(struct pcie_device *dev) 82static int __init dummy_probe(struct pcie_device *dev)
83{ 83{
84 int pos;
85 u32 slot_cap; 84 u32 slot_cap;
86 acpi_handle handle; 85 acpi_handle handle;
87 struct dummy_slot *slot, *tmp; 86 struct dummy_slot *slot, *tmp;
88 struct pci_dev *pdev = dev->port; 87 struct pci_dev *pdev = dev->port;
89 88
90 pos = pci_pcie_cap(pdev); 89 pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &slot_cap);
91 if (!pos)
92 return -ENODEV;
93 pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &slot_cap);
94 slot = kzalloc(sizeof(*slot), GFP_KERNEL); 90 slot = kzalloc(sizeof(*slot), GFP_KERNEL);
95 if (!slot) 91 if (!slot)
96 return -ENOMEM; 92 return -ENOMEM;
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 365c6b96c642..916bf4f53aba 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -300,24 +300,24 @@ static int pciehp_suspend (struct pcie_device *dev)
300 300
301static int pciehp_resume (struct pcie_device *dev) 301static int pciehp_resume (struct pcie_device *dev)
302{ 302{
303 struct controller *ctrl;
304 struct slot *slot;
305 u8 status;
306
303 dev_info(&dev->device, "%s ENTRY\n", __func__); 307 dev_info(&dev->device, "%s ENTRY\n", __func__);
304 if (pciehp_force) { 308 ctrl = get_service_data(dev);
305 struct controller *ctrl = get_service_data(dev);
306 struct slot *slot;
307 u8 status;
308 309
309 /* reinitialize the chipset's event detection logic */ 310 /* reinitialize the chipset's event detection logic */
310 pcie_enable_notification(ctrl); 311 pcie_enable_notification(ctrl);
311 312
312 slot = ctrl->slot; 313 slot = ctrl->slot;
313 314
314 /* Check if slot is occupied */ 315 /* Check if slot is occupied */
315 pciehp_get_adapter_status(slot, &status); 316 pciehp_get_adapter_status(slot, &status);
316 if (status) 317 if (status)
317 pciehp_enable_slot(slot); 318 pciehp_enable_slot(slot);
318 else 319 else
319 pciehp_disable_slot(slot); 320 pciehp_disable_slot(slot);
320 }
321 return 0; 321 return 0;
322} 322}
323#endif /* PM */ 323#endif /* PM */
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 302451e8289d..13b2eaf7ba43 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -44,25 +44,25 @@
44static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value) 44static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value)
45{ 45{
46 struct pci_dev *dev = ctrl->pcie->port; 46 struct pci_dev *dev = ctrl->pcie->port;
47 return pci_read_config_word(dev, pci_pcie_cap(dev) + reg, value); 47 return pcie_capability_read_word(dev, reg, value);
48} 48}
49 49
50static inline int pciehp_readl(struct controller *ctrl, int reg, u32 *value) 50static inline int pciehp_readl(struct controller *ctrl, int reg, u32 *value)
51{ 51{
52 struct pci_dev *dev = ctrl->pcie->port; 52 struct pci_dev *dev = ctrl->pcie->port;
53 return pci_read_config_dword(dev, pci_pcie_cap(dev) + reg, value); 53 return pcie_capability_read_dword(dev, reg, value);
54} 54}
55 55
56static inline int pciehp_writew(struct controller *ctrl, int reg, u16 value) 56static inline int pciehp_writew(struct controller *ctrl, int reg, u16 value)
57{ 57{
58 struct pci_dev *dev = ctrl->pcie->port; 58 struct pci_dev *dev = ctrl->pcie->port;
59 return pci_write_config_word(dev, pci_pcie_cap(dev) + reg, value); 59 return pcie_capability_write_word(dev, reg, value);
60} 60}
61 61
62static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) 62static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value)
63{ 63{
64 struct pci_dev *dev = ctrl->pcie->port; 64 struct pci_dev *dev = ctrl->pcie->port;
65 return pci_write_config_dword(dev, pci_pcie_cap(dev) + reg, value); 65 return pcie_capability_write_dword(dev, reg, value);
66} 66}
67 67
68/* Power Control Command */ 68/* Power Control Command */
@@ -855,10 +855,6 @@ struct controller *pcie_init(struct pcie_device *dev)
855 goto abort; 855 goto abort;
856 } 856 }
857 ctrl->pcie = dev; 857 ctrl->pcie = dev;
858 if (!pci_pcie_cap(pdev)) {
859 ctrl_err(ctrl, "Cannot find PCI Express capability\n");
860 goto abort_ctrl;
861 }
862 if (pciehp_readl(ctrl, PCI_EXP_SLTCAP, &slot_cap)) { 858 if (pciehp_readl(ctrl, PCI_EXP_SLTCAP, &slot_cap)) {
863 ctrl_err(ctrl, "Cannot read SLOTCAP register\n"); 859 ctrl_err(ctrl, "Cannot read SLOTCAP register\n");
864 goto abort_ctrl; 860 goto abort_ctrl;
diff --git a/drivers/pci/hotplug/pcihp_slot.c b/drivers/pci/hotplug/pcihp_slot.c
index 8c05a18c9770..fec2d5b75440 100644
--- a/drivers/pci/hotplug/pcihp_slot.c
+++ b/drivers/pci/hotplug/pcihp_slot.c
@@ -96,17 +96,11 @@ static void program_hpp_type1(struct pci_dev *dev, struct hpp_type1 *hpp)
96static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) 96static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
97{ 97{
98 int pos; 98 int pos;
99 u16 reg16;
100 u32 reg32; 99 u32 reg32;
101 100
102 if (!hpp) 101 if (!hpp)
103 return; 102 return;
104 103
105 /* Find PCI Express capability */
106 pos = pci_pcie_cap(dev);
107 if (!pos)
108 return;
109
110 if (hpp->revision > 1) { 104 if (hpp->revision > 1) {
111 dev_warn(&dev->dev, "PCIe settings rev %d not supported\n", 105 dev_warn(&dev->dev, "PCIe settings rev %d not supported\n",
112 hpp->revision); 106 hpp->revision);
@@ -114,17 +108,13 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
114 } 108 }
115 109
116 /* Initialize Device Control Register */ 110 /* Initialize Device Control Register */
117 pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &reg16); 111 pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL,
118 reg16 = (reg16 & hpp->pci_exp_devctl_and) | hpp->pci_exp_devctl_or; 112 ~hpp->pci_exp_devctl_and, hpp->pci_exp_devctl_or);
119 pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16);
120 113
121 /* Initialize Link Control Register */ 114 /* Initialize Link Control Register */
122 if (dev->subordinate) { 115 if (dev->subordinate)
123 pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &reg16); 116 pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL,
124 reg16 = (reg16 & hpp->pci_exp_lnkctl_and) 117 ~hpp->pci_exp_lnkctl_and, hpp->pci_exp_lnkctl_or);
125 | hpp->pci_exp_lnkctl_or;
126 pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, reg16);
127 }
128 118
129 /* Find Advanced Error Reporting Enhanced Capability */ 119 /* Find Advanced Error Reporting Enhanced Capability */
130 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); 120 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);