diff options
| -rw-r--r-- | drivers/pci/hotplug/shpchp_hpc.c | 192 |
1 files changed, 112 insertions, 80 deletions
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 66123cf4deaa..3abeb54964ae 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c | |||
| @@ -208,6 +208,49 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs); | |||
| 208 | static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds); | 208 | static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds); |
| 209 | static int hpc_check_cmd_status(struct controller *ctrl); | 209 | static int hpc_check_cmd_status(struct controller *ctrl); |
| 210 | 210 | ||
| 211 | static inline u8 shpc_readb(struct controller *ctrl, int reg) | ||
| 212 | { | ||
| 213 | return readb(ctrl->hpc_ctlr_handle->creg + reg); | ||
| 214 | } | ||
| 215 | |||
| 216 | static inline void shpc_writeb(struct controller *ctrl, int reg, u8 val) | ||
| 217 | { | ||
| 218 | writeb(val, ctrl->hpc_ctlr_handle->creg + reg); | ||
| 219 | } | ||
| 220 | |||
| 221 | static inline u16 shpc_readw(struct controller *ctrl, int reg) | ||
| 222 | { | ||
| 223 | return readw(ctrl->hpc_ctlr_handle->creg + reg); | ||
| 224 | } | ||
| 225 | |||
| 226 | static inline void shpc_writew(struct controller *ctrl, int reg, u16 val) | ||
| 227 | { | ||
| 228 | writew(val, ctrl->hpc_ctlr_handle->creg + reg); | ||
| 229 | } | ||
| 230 | |||
| 231 | static inline u32 shpc_readl(struct controller *ctrl, int reg) | ||
| 232 | { | ||
| 233 | return readl(ctrl->hpc_ctlr_handle->creg + reg); | ||
| 234 | } | ||
| 235 | |||
| 236 | static inline void shpc_writel(struct controller *ctrl, int reg, u32 val) | ||
| 237 | { | ||
| 238 | writel(val, ctrl->hpc_ctlr_handle->creg + reg); | ||
| 239 | } | ||
| 240 | |||
| 241 | static inline int shpc_indirect_read(struct controller *ctrl, int index, | ||
| 242 | u32 *value) | ||
| 243 | { | ||
| 244 | int rc; | ||
| 245 | u32 cap_offset = ctrl->cap_offset; | ||
| 246 | struct pci_dev *pdev = ctrl->pci_dev; | ||
| 247 | |||
| 248 | rc = pci_write_config_byte(pdev, cap_offset + DWORD_SELECT, index); | ||
| 249 | if (rc) | ||
| 250 | return rc; | ||
| 251 | return pci_read_config_dword(pdev, cap_offset + DWORD_DATA, value); | ||
| 252 | } | ||
| 253 | |||
| 211 | /* This is the interrupt polling timeout function. */ | 254 | /* This is the interrupt polling timeout function. */ |
| 212 | static void int_poll_timeout(unsigned long lphp_ctlr) | 255 | static void int_poll_timeout(unsigned long lphp_ctlr) |
| 213 | { | 256 | { |
| @@ -273,6 +316,7 @@ static inline int shpc_wait_cmd(struct controller *ctrl) | |||
| 273 | static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) | 316 | static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) |
| 274 | { | 317 | { |
| 275 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 318 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; |
| 319 | struct controller *ctrl = slot->ctrl; | ||
| 276 | u16 cmd_status; | 320 | u16 cmd_status; |
| 277 | int retval = 0; | 321 | int retval = 0; |
| 278 | u16 temp_word; | 322 | u16 temp_word; |
| @@ -289,7 +333,7 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) | |||
| 289 | } | 333 | } |
| 290 | 334 | ||
| 291 | for (i = 0; i < 10; i++) { | 335 | for (i = 0; i < 10; i++) { |
| 292 | cmd_status = readw(php_ctlr->creg + CMD_STATUS); | 336 | cmd_status = shpc_readw(ctrl, CMD_STATUS); |
| 293 | 337 | ||
| 294 | if (!(cmd_status & 0x1)) | 338 | if (!(cmd_status & 0x1)) |
| 295 | break; | 339 | break; |
| @@ -297,7 +341,7 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) | |||
| 297 | msleep(100); | 341 | msleep(100); |
| 298 | } | 342 | } |
| 299 | 343 | ||
| 300 | cmd_status = readw(php_ctlr->creg + CMD_STATUS); | 344 | cmd_status = shpc_readw(ctrl, CMD_STATUS); |
| 301 | 345 | ||
| 302 | if (cmd_status & 0x1) { | 346 | if (cmd_status & 0x1) { |
| 303 | /* After 1 sec and and the controller is still busy */ | 347 | /* After 1 sec and and the controller is still busy */ |
| @@ -314,7 +358,7 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) | |||
| 314 | * command. | 358 | * command. |
| 315 | */ | 359 | */ |
| 316 | slot->ctrl->cmd_busy = 1; | 360 | slot->ctrl->cmd_busy = 1; |
| 317 | writew(temp_word, php_ctlr->creg + CMD); | 361 | shpc_writew(ctrl, CMD, temp_word); |
| 318 | 362 | ||
| 319 | /* | 363 | /* |
| 320 | * Wait for command completion. | 364 | * Wait for command completion. |
| @@ -338,7 +382,6 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) | |||
| 338 | 382 | ||
| 339 | static int hpc_check_cmd_status(struct controller *ctrl) | 383 | static int hpc_check_cmd_status(struct controller *ctrl) |
| 340 | { | 384 | { |
| 341 | struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; | ||
| 342 | u16 cmd_status; | 385 | u16 cmd_status; |
| 343 | int retval = 0; | 386 | int retval = 0; |
| 344 | 387 | ||
| @@ -349,7 +392,7 @@ static int hpc_check_cmd_status(struct controller *ctrl) | |||
| 349 | return -1; | 392 | return -1; |
| 350 | } | 393 | } |
| 351 | 394 | ||
| 352 | cmd_status = readw(php_ctlr->creg + CMD_STATUS) & 0x000F; | 395 | cmd_status = shpc_readw(ctrl, CMD_STATUS) & 0x000F; |
| 353 | 396 | ||
| 354 | switch (cmd_status >> 1) { | 397 | switch (cmd_status >> 1) { |
| 355 | case 0: | 398 | case 0: |
| @@ -378,7 +421,7 @@ static int hpc_check_cmd_status(struct controller *ctrl) | |||
| 378 | 421 | ||
| 379 | static int hpc_get_attention_status(struct slot *slot, u8 *status) | 422 | static int hpc_get_attention_status(struct slot *slot, u8 *status) |
| 380 | { | 423 | { |
| 381 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 424 | struct controller *ctrl = slot->ctrl; |
| 382 | u32 slot_reg; | 425 | u32 slot_reg; |
| 383 | u16 slot_status; | 426 | u16 slot_status; |
| 384 | u8 atten_led_state; | 427 | u8 atten_led_state; |
| @@ -390,7 +433,7 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status) | |||
| 390 | return -1; | 433 | return -1; |
| 391 | } | 434 | } |
| 392 | 435 | ||
| 393 | slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot)); | 436 | slot_reg = shpc_readl(ctrl, SLOT1 + 4*(slot->hp_slot)); |
| 394 | slot_status = (u16) slot_reg; | 437 | slot_status = (u16) slot_reg; |
| 395 | atten_led_state = (slot_status & 0x0030) >> 4; | 438 | atten_led_state = (slot_status & 0x0030) >> 4; |
| 396 | 439 | ||
| @@ -418,7 +461,7 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status) | |||
| 418 | 461 | ||
| 419 | static int hpc_get_power_status(struct slot * slot, u8 *status) | 462 | static int hpc_get_power_status(struct slot * slot, u8 *status) |
| 420 | { | 463 | { |
| 421 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 464 | struct controller *ctrl = slot->ctrl; |
| 422 | u32 slot_reg; | 465 | u32 slot_reg; |
| 423 | u16 slot_status; | 466 | u16 slot_status; |
| 424 | u8 slot_state; | 467 | u8 slot_state; |
| @@ -431,7 +474,7 @@ static int hpc_get_power_status(struct slot * slot, u8 *status) | |||
| 431 | return -1; | 474 | return -1; |
| 432 | } | 475 | } |
| 433 | 476 | ||
| 434 | slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot)); | 477 | slot_reg = shpc_readl(ctrl, SLOT1 + 4*(slot->hp_slot)); |
| 435 | slot_status = (u16) slot_reg; | 478 | slot_status = (u16) slot_reg; |
| 436 | slot_state = (slot_status & 0x0003); | 479 | slot_state = (slot_status & 0x0003); |
| 437 | 480 | ||
| @@ -460,7 +503,7 @@ static int hpc_get_power_status(struct slot * slot, u8 *status) | |||
| 460 | 503 | ||
| 461 | static int hpc_get_latch_status(struct slot *slot, u8 *status) | 504 | static int hpc_get_latch_status(struct slot *slot, u8 *status) |
| 462 | { | 505 | { |
| 463 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 506 | struct controller *ctrl = slot->ctrl; |
| 464 | u32 slot_reg; | 507 | u32 slot_reg; |
| 465 | u16 slot_status; | 508 | u16 slot_status; |
| 466 | 509 | ||
| @@ -471,7 +514,7 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status) | |||
| 471 | return -1; | 514 | return -1; |
| 472 | } | 515 | } |
| 473 | 516 | ||
| 474 | slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot)); | 517 | slot_reg = shpc_readl(ctrl, SLOT1 + 4*(slot->hp_slot)); |
| 475 | slot_status = (u16)slot_reg; | 518 | slot_status = (u16)slot_reg; |
| 476 | 519 | ||
| 477 | *status = ((slot_status & 0x0100) == 0) ? 0 : 1; /* 0 -> close; 1 -> open */ | 520 | *status = ((slot_status & 0x0100) == 0) ? 0 : 1; /* 0 -> close; 1 -> open */ |
| @@ -483,7 +526,7 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status) | |||
| 483 | 526 | ||
| 484 | static int hpc_get_adapter_status(struct slot *slot, u8 *status) | 527 | static int hpc_get_adapter_status(struct slot *slot, u8 *status) |
| 485 | { | 528 | { |
| 486 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 529 | struct controller *ctrl = slot->ctrl; |
| 487 | u32 slot_reg; | 530 | u32 slot_reg; |
| 488 | u16 slot_status; | 531 | u16 slot_status; |
| 489 | u8 card_state; | 532 | u8 card_state; |
| @@ -495,7 +538,7 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status) | |||
| 495 | return -1; | 538 | return -1; |
| 496 | } | 539 | } |
| 497 | 540 | ||
| 498 | slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot)); | 541 | slot_reg = shpc_readl(ctrl, SLOT1 + 4*(slot->hp_slot)); |
| 499 | slot_status = (u16)slot_reg; | 542 | slot_status = (u16)slot_reg; |
| 500 | card_state = (u8)((slot_status & 0x0C00) >> 10); | 543 | card_state = (u8)((slot_status & 0x0C00) >> 10); |
| 501 | *status = (card_state != 0x3) ? 1 : 0; | 544 | *status = (card_state != 0x3) ? 1 : 0; |
| @@ -506,7 +549,7 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status) | |||
| 506 | 549 | ||
| 507 | static int hpc_get_prog_int(struct slot *slot, u8 *prog_int) | 550 | static int hpc_get_prog_int(struct slot *slot, u8 *prog_int) |
| 508 | { | 551 | { |
| 509 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 552 | struct controller *ctrl = slot->ctrl; |
| 510 | 553 | ||
| 511 | DBG_ENTER_ROUTINE | 554 | DBG_ENTER_ROUTINE |
| 512 | 555 | ||
| @@ -515,7 +558,7 @@ static int hpc_get_prog_int(struct slot *slot, u8 *prog_int) | |||
| 515 | return -1; | 558 | return -1; |
| 516 | } | 559 | } |
| 517 | 560 | ||
| 518 | *prog_int = readb(php_ctlr->creg + PROG_INTERFACE); | 561 | *prog_int = shpc_readb(ctrl, PROG_INTERFACE); |
| 519 | 562 | ||
| 520 | DBG_LEAVE_ROUTINE | 563 | DBG_LEAVE_ROUTINE |
| 521 | return 0; | 564 | return 0; |
| @@ -524,8 +567,8 @@ static int hpc_get_prog_int(struct slot *slot, u8 *prog_int) | |||
| 524 | static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value) | 567 | static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value) |
| 525 | { | 568 | { |
| 526 | int retval = 0; | 569 | int retval = 0; |
| 527 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 570 | struct controller *ctrl = slot->ctrl; |
| 528 | u32 slot_reg = readl(php_ctlr->creg + SLOT1 + 4 * slot->hp_slot); | 571 | u32 slot_reg = shpc_readl(ctrl, SLOT1 + 4 * slot->hp_slot); |
| 529 | u8 pcix_cap = (slot_reg >> 12) & 7; | 572 | u8 pcix_cap = (slot_reg >> 12) & 7; |
| 530 | u8 m66_cap = (slot_reg >> 9) & 1; | 573 | u8 m66_cap = (slot_reg >> 9) & 1; |
| 531 | 574 | ||
| @@ -564,7 +607,7 @@ static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value) | |||
| 564 | 607 | ||
| 565 | static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode) | 608 | static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode) |
| 566 | { | 609 | { |
| 567 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 610 | struct controller *ctrl = slot->ctrl; |
| 568 | u16 sec_bus_status; | 611 | u16 sec_bus_status; |
| 569 | u8 pi; | 612 | u8 pi; |
| 570 | int retval = 0; | 613 | int retval = 0; |
| @@ -576,8 +619,8 @@ static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode) | |||
| 576 | return -1; | 619 | return -1; |
| 577 | } | 620 | } |
| 578 | 621 | ||
| 579 | pi = readb(php_ctlr->creg + PROG_INTERFACE); | 622 | pi = shpc_readb(ctrl, PROG_INTERFACE); |
| 580 | sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG); | 623 | sec_bus_status = shpc_readw(ctrl, SEC_BUS_CONFIG); |
| 581 | 624 | ||
| 582 | if (pi == 2) { | 625 | if (pi == 2) { |
| 583 | *mode = (sec_bus_status & 0x0100) >> 8; | 626 | *mode = (sec_bus_status & 0x0100) >> 8; |
| @@ -593,7 +636,7 @@ static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode) | |||
| 593 | 636 | ||
| 594 | static int hpc_query_power_fault(struct slot * slot) | 637 | static int hpc_query_power_fault(struct slot * slot) |
| 595 | { | 638 | { |
| 596 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 639 | struct controller *ctrl = slot->ctrl; |
| 597 | u32 slot_reg; | 640 | u32 slot_reg; |
| 598 | u16 slot_status; | 641 | u16 slot_status; |
| 599 | u8 pwr_fault_state, status; | 642 | u8 pwr_fault_state, status; |
| @@ -605,7 +648,7 @@ static int hpc_query_power_fault(struct slot * slot) | |||
| 605 | return -1; | 648 | return -1; |
| 606 | } | 649 | } |
| 607 | 650 | ||
| 608 | slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot)); | 651 | slot_reg = shpc_readl(ctrl, SLOT1 + 4*(slot->hp_slot)); |
| 609 | slot_status = (u16) slot_reg; | 652 | slot_status = (u16) slot_reg; |
| 610 | pwr_fault_state = (slot_status & 0x0040) >> 7; | 653 | pwr_fault_state = (slot_status & 0x0040) >> 7; |
| 611 | status = (pwr_fault_state == 1) ? 0 : 1; | 654 | status = (pwr_fault_state == 1) ? 0 : 1; |
| @@ -724,7 +767,7 @@ int shpc_get_ctlr_slot_config(struct controller *ctrl, | |||
| 724 | int *updown, /* physical_slot_num increament: 1 or -1 */ | 767 | int *updown, /* physical_slot_num increament: 1 or -1 */ |
| 725 | int *flags) | 768 | int *flags) |
| 726 | { | 769 | { |
| 727 | struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; | 770 | u32 slot_config; |
| 728 | 771 | ||
| 729 | DBG_ENTER_ROUTINE | 772 | DBG_ENTER_ROUTINE |
| 730 | 773 | ||
| @@ -733,12 +776,13 @@ int shpc_get_ctlr_slot_config(struct controller *ctrl, | |||
| 733 | return -1; | 776 | return -1; |
| 734 | } | 777 | } |
| 735 | 778 | ||
| 736 | *first_device_num = php_ctlr->slot_device_offset; /* Obtained in shpc_init() */ | 779 | slot_config = shpc_readl(ctrl, SLOT_CONFIG); |
| 737 | *num_ctlr_slots = php_ctlr->num_slots; /* Obtained in shpc_init() */ | 780 | *first_device_num = (slot_config & FIRST_DEV_NUM) >> 8; |
| 781 | *num_ctlr_slots = slot_config & SLOT_NUM; | ||
| 782 | *physical_slot_num = (slot_config & PSN) >> 16; | ||
| 783 | *updown = ((slot_config & UPDOWN) >> 29) ? 1 : -1; | ||
| 738 | 784 | ||
| 739 | *physical_slot_num = (readl(php_ctlr->creg + SLOT_CONFIG) & PSN) >> 16; | ||
| 740 | dbg("%s: physical_slot_num = %x\n", __FUNCTION__, *physical_slot_num); | 785 | dbg("%s: physical_slot_num = %x\n", __FUNCTION__, *physical_slot_num); |
| 741 | *updown = ((readl(php_ctlr->creg + SLOT_CONFIG) & UPDOWN ) >> 29) ? 1 : -1; | ||
| 742 | 786 | ||
| 743 | DBG_LEAVE_ROUTINE | 787 | DBG_LEAVE_ROUTINE |
| 744 | return 0; | 788 | return 0; |
| @@ -761,7 +805,7 @@ static void hpc_release_ctlr(struct controller *ctrl) | |||
| 761 | * Mask all slot event interrupts | 805 | * Mask all slot event interrupts |
| 762 | */ | 806 | */ |
| 763 | for (i = 0; i < ctrl->num_slots; i++) | 807 | for (i = 0; i < ctrl->num_slots; i++) |
| 764 | writel(0xffff3fff, php_ctlr->creg + SLOT1 + (4 * i)); | 808 | shpc_writel(ctrl, SLOT1 + (4 * i), 0xffff3fff); |
| 765 | 809 | ||
| 766 | cleanup_slots(ctrl); | 810 | cleanup_slots(ctrl); |
| 767 | 811 | ||
| @@ -901,12 +945,12 @@ static int hpc_slot_disable(struct slot * slot) | |||
| 901 | static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) | 945 | static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) |
| 902 | { | 946 | { |
| 903 | int retval; | 947 | int retval; |
| 904 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 948 | struct controller *ctrl = slot->ctrl; |
| 905 | u8 pi, cmd; | 949 | u8 pi, cmd; |
| 906 | 950 | ||
| 907 | DBG_ENTER_ROUTINE | 951 | DBG_ENTER_ROUTINE |
| 908 | 952 | ||
| 909 | pi = readb(php_ctlr->creg + PROG_INTERFACE); | 953 | pi = shpc_readb(ctrl, PROG_INTERFACE); |
| 910 | if ((pi == 1) && (value > PCI_SPEED_133MHz_PCIX)) | 954 | if ((pi == 1) && (value > PCI_SPEED_133MHz_PCIX)) |
| 911 | return -EINVAL; | 955 | return -EINVAL; |
| 912 | 956 | ||
| @@ -992,7 +1036,7 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) | |||
| 992 | return IRQ_NONE; | 1036 | return IRQ_NONE; |
| 993 | 1037 | ||
| 994 | /* Check to see if it was our interrupt */ | 1038 | /* Check to see if it was our interrupt */ |
| 995 | intr_loc = readl(php_ctlr->creg + INTR_LOC); | 1039 | intr_loc = shpc_readl(ctrl, INTR_LOC); |
| 996 | 1040 | ||
| 997 | if (!intr_loc) | 1041 | if (!intr_loc) |
| 998 | return IRQ_NONE; | 1042 | return IRQ_NONE; |
| @@ -1001,11 +1045,11 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) | |||
| 1001 | if(!shpchp_poll_mode) { | 1045 | if(!shpchp_poll_mode) { |
| 1002 | /* Mask Global Interrupt Mask - see implementation note on p. 139 */ | 1046 | /* Mask Global Interrupt Mask - see implementation note on p. 139 */ |
| 1003 | /* of SHPC spec rev 1.0*/ | 1047 | /* of SHPC spec rev 1.0*/ |
| 1004 | temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); | 1048 | temp_dword = shpc_readl(ctrl, SERR_INTR_ENABLE); |
| 1005 | temp_dword |= 0x00000001; | 1049 | temp_dword |= 0x00000001; |
| 1006 | writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); | 1050 | shpc_writel(ctrl, SERR_INTR_ENABLE, temp_dword); |
| 1007 | 1051 | ||
| 1008 | intr_loc2 = readl(php_ctlr->creg + INTR_LOC); | 1052 | intr_loc2 = shpc_readl(ctrl, INTR_LOC); |
| 1009 | dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); | 1053 | dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); |
| 1010 | } | 1054 | } |
| 1011 | 1055 | ||
| @@ -1015,9 +1059,9 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) | |||
| 1015 | * RO only - clear by writing 1 to the Command Completion | 1059 | * RO only - clear by writing 1 to the Command Completion |
| 1016 | * Detect bit in Controller SERR-INT register | 1060 | * Detect bit in Controller SERR-INT register |
| 1017 | */ | 1061 | */ |
| 1018 | temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); | 1062 | temp_dword = shpc_readl(ctrl, SERR_INTR_ENABLE); |
| 1019 | temp_dword &= 0xfffdffff; | 1063 | temp_dword &= 0xfffdffff; |
| 1020 | writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); | 1064 | shpc_writel(ctrl, SERR_INTR_ENABLE, temp_dword); |
| 1021 | ctrl->cmd_busy = 0; | 1065 | ctrl->cmd_busy = 0; |
| 1022 | wake_up_interruptible(&ctrl->queue); | 1066 | wake_up_interruptible(&ctrl->queue); |
| 1023 | } | 1067 | } |
| @@ -1028,7 +1072,7 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) | |||
| 1028 | for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { | 1072 | for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { |
| 1029 | /* To find out which slot has interrupt pending */ | 1073 | /* To find out which slot has interrupt pending */ |
| 1030 | if ((intr_loc >> hp_slot) & 0x01) { | 1074 | if ((intr_loc >> hp_slot) & 0x01) { |
| 1031 | temp_dword = readl(php_ctlr->creg + SLOT1 + (4*hp_slot)); | 1075 | temp_dword = shpc_readl(ctrl, SLOT1 + (4*hp_slot)); |
| 1032 | dbg("%s: Slot %x with intr, slot register = %x\n", | 1076 | dbg("%s: Slot %x with intr, slot register = %x\n", |
| 1033 | __FUNCTION__, hp_slot, temp_dword); | 1077 | __FUNCTION__, hp_slot, temp_dword); |
| 1034 | temp_byte = (temp_dword >> 16) & 0xFF; | 1078 | temp_byte = (temp_dword >> 16) & 0xFF; |
| @@ -1047,18 +1091,18 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) | |||
| 1047 | 1091 | ||
| 1048 | /* Clear all slot events */ | 1092 | /* Clear all slot events */ |
| 1049 | temp_dword = 0xe01f3fff; | 1093 | temp_dword = 0xe01f3fff; |
| 1050 | writel(temp_dword, php_ctlr->creg + SLOT1 + (4*hp_slot)); | 1094 | shpc_writel(ctrl, SLOT1 + (4*hp_slot), temp_dword); |
| 1051 | 1095 | ||
| 1052 | intr_loc2 = readl(php_ctlr->creg + INTR_LOC); | 1096 | intr_loc2 = shpc_readl(ctrl, INTR_LOC); |
| 1053 | dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); | 1097 | dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); |
| 1054 | } | 1098 | } |
| 1055 | } | 1099 | } |
| 1056 | out: | 1100 | out: |
| 1057 | if (!shpchp_poll_mode) { | 1101 | if (!shpchp_poll_mode) { |
| 1058 | /* Unmask Global Interrupt Mask */ | 1102 | /* Unmask Global Interrupt Mask */ |
| 1059 | temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); | 1103 | temp_dword = shpc_readl(ctrl, SERR_INTR_ENABLE); |
| 1060 | temp_dword &= 0xfffffffe; | 1104 | temp_dword &= 0xfffffffe; |
| 1061 | writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); | 1105 | shpc_writel(ctrl, SERR_INTR_ENABLE, temp_dword); |
| 1062 | } | 1106 | } |
| 1063 | 1107 | ||
| 1064 | return IRQ_HANDLED; | 1108 | return IRQ_HANDLED; |
| @@ -1067,11 +1111,11 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) | |||
| 1067 | static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) | 1111 | static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) |
| 1068 | { | 1112 | { |
| 1069 | int retval = 0; | 1113 | int retval = 0; |
| 1070 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 1114 | struct controller *ctrl = slot->ctrl; |
| 1071 | enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; | 1115 | enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; |
| 1072 | u8 pi = readb(php_ctlr->creg + PROG_INTERFACE); | 1116 | u8 pi = shpc_readb(ctrl, PROG_INTERFACE); |
| 1073 | u32 slot_avail1 = readl(php_ctlr->creg + SLOT_AVAIL1); | 1117 | u32 slot_avail1 = shpc_readl(ctrl, SLOT_AVAIL1); |
| 1074 | u32 slot_avail2 = readl(php_ctlr->creg + SLOT_AVAIL2); | 1118 | u32 slot_avail2 = shpc_readl(ctrl, SLOT_AVAIL2); |
| 1075 | 1119 | ||
| 1076 | DBG_ENTER_ROUTINE | 1120 | DBG_ENTER_ROUTINE |
| 1077 | 1121 | ||
| @@ -1114,10 +1158,10 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) | |||
| 1114 | static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value) | 1158 | static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value) |
| 1115 | { | 1159 | { |
| 1116 | int retval = 0; | 1160 | int retval = 0; |
| 1117 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 1161 | struct controller *ctrl = slot->ctrl; |
| 1118 | enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; | 1162 | enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; |
| 1119 | u16 sec_bus_reg = readw(php_ctlr->creg + SEC_BUS_CONFIG); | 1163 | u16 sec_bus_reg = shpc_readw(ctrl, SEC_BUS_CONFIG); |
| 1120 | u8 pi = readb(php_ctlr->creg + PROG_INTERFACE); | 1164 | u8 pi = shpc_readb(ctrl, PROG_INTERFACE); |
| 1121 | u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7); | 1165 | u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7); |
| 1122 | 1166 | ||
| 1123 | DBG_ENTER_ROUTINE | 1167 | DBG_ENTER_ROUTINE |
| @@ -1206,19 +1250,6 @@ static struct hpc_ops shpchp_hpc_ops = { | |||
| 1206 | .release_ctlr = hpc_release_ctlr, | 1250 | .release_ctlr = hpc_release_ctlr, |
| 1207 | }; | 1251 | }; |
| 1208 | 1252 | ||
| 1209 | inline static int shpc_indirect_creg_read(struct controller *ctrl, int index, | ||
| 1210 | u32 *value) | ||
| 1211 | { | ||
| 1212 | int rc; | ||
| 1213 | u32 cap_offset = ctrl->cap_offset; | ||
| 1214 | struct pci_dev *pdev = ctrl->pci_dev; | ||
| 1215 | |||
| 1216 | rc = pci_write_config_byte(pdev, cap_offset + DWORD_SELECT, index); | ||
| 1217 | if (rc) | ||
| 1218 | return rc; | ||
| 1219 | return pci_read_config_dword(pdev, cap_offset + DWORD_DATA, value); | ||
| 1220 | } | ||
| 1221 | |||
| 1222 | int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | 1253 | int shpc_init(struct controller * ctrl, struct pci_dev * pdev) |
| 1223 | { | 1254 | { |
| 1224 | struct php_ctlr_state_s *php_ctlr, *p; | 1255 | struct php_ctlr_state_s *php_ctlr, *p; |
| @@ -1227,7 +1258,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
| 1227 | u8 hp_slot; | 1258 | u8 hp_slot; |
| 1228 | static int first = 1; | 1259 | static int first = 1; |
| 1229 | u32 shpc_base_offset; | 1260 | u32 shpc_base_offset; |
| 1230 | u32 tempdword, slot_reg; | 1261 | u32 tempdword, slot_reg, slot_config; |
| 1231 | u8 i; | 1262 | u8 i; |
| 1232 | 1263 | ||
| 1233 | DBG_ENTER_ROUTINE | 1264 | DBG_ENTER_ROUTINE |
| @@ -1257,13 +1288,13 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
| 1257 | } | 1288 | } |
| 1258 | dbg("%s: cap_offset = %x\n", __FUNCTION__, ctrl->cap_offset); | 1289 | dbg("%s: cap_offset = %x\n", __FUNCTION__, ctrl->cap_offset); |
| 1259 | 1290 | ||
| 1260 | rc = shpc_indirect_creg_read(ctrl, 0, &shpc_base_offset); | 1291 | rc = shpc_indirect_read(ctrl, 0, &shpc_base_offset); |
| 1261 | if (rc) { | 1292 | if (rc) { |
| 1262 | err("%s: cannot read base_offset\n", __FUNCTION__); | 1293 | err("%s: cannot read base_offset\n", __FUNCTION__); |
| 1263 | goto abort_free_ctlr; | 1294 | goto abort_free_ctlr; |
| 1264 | } | 1295 | } |
| 1265 | 1296 | ||
| 1266 | rc = shpc_indirect_creg_read(ctrl, 3, &tempdword); | 1297 | rc = shpc_indirect_read(ctrl, 3, &tempdword); |
| 1267 | if (rc) { | 1298 | if (rc) { |
| 1268 | err("%s: cannot read slot config\n", __FUNCTION__); | 1299 | err("%s: cannot read slot config\n", __FUNCTION__); |
| 1269 | goto abort_free_ctlr; | 1300 | goto abort_free_ctlr; |
| @@ -1272,7 +1303,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
| 1272 | dbg("%s: num_slots (indirect) %x\n", __FUNCTION__, num_slots); | 1303 | dbg("%s: num_slots (indirect) %x\n", __FUNCTION__, num_slots); |
| 1273 | 1304 | ||
| 1274 | for (i = 0; i < 9 + num_slots; i++) { | 1305 | for (i = 0; i < 9 + num_slots; i++) { |
| 1275 | rc = shpc_indirect_creg_read(ctrl, i, &tempdword); | 1306 | rc = shpc_indirect_read(ctrl, i, &tempdword); |
| 1276 | if (rc) { | 1307 | if (rc) { |
| 1277 | err("%s: cannot read creg (index = %d)\n", | 1308 | err("%s: cannot read creg (index = %d)\n", |
| 1278 | __FUNCTION__, i); | 1309 | __FUNCTION__, i); |
| @@ -1326,29 +1357,33 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
| 1326 | php_ctlr->power_fault_callback = shpchp_handle_power_fault; | 1357 | php_ctlr->power_fault_callback = shpchp_handle_power_fault; |
| 1327 | php_ctlr->callback_instance_id = instance_id; | 1358 | php_ctlr->callback_instance_id = instance_id; |
| 1328 | 1359 | ||
| 1360 | ctrl->hpc_ctlr_handle = php_ctlr; | ||
| 1361 | ctrl->hpc_ops = &shpchp_hpc_ops; | ||
| 1362 | |||
| 1329 | /* Return PCI Controller Info */ | 1363 | /* Return PCI Controller Info */ |
| 1330 | php_ctlr->slot_device_offset = (readl(php_ctlr->creg + SLOT_CONFIG) & FIRST_DEV_NUM ) >> 8; | 1364 | slot_config = shpc_readl(ctrl, SLOT_CONFIG); |
| 1331 | php_ctlr->num_slots = readl(php_ctlr->creg + SLOT_CONFIG) & SLOT_NUM; | 1365 | php_ctlr->slot_device_offset = (slot_config & FIRST_DEV_NUM) >> 8; |
| 1366 | php_ctlr->num_slots = slot_config & SLOT_NUM; | ||
| 1332 | dbg("%s: slot_device_offset %x\n", __FUNCTION__, php_ctlr->slot_device_offset); | 1367 | dbg("%s: slot_device_offset %x\n", __FUNCTION__, php_ctlr->slot_device_offset); |
| 1333 | dbg("%s: num_slots %x\n", __FUNCTION__, php_ctlr->num_slots); | 1368 | dbg("%s: num_slots %x\n", __FUNCTION__, php_ctlr->num_slots); |
| 1334 | 1369 | ||
| 1335 | /* Mask Global Interrupt Mask & Command Complete Interrupt Mask */ | 1370 | /* Mask Global Interrupt Mask & Command Complete Interrupt Mask */ |
| 1336 | tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE); | 1371 | tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE); |
| 1337 | dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); | 1372 | dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); |
| 1338 | tempdword = 0x0003000f; | 1373 | tempdword = 0x0003000f; |
| 1339 | writel(tempdword, php_ctlr->creg + SERR_INTR_ENABLE); | 1374 | shpc_writel(ctrl, SERR_INTR_ENABLE, tempdword); |
| 1340 | tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE); | 1375 | tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE); |
| 1341 | dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); | 1376 | dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); |
| 1342 | 1377 | ||
| 1343 | /* Mask the MRL sensor SERR Mask of individual slot in | 1378 | /* Mask the MRL sensor SERR Mask of individual slot in |
| 1344 | * Slot SERR-INT Mask & clear all the existing event if any | 1379 | * Slot SERR-INT Mask & clear all the existing event if any |
| 1345 | */ | 1380 | */ |
| 1346 | for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) { | 1381 | for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) { |
| 1347 | slot_reg = readl(php_ctlr->creg + SLOT1 + 4*hp_slot ); | 1382 | slot_reg = shpc_readl(ctrl, SLOT1 + 4*hp_slot ); |
| 1348 | dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__, | 1383 | dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__, |
| 1349 | hp_slot, slot_reg); | 1384 | hp_slot, slot_reg); |
| 1350 | tempdword = 0xffff3fff; | 1385 | tempdword = 0xffff3fff; |
| 1351 | writel(tempdword, php_ctlr->creg + SLOT1 + (4*hp_slot)); | 1386 | shpc_writel(ctrl, SLOT1 + (4*hp_slot), tempdword); |
| 1352 | } | 1387 | } |
| 1353 | 1388 | ||
| 1354 | if (shpchp_poll_mode) {/* Install interrupt polling code */ | 1389 | if (shpchp_poll_mode) {/* Install interrupt polling code */ |
| @@ -1392,24 +1427,21 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
| 1392 | } | 1427 | } |
| 1393 | spin_unlock(&list_lock); | 1428 | spin_unlock(&list_lock); |
| 1394 | 1429 | ||
| 1395 | |||
| 1396 | ctlr_seq_num++; | 1430 | ctlr_seq_num++; |
| 1397 | ctrl->hpc_ctlr_handle = php_ctlr; | ||
| 1398 | ctrl->hpc_ops = &shpchp_hpc_ops; | ||
| 1399 | 1431 | ||
| 1400 | for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) { | 1432 | for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) { |
| 1401 | slot_reg = readl(php_ctlr->creg + SLOT1 + 4*hp_slot ); | 1433 | slot_reg = shpc_readl(ctrl, SLOT1 + 4*hp_slot ); |
| 1402 | dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__, | 1434 | dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__, |
| 1403 | hp_slot, slot_reg); | 1435 | hp_slot, slot_reg); |
| 1404 | tempdword = 0xe01f3fff; | 1436 | tempdword = 0xe01f3fff; |
| 1405 | writel(tempdword, php_ctlr->creg + SLOT1 + (4*hp_slot)); | 1437 | shpc_writel(ctrl, SLOT1 + (4*hp_slot), tempdword); |
| 1406 | } | 1438 | } |
| 1407 | if (!shpchp_poll_mode) { | 1439 | if (!shpchp_poll_mode) { |
| 1408 | /* Unmask all general input interrupts and SERR */ | 1440 | /* Unmask all general input interrupts and SERR */ |
| 1409 | tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE); | 1441 | tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE); |
| 1410 | tempdword = 0x0000000a; | 1442 | tempdword = 0x0000000a; |
| 1411 | writel(tempdword, php_ctlr->creg + SERR_INTR_ENABLE); | 1443 | shpc_writel(ctrl, SERR_INTR_ENABLE, tempdword); |
| 1412 | tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE); | 1444 | tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE); |
| 1413 | dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); | 1445 | dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); |
| 1414 | } | 1446 | } |
| 1415 | 1447 | ||
