diff options
-rw-r--r-- | drivers/of/address.c | 116 | ||||
-rw-r--r-- | drivers/pci/pci.c | 115 | ||||
-rw-r--r-- | include/linux/of_address.h | 9 | ||||
-rw-r--r-- | include/linux/pci.h | 5 |
4 files changed, 121 insertions, 124 deletions
diff --git a/drivers/of/address.c b/drivers/of/address.c index 91a469d55b8f..0a553c084a81 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/ioport.h> | 4 | #include <linux/ioport.h> |
5 | #include <linux/module.h> | 5 | #include <linux/module.h> |
6 | #include <linux/of_address.h> | 6 | #include <linux/of_address.h> |
7 | #include <linux/pci.h> | ||
7 | #include <linux/pci_regs.h> | 8 | #include <linux/pci_regs.h> |
8 | #include <linux/sizes.h> | 9 | #include <linux/sizes.h> |
9 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
@@ -673,121 +674,6 @@ const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, | |||
673 | } | 674 | } |
674 | EXPORT_SYMBOL(of_get_address); | 675 | EXPORT_SYMBOL(of_get_address); |
675 | 676 | ||
676 | #ifdef PCI_IOBASE | ||
677 | struct io_range { | ||
678 | struct list_head list; | ||
679 | phys_addr_t start; | ||
680 | resource_size_t size; | ||
681 | }; | ||
682 | |||
683 | static LIST_HEAD(io_range_list); | ||
684 | static DEFINE_SPINLOCK(io_range_lock); | ||
685 | #endif | ||
686 | |||
687 | /* | ||
688 | * Record the PCI IO range (expressed as CPU physical address + size). | ||
689 | * Return a negative value if an error has occured, zero otherwise | ||
690 | */ | ||
691 | int __weak pci_register_io_range(phys_addr_t addr, resource_size_t size) | ||
692 | { | ||
693 | int err = 0; | ||
694 | |||
695 | #ifdef PCI_IOBASE | ||
696 | struct io_range *range; | ||
697 | resource_size_t allocated_size = 0; | ||
698 | |||
699 | /* check if the range hasn't been previously recorded */ | ||
700 | spin_lock(&io_range_lock); | ||
701 | list_for_each_entry(range, &io_range_list, list) { | ||
702 | if (addr >= range->start && addr + size <= range->start + size) { | ||
703 | /* range already registered, bail out */ | ||
704 | goto end_register; | ||
705 | } | ||
706 | allocated_size += range->size; | ||
707 | } | ||
708 | |||
709 | /* range not registed yet, check for available space */ | ||
710 | if (allocated_size + size - 1 > IO_SPACE_LIMIT) { | ||
711 | /* if it's too big check if 64K space can be reserved */ | ||
712 | if (allocated_size + SZ_64K - 1 > IO_SPACE_LIMIT) { | ||
713 | err = -E2BIG; | ||
714 | goto end_register; | ||
715 | } | ||
716 | |||
717 | size = SZ_64K; | ||
718 | pr_warn("Requested IO range too big, new size set to 64K\n"); | ||
719 | } | ||
720 | |||
721 | /* add the range to the list */ | ||
722 | range = kzalloc(sizeof(*range), GFP_ATOMIC); | ||
723 | if (!range) { | ||
724 | err = -ENOMEM; | ||
725 | goto end_register; | ||
726 | } | ||
727 | |||
728 | range->start = addr; | ||
729 | range->size = size; | ||
730 | |||
731 | list_add_tail(&range->list, &io_range_list); | ||
732 | |||
733 | end_register: | ||
734 | spin_unlock(&io_range_lock); | ||
735 | #endif | ||
736 | |||
737 | return err; | ||
738 | } | ||
739 | |||
740 | phys_addr_t pci_pio_to_address(unsigned long pio) | ||
741 | { | ||
742 | phys_addr_t address = (phys_addr_t)OF_BAD_ADDR; | ||
743 | |||
744 | #ifdef PCI_IOBASE | ||
745 | struct io_range *range; | ||
746 | resource_size_t allocated_size = 0; | ||
747 | |||
748 | if (pio > IO_SPACE_LIMIT) | ||
749 | return address; | ||
750 | |||
751 | spin_lock(&io_range_lock); | ||
752 | list_for_each_entry(range, &io_range_list, list) { | ||
753 | if (pio >= allocated_size && pio < allocated_size + range->size) { | ||
754 | address = range->start + pio - allocated_size; | ||
755 | break; | ||
756 | } | ||
757 | allocated_size += range->size; | ||
758 | } | ||
759 | spin_unlock(&io_range_lock); | ||
760 | #endif | ||
761 | |||
762 | return address; | ||
763 | } | ||
764 | |||
765 | unsigned long __weak pci_address_to_pio(phys_addr_t address) | ||
766 | { | ||
767 | #ifdef PCI_IOBASE | ||
768 | struct io_range *res; | ||
769 | resource_size_t offset = 0; | ||
770 | unsigned long addr = -1; | ||
771 | |||
772 | spin_lock(&io_range_lock); | ||
773 | list_for_each_entry(res, &io_range_list, list) { | ||
774 | if (address >= res->start && address < res->start + res->size) { | ||
775 | addr = address - res->start + offset; | ||
776 | break; | ||
777 | } | ||
778 | offset += res->size; | ||
779 | } | ||
780 | spin_unlock(&io_range_lock); | ||
781 | |||
782 | return addr; | ||
783 | #else | ||
784 | if (address > IO_SPACE_LIMIT) | ||
785 | return (unsigned long)-1; | ||
786 | |||
787 | return (unsigned long) address; | ||
788 | #endif | ||
789 | } | ||
790 | |||
791 | static int __of_address_to_resource(struct device_node *dev, | 677 | static int __of_address_to_resource(struct device_node *dev, |
792 | const __be32 *addrp, u64 size, unsigned int flags, | 678 | const __be32 *addrp, u64 size, unsigned int flags, |
793 | const char *name, struct resource *r) | 679 | const char *name, struct resource *r) |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 25e0327d4429..bc0c914b8afc 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -3021,6 +3021,121 @@ int pci_request_regions_exclusive(struct pci_dev *pdev, const char *res_name) | |||
3021 | } | 3021 | } |
3022 | EXPORT_SYMBOL(pci_request_regions_exclusive); | 3022 | EXPORT_SYMBOL(pci_request_regions_exclusive); |
3023 | 3023 | ||
3024 | #ifdef PCI_IOBASE | ||
3025 | struct io_range { | ||
3026 | struct list_head list; | ||
3027 | phys_addr_t start; | ||
3028 | resource_size_t size; | ||
3029 | }; | ||
3030 | |||
3031 | static LIST_HEAD(io_range_list); | ||
3032 | static DEFINE_SPINLOCK(io_range_lock); | ||
3033 | #endif | ||
3034 | |||
3035 | /* | ||
3036 | * Record the PCI IO range (expressed as CPU physical address + size). | ||
3037 | * Return a negative value if an error has occured, zero otherwise | ||
3038 | */ | ||
3039 | int __weak pci_register_io_range(phys_addr_t addr, resource_size_t size) | ||
3040 | { | ||
3041 | int err = 0; | ||
3042 | |||
3043 | #ifdef PCI_IOBASE | ||
3044 | struct io_range *range; | ||
3045 | resource_size_t allocated_size = 0; | ||
3046 | |||
3047 | /* check if the range hasn't been previously recorded */ | ||
3048 | spin_lock(&io_range_lock); | ||
3049 | list_for_each_entry(range, &io_range_list, list) { | ||
3050 | if (addr >= range->start && addr + size <= range->start + size) { | ||
3051 | /* range already registered, bail out */ | ||
3052 | goto end_register; | ||
3053 | } | ||
3054 | allocated_size += range->size; | ||
3055 | } | ||
3056 | |||
3057 | /* range not registed yet, check for available space */ | ||
3058 | if (allocated_size + size - 1 > IO_SPACE_LIMIT) { | ||
3059 | /* if it's too big check if 64K space can be reserved */ | ||
3060 | if (allocated_size + SZ_64K - 1 > IO_SPACE_LIMIT) { | ||
3061 | err = -E2BIG; | ||
3062 | goto end_register; | ||
3063 | } | ||
3064 | |||
3065 | size = SZ_64K; | ||
3066 | pr_warn("Requested IO range too big, new size set to 64K\n"); | ||
3067 | } | ||
3068 | |||
3069 | /* add the range to the list */ | ||
3070 | range = kzalloc(sizeof(*range), GFP_ATOMIC); | ||
3071 | if (!range) { | ||
3072 | err = -ENOMEM; | ||
3073 | goto end_register; | ||
3074 | } | ||
3075 | |||
3076 | range->start = addr; | ||
3077 | range->size = size; | ||
3078 | |||
3079 | list_add_tail(&range->list, &io_range_list); | ||
3080 | |||
3081 | end_register: | ||
3082 | spin_unlock(&io_range_lock); | ||
3083 | #endif | ||
3084 | |||
3085 | return err; | ||
3086 | } | ||
3087 | |||
3088 | phys_addr_t pci_pio_to_address(unsigned long pio) | ||
3089 | { | ||
3090 | phys_addr_t address = (phys_addr_t)OF_BAD_ADDR; | ||
3091 | |||
3092 | #ifdef PCI_IOBASE | ||
3093 | struct io_range *range; | ||
3094 | resource_size_t allocated_size = 0; | ||
3095 | |||
3096 | if (pio > IO_SPACE_LIMIT) | ||
3097 | return address; | ||
3098 | |||
3099 | spin_lock(&io_range_lock); | ||
3100 | list_for_each_entry(range, &io_range_list, list) { | ||
3101 | if (pio >= allocated_size && pio < allocated_size + range->size) { | ||
3102 | address = range->start + pio - allocated_size; | ||
3103 | break; | ||
3104 | } | ||
3105 | allocated_size += range->size; | ||
3106 | } | ||
3107 | spin_unlock(&io_range_lock); | ||
3108 | #endif | ||
3109 | |||
3110 | return address; | ||
3111 | } | ||
3112 | |||
3113 | unsigned long __weak pci_address_to_pio(phys_addr_t address) | ||
3114 | { | ||
3115 | #ifdef PCI_IOBASE | ||
3116 | struct io_range *res; | ||
3117 | resource_size_t offset = 0; | ||
3118 | unsigned long addr = -1; | ||
3119 | |||
3120 | spin_lock(&io_range_lock); | ||
3121 | list_for_each_entry(res, &io_range_list, list) { | ||
3122 | if (address >= res->start && address < res->start + res->size) { | ||
3123 | addr = address - res->start + offset; | ||
3124 | break; | ||
3125 | } | ||
3126 | offset += res->size; | ||
3127 | } | ||
3128 | spin_unlock(&io_range_lock); | ||
3129 | |||
3130 | return addr; | ||
3131 | #else | ||
3132 | if (address > IO_SPACE_LIMIT) | ||
3133 | return (unsigned long)-1; | ||
3134 | |||
3135 | return (unsigned long) address; | ||
3136 | #endif | ||
3137 | } | ||
3138 | |||
3024 | /** | 3139 | /** |
3025 | * pci_remap_iospace - Remap the memory mapped I/O space | 3140 | * pci_remap_iospace - Remap the memory mapped I/O space |
3026 | * @res: Resource describing the I/O space | 3141 | * @res: Resource describing the I/O space |
diff --git a/include/linux/of_address.h b/include/linux/of_address.h index 01c0a556448b..37864734ca50 100644 --- a/include/linux/of_address.h +++ b/include/linux/of_address.h | |||
@@ -47,10 +47,6 @@ void __iomem *of_io_request_and_map(struct device_node *device, | |||
47 | extern const __be32 *of_get_address(struct device_node *dev, int index, | 47 | extern const __be32 *of_get_address(struct device_node *dev, int index, |
48 | u64 *size, unsigned int *flags); | 48 | u64 *size, unsigned int *flags); |
49 | 49 | ||
50 | extern int pci_register_io_range(phys_addr_t addr, resource_size_t size); | ||
51 | extern unsigned long pci_address_to_pio(phys_addr_t addr); | ||
52 | extern phys_addr_t pci_pio_to_address(unsigned long pio); | ||
53 | |||
54 | extern int of_pci_range_parser_init(struct of_pci_range_parser *parser, | 50 | extern int of_pci_range_parser_init(struct of_pci_range_parser *parser, |
55 | struct device_node *node); | 51 | struct device_node *node); |
56 | extern struct of_pci_range *of_pci_range_parser_one( | 52 | 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, | |||
86 | return NULL; | 82 | return NULL; |
87 | } | 83 | } |
88 | 84 | ||
89 | static inline phys_addr_t pci_pio_to_address(unsigned long pio) | ||
90 | { | ||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static inline int of_pci_range_parser_init(struct of_pci_range_parser *parser, | 85 | static inline int of_pci_range_parser_init(struct of_pci_range_parser *parser, |
95 | struct device_node *node) | 86 | struct device_node *node) |
96 | { | 87 | { |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 004b8133417d..1824ef80e10d 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -1164,6 +1164,9 @@ int __must_check pci_bus_alloc_resource(struct pci_bus *bus, | |||
1164 | void *alignf_data); | 1164 | void *alignf_data); |
1165 | 1165 | ||
1166 | 1166 | ||
1167 | int pci_register_io_range(phys_addr_t addr, resource_size_t size); | ||
1168 | unsigned long pci_address_to_pio(phys_addr_t addr); | ||
1169 | phys_addr_t pci_pio_to_address(unsigned long pio); | ||
1167 | int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr); | 1170 | int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr); |
1168 | 1171 | ||
1169 | static inline pci_bus_addr_t pci_bus_address(struct pci_dev *pdev, int bar) | 1172 | 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) | |||
1480 | { return -EIO; } | 1483 | { return -EIO; } |
1481 | static inline void pci_release_regions(struct pci_dev *dev) { } | 1484 | static inline void pci_release_regions(struct pci_dev *dev) { } |
1482 | 1485 | ||
1486 | static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; } | ||
1487 | |||
1483 | static inline void pci_block_cfg_access(struct pci_dev *dev) { } | 1488 | static inline void pci_block_cfg_access(struct pci_dev *dev) { } |
1484 | static inline int pci_block_cfg_access_in_atomic(struct pci_dev *dev) | 1489 | static inline int pci_block_cfg_access_in_atomic(struct pci_dev *dev) |
1485 | { return 0; } | 1490 | { return 0; } |