From 955268e13f8f9422e7e89ee6350ec793dddd1e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Tue, 1 Nov 2022 09:44:59 +0100 Subject: nixos: try to fix Turris Omnia PCIe on Linux 6.0 Unfortunatelly this seems to not work. --- ...-Enable-DLLSC-interrupt-only-if-supported.patch | 139 +++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 nixos/modules/omnia-kernel-patches/0043-PCI-pciehp-Enable-DLLSC-interrupt-only-if-supported.patch (limited to 'nixos/modules/omnia-kernel-patches/0043-PCI-pciehp-Enable-DLLSC-interrupt-only-if-supported.patch') diff --git a/nixos/modules/omnia-kernel-patches/0043-PCI-pciehp-Enable-DLLSC-interrupt-only-if-supported.patch b/nixos/modules/omnia-kernel-patches/0043-PCI-pciehp-Enable-DLLSC-interrupt-only-if-supported.patch new file mode 100644 index 0000000..17b5aea --- /dev/null +++ b/nixos/modules/omnia-kernel-patches/0043-PCI-pciehp-Enable-DLLSC-interrupt-only-if-supported.patch @@ -0,0 +1,139 @@ +From 337891ffea7c9e65b456663e080028371401f3be Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= +Date: Wed, 31 Mar 2021 15:12:50 +0200 +Subject: [PATCH 43/53] PCI: pciehp: Enable DLLSC interrupt only if supported +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Don't enable Data Link Layer State Changed interrupt if it isn't +supported. + +Data Link Layer Link Active Reporting Capable bit in Link Capabilities +register indicates if Data Link Layer State Changed Enable is supported. + +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +--- + drivers/pci/hotplug/pciehp_hpc.c | 32 ++++++++++++++++++++++++-------- + drivers/pci/hotplug/pnv_php.c | 13 +++++++++---- + 2 files changed, 33 insertions(+), 12 deletions(-) + +diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c +index 040ae076ec0e..ef807c79b1b1 100644 +--- a/drivers/pci/hotplug/pciehp_hpc.c ++++ b/drivers/pci/hotplug/pciehp_hpc.c +@@ -788,6 +788,7 @@ static int pciehp_poll(void *data) + static void pcie_enable_notification(struct controller *ctrl) + { + u16 cmd, mask; ++ u32 link_cap; + + /* + * TBD: Power fault detected software notification support. +@@ -800,12 +801,17 @@ static void pcie_enable_notification(struct controller *ctrl) + * next power fault detected interrupt was notified again. + */ + ++ pcie_capability_read_dword(ctrl_dev(ctrl), PCI_EXP_LNKCAP, &link_cap); ++ + /* +- * Always enable link events: thus link-up and link-down shall +- * always be treated as hotplug and unplug respectively. Enable +- * presence detect only if Attention Button is not present. +- */ +- cmd = PCI_EXP_SLTCTL_DLLSCE; ++ * Enable link events if their support is indicated in Link Capability ++ * register: thus link-up and link-down shall always be treated as ++ * hotplug and unplug respectively. Enable presence detect only if ++ * Attention Button is not present. ++ */ ++ cmd = 0; ++ if (link_cap & PCI_EXP_LNKCAP_DLLLARC) ++ cmd |= PCI_EXP_SLTCTL_DLLSCE; + if (ATTN_BUTTN(ctrl)) + cmd |= PCI_EXP_SLTCTL_ABPE; + else +@@ -845,8 +851,13 @@ void pcie_clear_hotplug_events(struct controller *ctrl) + void pcie_enable_interrupt(struct controller *ctrl) + { + u16 mask; ++ u32 link_cap; + +- mask = PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_DLLSCE; ++ pcie_capability_read_dword(ctrl_dev(ctrl), PCI_EXP_LNKCAP, &link_cap); ++ ++ mask = PCI_EXP_SLTCTL_HPIE; ++ if (link_cap & PCI_EXP_LNKCAP_DLLLARC) ++ mask |= PCI_EXP_SLTCTL_DLLSCE; + pcie_write_cmd(ctrl, mask, mask); + } + +@@ -904,19 +915,24 @@ int pciehp_reset_slot(struct hotplug_slot *hotplug_slot, bool probe) + struct controller *ctrl = to_ctrl(hotplug_slot); + struct pci_dev *pdev = ctrl_dev(ctrl); + u16 stat_mask = 0, ctrl_mask = 0; ++ u32 link_cap; + int rc; + + if (probe) + return 0; + ++ pcie_capability_read_dword(pdev, PCI_EXP_LNKCAP, &link_cap); ++ + down_write_nested(&ctrl->reset_lock, ctrl->depth); + + if (!ATTN_BUTTN(ctrl)) { + ctrl_mask |= PCI_EXP_SLTCTL_PDCE; + stat_mask |= PCI_EXP_SLTSTA_PDC; + } +- ctrl_mask |= PCI_EXP_SLTCTL_DLLSCE; +- stat_mask |= PCI_EXP_SLTSTA_DLLSC; ++ if (link_cap & PCI_EXP_LNKCAP_DLLLARC) { ++ ctrl_mask |= PCI_EXP_SLTCTL_DLLSCE; ++ stat_mask |= PCI_EXP_SLTSTA_DLLSC; ++ } + + pcie_write_cmd(ctrl, 0, ctrl_mask); + ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, +diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c +index 881d420637bf..5c700d3a9009 100644 +--- a/drivers/pci/hotplug/pnv_php.c ++++ b/drivers/pci/hotplug/pnv_php.c +@@ -840,6 +840,7 @@ static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq) + { + struct pci_dev *pdev = php_slot->pdev; + u32 broken_pdc = 0; ++ u32 link_cap; + u16 sts, ctrl; + int ret; + +@@ -874,17 +875,21 @@ static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq) + return; + } + ++ pcie_capability_read_dword(pdev, PCI_EXP_LNKCAP, &link_cap); ++ + /* Enable the interrupts */ + pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &ctrl); + if (php_slot->flags & PNV_PHP_FLAG_BROKEN_PDC) { + ctrl &= ~PCI_EXP_SLTCTL_PDCE; +- ctrl |= (PCI_EXP_SLTCTL_HPIE | +- PCI_EXP_SLTCTL_DLLSCE); ++ ctrl |= PCI_EXP_SLTCTL_HPIE; + } else { + ctrl |= (PCI_EXP_SLTCTL_HPIE | +- PCI_EXP_SLTCTL_PDCE | +- PCI_EXP_SLTCTL_DLLSCE); ++ PCI_EXP_SLTCTL_PDCE); + } ++ if (link_cap & PCI_EXP_LNKCAP_DLLLARC) ++ ctrl |= PCI_EXP_SLTCTL_DLLSCE; ++ else ++ ctrl &= ~PCI_EXP_SLTCTL_DLLSCE; + pcie_capability_write_word(pdev, PCI_EXP_SLTCTL, ctrl); + + /* The interrupt is initialized successfully when @irq is valid */ +-- +2.37.3 + -- cgit v1.2.3