Commit 7dd113b7 authored by Bjorn Helgaas's avatar Bjorn Helgaas Committed by Bjorn Helgaas

Merge remote-tracking branch 'lorenzo/pci/endpoint' into next

* lorenzo/pci/endpoint:
  PCI: endpoint: Use EPC's device in dma_alloc_coherent()/dma_free_coherent()
  PCI: designware-ep: Fix ->get_msi() to check MSI_EN bit
  PCI: endpoint: Fix find_first_zero_bit() usage
  PCI: endpoint: Populate func_no before calling pci_epc_add_epf()
  PCI: designware-ep: Fix find_first_zero_bit() usage
parents 16093362 b330104f
...@@ -74,8 +74,7 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, enum pci_barno bar, ...@@ -74,8 +74,7 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, enum pci_barno bar,
u32 free_win; u32 free_win;
struct dw_pcie *pci = to_dw_pcie_from_ep(ep); struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
free_win = find_first_zero_bit(&ep->ib_window_map, free_win = find_first_zero_bit(ep->ib_window_map, ep->num_ib_windows);
sizeof(ep->ib_window_map));
if (free_win >= ep->num_ib_windows) { if (free_win >= ep->num_ib_windows) {
dev_err(pci->dev, "no free inbound window\n"); dev_err(pci->dev, "no free inbound window\n");
return -EINVAL; return -EINVAL;
...@@ -89,7 +88,7 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, enum pci_barno bar, ...@@ -89,7 +88,7 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, enum pci_barno bar,
} }
ep->bar_to_atu[bar] = free_win; ep->bar_to_atu[bar] = free_win;
set_bit(free_win, &ep->ib_window_map); set_bit(free_win, ep->ib_window_map);
return 0; return 0;
} }
...@@ -100,8 +99,7 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t phys_addr, ...@@ -100,8 +99,7 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t phys_addr,
u32 free_win; u32 free_win;
struct dw_pcie *pci = to_dw_pcie_from_ep(ep); struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
free_win = find_first_zero_bit(&ep->ob_window_map, free_win = find_first_zero_bit(ep->ob_window_map, ep->num_ob_windows);
sizeof(ep->ob_window_map));
if (free_win >= ep->num_ob_windows) { if (free_win >= ep->num_ob_windows) {
dev_err(pci->dev, "no free outbound window\n"); dev_err(pci->dev, "no free outbound window\n");
return -EINVAL; return -EINVAL;
...@@ -110,7 +108,7 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t phys_addr, ...@@ -110,7 +108,7 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t phys_addr,
dw_pcie_prog_outbound_atu(pci, free_win, PCIE_ATU_TYPE_MEM, dw_pcie_prog_outbound_atu(pci, free_win, PCIE_ATU_TYPE_MEM,
phys_addr, pci_addr, size); phys_addr, pci_addr, size);
set_bit(free_win, &ep->ob_window_map); set_bit(free_win, ep->ob_window_map);
ep->outbound_addr[free_win] = phys_addr; ep->outbound_addr[free_win] = phys_addr;
return 0; return 0;
...@@ -126,7 +124,7 @@ static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no, ...@@ -126,7 +124,7 @@ static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no,
dw_pcie_ep_reset_bar(pci, bar); dw_pcie_ep_reset_bar(pci, bar);
dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_INBOUND); dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_INBOUND);
clear_bit(atu_index, &ep->ib_window_map); clear_bit(atu_index, ep->ib_window_map);
} }
static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no,
...@@ -184,7 +182,7 @@ static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no, ...@@ -184,7 +182,7 @@ static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no,
return; return;
dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_OUTBOUND); dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_OUTBOUND);
clear_bit(atu_index, &ep->ob_window_map); clear_bit(atu_index, ep->ob_window_map);
} }
static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no, static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no,
...@@ -207,20 +205,14 @@ static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no, ...@@ -207,20 +205,14 @@ static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no,
static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no) static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no)
{ {
int val; int val;
u32 lower_addr;
u32 upper_addr;
struct dw_pcie_ep *ep = epc_get_drvdata(epc); struct dw_pcie_ep *ep = epc_get_drvdata(epc);
struct dw_pcie *pci = to_dw_pcie_from_ep(ep); struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
val = dw_pcie_readb_dbi(pci, MSI_MESSAGE_CONTROL); val = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL);
val = (val & MSI_CAP_MME_MASK) >> MSI_CAP_MME_SHIFT; if (!(val & MSI_CAP_MSI_EN_MASK))
lower_addr = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_L32);
upper_addr = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_U32);
if (!(lower_addr || upper_addr))
return -EINVAL; return -EINVAL;
val = (val & MSI_CAP_MME_MASK) >> MSI_CAP_MME_SHIFT;
return val; return val;
} }
...@@ -350,12 +342,32 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) ...@@ -350,12 +342,32 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
dev_err(dev, "unable to read *num-ib-windows* property\n"); dev_err(dev, "unable to read *num-ib-windows* property\n");
return ret; return ret;
} }
if (ep->num_ib_windows > MAX_IATU_IN) {
dev_err(dev, "invalid *num-ib-windows*\n");
return -EINVAL;
}
ret = of_property_read_u32(np, "num-ob-windows", &ep->num_ob_windows); ret = of_property_read_u32(np, "num-ob-windows", &ep->num_ob_windows);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "unable to read *num-ob-windows* property\n"); dev_err(dev, "unable to read *num-ob-windows* property\n");
return ret; return ret;
} }
if (ep->num_ob_windows > MAX_IATU_OUT) {
dev_err(dev, "invalid *num-ob-windows*\n");
return -EINVAL;
}
ep->ib_window_map = devm_kzalloc(dev, sizeof(long) *
BITS_TO_LONGS(ep->num_ib_windows),
GFP_KERNEL);
if (!ep->ib_window_map)
return -ENOMEM;
ep->ob_window_map = devm_kzalloc(dev, sizeof(long) *
BITS_TO_LONGS(ep->num_ob_windows),
GFP_KERNEL);
if (!ep->ob_window_map)
return -ENOMEM;
addr = devm_kzalloc(dev, sizeof(phys_addr_t) * ep->num_ob_windows, addr = devm_kzalloc(dev, sizeof(phys_addr_t) * ep->num_ob_windows,
GFP_KERNEL); GFP_KERNEL);
......
...@@ -103,6 +103,7 @@ ...@@ -103,6 +103,7 @@
#define MSI_CAP_MMC_SHIFT 1 #define MSI_CAP_MMC_SHIFT 1
#define MSI_CAP_MMC_MASK (7 << MSI_CAP_MMC_SHIFT) #define MSI_CAP_MMC_MASK (7 << MSI_CAP_MMC_SHIFT)
#define MSI_CAP_MME_SHIFT 4 #define MSI_CAP_MME_SHIFT 4
#define MSI_CAP_MSI_EN_MASK 0x1
#define MSI_CAP_MME_MASK (7 << MSI_CAP_MME_SHIFT) #define MSI_CAP_MME_MASK (7 << MSI_CAP_MME_SHIFT)
#define MSI_MESSAGE_ADDR_L32 0x54 #define MSI_MESSAGE_ADDR_L32 0x54
#define MSI_MESSAGE_ADDR_U32 0x58 #define MSI_MESSAGE_ADDR_U32 0x58
...@@ -117,6 +118,10 @@ ...@@ -117,6 +118,10 @@
#define MAX_MSI_IRQS 32 #define MAX_MSI_IRQS 32
#define MAX_MSI_CTRLS (MAX_MSI_IRQS / 32) #define MAX_MSI_CTRLS (MAX_MSI_IRQS / 32)
/* Maximum number of inbound/outbound iATUs */
#define MAX_IATU_IN 256
#define MAX_IATU_OUT 256
struct pcie_port; struct pcie_port;
struct dw_pcie; struct dw_pcie;
struct dw_pcie_ep; struct dw_pcie_ep;
...@@ -196,8 +201,8 @@ struct dw_pcie_ep { ...@@ -196,8 +201,8 @@ struct dw_pcie_ep {
size_t page_size; size_t page_size;
u8 bar_to_atu[6]; u8 bar_to_atu[6];
phys_addr_t *outbound_addr; phys_addr_t *outbound_addr;
unsigned long ib_window_map; unsigned long *ib_window_map;
unsigned long ob_window_map; unsigned long *ob_window_map;
u32 num_ib_windows; u32 num_ib_windows;
u32 num_ob_windows; u32 num_ob_windows;
void __iomem *msi_mem; void __iomem *msi_mem;
......
...@@ -101,22 +101,23 @@ static int pci_epc_epf_link(struct config_item *epc_item, ...@@ -101,22 +101,23 @@ static int pci_epc_epf_link(struct config_item *epc_item,
{ {
int ret; int ret;
u32 func_no = 0; u32 func_no = 0;
struct pci_epc *epc;
struct pci_epf *epf;
struct pci_epf_group *epf_group = to_pci_epf_group(epf_item); struct pci_epf_group *epf_group = to_pci_epf_group(epf_item);
struct pci_epc_group *epc_group = to_pci_epc_group(epc_item); struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
struct pci_epc *epc = epc_group->epc;
epc = epc_group->epc; struct pci_epf *epf = epf_group->epf;
epf = epf_group->epf;
ret = pci_epc_add_epf(epc, epf);
if (ret)
goto err_add_epf;
func_no = find_first_zero_bit(&epc_group->function_num_map, func_no = find_first_zero_bit(&epc_group->function_num_map,
sizeof(epc_group->function_num_map)); BITS_PER_LONG);
if (func_no >= BITS_PER_LONG)
return -EINVAL;
set_bit(func_no, &epc_group->function_num_map); set_bit(func_no, &epc_group->function_num_map);
epf->func_no = func_no; epf->func_no = func_no;
ret = pci_epc_add_epf(epc, epf);
if (ret)
goto err_add_epf;
ret = pci_epf_bind(epf); ret = pci_epf_bind(epf);
if (ret) if (ret)
goto err_epf_bind; goto err_epf_bind;
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
*/ */
#include <linux/device.h> #include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_device.h> #include <linux/of_device.h>
...@@ -381,7 +380,6 @@ EXPORT_SYMBOL_GPL(pci_epc_write_header); ...@@ -381,7 +380,6 @@ EXPORT_SYMBOL_GPL(pci_epc_write_header);
int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf) int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf)
{ {
unsigned long flags; unsigned long flags;
struct device *dev = epc->dev.parent;
if (epf->epc) if (epf->epc)
return -EBUSY; return -EBUSY;
...@@ -393,12 +391,6 @@ int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf) ...@@ -393,12 +391,6 @@ int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf)
return -EINVAL; return -EINVAL;
epf->epc = epc; epf->epc = epc;
if (dev->of_node) {
of_dma_configure(&epf->dev, dev->of_node);
} else {
dma_set_coherent_mask(&epf->dev, epc->dev.coherent_dma_mask);
epf->dev.dma_mask = epc->dev.dma_mask;
}
spin_lock_irqsave(&epc->lock, flags); spin_lock_irqsave(&epc->lock, flags);
list_add_tail(&epf->list, &epc->pci_epf); list_add_tail(&epf->list, &epc->pci_epf);
...@@ -513,9 +505,7 @@ __pci_epc_create(struct device *dev, const struct pci_epc_ops *ops, ...@@ -513,9 +505,7 @@ __pci_epc_create(struct device *dev, const struct pci_epc_ops *ops,
INIT_LIST_HEAD(&epc->pci_epf); INIT_LIST_HEAD(&epc->pci_epf);
device_initialize(&epc->dev); device_initialize(&epc->dev);
dma_set_coherent_mask(&epc->dev, dev->coherent_dma_mask);
epc->dev.class = pci_epc_class; epc->dev.class = pci_epc_class;
epc->dev.dma_mask = dev->dma_mask;
epc->dev.parent = dev; epc->dev.parent = dev;
epc->ops = ops; epc->ops = ops;
......
...@@ -99,7 +99,7 @@ EXPORT_SYMBOL_GPL(pci_epf_bind); ...@@ -99,7 +99,7 @@ EXPORT_SYMBOL_GPL(pci_epf_bind);
*/ */
void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar) void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar)
{ {
struct device *dev = &epf->dev; struct device *dev = epf->epc->dev.parent;
if (!addr) if (!addr)
return; return;
...@@ -122,7 +122,7 @@ EXPORT_SYMBOL_GPL(pci_epf_free_space); ...@@ -122,7 +122,7 @@ EXPORT_SYMBOL_GPL(pci_epf_free_space);
void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar) void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar)
{ {
void *space; void *space;
struct device *dev = &epf->dev; struct device *dev = epf->epc->dev.parent;
dma_addr_t phys_addr; dma_addr_t phys_addr;
if (size < 128) if (size < 128)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment