Switch the footbridge PCI devices to use dma_direct_set_offset to set the DMA offset instead of using direct hooks into the DMA mapping code and remove the now unused hooks. Signed-off-by: Christoph Hellwig <hch@xxxxxx> --- arch/arm/include/asm/dma-direct.h | 4 +- arch/arm/include/asm/memory.h | 2 - arch/arm/mach-footbridge/cats-pci.c | 7 +++- arch/arm/mach-footbridge/common.c | 40 ++++++++++++++----- arch/arm/mach-footbridge/common.h | 3 ++ arch/arm/mach-footbridge/ebsa285-pci.c | 7 +++- .../arm/mach-footbridge/include/mach/memory.h | 4 -- arch/arm/mach-footbridge/netwinder-pci.c | 7 +++- arch/arm/mach-footbridge/personal-pci.c | 7 +++- 9 files changed, 54 insertions(+), 27 deletions(-) diff --git a/arch/arm/include/asm/dma-direct.h b/arch/arm/include/asm/dma-direct.h index 77fcb7ee5ec907..1f04a5e1c615de 100644 --- a/arch/arm/include/asm/dma-direct.h +++ b/arch/arm/include/asm/dma-direct.h @@ -13,12 +13,12 @@ static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn) { if (dev && dev->dma_range_map) pfn = PFN_DOWN(translate_phys_to_dma(dev, PFN_PHYS(pfn))); - return (dma_addr_t)__pfn_to_bus(pfn); + return (dma_addr_t)__pfn_to_phys(pfn); } static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr) { - unsigned long pfn = __bus_to_pfn(addr); + unsigned long pfn = __phys_to_pfn(addr); if (dev && dev->dma_range_map) pfn = PFN_DOWN(translate_dma_to_phys(dev, PFN_PHYS(pfn))); diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index 99035b5891ef44..af612606136ff2 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -346,8 +346,6 @@ static inline unsigned long __virt_to_idmap(unsigned long x) #ifndef __virt_to_bus #define __virt_to_bus __virt_to_phys #define __bus_to_virt __phys_to_virt -#define __pfn_to_bus(x) __pfn_to_phys(x) -#define __bus_to_pfn(x) __phys_to_pfn(x) #endif /* diff --git a/arch/arm/mach-footbridge/cats-pci.c b/arch/arm/mach-footbridge/cats-pci.c index 0b2fd7e2e9b429..257cb068ac0c5b 100644 --- a/arch/arm/mach-footbridge/cats-pci.c +++ b/arch/arm/mach-footbridge/cats-pci.c @@ -13,6 +13,7 @@ #include <asm/irq.h> #include <asm/mach/pci.h> #include <asm/mach-types.h> +#include "common.h" /* cats host-specific stuff */ static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 }; @@ -56,8 +57,10 @@ static struct hw_pci cats_pci __initdata = { static int __init cats_pci_init(void) { - if (machine_is_cats()) - pci_common_init(&cats_pci); + if (!machine_is_cats()) + return 0; + bus_register_notifier(&pci_bus_type, &footbridge_pci_dma_nb); + pci_common_init(&cats_pci); return 0; } diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c index eee095f0e2f6c2..dc14d72ca7bb3f 100644 --- a/arch/arm/mach-footbridge/common.c +++ b/arch/arm/mach-footbridge/common.c @@ -12,6 +12,8 @@ #include <linux/init.h> #include <linux/io.h> #include <linux/spinlock.h> +#include <linux/device/bus.h> +#include <linux/dma-mapping.h> #include <video/vga.h> #include <asm/page.h> @@ -219,8 +221,17 @@ void footbridge_restart(enum reboot_mode mode, const char *cmd) } } -#ifdef CONFIG_FOOTBRIDGE_ADDIN - +#ifdef CONFIG_FOOTBRIDGE_HOST +/* + * The footbridge is programmed to expose the system RAM at 0xe0000000. + * The requirement is that the RAM isn't placed at bus address 0, which + * would clash with VGA cards. + */ +static inline unsigned long fb_bus_sdram_offset(void) +{ + return 0xe0000000; +} +#elif defined(CONFIG_FOOTBRIDGE_ADDIN) static inline unsigned long fb_bus_sdram_offset(void) { return *CSR_PCISDRAMBASE & 0xfffffff0; @@ -248,17 +259,24 @@ unsigned long __bus_to_virt(unsigned long res) return res; } EXPORT_SYMBOL(__bus_to_virt); +#else +#error "Undefined footbridge mode" +#endif -unsigned long __pfn_to_bus(unsigned long pfn) +static int footbridge_pci_dma_notifier(struct notifier_block *nb, + unsigned long event, void *data) { - return __pfn_to_phys(pfn) + (fb_bus_sdram_offset() - PHYS_OFFSET); -} -EXPORT_SYMBOL(__pfn_to_bus); + struct device *dev = data; -unsigned long __bus_to_pfn(unsigned long bus) -{ - return __phys_to_pfn(bus - (fb_bus_sdram_offset() - PHYS_OFFSET)); + if (event != BUS_NOTIFY_ADD_DEVICE) + return NOTIFY_DONE; + + if (dma_direct_set_offset(dev, PAGE_OFFSET, fb_bus_sdram_offset(), + (u64)-1)) + WARN_ONCE(1, "failed to set DMA offset\n"); + return NOTIFY_OK; } -EXPORT_SYMBOL(__bus_to_pfn); -#endif +struct notifier_block footbridge_pci_dma_nb = { + .notifier_call = footbridge_pci_dma_notifier, +}; diff --git a/arch/arm/mach-footbridge/common.h b/arch/arm/mach-footbridge/common.h index e12587db59c4c8..1773a4183b580c 100644 --- a/arch/arm/mach-footbridge/common.h +++ b/arch/arm/mach-footbridge/common.h @@ -1,4 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0 */ +#include <linux/notifier.h> #include <linux/reboot.h> extern void footbridge_timer_init(void); @@ -13,3 +14,5 @@ extern void isa_init_irq(unsigned int irq); extern void footbridge_restart(enum reboot_mode, const char *); extern void footbridge_sched_clock(void); + +extern struct notifier_block footbridge_pci_dma_nb; diff --git a/arch/arm/mach-footbridge/ebsa285-pci.c b/arch/arm/mach-footbridge/ebsa285-pci.c index 6f28aaa9ca79b2..80b4f5ace20b35 100644 --- a/arch/arm/mach-footbridge/ebsa285-pci.c +++ b/arch/arm/mach-footbridge/ebsa285-pci.c @@ -13,6 +13,7 @@ #include <asm/irq.h> #include <asm/mach/pci.h> #include <asm/mach-types.h> +#include "common.h" static int irqmap_ebsa285[] __initdata = { IRQ_IN3, IRQ_IN1, IRQ_IN0, IRQ_PCI }; @@ -40,8 +41,10 @@ static struct hw_pci ebsa285_pci __initdata = { static int __init ebsa285_init_pci(void) { - if (machine_is_ebsa285()) - pci_common_init(&ebsa285_pci); + if (!machine_is_ebsa285()) + return 0; + bus_register_notifier(&pci_bus_type, &footbridge_pci_dma_nb); + pci_common_init(&ebsa285_pci); return 0; } diff --git a/arch/arm/mach-footbridge/include/mach/memory.h b/arch/arm/mach-footbridge/include/mach/memory.h index 46fd4a8872b9a3..3a5d2638c18f88 100644 --- a/arch/arm/mach-footbridge/include/mach/memory.h +++ b/arch/arm/mach-footbridge/include/mach/memory.h @@ -26,8 +26,6 @@ #ifndef __ASSEMBLY__ extern unsigned long __virt_to_bus(unsigned long); extern unsigned long __bus_to_virt(unsigned long); -extern unsigned long __pfn_to_bus(unsigned long); -extern unsigned long __bus_to_pfn(unsigned long); #endif #define __virt_to_bus __virt_to_bus #define __bus_to_virt __bus_to_virt @@ -42,8 +40,6 @@ extern unsigned long __bus_to_pfn(unsigned long); #define BUS_OFFSET 0xe0000000 #define __virt_to_bus(x) ((x) + (BUS_OFFSET - PAGE_OFFSET)) #define __bus_to_virt(x) ((x) - (BUS_OFFSET - PAGE_OFFSET)) -#define __pfn_to_bus(x) (__pfn_to_phys(x) + (BUS_OFFSET - PHYS_OFFSET)) -#define __bus_to_pfn(x) __phys_to_pfn((x) - (BUS_OFFSET - PHYS_OFFSET)) #else diff --git a/arch/arm/mach-footbridge/netwinder-pci.c b/arch/arm/mach-footbridge/netwinder-pci.c index 9473aa0305e5f7..68dac9446e7f44 100644 --- a/arch/arm/mach-footbridge/netwinder-pci.c +++ b/arch/arm/mach-footbridge/netwinder-pci.c @@ -13,6 +13,7 @@ #include <asm/irq.h> #include <asm/mach/pci.h> #include <asm/mach-types.h> +#include "common.h" /* * We now use the slot ID instead of the device identifiers to select @@ -54,8 +55,10 @@ static struct hw_pci netwinder_pci __initdata = { static int __init netwinder_pci_init(void) { - if (machine_is_netwinder()) - pci_common_init(&netwinder_pci); + if (!machine_is_netwinder()) + return 0; + bus_register_notifier(&pci_bus_type, &footbridge_pci_dma_nb); + pci_common_init(&netwinder_pci); return 0; } diff --git a/arch/arm/mach-footbridge/personal-pci.c b/arch/arm/mach-footbridge/personal-pci.c index 4391e433a4b2fc..5d6759e158b9d0 100644 --- a/arch/arm/mach-footbridge/personal-pci.c +++ b/arch/arm/mach-footbridge/personal-pci.c @@ -13,6 +13,7 @@ #include <asm/irq.h> #include <asm/mach/pci.h> #include <asm/mach-types.h> +#include "common.h" static int irqmap_personal_server[] __initdata = { IRQ_IN0, IRQ_IN1, IRQ_IN2, IRQ_IN3, 0, 0, 0, @@ -50,8 +51,10 @@ static struct hw_pci personal_server_pci __initdata = { static int __init personal_pci_init(void) { - if (machine_is_personal_server()) - pci_common_init(&personal_server_pci); + if (!machine_is_personal_server()) + return 0; + bus_register_notifier(&pci_bus_type, &footbridge_pci_dma_nb); + pci_common_init(&personal_server_pci); return 0; } -- 2.28.0