diff options
-rw-r--r-- | drivers/pci/pcie/dpc.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c index f6098dd171f3..fd6b96ca1c2d 100644 --- a/drivers/pci/pcie/dpc.c +++ b/drivers/pci/pcie/dpc.c | |||
@@ -17,7 +17,6 @@ | |||
17 | 17 | ||
18 | struct dpc_dev { | 18 | struct dpc_dev { |
19 | struct pcie_device *dev; | 19 | struct pcie_device *dev; |
20 | struct work_struct work; | ||
21 | u16 cap_pos; | 20 | u16 cap_pos; |
22 | bool rp_extensions; | 21 | bool rp_extensions; |
23 | u8 rp_log_size; | 22 | u8 rp_log_size; |
@@ -160,10 +159,10 @@ static void dpc_process_rp_pio_error(struct dpc_dev *dpc) | |||
160 | pci_write_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_STATUS, status); | 159 | pci_write_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_STATUS, status); |
161 | } | 160 | } |
162 | 161 | ||
163 | static void dpc_work(struct work_struct *work) | 162 | static irqreturn_t dpc_handler(int irq, void *context) |
164 | { | 163 | { |
165 | struct aer_err_info info; | 164 | struct aer_err_info info; |
166 | struct dpc_dev *dpc = container_of(work, struct dpc_dev, work); | 165 | struct dpc_dev *dpc = context; |
167 | struct pci_dev *pdev = dpc->dev->port; | 166 | struct pci_dev *pdev = dpc->dev->port; |
168 | struct device *dev = &dpc->dev->device; | 167 | struct device *dev = &dpc->dev->device; |
169 | u16 cap = dpc->cap_pos, status, source, reason, ext_reason; | 168 | u16 cap = dpc->cap_pos, status, source, reason, ext_reason; |
@@ -194,6 +193,8 @@ static void dpc_work(struct work_struct *work) | |||
194 | 193 | ||
195 | /* We configure DPC so it only triggers on ERR_FATAL */ | 194 | /* We configure DPC so it only triggers on ERR_FATAL */ |
196 | pcie_do_fatal_recovery(pdev, PCIE_PORT_SERVICE_DPC); | 195 | pcie_do_fatal_recovery(pdev, PCIE_PORT_SERVICE_DPC); |
196 | |||
197 | return IRQ_HANDLED; | ||
197 | } | 198 | } |
198 | 199 | ||
199 | static irqreturn_t dpc_irq(int irq, void *context) | 200 | static irqreturn_t dpc_irq(int irq, void *context) |
@@ -210,7 +211,7 @@ static irqreturn_t dpc_irq(int irq, void *context) | |||
210 | pci_write_config_word(pdev, cap + PCI_EXP_DPC_STATUS, | 211 | pci_write_config_word(pdev, cap + PCI_EXP_DPC_STATUS, |
211 | PCI_EXP_DPC_STATUS_INTERRUPT); | 212 | PCI_EXP_DPC_STATUS_INTERRUPT); |
212 | if (status & PCI_EXP_DPC_STATUS_TRIGGER) | 213 | if (status & PCI_EXP_DPC_STATUS_TRIGGER) |
213 | schedule_work(&dpc->work); | 214 | return IRQ_WAKE_THREAD; |
214 | return IRQ_HANDLED; | 215 | return IRQ_HANDLED; |
215 | } | 216 | } |
216 | 217 | ||
@@ -232,11 +233,11 @@ static int dpc_probe(struct pcie_device *dev) | |||
232 | 233 | ||
233 | dpc->cap_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_DPC); | 234 | dpc->cap_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_DPC); |
234 | dpc->dev = dev; | 235 | dpc->dev = dev; |
235 | INIT_WORK(&dpc->work, dpc_work); | ||
236 | set_service_data(dev, dpc); | 236 | set_service_data(dev, dpc); |
237 | 237 | ||
238 | status = devm_request_irq(device, dev->irq, dpc_irq, IRQF_SHARED, | 238 | status = devm_request_threaded_irq(device, dev->irq, dpc_irq, |
239 | "pcie-dpc", dpc); | 239 | dpc_handler, IRQF_SHARED, |
240 | "pcie-dpc", dpc); | ||
240 | if (status) { | 241 | if (status) { |
241 | dev_warn(device, "request IRQ%d failed: %d\n", dev->irq, | 242 | dev_warn(device, "request IRQ%d failed: %d\n", dev->irq, |
242 | status); | 243 | status); |