From 9b7e30ab975334448dc4c82941a48a3685a7642b Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Tue, 2 May 2017 13:00:12 +0000 Subject: sh: fix futex FUTEX_OP_SET op on userspace addresses Commit 00b73d8d1b71 ("sh: add working futex atomic ops on userspace addresses for smp") changed the futex_atomic_op_inuser function to use a loop. In case of the FUTEX_OP_SET op with a userspace address containing a value different of 0, this loop is an endless loop. Fix that by loading the value of oldval from the userspace before doing the cmpxchg op, also for the FUTEX_OP_SET case. Signed-off-by: Aurelien Jarno Signed-off-by: Rich Felker --- arch/sh/include/asm/futex.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/futex.h b/arch/sh/include/asm/futex.h index 15bf07bfa96b..6d192f4908a7 100644 --- a/arch/sh/include/asm/futex.h +++ b/arch/sh/include/asm/futex.h @@ -37,10 +37,7 @@ static inline int arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, pagefault_disable(); do { - if (op == FUTEX_OP_SET) - ret = oldval = 0; - else - ret = get_user(oldval, uaddr); + ret = get_user(oldval, uaddr); if (ret) break; -- cgit v1.2.3 From eb6b6930a70faefe04479a71088cc10366782d9a Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Mon, 31 Jul 2017 01:27:50 -0400 Subject: sh: fix memory corruption of unflattened device tree unflatten_device_tree() makes use of memblock allocation, and therefore must be called before paging_init() migrates the memblock allocation data to the bootmem framework. Otherwise the record of the allocation for the expanded device tree will be lost, and will eventually be clobbered when allocated for another use. Signed-off-by: Rich Felker --- arch/sh/boards/of-generic.c | 6 ------ arch/sh/kernel/setup.c | 8 ++++++++ 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/of-generic.c b/arch/sh/boards/of-generic.c index 4feb7c86f4ac..46b2481eec90 100644 --- a/arch/sh/boards/of-generic.c +++ b/arch/sh/boards/of-generic.c @@ -126,12 +126,6 @@ static void __init sh_of_setup(char **cmdline_p) { struct device_node *root; -#ifdef CONFIG_USE_BUILTIN_DTB - unflatten_and_copy_device_tree(); -#else - unflatten_device_tree(); -#endif - board_time_init = sh_of_time_init; sh_mv.mv_name = "Unknown SH model"; diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index b95c411d0333..d34e998b809f 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -330,6 +330,14 @@ void __init setup_arch(char **cmdline_p) /* Let earlyprintk output early console messages */ early_platform_driver_probe("earlyprintk", 1, 1); +#ifdef CONFIG_OF_FLATTREE +#ifdef CONFIG_USE_BUILTIN_DTB + unflatten_and_copy_device_tree(); +#else + unflatten_device_tree(); +#endif +#endif + paging_init(); #ifdef CONFIG_DUMMY_CONSOLE -- cgit v1.2.3 From 96a598996f6ac518ac79839ecbb17c91af91f4f7 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Thu, 15 Mar 2018 20:01:36 -0400 Subject: sh: fix debug trap failure to process signals before return to user When responding to a debug trap (breakpoint) in userspace, the kernel's trap handler raised SIGTRAP but returned from the trap via a code path that ignored pending signals, resulting in an infinite loop re-executing the trapping instruction. Signed-off-by: Rich Felker --- arch/sh/kernel/entry-common.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S index c001f782c5f1..28cc61216b64 100644 --- a/arch/sh/kernel/entry-common.S +++ b/arch/sh/kernel/entry-common.S @@ -255,7 +255,7 @@ debug_trap: mov.l @r8, r8 jsr @r8 nop - bra __restore_all + bra ret_from_exception nop CFI_ENDPROC -- cgit v1.2.3 From bc05aa6e13a717e1abff6f863f7ba82b14556df4 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Mon, 4 Dec 2017 16:09:00 +0100 Subject: arch/sh: add sh7786_mm_sel() function The SH7786 has different physical memory layout configurations, configurable through the MMSELR register. The configuration is typically defined by the bootloader, so Linux generally doesn't care. Except that depending on the configuration, some PCI MEM areas may or may not be available. This commit adds a helper function that allows to retrieve the current physical memory layout configuration. It will be used in a following patch to exclude unusable PCI MEM areas during the PCI initialization. Signed-off-by: Thomas Petazzoni Signed-off-by: Rich Felker --- arch/sh/include/cpu-sh4/cpu/sh7786.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/include/cpu-sh4/cpu/sh7786.h b/arch/sh/include/cpu-sh4/cpu/sh7786.h index 0df09e638f09..96b8cb1f754a 100644 --- a/arch/sh/include/cpu-sh4/cpu/sh7786.h +++ b/arch/sh/include/cpu-sh4/cpu/sh7786.h @@ -14,6 +14,8 @@ #ifndef __CPU_SH7786_H__ #define __CPU_SH7786_H__ +#include + enum { /* PA */ GPIO_PA7, GPIO_PA6, GPIO_PA5, GPIO_PA4, @@ -131,4 +133,9 @@ enum { GPIO_FN_IRL7, GPIO_FN_IRL6, GPIO_FN_IRL5, GPIO_FN_IRL4, }; +static inline u32 sh7786_mm_sel(void) +{ + return __raw_readl(0xFC400020) & 0x7; +} + #endif /* __CPU_SH7786_H__ */ -- cgit v1.2.3 From ce88313069c36eef80f21fd7403f16620ecd21a2 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Mon, 4 Dec 2017 16:09:01 +0100 Subject: arch/sh: make the DMA mapping operations observe dev->dma_pfn_offset Some devices may have a non-zero DMA offset, i.e an offset between the DMA address and the physical address. Such an offset can be encoded into the dma_pfn_offset field of "struct device", but the SuperH implementation of the DMA mapping API does not observe this information. This commit fixes that by ensuring the DMA address is properly calculated depending on this DMA offset. Signed-off-by: Thomas Petazzoni Signed-off-by: Rich Felker --- arch/sh/kernel/dma-nommu.c | 7 +++++-- arch/sh/mm/consistent.c | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/dma-nommu.c b/arch/sh/kernel/dma-nommu.c index 62b485107eae..178457d7620c 100644 --- a/arch/sh/kernel/dma-nommu.c +++ b/arch/sh/kernel/dma-nommu.c @@ -16,7 +16,8 @@ static dma_addr_t nommu_map_page(struct device *dev, struct page *page, enum dma_data_direction dir, unsigned long attrs) { - dma_addr_t addr = page_to_phys(page) + offset; + dma_addr_t addr = page_to_phys(page) + offset + - PFN_PHYS(dev->dma_pfn_offset); WARN_ON(size == 0); @@ -36,12 +37,14 @@ static int nommu_map_sg(struct device *dev, struct scatterlist *sg, WARN_ON(nents == 0 || sg[0].length == 0); for_each_sg(sg, s, nents, i) { + dma_addr_t offset = PFN_PHYS(dev->dma_pfn_offset); + BUG_ON(!sg_page(s)); if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) sh_sync_dma_for_device(sg_virt(s), s->length, dir); - s->dma_address = sg_phys(s); + s->dma_address = sg_phys(s) - offset; s->dma_length = s->length; } diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c index 6ea3aab508f2..8ce98691d822 100644 --- a/arch/sh/mm/consistent.c +++ b/arch/sh/mm/consistent.c @@ -59,7 +59,7 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size, split_page(pfn_to_page(virt_to_phys(ret) >> PAGE_SHIFT), order); - *dma_handle = virt_to_phys(ret); + *dma_handle = virt_to_phys(ret) - PFN_PHYS(dev->dma_pfn_offset); return ret_nocache; } @@ -69,7 +69,7 @@ void dma_generic_free_coherent(struct device *dev, size_t size, unsigned long attrs) { int order = get_order(size); - unsigned long pfn = dma_handle >> PAGE_SHIFT; + unsigned long pfn = (dma_handle >> PAGE_SHIFT) + dev->dma_pfn_offset; int k; for (k = 0; k < (1 << order); k++) -- cgit v1.2.3 From 3aeb93a014058eb889cbb12c1f61f59666b9a081 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Mon, 4 Dec 2017 16:09:02 +0100 Subject: arch/sh: pci: don't use disabled resources In pcibios_scanbus(), we provide to the PCI core the usable MEM and IO regions using pci_add_resource_offset(). We travel through all resources available in the "struct pci_channel". Also, in register_pci_controller(), we travel through all resources to request them, making sure they don't conflict with already requested resources. However, some resources may be disabled, in which case they should not be requested nor provided to the PCI core. In the current situation, none of the resources are disabled. However, follow-up patches in this series will make some resources disabled, making this preliminary change necessary. Signed-off-by: Thomas Petazzoni Signed-off-by: Rich Felker --- arch/sh/drivers/pci/pci.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 5976a2c8a3e3..e5b7437ab4af 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -49,6 +49,8 @@ static void pcibios_scanbus(struct pci_channel *hose) for (i = 0; i < hose->nr_resources; i++) { res = hose->resources + i; offset = 0; + if (res->flags & IORESOURCE_DISABLED) + continue; if (res->flags & IORESOURCE_IO) offset = hose->io_offset; else if (res->flags & IORESOURCE_MEM) @@ -102,6 +104,9 @@ int register_pci_controller(struct pci_channel *hose) for (i = 0; i < hose->nr_resources; i++) { struct resource *res = hose->resources + i; + if (res->flags & IORESOURCE_DISABLED) + continue; + if (res->flags & IORESOURCE_IO) { if (request_resource(&ioport_resource, res) < 0) goto out; -- cgit v1.2.3 From 7dd7f69809b4e3bed5c28dd8600a3a8b20f6441c Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Mon, 4 Dec 2017 16:09:03 +0100 Subject: arch/sh: pcie-sh7786: mark unavailable PCI resource as disabled Some PCI MEM resources are marked as IORESOURCE_MEM_32BIT, which means they are only usable when the SH core runs in 32-bit mode. In 29-bit mode, such memory regions are not usable. The existing code for SH7786 properly skips such regions when configuring the PCIe controller registers. However, because such regions are still described in the resource array, the pcibios_scanbus() function in the SuperH pci.c will register them to the PCI core. Due to this, the PCI core will allocate MEM areas from this resource, and assign BARs pointing to this area, even though it's unusable. In order to prevent this from happening, we mark such regions as IORESOURCE_DISABLED, which tells the SuperH pci.c pcibios_scanbus() function to skip them. Note that we separate marking the region as disabled from skipping it, because other regions will be marked as disabled in follow-up patches. Signed-off-by: Thomas Petazzoni Signed-off-by: Rich Felker --- arch/sh/drivers/pci/pcie-sh7786.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index 0167a7352719..e713c398a6b9 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c @@ -438,6 +438,9 @@ static int __init pcie_init(struct sh7786_pcie_port *port) * mode, so just skip them entirely. */ if ((res->flags & IORESOURCE_MEM_32BIT) && __in_29bit_mode()) + res->flags |= IORESOURCE_DISABLED; + + if (res->flags & IORESOURCE_DISABLED) continue; pci_write_reg(chan, 0x00000000, SH4A_PCIEPTCTLR(win)); -- cgit v1.2.3 From d62e9bf5dd4c0298465dd70b78b5532ea6708d63 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Mon, 4 Dec 2017 16:09:04 +0100 Subject: arch/sh: pcie-sh7786: exclude unusable PCI MEM areas Depending on the physical memory layout, some PCI MEM areas are not usable. According to the SH7786 datasheet, the PCI MEM area from 1000_0000 to 13FF_FFFF is only usable if the physical memory layout (in MMSELR) is 1, 2, 5 or 6. In all other configurations, this PCI MEM area is not usable (because it overlaps with DRAM). Therefore, this commit adjusts the PCI SH7786 initialization to mark the relevant PCI resource as IORESOURCE_DISABLED if we can't use it. Signed-off-by: Thomas Petazzoni Signed-off-by: Rich Felker --- arch/sh/drivers/pci/pcie-sh7786.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index e713c398a6b9..72a1d794a7ba 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "pcie-sh7786.h" #include @@ -530,6 +531,7 @@ static struct sh7786_pcie_hwops sh7786_65nm_pcie_hwops __initdata = { static int __init sh7786_pcie_init(void) { struct clk *platclk; + u32 mm_sel; int i; printk(KERN_NOTICE "PCI: Starting initialization.\n"); @@ -563,6 +565,16 @@ static int __init sh7786_pcie_init(void) clk_enable(platclk); + mm_sel = sh7786_mm_sel(); + + /* + * Depending on the MMSELR register value, the PCIe0 MEM 1 + * area may not be available. See Table 13.11 of the SH7786 + * datasheet. + */ + if (mm_sel != 1 && mm_sel != 2 && mm_sel != 5 && mm_sel != 6) + sh7786_pci0_resources[2].flags |= IORESOURCE_DISABLED; + printk(KERN_NOTICE "PCI: probing %d ports.\n", nr_ports); for (i = 0; i < nr_ports; i++) { -- cgit v1.2.3 From 5da1bb96dc8dfce9d1b9d7c410803e8fa88f678c Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Mon, 4 Dec 2017 16:09:05 +0100 Subject: arch/sh: pcie-sh7786: adjust PCI MEM and IO regions The current definition of the PCIe IO and MEM resources for SH7786 doesn't match what the datasheet says. For example, for PCIe0 0xfe100000 is advertised by the datasheet as a PCI IO region, while 0xfd000000 is advertised as a PCI MEM region. The code currently inverts the two. The SH4A_PCIEPARL and SH4A_PCIEPTCTLR registers allow to define the base address and role of the different regions (including whether it's a MEM or IO region). However, practical experience on a SH7786 shows that if 0xfe100000 is used for LEL and 0xfd000000 for IO, a PCIe device using two MEM BARs cannot be accessed at all. Simply using 0xfe100000 for IO and 0xfd000000 for MEM makes the PCIe device accessible. It is very likely that this was never seen because there are two other PCI MEM region listed in the resources. However, for different reasons, none of the two other MEM regions are usable on the specific SH7786 platform the problem was encountered. Therefore, the last MEM region at 0xfe100000 was used to place the BARs, making the device non-functional. This commit therefore adjusts those PCI MEM and IO resources definitions so that they match what the datasheet says. They have only been tested with PCIe 0. Signed-off-by: Thomas Petazzoni Signed-off-by: Rich Felker --- arch/sh/drivers/pci/pcie-sh7786.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index 72a1d794a7ba..57abae2f6822 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c @@ -41,73 +41,73 @@ static struct sh7786_pcie_hwops { static struct resource sh7786_pci0_resources[] = { { - .name = "PCIe0 IO", + .name = "PCIe0 MEM 0", .start = 0xfd000000, .end = 0xfd000000 + SZ_8M - 1, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_MEM, }, { - .name = "PCIe0 MEM 0", + .name = "PCIe0 MEM 1", .start = 0xc0000000, .end = 0xc0000000 + SZ_512M - 1, .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, }, { - .name = "PCIe0 MEM 1", + .name = "PCIe0 MEM 2", .start = 0x10000000, .end = 0x10000000 + SZ_64M - 1, .flags = IORESOURCE_MEM, }, { - .name = "PCIe0 MEM 2", + .name = "PCIe0 IO", .start = 0xfe100000, .end = 0xfe100000 + SZ_1M - 1, - .flags = IORESOURCE_MEM, + .flags = IORESOURCE_IO, }, }; static struct resource sh7786_pci1_resources[] = { { - .name = "PCIe1 IO", + .name = "PCIe1 MEM 0", .start = 0xfd800000, .end = 0xfd800000 + SZ_8M - 1, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_MEM, }, { - .name = "PCIe1 MEM 0", + .name = "PCIe1 MEM 1", .start = 0xa0000000, .end = 0xa0000000 + SZ_512M - 1, .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, }, { - .name = "PCIe1 MEM 1", + .name = "PCIe1 MEM 2", .start = 0x30000000, .end = 0x30000000 + SZ_256M - 1, .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, }, { - .name = "PCIe1 MEM 2", + .name = "PCIe1 IO", .start = 0xfe300000, .end = 0xfe300000 + SZ_1M - 1, - .flags = IORESOURCE_MEM, + .flags = IORESOURCE_IO, }, }; static struct resource sh7786_pci2_resources[] = { { - .name = "PCIe2 IO", + .name = "PCIe2 MEM 0", .start = 0xfc800000, .end = 0xfc800000 + SZ_4M - 1, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_MEM, }, { - .name = "PCIe2 MEM 0", + .name = "PCIe2 MEM 1", .start = 0x80000000, .end = 0x80000000 + SZ_512M - 1, .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, }, { - .name = "PCIe2 MEM 1", + .name = "PCIe2 MEM 2", .start = 0x20000000, .end = 0x20000000 + SZ_256M - 1, .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, }, { - .name = "PCIe2 MEM 2", + .name = "PCIe2 IO", .start = 0xfcd00000, .end = 0xfcd00000 + SZ_1M - 1, - .flags = IORESOURCE_MEM, + .flags = IORESOURCE_IO, }, }; -- cgit v1.2.3 From 79e1c5e70b2a0fadb7b61c69de8442703e7d0dc4 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Mon, 4 Dec 2017 16:09:06 +0100 Subject: arch/sh: pcie-sh7786: adjust the memory mapping The code setting up the PCI -> SuperHighway mapping doesn't take into account the fact that the address stored in PCIELARx must be aligned with the size stored in PCIELAMRx. For example, when your physical memory starts at 0x0800_0000 (128 MB), a size of 64 MB or 128 MB is fine. However, if you have 256 MB of memory, it doesn't work because the base address is not aligned on the size. In such situation, we have to round down the base address to make sure it is aligned on the size of the area. For for a 0x0800_0000 base address with 256 MB of memory, we will round down to 0x0, and extend the size of the mapping to 512 MB. This allows the mapping to work on platforms that have 256 MB of RAM. The current setup would only work with 128 MB of RAM or less. Signed-off-by: Thomas Petazzoni Signed-off-by: Rich Felker --- arch/sh/drivers/pci/pcie-sh7786.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index 57abae2f6822..b8f411451647 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c @@ -302,7 +302,7 @@ static int __init pcie_init(struct sh7786_pcie_port *port) { struct pci_channel *chan = port->hose; unsigned int data; - phys_addr_t memphys; + phys_addr_t memstart, memend; size_t memsize; int ret, i, win; @@ -358,15 +358,24 @@ static int __init pcie_init(struct sh7786_pcie_port *port) data |= (0xff << 16); pci_write_reg(chan, data, SH4A_PCIEMACCTLR); - memphys = __pa(memory_start); - memsize = roundup_pow_of_two(memory_end - memory_start); + memstart = __pa(memory_start); + memend = __pa(memory_end); + memsize = roundup_pow_of_two(memend - memstart); + + /* + * The start address must be aligned on its size. So we round + * it down, and then recalculate the size so that it covers + * the entire memory. + */ + memstart = ALIGN_DOWN(memstart, memsize); + memsize = roundup_pow_of_two(memend - memstart); /* * If there's more than 512MB of memory, we need to roll over to * LAR1/LAMR1. */ if (memsize > SZ_512M) { - pci_write_reg(chan, memphys + SZ_512M, SH4A_PCIELAR1); + pci_write_reg(chan, memstart + SZ_512M, SH4A_PCIELAR1); pci_write_reg(chan, ((memsize - SZ_512M) - SZ_256) | 1, SH4A_PCIELAMR1); memsize = SZ_512M; @@ -382,7 +391,7 @@ static int __init pcie_init(struct sh7786_pcie_port *port) * LAR0/LAMR0 covers up to the first 512MB, which is enough to * cover all of lowmem on most platforms. */ - pci_write_reg(chan, memphys, SH4A_PCIELAR0); + pci_write_reg(chan, memstart, SH4A_PCIELAR0); pci_write_reg(chan, (memsize - SZ_256) | 1, SH4A_PCIELAMR0); /* Finish initialization */ -- cgit v1.2.3 From bf9c7e3d7924f72225f8f9c28438b4a711192ad3 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Mon, 4 Dec 2017 16:09:07 +0100 Subject: arch/sh: pcie-sh7786: handle non-zero DMA offset On SuperH, the base of the physical memory might be different from zero. In this case, PCI address zero will map to a non-zero physical address. In order to make sure that the DMA mapping API takes care of this DMA offset, we must fill in the dev->dma_pfn_offset field for PCI devices. This gets done in the pcibios_bus_add_device() hook, called for each new PCI device detected. The dma_pfn_offset global variable is re-calculated for every PCI controller available on the platform, but that's not an issue because its value will each time be exactly the same, as it only depends on the memory start address and memory size. Signed-off-by: Thomas Petazzoni Signed-off-by: Rich Felker --- arch/sh/drivers/pci/pcie-sh7786.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index b8f411451647..382e7ecf4c82 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c @@ -33,6 +33,7 @@ struct sh7786_pcie_port { static struct sh7786_pcie_port *sh7786_pcie_ports; static unsigned int nr_ports; +static unsigned long dma_pfn_offset; static struct sh7786_pcie_hwops { int (*core_init)(void); @@ -370,6 +371,8 @@ static int __init pcie_init(struct sh7786_pcie_port *port) memstart = ALIGN_DOWN(memstart, memsize); memsize = roundup_pow_of_two(memend - memstart); + dma_pfn_offset = memstart >> PAGE_SHIFT; + /* * If there's more than 512MB of memory, we need to roll over to * LAR1/LAMR1. @@ -485,6 +488,11 @@ int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) return evt2irq(0xae0); } +void pcibios_bus_add_device(struct pci_dev *pdev) +{ + pdev->dev.dma_pfn_offset = dma_pfn_offset; +} + static int __init sh7786_pcie_core_init(void) { /* Return the number of ports */ -- cgit v1.2.3