PCI, of: Move PCI I/O space management to PCI core code
authorTomasz Nowicki <tn@semihalf.com>
Wed, 11 May 2016 22:34:51 +0000 (17:34 -0500)
committerBjorn Helgaas <bhelgaas@google.com>
Thu, 12 May 2016 12:07:42 +0000 (07:07 -0500)
No functional changes in this patch.

PCI I/O space mapping code does not depend on OF; therefore it can be moved
to PCI core code.  This way we will be able to use it, e.g., in ACPI PCI
code.

Suggested-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
CC: Arnd Bergmann <arnd@arndb.de>
CC: Liviu Dudau <Liviu.Dudau@arm.com>
drivers/of/address.c
drivers/pci/pci.c
include/linux/of_address.h
include/linux/pci.h

index 91a469d55b8fb8d36460cfa8ea3f2a9bad3f6106..0a553c084a81c25ada2442071a27c50cc1f0086f 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/ioport.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
+#include <linux/pci.h>
 #include <linux/pci_regs.h>
 #include <linux/sizes.h>
 #include <linux/slab.h>
@@ -673,121 +674,6 @@ const __be32 *of_get_address(struct device_node *dev, int index, u64 *size,
 }
 EXPORT_SYMBOL(of_get_address);
 
-#ifdef PCI_IOBASE
-struct io_range {
-       struct list_head list;
-       phys_addr_t start;
-       resource_size_t size;
-};
-
-static LIST_HEAD(io_range_list);
-static DEFINE_SPINLOCK(io_range_lock);
-#endif
-
-/*
- * Record the PCI IO range (expressed as CPU physical address + size).
- * Return a negative value if an error has occured, zero otherwise
- */
-int __weak pci_register_io_range(phys_addr_t addr, resource_size_t size)
-{
-       int err = 0;
-
-#ifdef PCI_IOBASE
-       struct io_range *range;
-       resource_size_t allocated_size = 0;
-
-       /* check if the range hasn't been previously recorded */
-       spin_lock(&io_range_lock);
-       list_for_each_entry(range, &io_range_list, list) {
-               if (addr >= range->start && addr + size <= range->start + size) {
-                       /* range already registered, bail out */
-                       goto end_register;
-               }
-               allocated_size += range->size;
-       }
-
-       /* range not registed yet, check for available space */
-       if (allocated_size + size - 1 > IO_SPACE_LIMIT) {
-               /* if it's too big check if 64K space can be reserved */
-               if (allocated_size + SZ_64K - 1 > IO_SPACE_LIMIT) {
-                       err = -E2BIG;
-                       goto end_register;
-               }
-
-               size = SZ_64K;
-               pr_warn("Requested IO range too big, new size set to 64K\n");
-       }
-
-       /* add the range to the list */
-       range = kzalloc(sizeof(*range), GFP_ATOMIC);
-       if (!range) {
-               err = -ENOMEM;
-               goto end_register;
-       }
-
-       range->start = addr;
-       range->size = size;
-
-       list_add_tail(&range->list, &io_range_list);
-
-end_register:
-       spin_unlock(&io_range_lock);
-#endif
-
-       return err;
-}
-
-phys_addr_t pci_pio_to_address(unsigned long pio)
-{
-       phys_addr_t address = (phys_addr_t)OF_BAD_ADDR;
-
-#ifdef PCI_IOBASE
-       struct io_range *range;
-       resource_size_t allocated_size = 0;
-
-       if (pio > IO_SPACE_LIMIT)
-               return address;
-
-       spin_lock(&io_range_lock);
-       list_for_each_entry(range, &io_range_list, list) {
-               if (pio >= allocated_size && pio < allocated_size + range->size) {
-                       address = range->start + pio - allocated_size;
-                       break;
-               }
-               allocated_size += range->size;
-       }
-       spin_unlock(&io_range_lock);
-#endif
-
-       return address;
-}
-
-unsigned long __weak pci_address_to_pio(phys_addr_t address)
-{
-#ifdef PCI_IOBASE
-       struct io_range *res;
-       resource_size_t offset = 0;
-       unsigned long addr = -1;
-
-       spin_lock(&io_range_lock);
-       list_for_each_entry(res, &io_range_list, list) {
-               if (address >= res->start && address < res->start + res->size) {
-                       addr = address - res->start + offset;
-                       break;
-               }
-               offset += res->size;
-       }
-       spin_unlock(&io_range_lock);
-
-       return addr;
-#else
-       if (address > IO_SPACE_LIMIT)
-               return (unsigned long)-1;
-
-       return (unsigned long) address;
-#endif
-}
-
 static int __of_address_to_resource(struct device_node *dev,
                const __be32 *addrp, u64 size, unsigned int flags,
                const char *name, struct resource *r)
index 25e0327d4429bfc00a694f66f4a28fc7233fb7df..bc0c914b8afcfb05b4bc2a4e2153993091cd1bbf 100644 (file)
@@ -3021,6 +3021,121 @@ int pci_request_regions_exclusive(struct pci_dev *pdev, const char *res_name)
 }
 EXPORT_SYMBOL(pci_request_regions_exclusive);
 
