Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7c7a0e94 authored by Gabriele Paoloni's avatar Gabriele Paoloni Committed by Bjorn Helgaas
Browse files

ARM/PCI: Move align_resource function pointer to pci_host_bridge structure



Commit b3a72384 ("ARM/PCI: Replace pci_sys_data->align_resource with
global function pointer") introduced an ARM-specific align_resource()
function pointer.  This is not portable to other arches and doesn't work
for platforms with two different PCIe host bridge controllers.

Move the function pointer to the pci_host_bridge structure so each host
bridge driver can specify its own align_resource() function.

Signed-off-by: default avatarGabriele Paoloni <gabriele.paoloni@huawei.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Reviewed-by: default avatarArnd Bergmann <arnd@arndb.de>
parent 9f55cf56
Loading
Loading
Loading
Loading
+11 −8
Original line number Diff line number Diff line
@@ -17,11 +17,6 @@
#include <asm/mach/pci.h>

static int debug_pci;
static resource_size_t (*align_resource)(struct pci_dev *dev,
		  const struct resource *res,
		  resource_size_t start,
		  resource_size_t size,
		  resource_size_t align) = NULL;

/*
 * We can't use pci_get_device() here since we are
@@ -461,7 +456,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
		sys->busnr   = busnr;
		sys->swizzle = hw->swizzle;
		sys->map_irq = hw->map_irq;
		align_resource = hw->align_resource;
		INIT_LIST_HEAD(&sys->resources);

		if (hw->private_data)
@@ -470,6 +464,8 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
		ret = hw->setup(nr, sys);

		if (ret > 0) {
			struct pci_host_bridge *host_bridge;

			ret = pcibios_init_resources(nr, sys);
			if (ret)  {
				kfree(sys);
@@ -491,6 +487,9 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
			busnr = sys->bus->busn_res.end + 1;

			list_add(&sys->node, head);

			host_bridge = pci_find_host_bridge(sys->bus);
			host_bridge->align_resource = hw->align_resource;
		} else {
			kfree(sys);
			if (ret < 0)
@@ -578,14 +577,18 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
{
	struct pci_dev *dev = data;
	resource_size_t start = res->start;
	struct pci_host_bridge *host_bridge;

	if (res->flags & IORESOURCE_IO && start & 0x300)
		start = (start + 0x3ff) & ~0x3ff;

	start = (start + align - 1) & ~(align - 1);

	if (align_resource)
		return align_resource(dev, res, start, size, align);
	host_bridge = pci_find_host_bridge(dev->bus);

	if (host_bridge->align_resource)
		return host_bridge->align_resource(dev, res,
				start, size, align);

	return start;
}
+0 −2
Original line number Diff line number Diff line
@@ -337,6 +337,4 @@ static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe)
}
#endif

struct pci_host_bridge *pci_find_host_bridge(struct pci_bus *bus);

#endif /* DRIVERS_PCI_H */
+9 −0
Original line number Diff line number Diff line
@@ -412,9 +412,18 @@ struct pci_host_bridge {
	void (*release_fn)(struct pci_host_bridge *);
	void *release_data;
	unsigned int ignore_reset_delay:1;	/* for entire hierarchy */
	/* Resource alignment requirements */
	resource_size_t (*align_resource)(struct pci_dev *dev,
			const struct resource *res,
			resource_size_t start,
			resource_size_t size,
			resource_size_t align);
};

#define	to_pci_host_bridge(n) container_of(n, struct pci_host_bridge, dev)

struct pci_host_bridge *pci_find_host_bridge(struct pci_bus *bus);

void pci_set_host_bridge_release(struct pci_host_bridge *bridge,
		     void (*release_fn)(struct pci_host_bridge *),
		     void *release_data);