Lines Matching full:ctrl
49 static inline struct pci_dev *ctrl_dev(struct controller *ctrl) in ctrl_dev() argument
51 return ctrl->pcie->port; in ctrl_dev()
58 static inline int pciehp_request_irq(struct controller *ctrl) in pciehp_request_irq() argument
60 int retval, irq = ctrl->pcie->irq; in pciehp_request_irq()
63 ctrl->poll_thread = kthread_run(&pciehp_poll, ctrl, in pciehp_request_irq()
65 slot_name(ctrl)); in pciehp_request_irq()
66 return PTR_ERR_OR_ZERO(ctrl->poll_thread); in pciehp_request_irq()
71 IRQF_SHARED, "pciehp", ctrl); in pciehp_request_irq()
73 ctrl_err(ctrl, "Cannot get irq %d for the hotplug controller\n", in pciehp_request_irq()
78 static inline void pciehp_free_irq(struct controller *ctrl) in pciehp_free_irq() argument
81 kthread_stop(ctrl->poll_thread); in pciehp_free_irq()
83 free_irq(ctrl->pcie->irq, ctrl); in pciehp_free_irq()
86 static int pcie_poll_cmd(struct controller *ctrl, int timeout) in pcie_poll_cmd() argument
88 struct pci_dev *pdev = ctrl_dev(ctrl); in pcie_poll_cmd()
94 ctrl_info(ctrl, "%s: no response from device\n", in pcie_poll_cmd()
102 ctrl->cmd_busy = 0; in pcie_poll_cmd()
112 static void pcie_wait_cmd(struct controller *ctrl) in pcie_wait_cmd() argument
116 unsigned long cmd_timeout = ctrl->cmd_started + duration; in pcie_wait_cmd()
124 if (NO_CMD_CMPL(ctrl)) in pcie_wait_cmd()
127 if (!ctrl->cmd_busy) in pcie_wait_cmd()
140 if (ctrl->slot_ctrl & PCI_EXP_SLTCTL_HPIE && in pcie_wait_cmd()
141 ctrl->slot_ctrl & PCI_EXP_SLTCTL_CCIE) in pcie_wait_cmd()
142 rc = wait_event_timeout(ctrl->queue, !ctrl->cmd_busy, timeout); in pcie_wait_cmd()
144 rc = pcie_poll_cmd(ctrl, jiffies_to_msecs(timeout)); in pcie_wait_cmd()
147 ctrl_info(ctrl, "Timeout on hotplug command %#06x (issued %u msec ago)\n", in pcie_wait_cmd()
148 ctrl->slot_ctrl, in pcie_wait_cmd()
149 jiffies_to_msecs(jiffies - ctrl->cmd_started)); in pcie_wait_cmd()
157 static void pcie_do_write_cmd(struct controller *ctrl, u16 cmd, in pcie_do_write_cmd() argument
160 struct pci_dev *pdev = ctrl_dev(ctrl); in pcie_do_write_cmd()
163 mutex_lock(&ctrl->ctrl_lock); in pcie_do_write_cmd()
168 pcie_wait_cmd(ctrl); in pcie_do_write_cmd()
172 ctrl_info(ctrl, "%s: no response from device\n", __func__); in pcie_do_write_cmd()
179 ctrl->cmd_busy = 1; in pcie_do_write_cmd()
181 ctrl->slot_ctrl = slot_ctrl; in pcie_do_write_cmd()
183 ctrl->cmd_started = jiffies; in pcie_do_write_cmd()
194 ctrl->cmd_busy = 0; in pcie_do_write_cmd()
201 pcie_wait_cmd(ctrl); in pcie_do_write_cmd()
204 mutex_unlock(&ctrl->ctrl_lock); in pcie_do_write_cmd()
209 * @ctrl: controller to which the command is issued
213 static void pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) in pcie_write_cmd() argument
215 pcie_do_write_cmd(ctrl, cmd, mask, true); in pcie_write_cmd()
219 static void pcie_write_cmd_nowait(struct controller *ctrl, u16 cmd, u16 mask) in pcie_write_cmd_nowait() argument
221 pcie_do_write_cmd(ctrl, cmd, mask, false); in pcie_write_cmd_nowait()
226 * @ctrl: PCIe hotplug controller
235 int pciehp_check_link_active(struct controller *ctrl) in pciehp_check_link_active() argument
237 struct pci_dev *pdev = ctrl_dev(ctrl); in pciehp_check_link_active()
246 ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status); in pciehp_check_link_active()
291 int pciehp_check_link_status(struct controller *ctrl) in pciehp_check_link_status() argument
293 struct pci_dev *pdev = ctrl_dev(ctrl); in pciehp_check_link_status()
298 ctrl_info(ctrl, "Slot(%s): No link\n", slot_name(ctrl)); in pciehp_check_link_status()
302 if (ctrl->inband_presence_disabled) in pciehp_check_link_status()
305 found = pci_bus_check_dev(ctrl->pcie->port->subordinate, in pciehp_check_link_status()
311 &ctrl->pending_events); in pciehp_check_link_status()
314 ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status); in pciehp_check_link_status()
317 ctrl_info(ctrl, "Slot(%s): Cannot train link: status %#06x\n", in pciehp_check_link_status()
318 slot_name(ctrl), lnk_status); in pciehp_check_link_status()
323 __pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status, linksta2); in pciehp_check_link_status()
326 ctrl_info(ctrl, "Slot(%s): No device found\n", in pciehp_check_link_status()
327 slot_name(ctrl)); in pciehp_check_link_status()
334 static int __pciehp_link_set(struct controller *ctrl, bool enable) in __pciehp_link_set() argument
336 struct pci_dev *pdev = ctrl_dev(ctrl); in __pciehp_link_set()
345 static int pciehp_link_enable(struct controller *ctrl) in pciehp_link_enable() argument
347 return __pciehp_link_set(ctrl, true); in pciehp_link_enable()
353 struct controller *ctrl = to_ctrl(hotplug_slot); in pciehp_get_raw_indicator_status() local
354 struct pci_dev *pdev = ctrl_dev(ctrl); in pciehp_get_raw_indicator_status()
366 struct controller *ctrl = to_ctrl(hotplug_slot); in pciehp_get_attention_status() local
367 struct pci_dev *pdev = ctrl_dev(ctrl); in pciehp_get_attention_status()
373 ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", __func__, in pciehp_get_attention_status()
374 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl); in pciehp_get_attention_status()
394 void pciehp_get_power_status(struct controller *ctrl, u8 *status) in pciehp_get_power_status() argument
396 struct pci_dev *pdev = ctrl_dev(ctrl); in pciehp_get_power_status()
400 ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n", __func__, in pciehp_get_power_status()
401 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl); in pciehp_get_power_status()
416 void pciehp_get_latch_status(struct controller *ctrl, u8 *status) in pciehp_get_latch_status() argument
418 struct pci_dev *pdev = ctrl_dev(ctrl); in pciehp_get_latch_status()
427 * @ctrl: PCIe hotplug controller
437 int pciehp_card_present(struct controller *ctrl) in pciehp_card_present() argument
439 struct pci_dev *pdev = ctrl_dev(ctrl); in pciehp_card_present()
452 * @ctrl: PCIe hotplug controller
462 int pciehp_card_present_or_link_active(struct controller *ctrl) in pciehp_card_present_or_link_active() argument
466 ret = pciehp_card_present(ctrl); in pciehp_card_present_or_link_active()
470 return pciehp_check_link_active(ctrl); in pciehp_card_present_or_link_active()
473 int pciehp_query_power_fault(struct controller *ctrl) in pciehp_query_power_fault() argument
475 struct pci_dev *pdev = ctrl_dev(ctrl); in pciehp_query_power_fault()
485 struct controller *ctrl = to_ctrl(hotplug_slot); in pciehp_set_raw_indicator_status() local
486 struct pci_dev *pdev = ctrl_dev(ctrl); in pciehp_set_raw_indicator_status()
491 pcie_write_cmd_nowait(ctrl, FIELD_PREP(PCI_EXP_SLTCTL_AIC | PCI_EXP_SLTCTL_PIC, status), in pciehp_set_raw_indicator_status()
499 * @ctrl: PCIe hotplug controller
512 void pciehp_set_indicators(struct controller *ctrl, int pwr, int attn) in pciehp_set_indicators() argument
516 if (PWR_LED(ctrl) && pwr != INDICATOR_NOOP) { in pciehp_set_indicators()
521 if (ATTN_LED(ctrl) && attn != INDICATOR_NOOP) { in pciehp_set_indicators()
527 pcie_write_cmd_nowait(ctrl, cmd, mask); in pciehp_set_indicators()
528 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, in pciehp_set_indicators()
529 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, cmd); in pciehp_set_indicators()
533 int pciehp_power_on_slot(struct controller *ctrl) in pciehp_power_on_slot() argument
535 struct pci_dev *pdev = ctrl_dev(ctrl); in pciehp_power_on_slot()
544 ctrl->power_fault_detected = 0; in pciehp_power_on_slot()
546 pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_ON, PCI_EXP_SLTCTL_PCC); in pciehp_power_on_slot()
547 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, in pciehp_power_on_slot()
548 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, in pciehp_power_on_slot()
551 retval = pciehp_link_enable(ctrl); in pciehp_power_on_slot()
553 ctrl_err(ctrl, "%s: Can not enable the link!\n", __func__); in pciehp_power_on_slot()
558 void pciehp_power_off_slot(struct controller *ctrl) in pciehp_power_off_slot() argument
560 pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_OFF, PCI_EXP_SLTCTL_PCC); in pciehp_power_off_slot()
561 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, in pciehp_power_off_slot()
562 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, in pciehp_power_off_slot()
566 static void pciehp_ignore_dpc_link_change(struct controller *ctrl, in pciehp_ignore_dpc_link_change() argument
574 atomic_and(~PCI_EXP_SLTSTA_DLLSC, &ctrl->pending_events); in pciehp_ignore_dpc_link_change()
578 ctrl_info(ctrl, "Slot(%s): Link Down/Up ignored (recovered by DPC)\n", in pciehp_ignore_dpc_link_change()
579 slot_name(ctrl)); in pciehp_ignore_dpc_link_change()
586 down_read_nested(&ctrl->reset_lock, ctrl->depth); in pciehp_ignore_dpc_link_change()
587 if (!pciehp_check_link_active(ctrl)) in pciehp_ignore_dpc_link_change()
588 pciehp_request(ctrl, PCI_EXP_SLTSTA_DLLSC); in pciehp_ignore_dpc_link_change()
589 up_read(&ctrl->reset_lock); in pciehp_ignore_dpc_link_change()
594 struct controller *ctrl = (struct controller *)dev_id; in pciehp_isr() local
595 struct pci_dev *pdev = ctrl_dev(ctrl); in pciehp_isr()
604 (!(ctrl->slot_ctrl & PCI_EXP_SLTCTL_HPIE) && !pciehp_poll_mode)) in pciehp_isr()
617 atomic_or(RERUN_ISR, &ctrl->pending_events); in pciehp_isr()
625 ctrl_info(ctrl, "%s: no response from device\n", __func__); in pciehp_isr()
643 if (ctrl->power_fault_detected) in pciehp_isr()
646 ctrl->power_fault_detected = true; in pciehp_isr()
668 ctrl_dbg(ctrl, "pending interrupts %#06x from Slot Status\n", events); in pciehp_isr()
677 ctrl->cmd_busy = 0; in pciehp_isr()
679 wake_up(&ctrl->queue); in pciehp_isr()
688 ctrl_dbg(ctrl, "ignoring hotplug event %#06x\n", events); in pciehp_isr()
693 atomic_or(events, &ctrl->pending_events); in pciehp_isr()
699 struct controller *ctrl = (struct controller *)dev_id; in pciehp_ist() local
700 struct pci_dev *pdev = ctrl_dev(ctrl); in pciehp_ist()
704 ctrl->ist_running = true; in pciehp_ist()
708 if (atomic_fetch_and(~RERUN_ISR, &ctrl->pending_events) & RERUN_ISR) { in pciehp_ist()
716 events = atomic_xchg(&ctrl->pending_events, 0); in pciehp_ist()
724 pciehp_handle_button_press(ctrl); in pciehp_ist()
728 ctrl_err(ctrl, "Slot(%s): Power fault\n", slot_name(ctrl)); in pciehp_ist()
729 pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF, in pciehp_ist()
738 ctrl->state == ON_STATE) { in pciehp_ist()
740 pciehp_ignore_dpc_link_change(ctrl, pdev, irq); in pciehp_ist()
747 down_read_nested(&ctrl->reset_lock, ctrl->depth); in pciehp_ist()
749 pciehp_handle_disable_request(ctrl); in pciehp_ist()
751 pciehp_handle_presence_or_link_change(ctrl, events); in pciehp_ist()
752 up_read(&ctrl->reset_lock); in pciehp_ist()
757 ctrl->ist_running = false; in pciehp_ist()
758 wake_up(&ctrl->requester); in pciehp_ist()
764 struct controller *ctrl = data; in pciehp_poll() local
770 while (pciehp_isr(IRQ_NOTCONNECTED, ctrl) == IRQ_WAKE_THREAD || in pciehp_poll()
771 atomic_read(&ctrl->pending_events)) in pciehp_poll()
772 pciehp_ist(IRQ_NOTCONNECTED, ctrl); in pciehp_poll()
783 static void pcie_enable_notification(struct controller *ctrl) in pcie_enable_notification() argument
804 if (ATTN_BUTTN(ctrl)) in pcie_enable_notification()
810 if (!pciehp_poll_mode && !NO_CMD_CMPL(ctrl)) in pcie_enable_notification()
818 pcie_write_cmd_nowait(ctrl, cmd, mask); in pcie_enable_notification()
819 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, in pcie_enable_notification()
820 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, cmd); in pcie_enable_notification()
823 static void pcie_disable_notification(struct controller *ctrl) in pcie_disable_notification() argument
831 pcie_write_cmd(ctrl, 0, mask); in pcie_disable_notification()
832 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, in pcie_disable_notification()
833 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, 0); in pcie_disable_notification()
836 void pcie_clear_hotplug_events(struct controller *ctrl) in pcie_clear_hotplug_events() argument
838 pcie_capability_write_word(ctrl_dev(ctrl), PCI_EXP_SLTSTA, in pcie_clear_hotplug_events()
842 void pcie_enable_interrupt(struct controller *ctrl) in pcie_enable_interrupt() argument
849 pcie_write_cmd(ctrl, mask, mask); in pcie_enable_interrupt()
852 void pcie_disable_interrupt(struct controller *ctrl) in pcie_disable_interrupt() argument
864 pcie_write_cmd(ctrl, 0, mask); in pcie_disable_interrupt()
879 struct controller *ctrl = get_service_data(dev); in pciehp_slot_reset() local
881 if (ctrl->state != ON_STATE) in pciehp_slot_reset()
887 if (!pciehp_check_link_active(ctrl)) in pciehp_slot_reset()
888 pciehp_request(ctrl, PCI_EXP_SLTSTA_DLLSC); in pciehp_slot_reset()
903 struct controller *ctrl = to_ctrl(hotplug_slot); in pciehp_reset_slot() local
904 struct pci_dev *pdev = ctrl_dev(ctrl); in pciehp_reset_slot()
911 down_write_nested(&ctrl->reset_lock, ctrl->depth); in pciehp_reset_slot()
913 if (!ATTN_BUTTN(ctrl)) { in pciehp_reset_slot()
920 pcie_write_cmd(ctrl, 0, ctrl_mask); in pciehp_reset_slot()
921 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, in pciehp_reset_slot()
922 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, 0); in pciehp_reset_slot()
924 rc = pci_bridge_secondary_bus_reset(ctrl->pcie->port); in pciehp_reset_slot()
927 pcie_write_cmd_nowait(ctrl, ctrl_mask, ctrl_mask); in pciehp_reset_slot()
928 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, in pciehp_reset_slot()
929 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, ctrl_mask); in pciehp_reset_slot()
931 up_write(&ctrl->reset_lock); in pciehp_reset_slot()
935 int pcie_init_notification(struct controller *ctrl) in pcie_init_notification() argument
937 if (pciehp_request_irq(ctrl)) in pcie_init_notification()
939 pcie_enable_notification(ctrl); in pcie_init_notification()
940 ctrl->notification_enabled = 1; in pcie_init_notification()
944 void pcie_shutdown_notification(struct controller *ctrl) in pcie_shutdown_notification() argument
946 if (ctrl->notification_enabled) { in pcie_shutdown_notification()
947 pcie_disable_notification(ctrl); in pcie_shutdown_notification()
948 pciehp_free_irq(ctrl); in pcie_shutdown_notification()
949 ctrl->notification_enabled = 0; in pcie_shutdown_notification()
953 static inline void dbg_ctrl(struct controller *ctrl) in dbg_ctrl() argument
955 struct pci_dev *pdev = ctrl->pcie->port; in dbg_ctrl()
958 ctrl_dbg(ctrl, "Slot Capabilities : 0x%08x\n", ctrl->slot_cap); in dbg_ctrl()
960 ctrl_dbg(ctrl, "Slot Status : 0x%04x\n", reg16); in dbg_ctrl()
962 ctrl_dbg(ctrl, "Slot Control : 0x%04x\n", reg16); in dbg_ctrl()
983 struct controller *ctrl; in pcie_init() local
989 ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); in pcie_init()
990 if (!ctrl) in pcie_init()
993 ctrl->pcie = dev; in pcie_init()
994 ctrl->depth = pcie_hotplug_depth(dev->port); in pcie_init()
1007 ctrl->slot_cap = slot_cap; in pcie_init()
1008 mutex_init(&ctrl->ctrl_lock); in pcie_init()
1009 mutex_init(&ctrl->state_lock); in pcie_init()
1010 init_rwsem(&ctrl->reset_lock); in pcie_init()
1011 init_waitqueue_head(&ctrl->requester); in pcie_init()
1012 init_waitqueue_head(&ctrl->queue); in pcie_init()
1013 INIT_DELAYED_WORK(&ctrl->button_work, pciehp_queue_pushbutton_work); in pcie_init()
1014 dbg_ctrl(ctrl); in pcie_init()
1017 ctrl->state = list_empty(&subordinate->devices) ? OFF_STATE : ON_STATE; in pcie_init()
1022 pcie_write_cmd_nowait(ctrl, PCI_EXP_SLTCTL_IBPD_DISABLE, in pcie_init()
1024 ctrl->inband_presence_disabled = 1; in pcie_init()
1028 ctrl->inband_presence_disabled = 1; in pcie_init()
1036 …ctrl_info(ctrl, "Slot #%d AttnBtn%c PwrCtrl%c MRL%c AttnInd%c PwrInd%c HotPlug%c Surprise%c Interl… in pcie_init()
1055 if (POWER_CTRL(ctrl)) { in pcie_init()
1056 pciehp_get_power_status(ctrl, &poweron); in pcie_init()
1057 if (!pciehp_card_present_or_link_active(ctrl) && poweron) { in pcie_init()
1058 pcie_disable_notification(ctrl); in pcie_init()
1059 pciehp_power_off_slot(ctrl); in pcie_init()
1065 ctrl->dsn = pci_get_dsn(pdev); in pcie_init()
1068 return ctrl; in pcie_init()
1071 void pciehp_release_ctrl(struct controller *ctrl) in pciehp_release_ctrl() argument
1073 cancel_delayed_work_sync(&ctrl->button_work); in pciehp_release_ctrl()
1074 kfree(ctrl); in pciehp_release_ctrl()