aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/pciehp_hpc.c
diff options
context:
space:
mode:
authorMark Lord <lkml@rtr.ca>2007-11-28 18:11:46 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2008-02-01 18:04:23 -0500
commit08e7a7d27d71e92305980033ec03c0a86b3efb2d (patch)
tree4916e6831b974087cf17d3d8c0394563139319b4 /drivers/pci/hotplug/pciehp_hpc.c
parent0a3c33d77ff7ad5b988997536a8f09c49e35ad20 (diff)
PCI: more fixes for PCIe Hotplug so that it works with ExpressCard slots on Dell notebooks (and others?) in conjunction with modparam of pciehp_force=1
Split out the hotplug hardware initialization code from pcie_init() into pcie_init_enable_events(), without changing any functionality. Signed-off-by: Mark Lord <mlord@pobox.com> Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Theodore Ts'o <tytso@mit.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/pci/hotplug/pciehp_hpc.c')
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c185
1 files changed, 104 insertions, 81 deletions
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 06d025b8b13f..8b11d80bf651 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -1067,99 +1067,22 @@ int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev)
1067} 1067}
1068#endif 1068#endif
1069 1069
1070int pcie_init(struct controller * ctrl, struct pcie_device *dev) 1070int pcie_init_hardware(struct controller *ctrl, struct pcie_device *dev)
1071{ 1071{
1072 int rc; 1072 int rc;
1073 u16 temp_word; 1073 u16 temp_word;
1074 u16 cap_reg;
1075 u16 intr_enable = 0; 1074 u16 intr_enable = 0;
1076 u32 slot_cap; 1075 u32 slot_cap;
1077 int cap_base; 1076 u16 slot_status;
1078 u16 slot_status, slot_ctrl;
1079 struct pci_dev *pdev; 1077 struct pci_dev *pdev;
1080 1078
1081 pdev = dev->port; 1079 pdev = dev->port;
1082 ctrl->pci_dev = pdev; /* save pci_dev in context */
1083
1084 dbg("%s: hotplug controller vendor id 0x%x device id 0x%x\n",
1085 __FUNCTION__, pdev->vendor, pdev->device);
1086
1087 if ((cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP)) == 0) {
1088 dbg("%s: Can't find PCI_CAP_ID_EXP (0x10)\n", __FUNCTION__);
1089 goto abort_free_ctlr;
1090 }
1091
1092 ctrl->cap_base = cap_base;
1093
1094 dbg("%s: pcie_cap_base %x\n", __FUNCTION__, cap_base);
1095
1096 rc = pciehp_readw(ctrl, CAPREG, &cap_reg);
1097 if (rc) {
1098 err("%s: Cannot read CAPREG register\n", __FUNCTION__);
1099 goto abort_free_ctlr;
1100 }
1101 dbg("%s: CAPREG offset %x cap_reg %x\n",
1102 __FUNCTION__, ctrl->cap_base + CAPREG, cap_reg);
1103
1104 if (((cap_reg & SLOT_IMPL) == 0) ||
1105 (((cap_reg & DEV_PORT_TYPE) != 0x0040)
1106 && ((cap_reg & DEV_PORT_TYPE) != 0x0060))) {
1107 dbg("%s : This is not a root port or the port is not "
1108 "connected to a slot\n", __FUNCTION__);
1109 goto abort_free_ctlr;
1110 }
1111 1080
1112 rc = pciehp_readl(ctrl, SLOTCAP, &slot_cap); 1081 rc = pciehp_readl(ctrl, SLOTCAP, &slot_cap);
1113 if (rc) { 1082 if (rc) {
1114 err("%s: Cannot read SLOTCAP register\n", __FUNCTION__); 1083 err("%s: Cannot read SLOTCAP register\n", __FUNCTION__);
1115 goto abort_free_ctlr; 1084 goto abort_free_ctlr;
1116 } 1085 }
1117 dbg("%s: SLOTCAP offset %x slot_cap %x\n",
1118 __FUNCTION__, ctrl->cap_base + SLOTCAP, slot_cap);
1119
1120 if (!(slot_cap & HP_CAP)) {
1121 dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__);
1122 goto abort_free_ctlr;
1123 }
1124 /* For debugging purpose */
1125 rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
1126 if (rc) {
1127 err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__);
1128 goto abort_free_ctlr;
1129 }
1130 dbg("%s: SLOTSTATUS offset %x slot_status %x\n",
1131 __FUNCTION__, ctrl->cap_base + SLOTSTATUS, slot_status);
1132
1133 rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
1134 if (rc) {
1135 err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
1136 goto abort_free_ctlr;
1137 }
1138 dbg("%s: SLOTCTRL offset %x slot_ctrl %x\n",
1139 __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl);
1140
1141 for (rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++)
1142 if (pci_resource_len(pdev, rc) > 0)
1143 dbg("pci resource[%d] start=0x%llx(len=0x%llx)\n", rc,
1144 (unsigned long long)pci_resource_start(pdev, rc),
1145 (unsigned long long)pci_resource_len(pdev, rc));
1146
1147 info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n",
1148 pdev->vendor, pdev->device,
1149 pdev->subsystem_vendor, pdev->subsystem_device);
1150
1151 mutex_init(&ctrl->crit_sect);
1152 mutex_init(&ctrl->ctrl_lock);
1153 spin_lock_init(&ctrl->lock);
1154
1155 /* setup wait queue */
1156 init_waitqueue_head(&ctrl->queue);
1157
1158 /* return PCI Controller Info */
1159 ctrl->slot_device_offset = 0;
1160 ctrl->num_slots = 1;
1161 ctrl->first_slot = slot_cap >> 19;
1162 ctrl->ctrlcap = slot_cap & 0x0000007f;
1163 1086
1164 /* Mask Hot-plug Interrupt Enable */ 1087 /* Mask Hot-plug Interrupt Enable */
1165 rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); 1088 rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word);
@@ -1280,8 +1203,6 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1280 goto abort_disable_intr; 1203 goto abort_disable_intr;
1281 } 1204 }
1282 1205
1283 ctrl->hpc_ops = &pciehp_hpc_ops;
1284
1285 return 0; 1206 return 0;
1286 1207
1287 /* We end up here for the many possible ways to fail this API. */ 1208 /* We end up here for the many possible ways to fail this API. */
@@ -1303,3 +1224,105 @@ abort_free_irq:
1303abort_free_ctlr: 1224abort_free_ctlr:
1304 return -1; 1225 return -1;
1305} 1226}
1227
1228int pcie_init(struct controller *ctrl, struct pcie_device *dev)
1229{
1230 int rc;
1231 u16 cap_reg;
1232 u32 slot_cap;
1233 int cap_base;
1234 u16 slot_status, slot_ctrl;
1235 struct pci_dev *pdev;
1236
1237 pdev = dev->port;
1238 ctrl->pci_dev = pdev; /* save pci_dev in context */
1239
1240 dbg("%s: hotplug controller vendor id 0x%x device id 0x%x\n",
1241 __FUNCTION__, pdev->vendor, pdev->device);
1242
1243 cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP);
1244 if (cap_base == 0) {
1245 dbg("%s: Can't find PCI_CAP_ID_EXP (0x10)\n", __FUNCTION__);
1246 goto abort;
1247 }
1248
1249 ctrl->cap_base = cap_base;
1250
1251 dbg("%s: pcie_cap_base %x\n", __FUNCTION__, cap_base);
1252
1253 rc = pciehp_readw(ctrl, CAPREG, &cap_reg);
1254 if (rc) {
1255 err("%s: Cannot read CAPREG register\n", __FUNCTION__);
1256 goto abort;
1257 }
1258 dbg("%s: CAPREG offset %x cap_reg %x\n",
1259 __FUNCTION__, ctrl->cap_base + CAPREG, cap_reg);
1260
1261 if (((cap_reg & SLOT_IMPL) == 0) ||
1262 (((cap_reg & DEV_PORT_TYPE) != 0x0040)
1263 && ((cap_reg & DEV_PORT_TYPE) != 0x0060))) {
1264 dbg("%s : This is not a root port or the port is not "
1265 "connected to a slot\n", __FUNCTION__);
1266 goto abort;
1267 }
1268
1269 rc = pciehp_readl(ctrl, SLOTCAP, &slot_cap);
1270 if (rc) {
1271 err("%s: Cannot read SLOTCAP register\n", __FUNCTION__);
1272 goto abort;
1273 }
1274 dbg("%s: SLOTCAP offset %x slot_cap %x\n",
1275 __FUNCTION__, ctrl->cap_base + SLOTCAP, slot_cap);
1276
1277 if (!(slot_cap & HP_CAP)) {
1278 dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__);
1279 goto abort;
1280 }
1281 /* For debugging purpose */
1282 rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
1283 if (rc) {
1284 err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__);
1285 goto abort;
1286 }
1287 dbg("%s: SLOTSTATUS offset %x slot_status %x\n",
1288 __FUNCTION__, ctrl->cap_base + SLOTSTATUS, slot_status);
1289
1290 rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
1291 if (rc) {
1292 err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
1293 goto abort;
1294 }
1295 dbg("%s: SLOTCTRL offset %x slot_ctrl %x\n",
1296 __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl);
1297
1298 for (rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++)
1299 if (pci_resource_len(pdev, rc) > 0)
1300 dbg("pci resource[%d] start=0x%llx(len=0x%llx)\n", rc,
1301 (unsigned long long)pci_resource_start(pdev, rc),
1302 (unsigned long long)pci_resource_len(pdev, rc));
1303
1304 info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n",
1305 pdev->vendor, pdev->device,
1306 pdev->subsystem_vendor, pdev->subsystem_device);
1307
1308 mutex_init(&ctrl->crit_sect);
1309 mutex_init(&ctrl->ctrl_lock);
1310 spin_lock_init(&ctrl->lock);
1311
1312 /* setup wait queue */
1313 init_waitqueue_head(&ctrl->queue);
1314
1315 /* return PCI Controller Info */
1316 ctrl->slot_device_offset = 0;
1317 ctrl->num_slots = 1;
1318 ctrl->first_slot = slot_cap >> 19;
1319 ctrl->ctrlcap = slot_cap & 0x0000007f;
1320
1321 rc = pcie_init_hardware(ctrl, dev);
1322 if (rc == 0) {
1323 ctrl->hpc_ops = &pciehp_hpc_ops;
1324 return 0;
1325 }
1326abort:
1327 return -1;
1328}