+#ifdef PCI_IOBASE
+struct io_range {
+       struct list_head list;
+       phys_addr_t start;
+       resource_size_t size;
+};
+
+static LIST_HEAD(io_range_list);
+static DEFINE_SPINLOCK(io_range_lock);
+#endif
+
+/*
+ * Record the PCI IO range (expressed as CPU physical address + size).
+ * Return a negative value if an error has occured, zero otherwise
+ */
+int __weak pci_register_io_range(phys_addr_t addr, resource_size_t size)
+{
+       int err = 0;
+
+#ifdef PCI_IOBASE
+       struct io_range *range;
+       resource_size_t allocated_size = 0;
+
+       /* check if the range hasn't been previously recorded */
+       spin_lock(&io_range_lock);
+       list_for_each_entry(range, &io_range_list, list) {
+               if (addr >= range->start && addr + size <= range->start + size) {
+                       /* range already registered, bail out */
+                       goto end_register;
+               }
+               allocated_size += range->size;
+       }
+
+       /* range not registed yet, check for available space */
+       if (allocated_size + size - 1 > IO_SPACE_LIMIT) {
+               /* if it's too big check if 64K space can be reserved */
+               if (allocated_size + SZ_64K - 1 > IO_SPACE_LIMIT) {
+                       err = -E2BIG;
+                       goto end_register;
+               }
+
+               size = SZ_64K;
+               pr_warn("Requested IO range too big, new size set to 64K\n");
+       }
+
+       /* add the range to the list */
+       range = kzalloc(sizeof(*range), GFP_ATOMIC);
+       if (!range) {
+               err = -ENOMEM;
+               goto end_register;
+       }
+
+       range->start = addr;
+       range->size = size;
+
+       list_add_tail(&range->list, &io_range_list);
+
+end_register:
+       spin_unlock(&io_range_lock);
+#endif
+
+       return err;
+}
+
+phys_addr_t pci_pio_to_address(unsigned long pio)
+{
+       phys_addr_t address = (phys_addr_t)OF_BAD_ADDR;
+
+#ifdef PCI_IOBASE
+       struct io_range *range;
+       resource_size_t allocated_size = 0;
+
+       if (pio > IO_SPACE_LIMIT)
+               return address;
+
+       spin_lock(&io_range_lock);
+       list_for_each_entry(range, &io_range_list, list) {
+               if (pio >= allocated_size && pio < allocated_size + range->size) {
+                       address = range->start + pio - allocated_size;
+                       break;
+               }
+               allocated_size += range->size;
+       }
+       spin_unlock(&io_range_lock);
+#endif
+
+       return address;
+}
+
+unsigned long __weak pci_address_to_pio(phys_addr_t address)
+{
+#ifdef PCI_IOBASE
+       struct io_range *res;
+       resource_size_t offset = 0;
+       unsigned long addr = -1;
+
+       spin_lock(&io_range_lock);
+       list_for_each_entry(res, &io_range_list, list) {
+               if (address >= res->start && address < res->start + res->size) {
+                       addr = address - res->start + offset;
+                       break;
+               }
+               offset += res->size;
+       }
+       spin_unlock(&io_range_lock);
+
+       return addr;
+#else
+       if (address > IO_SPACE_LIMIT)
+               return (unsigned long)-1;
+
+       return (unsigned long) address;
+#endif
+}
+
 /**
  *     pci_remap_iospace - Remap the memory mapped I/O space
  *     @res: Resource describing the I/O space
index 01c0a556448b227e6cbc4717a78d62d399d64494..37864734ca50f76838cc1e95ea92f8d37bbdc856 100644 (file)
@@ -47,10 +47,6 @@ void __iomem *of_io_request_and_map(struct device_node *device,
 extern const __be32 *of_get_address(struct device_node *dev, int index,
                           u64 *size, unsigned int *flags);
 
-extern int pci_register_io_range(phys_addr_t addr, resource_size_t size);
-extern unsigned long pci_address_to_pio(phys_addr_t addr);
-extern phys_addr_t pci_pio_to_address(unsigned long pio);
-
 extern int of_pci_range_parser_init(struct of_pci_range_parser *parser,
                        struct device_node *node);
 extern struct of_pci_range *of_pci_range_parser_one(
@@ -86,11 +82,6 @@ static inline const __be32 *of_get_address(struct device_node *dev, int index,
        return NULL;
 }
 
-static inline phys_addr_t pci_pio_to_address(unsigned long pio)
-{
-       return 0;
-}
-
 static inline int of_pci_range_parser_init(struct of_pci_range_parser *parser,
                        struct device_node *node)
 {
index 004b8133417dc9dd54315b1ca5f15a9cc28e9a2a..1824ef80e10d2a405335e91c3aed5a3300085a32 100644 (file)
@@ -1164,6 +1164,9 @@ int __must_check pci_bus_alloc_resource(struct pci_bus *bus,
                        void *alignf_data);
 
 
+int pci_register_io_range(phys_addr_t addr, resource_size_t size);
+unsigned long pci_address_to_pio(phys_addr_t addr);
+phys_addr_t pci_pio_to_address(unsigned long pio);
 int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr);
 
 static inline pci_bus_addr_t pci_bus_address(struct pci_dev *pdev, int bar)
@@ -1480,6 +1483,8 @@ static inline int pci_request_regions(struct pci_dev *dev, const char *res_name)
 { return -EIO; }
 static inline void pci_release_regions(struct pci_dev *dev) { }
 
+static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; }
+
 static inline void pci_block_cfg_access(struct pci_dev *dev) { }
 static inline int pci_block_cfg_access_in_atomic(struct pci_dev *dev)
 { return 0; }