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
This commit is contained in:
Коммит
7dd113b7ca
|
@ -74,8 +74,7 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, enum pci_barno bar,
|
|||
u32 free_win;
|
||||
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
|
||||
|
||||
free_win = find_first_zero_bit(&ep->ib_window_map,
|
||||
sizeof(ep->ib_window_map));
|
||||
free_win = find_first_zero_bit(ep->ib_window_map, ep->num_ib_windows);
|
||||
if (free_win >= ep->num_ib_windows) {
|
||||
dev_err(pci->dev, "no free inbound window\n");
|
||||
return -EINVAL;
|
||||
|
@ -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;
|
||||
set_bit(free_win, &ep->ib_window_map);
|
||||
set_bit(free_win, ep->ib_window_map);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -100,8 +99,7 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t phys_addr,
|
|||
u32 free_win;
|
||||
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
|
||||
|
||||
free_win = find_first_zero_bit(&ep->ob_window_map,
|
||||
sizeof(ep->ob_window_map));
|
||||
free_win = find_first_zero_bit(ep->ob_window_map, ep->num_ob_windows);
|
||||
if (free_win >= ep->num_ob_windows) {
|
||||
dev_err(pci->dev, "no free outbound window\n");
|
||||
return -EINVAL;
|
||||
|
@ -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,
|
||||
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;
|
||||
|
||||
return 0;
|
||||
|
@ -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_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,
|
||||
|
@ -184,7 +182,7 @@ static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no,
|
|||
return;
|
||||
|
||||
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,
|
||||
|
@ -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)
|
||||
{
|
||||
int val;
|
||||
u32 lower_addr;
|
||||
u32 upper_addr;
|
||||
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
|
||||
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
|
||||
|
||||
val = dw_pcie_readb_dbi(pci, MSI_MESSAGE_CONTROL);
|
||||
val = (val & MSI_CAP_MME_MASK) >> MSI_CAP_MME_SHIFT;
|
||||
|
||||
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))
|
||||
val = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL);
|
||||
if (!(val & MSI_CAP_MSI_EN_MASK))
|
||||
return -EINVAL;
|
||||
|
||||
val = (val & MSI_CAP_MME_MASK) >> MSI_CAP_MME_SHIFT;
|
||||
return val;
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
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);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "unable to read *num-ob-windows* property\n");
|
||||
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,
|
||||
GFP_KERNEL);
|
||||
|
|
|
@ -103,6 +103,7 @@
|
|||
#define MSI_CAP_MMC_SHIFT 1
|
||||
#define MSI_CAP_MMC_MASK (7 << MSI_CAP_MMC_SHIFT)
|
||||
#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_MESSAGE_ADDR_L32 0x54
|
||||
#define MSI_MESSAGE_ADDR_U32 0x58
|
||||
|
@ -117,6 +118,10 @@
|
|||
#define 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 dw_pcie;
|
||||
struct dw_pcie_ep;
|
||||
|
@ -196,8 +201,8 @@ struct dw_pcie_ep {
|
|||
size_t page_size;
|
||||
u8 bar_to_atu[6];
|
||||
phys_addr_t *outbound_addr;
|
||||
unsigned long ib_window_map;
|
||||
unsigned long ob_window_map;
|
||||
unsigned long *ib_window_map;
|
||||
unsigned long *ob_window_map;
|
||||
u32 num_ib_windows;
|
||||
u32 num_ob_windows;
|
||||
void __iomem *msi_mem;
|
||||
|
|
|
@ -101,22 +101,23 @@ static int pci_epc_epf_link(struct config_item *epc_item,
|
|||
{
|
||||
int ret;
|
||||
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_epc_group *epc_group = to_pci_epc_group(epc_item);
|
||||
struct pci_epc *epc = epc_group->epc;
|
||||
struct pci_epf *epf = epf_group->epf;
|
||||
|
||||
func_no = find_first_zero_bit(&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);
|
||||
epf->func_no = func_no;
|
||||
|
||||
epc = epc_group->epc;
|
||||
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,
|
||||
sizeof(epc_group->function_num_map));
|
||||
set_bit(func_no, &epc_group->function_num_map);
|
||||
epf->func_no = func_no;
|
||||
|
||||
ret = pci_epf_bind(epf);
|
||||
if (ret)
|
||||
goto err_epf_bind;
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
|
@ -381,7 +380,6 @@ EXPORT_SYMBOL_GPL(pci_epc_write_header);
|
|||
int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct device *dev = epc->dev.parent;
|
||||
|
||||
if (epf->epc)
|
||||
return -EBUSY;
|
||||
|
@ -393,12 +391,6 @@ int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf)
|
|||
return -EINVAL;
|
||||
|
||||
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);
|
||||
list_add_tail(&epf->list, &epc->pci_epf);
|
||||
|
@ -513,9 +505,7 @@ __pci_epc_create(struct device *dev, const struct pci_epc_ops *ops,
|
|||
INIT_LIST_HEAD(&epc->pci_epf);
|
||||
|
||||
device_initialize(&epc->dev);
|
||||
dma_set_coherent_mask(&epc->dev, dev->coherent_dma_mask);
|
||||
epc->dev.class = pci_epc_class;
|
||||
epc->dev.dma_mask = dev->dma_mask;
|
||||
epc->dev.parent = dev;
|
||||
epc->ops = ops;
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
struct device *dev = &epf->dev;
|
||||
struct device *dev = epf->epc->dev.parent;
|
||||
|
||||
if (!addr)
|
||||
return;
|
||||
|
@ -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 *space;
|
||||
struct device *dev = &epf->dev;
|
||||
struct device *dev = epf->epc->dev.parent;
|
||||
dma_addr_t phys_addr;
|
||||
|
||||
if (size < 128)
|
||||
|
|
Загрузка…
Ссылка в новой задаче