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

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
Loading
Loading
Loading
Loading
+29 −17
Original line number Diff line number Diff line
@@ -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);
+7 −2
Original line number Diff line number Diff line
@@ -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;
+10 −9
Original line number Diff line number Diff line
@@ -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);

	epc = epc_group->epc;
	epf = epf_group->epf;
	ret = pci_epc_add_epf(epc, epf);
	if (ret)
		goto err_add_epf;
	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,
				      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);
	epf->func_no = func_no;

	ret = pci_epc_add_epf(epc, epf);
	if (ret)
		goto err_add_epf;

	ret = pci_epf_bind(epf);
	if (ret)
		goto err_epf_bind;
+0 −10
Original line number Diff line number Diff line
@@ -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;

+2 −2
Original line number Diff line number Diff line
@@ -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)