aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/dwc/pcie-designware-ep.c34
-rw-r--r--drivers/pci/dwc/pcie-designware.h8
2 files changed, 32 insertions, 10 deletions
diff --git a/drivers/pci/dwc/pcie-designware-ep.c b/drivers/pci/dwc/pcie-designware-ep.c
index d53d5f168363..d5eb143040e3 100644
--- a/drivers/pci/dwc/pcie-designware-ep.c
+++ b/drivers/pci/dwc/pcie-designware-ep.c
@@ -70,8 +70,7 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, enum pci_barno bar,
70 u32 free_win; 70 u32 free_win;
71 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 71 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
72 72
73 free_win = find_first_zero_bit(&ep->ib_window_map, 73 free_win = find_first_zero_bit(ep->ib_window_map, ep->num_ib_windows);
74 sizeof(ep->ib_window_map));
75 if (free_win >= ep->num_ib_windows) { 74 if (free_win >= ep->num_ib_windows) {
76 dev_err(pci->dev, "no free inbound window\n"); 75 dev_err(pci->dev, "no free inbound window\n");
77 return -EINVAL; 76 return -EINVAL;
@@ -85,7 +84,7 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, enum pci_barno bar,
85 } 84 }
86 85
87 ep->bar_to_atu[bar] = free_win; 86 ep->bar_to_atu[bar] = free_win;
88 set_bit(free_win, &ep->ib_window_map); 87 set_bit(free_win, ep->ib_window_map);
89 88
90 return 0; 89 return 0;
91} 90}
@@ -96,8 +95,7 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t phys_addr,
96 u32 free_win; 95 u32 free_win;
97 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 96 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
98 97
99 free_win = find_first_zero_bit(&ep->ob_window_map, 98 free_win = find_first_zero_bit(ep->ob_window_map, ep->num_ob_windows);
100 sizeof(ep->ob_window_map));
101 if (free_win >= ep->num_ob_windows) { 99 if (free_win >= ep->num_ob_windows) {
102 dev_err(pci->dev, "no free outbound window\n"); 100 dev_err(pci->dev, "no free outbound window\n");
103 return -EINVAL; 101 return -EINVAL;
@@ -106,7 +104,7 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t phys_addr,
106 dw_pcie_prog_outbound_atu(pci, free_win, PCIE_ATU_TYPE_MEM, 104 dw_pcie_prog_outbound_atu(pci, free_win, PCIE_ATU_TYPE_MEM,
107 phys_addr, pci_addr, size); 105 phys_addr, pci_addr, size);
108 106
109 set_bit(free_win, &ep->ob_window_map); 107 set_bit(free_win, ep->ob_window_map);
110 ep->outbound_addr[free_win] = phys_addr; 108 ep->outbound_addr[free_win] = phys_addr;
111 109
112 return 0; 110 return 0;
@@ -121,7 +119,7 @@ static void dw_pcie_ep_clear_bar(struct pci_epc *epc, enum pci_barno bar)
121 dw_pcie_ep_reset_bar(pci, bar); 119 dw_pcie_ep_reset_bar(pci, bar);
122 120
123 dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_INBOUND); 121 dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_INBOUND);
124 clear_bit(atu_index, &ep->ib_window_map); 122 clear_bit(atu_index, ep->ib_window_map);
125} 123}
126 124
127static int dw_pcie_ep_set_bar(struct pci_epc *epc, enum pci_barno bar, 125static int dw_pcie_ep_set_bar(struct pci_epc *epc, enum pci_barno bar,
@@ -175,7 +173,7 @@ static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, phys_addr_t addr)
175 return; 173 return;
176 174
177 dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_OUTBOUND); 175 dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_OUTBOUND);
178 clear_bit(atu_index, &ep->ob_window_map); 176 clear_bit(atu_index, ep->ob_window_map);
179} 177}
180 178
181static int dw_pcie_ep_map_addr(struct pci_epc *epc, phys_addr_t addr, 179static int dw_pcie_ep_map_addr(struct pci_epc *epc, phys_addr_t addr,
@@ -298,12 +296,32 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
298 dev_err(dev, "unable to read *num-ib-windows* property\n"); 296 dev_err(dev, "unable to read *num-ib-windows* property\n");
299 return ret; 297 return ret;
300 } 298 }
299 if (ep->num_ib_windows > MAX_IATU_IN) {
300 dev_err(dev, "invalid *num-ib-windows*\n");
301 return -EINVAL;
302 }
301 303
302 ret = of_property_read_u32(np, "num-ob-windows", &ep->num_ob_windows); 304 ret = of_property_read_u32(np, "num-ob-windows", &ep->num_ob_windows);
303 if (ret < 0) { 305 if (ret < 0) {
304 dev_err(dev, "unable to read *num-ob-windows* property\n"); 306 dev_err(dev, "unable to read *num-ob-windows* property\n");
305 return ret; 307 return ret;
306 } 308 }
309 if (ep->num_ob_windows > MAX_IATU_OUT) {
310 dev_err(dev, "invalid *num-ob-windows*\n");
311 return -EINVAL;
312 }
313
314 ep->ib_window_map = devm_kzalloc(dev, sizeof(long) *
315 BITS_TO_LONGS(ep->num_ib_windows),
316 GFP_KERNEL);
317 if (!ep->ib_window_map)
318 return -ENOMEM;
319
320 ep->ob_window_map = devm_kzalloc(dev, sizeof(long) *
321 BITS_TO_LONGS(ep->num_ob_windows),
322 GFP_KERNEL);
323 if (!ep->ob_window_map)
324 return -ENOMEM;
307 325
308 addr = devm_kzalloc(dev, sizeof(phys_addr_t) * ep->num_ob_windows, 326 addr = devm_kzalloc(dev, sizeof(phys_addr_t) * ep->num_ob_windows,
309 GFP_KERNEL); 327 GFP_KERNEL);
diff --git a/drivers/pci/dwc/pcie-designware.h b/drivers/pci/dwc/pcie-designware.h
index e5d9d77b778e..e6fd0b024b21 100644
--- a/drivers/pci/dwc/pcie-designware.h
+++ b/drivers/pci/dwc/pcie-designware.h
@@ -113,6 +113,10 @@
113#define MAX_MSI_IRQS 32 113#define MAX_MSI_IRQS 32
114#define MAX_MSI_CTRLS (MAX_MSI_IRQS / 32) 114#define MAX_MSI_CTRLS (MAX_MSI_IRQS / 32)
115 115
116/* Maximum number of inbound/outbound iATUs */
117#define MAX_IATU_IN 256
118#define MAX_IATU_OUT 256
119
116struct pcie_port; 120struct pcie_port;
117struct dw_pcie; 121struct dw_pcie;
118struct dw_pcie_ep; 122struct dw_pcie_ep;
@@ -192,8 +196,8 @@ struct dw_pcie_ep {
192 size_t page_size; 196 size_t page_size;
193 u8 bar_to_atu[6]; 197 u8 bar_to_atu[6];
194 phys_addr_t *outbound_addr; 198 phys_addr_t *outbound_addr;
195 unsigned long ib_window_map; 199 unsigned long *ib_window_map;
196 unsigned long ob_window_map; 200 unsigned long *ob_window_map;
197 u32 num_ib_windows; 201 u32 num_ib_windows;
198 u32 num_ob_windows; 202 u32 num_ob_windows;
199}; 203};