30 #include <linux/module.h>
31 #include <linux/kernel.h>
32 #include <linux/types.h>
33 #include <linux/slab.h>
34 #include <linux/pci.h>
39 static int shpchp_enable_slot(
struct slot *p_slot);
40 static int shpchp_disable_slot(
struct slot *p_slot);
65 ctrl_dbg(ctrl,
"Attention button interrupt received\n");
73 ctrl_info(ctrl,
"Button pressed on Slot(%s)\n", slot_name(p_slot));
76 queue_interrupt_event(p_slot, event_type);
89 ctrl_dbg(ctrl,
"Switch interrupt received\n");
93 p_slot->
hpc_ops->get_latch_status(p_slot, &getstatus);
94 ctrl_dbg(ctrl,
"Card present %x Power status %x\n",
101 ctrl_info(ctrl,
"Latch open on Slot(%s)\n", slot_name(p_slot));
105 ctrl_err(ctrl,
"Surprise Removal of card\n");
111 ctrl_info(ctrl,
"Latch close on Slot(%s)\n", slot_name(p_slot));
115 queue_interrupt_event(p_slot, event_type);
126 ctrl_dbg(ctrl,
"Presence/Notify input change\n");
138 ctrl_info(ctrl,
"Card present on Slot(%s)\n",
145 ctrl_info(ctrl,
"Card not present on Slot(%s)\n",
150 queue_interrupt_event(p_slot, event_type);
161 ctrl_dbg(ctrl,
"Power fault interrupt received\n");
165 if ( !(p_slot->
hpc_ops->query_power_fault(p_slot))) {
169 ctrl_info(ctrl,
"Power fault cleared on Slot(%s)\n",
177 ctrl_info(ctrl,
"Power fault on Slot(%s)\n", slot_name(p_slot));
181 ctrl_info(ctrl,
"Power fault bit %x set\n", hp_slot);
184 queue_interrupt_event(p_slot, event_type);
197 ctrl_dbg(ctrl,
"Change speed to %d\n", speed);
198 if ((rc = p_slot->
hpc_ops->set_bus_speed_mode(p_slot, speed))) {
199 ctrl_err(ctrl,
"%s: Issue of set bus speed mode command "
200 "failed\n", __func__);
206 static int fix_bus_speed(
struct controller *ctrl,
struct slot *pslot,
218 ctrl_err(ctrl,
"Speed of bus %x and adapter %x "
219 "mismatch\n", bsp, asp);
227 rc = change_bus_speed(ctrl, pslot, asp);
230 rc = change_bus_speed(ctrl, pslot, msp);
242 static int board_added(
struct slot *p_slot)
245 u8 slots_not_empty = 0;
254 "%s: p_slot->device, slot_offset, hp_slot = %d, %d ,%d\n",
258 rc = p_slot->
hpc_ops->power_on_slot(p_slot);
260 ctrl_err(ctrl,
"Failed to power on slot\n");
264 if ((ctrl->
pci_dev->vendor == 0x8086) && (ctrl->
pci_dev->device == 0x0332)) {
266 ctrl_err(ctrl,
"%s: Issue of set bus speed mode command"
267 " failed\n", __func__);
272 if ((rc = p_slot->
hpc_ops->slot_enable(p_slot))) {
273 ctrl_err(ctrl,
"Issue of Slot Enable command failed\n");
278 rc = p_slot->
hpc_ops->get_adapter_speed(p_slot, &asp);
280 ctrl_err(ctrl,
"Can't get adapter speed or "
281 "bus mode mismatch\n");
285 bsp = ctrl->
pci_dev->bus->cur_bus_speed;
286 msp = ctrl->
pci_dev->bus->max_bus_speed;
289 if (!list_empty(&ctrl->
pci_dev->subordinate->devices))
292 ctrl_dbg(ctrl,
"%s: slots_not_empty %d, adapter_speed %d, bus_speed %d,"
293 " max_bus_speed %d\n", __func__, slots_not_empty, asp,
296 rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, asp, bsp, msp);
301 if ((rc = p_slot->
hpc_ops->slot_enable(p_slot))) {
302 ctrl_err(ctrl,
"Issue of Slot Enable command failed\n");
309 ctrl_dbg(ctrl,
"%s: slot status = %x\n", __func__, p_slot->
status);
311 if (p_slot->
status == 0xFF) {
313 ctrl_dbg(ctrl,
"%s: Power fault\n", __func__);
320 ctrl_err(ctrl,
"Cannot add device at %04x:%02x:%02x\n",
329 p_slot->
hpc_ops->green_led_on(p_slot);
335 rc = p_slot->
hpc_ops->slot_disable(p_slot);
337 ctrl_err(ctrl,
"%s: Issue of Slot Disable command failed\n",
350 static int remove_board(
struct slot *p_slot)
362 ctrl_dbg(ctrl,
"%s: hp_slot = %d\n", __func__, hp_slot);
369 rc = p_slot->
hpc_ops->slot_disable(p_slot);
371 ctrl_err(ctrl,
"%s: Issue of Slot Disable command failed\n",
376 rc = p_slot->
hpc_ops->set_attention_status(p_slot, 0);
378 ctrl_err(ctrl,
"Issue of Set Attention command failed\n");
408 switch (p_slot->
state) {
411 shpchp_disable_slot(p_slot);
417 if (shpchp_enable_slot(p_slot))
418 p_slot->
hpc_ops->green_led_off(p_slot);
445 switch (p_slot->
state) {
461 static int update_slot_info (
struct slot *
slot)
483 static void handle_button_press_event(
struct slot *p_slot)
488 switch (p_slot->
state) {
490 p_slot->
hpc_ops->get_power_status(p_slot, &getstatus);
493 ctrl_info(ctrl,
"PCI slot #%s - powering off due to "
494 "button press.\n", slot_name(p_slot));
497 ctrl_info(ctrl,
"PCI slot #%s - powering on due to "
498 "button press.\n", slot_name(p_slot));
501 p_slot->
hpc_ops->green_led_blink(p_slot);
502 p_slot->
hpc_ops->set_attention_status(p_slot, 0);
513 ctrl_info(ctrl,
"Button cancel on Slot(%s)\n",
517 p_slot->
hpc_ops->green_led_on(p_slot);
519 p_slot->
hpc_ops->green_led_off(p_slot);
520 p_slot->
hpc_ops->set_attention_status(p_slot, 0);
521 ctrl_info(ctrl,
"PCI slot #%s - action canceled due to "
522 "button press\n", slot_name(p_slot));
532 ctrl_info(ctrl,
"Button ignore on Slot(%s)\n",
534 update_slot_info(p_slot);
542 static void interrupt_event_handler(
struct work_struct *work)
545 struct slot *p_slot = info->
p_slot;
550 handle_button_press_event(p_slot);
554 p_slot->
hpc_ops->set_attention_status(p_slot, 1);
555 p_slot->
hpc_ops->green_led_off(p_slot);
558 update_slot_info(p_slot);
567 static int shpchp_enable_slot (
struct slot *p_slot)
575 rc = p_slot->
hpc_ops->get_adapter_status(p_slot, &getstatus);
576 if (rc || !getstatus) {
577 ctrl_info(ctrl,
"No adapter on slot(%s)\n", slot_name(p_slot));
580 rc = p_slot->
hpc_ops->get_latch_status(p_slot, &getstatus);
581 if (rc || getstatus) {
582 ctrl_info(ctrl,
"Latch open on slot(%s)\n", slot_name(p_slot));
585 rc = p_slot->
hpc_ops->get_power_status(p_slot, &getstatus);
586 if (rc || getstatus) {
587 ctrl_info(ctrl,
"Already enabled on slot(%s)\n",
598 p_slot->
hpc_ops->get_latch_status(p_slot, &getstatus);
602 && p_slot->
ctrl->num_slots == 1) {
604 amd_pogo_errata_save_misc_reg(p_slot);
605 retval = board_added(p_slot);
607 amd_pogo_errata_restore_misc_reg(p_slot);
609 retval = board_added(p_slot);
612 p_slot->
hpc_ops->get_adapter_status(p_slot,
614 p_slot->
hpc_ops->get_latch_status(p_slot, &getstatus);
617 update_slot_info(p_slot);
624 static int shpchp_disable_slot (
struct slot *p_slot)
636 rc = p_slot->
hpc_ops->get_adapter_status(p_slot, &getstatus);
637 if (rc || !getstatus) {
638 ctrl_info(ctrl,
"No adapter on slot(%s)\n", slot_name(p_slot));
641 rc = p_slot->
hpc_ops->get_latch_status(p_slot, &getstatus);
642 if (rc || getstatus) {
643 ctrl_info(ctrl,
"Latch open on slot(%s)\n", slot_name(p_slot));
646 rc = p_slot->
hpc_ops->get_power_status(p_slot, &getstatus);
647 if (rc || !getstatus) {
648 ctrl_info(ctrl,
"Already disabled on slot(%s)\n",
653 retval = remove_board(p_slot);
654 update_slot_info(p_slot);
666 switch (p_slot->
state) {
672 retval = shpchp_enable_slot(p_slot);
677 ctrl_info(ctrl,
"Slot %s is already in powering on state\n",
682 ctrl_info(ctrl,
"Already enabled on slot %s\n",
686 ctrl_err(ctrl,
"Not a valid state on slot %s\n",
701 switch (p_slot->
state) {
707 retval = shpchp_disable_slot(p_slot);
712 ctrl_info(ctrl,
"Slot %s is already in powering off state\n",
717 ctrl_info(ctrl,
"Already disabled on slot %s\n",
721 ctrl_err(ctrl,
"Not a valid state on slot %s\n",