diff options
| -rw-r--r-- | drivers/pci/dwc/pcie-designware-ep.c | 34 | ||||
| -rw-r--r-- | drivers/pci/dwc/pcie-designware.h | 8 |
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 | ||
| 127 | static int dw_pcie_ep_set_bar(struct pci_epc *epc, enum pci_barno bar, | 125 | static 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 | ||
| 181 | static int dw_pcie_ep_map_addr(struct pci_epc *epc, phys_addr_t addr, | 179 | static 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 | |||
| 116 | struct pcie_port; | 120 | struct pcie_port; |
| 117 | struct dw_pcie; | 121 | struct dw_pcie; |
| 118 | struct dw_pcie_ep; | 122 | struct 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 | }; |
