diff options
author | Jisheng Zhang <Jisheng.Zhang@synaptics.com> | 2018-09-20 17:32:52 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2018-09-20 17:36:20 -0400 |
commit | 9024143e700f89d74b8cdaf316a3499d74fc56fe (patch) | |
tree | 21b380d0e4f4b0088a076d0c40be1fe975531ab0 /drivers/pci/controller/dwc | |
parent | b3027b7746ce1e5a9429715ee6492aca2a6e4cf0 (diff) |
PCI: dwc: Fix scheduling while atomic issues
When programming the inbound/outbound ATUs, we call usleep_range() after
each checking PCIE_ATU_ENABLE bit. Unfortunately, the ATU programming
can be executed in atomic context:
inbound ATU programming could be called through
pci_epc_write_header()
=>dw_pcie_ep_write_header()
=>dw_pcie_prog_inbound_atu()
outbound ATU programming could be called through
pci_bus_read_config_dword()
=>dw_pcie_rd_conf()
=>dw_pcie_prog_outbound_atu()
Fix this issue by calling mdelay() instead.
Fixes: f8aed6ec624f ("PCI: dwc: designware: Add EP mode support")
Fixes: d8bbeb39fbf3 ("PCI: designware: Wait for iATU enable")
Signed-off-by: Jisheng Zhang <Jisheng.Zhang@synaptics.com>
[lorenzo.pieralisi@arm.com: commit log update]
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
Diffstat (limited to 'drivers/pci/controller/dwc')
-rw-r--r-- | drivers/pci/controller/dwc/pcie-designware.c | 8 | ||||
-rw-r--r-- | drivers/pci/controller/dwc/pcie-designware.h | 3 |
2 files changed, 5 insertions, 6 deletions
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c index 778c4f76a884..2153956a0b20 100644 --- a/drivers/pci/controller/dwc/pcie-designware.c +++ b/drivers/pci/controller/dwc/pcie-designware.c | |||
@@ -135,7 +135,7 @@ static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, int index, | |||
135 | if (val & PCIE_ATU_ENABLE) | 135 | if (val & PCIE_ATU_ENABLE) |
136 | return; | 136 | return; |
137 | 137 | ||
138 | usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX); | 138 | mdelay(LINK_WAIT_IATU); |
139 | } | 139 | } |
140 | dev_err(pci->dev, "Outbound iATU is not being enabled\n"); | 140 | dev_err(pci->dev, "Outbound iATU is not being enabled\n"); |
141 | } | 141 | } |
@@ -178,7 +178,7 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type, | |||
178 | if (val & PCIE_ATU_ENABLE) | 178 | if (val & PCIE_ATU_ENABLE) |
179 | return; | 179 | return; |
180 | 180 | ||
181 | usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX); | 181 | mdelay(LINK_WAIT_IATU); |
182 | } | 182 | } |
183 | dev_err(pci->dev, "Outbound iATU is not being enabled\n"); | 183 | dev_err(pci->dev, "Outbound iATU is not being enabled\n"); |
184 | } | 184 | } |
@@ -236,7 +236,7 @@ static int dw_pcie_prog_inbound_atu_unroll(struct dw_pcie *pci, int index, | |||
236 | if (val & PCIE_ATU_ENABLE) | 236 | if (val & PCIE_ATU_ENABLE) |
237 | return 0; | 237 | return 0; |
238 | 238 | ||
239 | usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX); | 239 | mdelay(LINK_WAIT_IATU); |
240 | } | 240 | } |
241 | dev_err(pci->dev, "Inbound iATU is not being enabled\n"); | 241 | dev_err(pci->dev, "Inbound iATU is not being enabled\n"); |
242 | 242 | ||
@@ -282,7 +282,7 @@ int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int bar, | |||
282 | if (val & PCIE_ATU_ENABLE) | 282 | if (val & PCIE_ATU_ENABLE) |
283 | return 0; | 283 | return 0; |
284 | 284 | ||
285 | usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX); | 285 | mdelay(LINK_WAIT_IATU); |
286 | } | 286 | } |
287 | dev_err(pci->dev, "Inbound iATU is not being enabled\n"); | 287 | dev_err(pci->dev, "Inbound iATU is not being enabled\n"); |
288 | 288 | ||
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index 96126fd8403c..9f1a5e399b70 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h | |||
@@ -26,8 +26,7 @@ | |||
26 | 26 | ||
27 | /* Parameters for the waiting for iATU enabled routine */ | 27 | /* Parameters for the waiting for iATU enabled routine */ |
28 | #define LINK_WAIT_MAX_IATU_RETRIES 5 | 28 | #define LINK_WAIT_MAX_IATU_RETRIES 5 |
29 | #define LINK_WAIT_IATU_MIN 9000 | 29 | #define LINK_WAIT_IATU 9 |
30 | #define LINK_WAIT_IATU_MAX 10000 | ||
31 | 30 | ||
32 | /* Synopsys-specific PCIe configuration registers */ | 31 | /* Synopsys-specific PCIe configuration registers */ |
33 | #define PCIE_PORT_LINK_CONTROL 0x710 | 32 | #define PCIE_PORT_LINK_CONTROL 0x710 |