aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sh/boards/of-generic.c6
-rw-r--r--arch/sh/drivers/pci/pci.c5
-rw-r--r--arch/sh/drivers/pci/pcie-sh7786.c78
-rw-r--r--arch/sh/include/asm/futex.h5
-rw-r--r--arch/sh/include/cpu-sh4/cpu/sh7786.h7
-rw-r--r--arch/sh/kernel/dma-nommu.c7
-rw-r--r--arch/sh/kernel/entry-common.S2
-rw-r--r--arch/sh/kernel/setup.c8
-rw-r--r--arch/sh/mm/consistent.c4
9 files changed, 84 insertions, 38 deletions
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)
126{ 126{
127 struct device_node *root; 127 struct device_node *root;
128 128
129#ifdef CONFIG_USE_BUILTIN_DTB
130 unflatten_and_copy_device_tree();
131#else
132 unflatten_device_tree();
133#endif
134
135 board_time_init = sh_of_time_init; 129 board_time_init = sh_of_time_init;
136 130
137 sh_mv.mv_name = "Unknown SH model"; 131 sh_mv.mv_name = "Unknown SH model";
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)
49 for (i = 0; i < hose->nr_resources; i++) { 49 for (i = 0; i < hose->nr_resources; i++) {
50 res = hose->resources + i; 50 res = hose->resources + i;
51 offset = 0; 51 offset = 0;
52 if (res->flags & IORESOURCE_DISABLED)
53 continue;
52 if (res->flags & IORESOURCE_IO) 54 if (res->flags & IORESOURCE_IO)
53 offset = hose->io_offset; 55 offset = hose->io_offset;
54 else if (res->flags & IORESOURCE_MEM) 56 else if (res->flags & IORESOURCE_MEM)
@@ -102,6 +104,9 @@ int register_pci_controller(struct pci_channel *hose)
102 for (i = 0; i < hose->nr_resources; i++) { 104 for (i = 0; i < hose->nr_resources; i++) {
103 struct resource *res = hose->resources + i; 105 struct resource *res = hose->resources + i;
104 106
107 if (res->flags & IORESOURCE_DISABLED)
108 continue;
109
105 if (res->flags & IORESOURCE_IO) { 110 if (res->flags & IORESOURCE_IO) {
106 if (request_resource(&ioport_resource, res) < 0) 111 if (request_resource(&ioport_resource, res) < 0)
107 goto out; 112 goto out;
diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c
index 0167a7352719..382e7ecf4c82 100644
--- a/arch/sh/drivers/pci/pcie-sh7786.c
+++ b/arch/sh/drivers/pci/pcie-sh7786.c
@@ -19,6 +19,7 @@
19#include <linux/clk.h> 19#include <linux/clk.h>
20#include <linux/sh_clk.h> 20#include <linux/sh_clk.h>
21#include <linux/sh_intc.h> 21#include <linux/sh_intc.h>
22#include <cpu/sh7786.h>
22#include "pcie-sh7786.h" 23#include "pcie-sh7786.h"
23#include <asm/sizes.h> 24#include <asm/sizes.h>
24 25
@@ -32,6 +33,7 @@ struct sh7786_pcie_port {
32 33
33static struct sh7786_pcie_port *sh7786_pcie_ports; 34static struct sh7786_pcie_port *sh7786_pcie_ports;
34static unsigned int nr_ports; 35static unsigned int nr_ports;
36static unsigned long dma_pfn_offset;
35 37
36static struct sh7786_pcie_hwops { 38static struct sh7786_pcie_hwops {
37 int (*core_init)(void); 39 int (*core_init)(void);
@@ -40,73 +42,73 @@ static struct sh7786_pcie_hwops {
40 42
41static struct resource sh7786_pci0_resources[] = { 43static struct resource sh7786_pci0_resources[] = {
42 { 44 {
43 .name = "PCIe0 IO", 45 .name = "PCIe0 MEM 0",
44 .start = 0xfd000000, 46 .start = 0xfd000000,
45 .end = 0xfd000000 + SZ_8M - 1, 47 .end = 0xfd000000 + SZ_8M - 1,
46 .flags = IORESOURCE_IO, 48 .flags = IORESOURCE_MEM,
47 }, { 49 }, {
48 .name = "PCIe0 MEM 0", 50 .name = "PCIe0 MEM 1",
49 .start = 0xc0000000, 51 .start = 0xc0000000,
50 .end = 0xc0000000 + SZ_512M - 1, 52 .end = 0xc0000000 + SZ_512M - 1,
51 .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, 53 .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
52 }, { 54 }, {
53 .name = "PCIe0 MEM 1", 55 .name = "PCIe0 MEM 2",
54 .start = 0x10000000, 56 .start = 0x10000000,
55 .end = 0x10000000 + SZ_64M - 1, 57 .end = 0x10000000 + SZ_64M - 1,
56 .flags = IORESOURCE_MEM, 58 .flags = IORESOURCE_MEM,
57 }, { 59 }, {
58 .name = "PCIe0 MEM 2", 60 .name = "PCIe0 IO",
59 .start = 0xfe100000, 61 .start = 0xfe100000,
60 .end = 0xfe100000 + SZ_1M - 1, 62 .end = 0xfe100000 + SZ_1M - 1,
61 .flags = IORESOURCE_MEM, 63 .flags = IORESOURCE_IO,
62 }, 64 },
63}; 65};
64 66
65static struct resource sh7786_pci1_resources[] = { 67static struct resource sh7786_pci1_resources[] = {
66 { 68 {
67 .name = "PCIe1 IO", 69 .name = "PCIe1 MEM 0",
68 .start = 0xfd800000, 70 .start = 0xfd800000,
69 .end = 0xfd800000 + SZ_8M - 1, 71 .end = 0xfd800000 + SZ_8M - 1,
70 .flags = IORESOURCE_IO, 72 .flags = IORESOURCE_MEM,
71 }, { 73 }, {
72 .name = "PCIe1 MEM 0", 74 .name = "PCIe1 MEM 1",
73 .start = 0xa0000000, 75 .start = 0xa0000000,
74 .end = 0xa0000000 + SZ_512M - 1, 76 .end = 0xa0000000 + SZ_512M - 1,
75 .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, 77 .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
76 }, { 78 }, {
77 .name = "PCIe1 MEM 1", 79 .name = "PCIe1 MEM 2",
78 .start = 0x30000000, 80 .start = 0x30000000,
79 .end = 0x30000000 + SZ_256M - 1, 81 .end = 0x30000000 + SZ_256M - 1,
80 .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, 82 .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
81 }, { 83 }, {
82 .name = "PCIe1 MEM 2", 84 .name = "PCIe1 IO",
83 .start = 0xfe300000, 85 .start = 0xfe300000,
84 .end = 0xfe300000 + SZ_1M - 1, 86 .end = 0xfe300000 + SZ_1M - 1,
85 .flags = IORESOURCE_MEM, 87 .flags = IORESOURCE_IO,
86 }, 88 },
87}; 89};
88 90
89static struct resource sh7786_pci2_resources[] = { 91static struct resource sh7786_pci2_resources[] = {
90 { 92 {
91 .name = "PCIe2 IO", 93 .name = "PCIe2 MEM 0",
92 .start = 0xfc800000, 94 .start = 0xfc800000,
93 .end = 0xfc800000 + SZ_4M - 1, 95 .end = 0xfc800000 + SZ_4M - 1,
94 .flags = IORESOURCE_IO, 96 .flags = IORESOURCE_MEM,
95 }, { 97 }, {
96 .name = "PCIe2 MEM 0", 98 .name = "PCIe2 MEM 1",
97 .start = 0x80000000, 99 .start = 0x80000000,
98 .end = 0x80000000 + SZ_512M - 1, 100 .end = 0x80000000 + SZ_512M - 1,
99 .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, 101 .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
100 }, { 102 }, {
101 .name = "PCIe2 MEM 1", 103 .name = "PCIe2 MEM 2",
102 .start = 0x20000000, 104 .start = 0x20000000,
103 .end = 0x20000000 + SZ_256M - 1, 105 .end = 0x20000000 + SZ_256M - 1,
104 .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, 106 .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
105 }, { 107 }, {
106 .name = "PCIe2 MEM 2", 108 .name = "PCIe2 IO",
107 .start = 0xfcd00000, 109 .start = 0xfcd00000,
108 .end = 0xfcd00000 + SZ_1M - 1, 110 .end = 0xfcd00000 + SZ_1M - 1,
109 .flags = IORESOURCE_MEM, 111 .flags = IORESOURCE_IO,
110 }, 112 },
111}; 113};
112 114
@@ -301,7 +303,7 @@ static int __init pcie_init(struct sh7786_pcie_port *port)
301{ 303{
302 struct pci_channel *chan = port->hose; 304 struct pci_channel *chan = port->hose;
303 unsigned int data; 305 unsigned int data;
304 phys_addr_t memphys; 306 phys_addr_t memstart, memend;
305 size_t memsize; 307 size_t memsize;
306 int ret, i, win; 308 int ret, i, win;
307 309
@@ -357,15 +359,26 @@ static int __init pcie_init(struct sh7786_pcie_port *port)
357 data |= (0xff << 16); 359 data |= (0xff << 16);
358 pci_write_reg(chan, data, SH4A_PCIEMACCTLR); 360 pci_write_reg(chan, data, SH4A_PCIEMACCTLR);
359 361
360 memphys = __pa(memory_start); 362 memstart = __pa(memory_start);
361 memsize = roundup_pow_of_two(memory_end - memory_start); 363 memend = __pa(memory_end);
364 memsize = roundup_pow_of_two(memend - memstart);
365
366 /*
367 * The start address must be aligned on its size. So we round
368 * it down, and then recalculate the size so that it covers
369 * the entire memory.
370 */
371 memstart = ALIGN_DOWN(memstart, memsize);
372 memsize = roundup_pow_of_two(memend - memstart);
373
374 dma_pfn_offset = memstart >> PAGE_SHIFT;
362 375
363 /* 376 /*
364 * If there's more than 512MB of memory, we need to roll over to 377 * If there's more than 512MB of memory, we need to roll over to
365 * LAR1/LAMR1. 378 * LAR1/LAMR1.
366 */ 379 */
367 if (memsize > SZ_512M) { 380 if (memsize > SZ_512M) {
368 pci_write_reg(chan, memphys + SZ_512M, SH4A_PCIELAR1); 381 pci_write_reg(chan, memstart + SZ_512M, SH4A_PCIELAR1);
369 pci_write_reg(chan, ((memsize - SZ_512M) - SZ_256) | 1, 382 pci_write_reg(chan, ((memsize - SZ_512M) - SZ_256) | 1,
370 SH4A_PCIELAMR1); 383 SH4A_PCIELAMR1);
371 memsize = SZ_512M; 384 memsize = SZ_512M;
@@ -381,7 +394,7 @@ static int __init pcie_init(struct sh7786_pcie_port *port)
381 * LAR0/LAMR0 covers up to the first 512MB, which is enough to 394 * LAR0/LAMR0 covers up to the first 512MB, which is enough to
382 * cover all of lowmem on most platforms. 395 * cover all of lowmem on most platforms.
383 */ 396 */
384 pci_write_reg(chan, memphys, SH4A_PCIELAR0); 397 pci_write_reg(chan, memstart, SH4A_PCIELAR0);
385 pci_write_reg(chan, (memsize - SZ_256) | 1, SH4A_PCIELAMR0); 398 pci_write_reg(chan, (memsize - SZ_256) | 1, SH4A_PCIELAMR0);
386 399
387 /* Finish initialization */ 400 /* Finish initialization */
@@ -438,6 +451,9 @@ static int __init pcie_init(struct sh7786_pcie_port *port)
438 * mode, so just skip them entirely. 451 * mode, so just skip them entirely.
439 */ 452 */
440 if ((res->flags & IORESOURCE_MEM_32BIT) && __in_29bit_mode()) 453 if ((res->flags & IORESOURCE_MEM_32BIT) && __in_29bit_mode())
454 res->flags |= IORESOURCE_DISABLED;
455
456 if (res->flags & IORESOURCE_DISABLED)
441 continue; 457 continue;
442 458
443 pci_write_reg(chan, 0x00000000, SH4A_PCIEPTCTLR(win)); 459 pci_write_reg(chan, 0x00000000, SH4A_PCIEPTCTLR(win));
@@ -472,6 +488,11 @@ int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
472 return evt2irq(0xae0); 488 return evt2irq(0xae0);
473} 489}
474 490
491void pcibios_bus_add_device(struct pci_dev *pdev)
492{
493 pdev->dev.dma_pfn_offset = dma_pfn_offset;
494}
495
475static int __init sh7786_pcie_core_init(void) 496static int __init sh7786_pcie_core_init(void)
476{ 497{
477 /* Return the number of ports */ 498 /* Return the number of ports */
@@ -527,6 +548,7 @@ static struct sh7786_pcie_hwops sh7786_65nm_pcie_hwops __initdata = {
527static int __init sh7786_pcie_init(void) 548static int __init sh7786_pcie_init(void)
528{ 549{
529 struct clk *platclk; 550 struct clk *platclk;
551 u32 mm_sel;
530 int i; 552 int i;
531 553
532 printk(KERN_NOTICE "PCI: Starting initialization.\n"); 554 printk(KERN_NOTICE "PCI: Starting initialization.\n");
@@ -560,6 +582,16 @@ static int __init sh7786_pcie_init(void)
560 582
561 clk_enable(platclk); 583 clk_enable(platclk);
562 584
585 mm_sel = sh7786_mm_sel();
586
587 /*
588 * Depending on the MMSELR register value, the PCIe0 MEM 1
589 * area may not be available. See Table 13.11 of the SH7786
590 * datasheet.
591 */
592 if (mm_sel != 1 && mm_sel != 2 && mm_sel != 5 && mm_sel != 6)
593 sh7786_pci0_resources[2].flags |= IORESOURCE_DISABLED;
594
563 printk(KERN_NOTICE "PCI: probing %d ports.\n", nr_ports); 595 printk(KERN_NOTICE "PCI: probing %d ports.\n", nr_ports);
564 596
565 for (i = 0; i < nr_ports; i++) { 597 for (i = 0; i < nr_ports; i++) {
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,
37 pagefault_disable(); 37 pagefault_disable();
38 38
39 do { 39 do {
40 if (op == FUTEX_OP_SET) 40 ret = get_user(oldval, uaddr);
41 ret = oldval = 0;
42 else
43 ret = get_user(oldval, uaddr);
44 41
45 if (ret) break; 42 if (ret) break;
46 43
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 @@
14#ifndef __CPU_SH7786_H__ 14#ifndef __CPU_SH7786_H__
15#define __CPU_SH7786_H__ 15#define __CPU_SH7786_H__
16 16
17#include <linux/io.h>
18
17enum { 19enum {
18 /* PA */ 20 /* PA */
19 GPIO_PA7, GPIO_PA6, GPIO_PA5, GPIO_PA4, 21 GPIO_PA7, GPIO_PA6, GPIO_PA5, GPIO_PA4,
@@ -131,4 +133,9 @@ enum {
131 GPIO_FN_IRL7, GPIO_FN_IRL6, GPIO_FN_IRL5, GPIO_FN_IRL4, 133 GPIO_FN_IRL7, GPIO_FN_IRL6, GPIO_FN_IRL5, GPIO_FN_IRL4,
132}; 134};
133 135
136static inline u32 sh7786_mm_sel(void)
137{
138 return __raw_readl(0xFC400020) & 0x7;
139}
140
134#endif /* __CPU_SH7786_H__ */ 141#endif /* __CPU_SH7786_H__ */
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,
16 enum dma_data_direction dir, 16 enum dma_data_direction dir,
17 unsigned long attrs) 17 unsigned long attrs)
18{ 18{
19 dma_addr_t addr = page_to_phys(page) + offset; 19 dma_addr_t addr = page_to_phys(page) + offset
20 - PFN_PHYS(dev->dma_pfn_offset);
20 21
21 WARN_ON(size == 0); 22 WARN_ON(size == 0);
22 23
@@ -36,12 +37,14 @@ static int nommu_map_sg(struct device *dev, struct scatterlist *sg,
36 WARN_ON(nents == 0 || sg[0].length == 0); 37 WARN_ON(nents == 0 || sg[0].length == 0);
37 38
38 for_each_sg(sg, s, nents, i) { 39 for_each_sg(sg, s, nents, i) {
40 dma_addr_t offset = PFN_PHYS(dev->dma_pfn_offset);
41
39 BUG_ON(!sg_page(s)); 42 BUG_ON(!sg_page(s));
40 43
41 if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) 44 if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
42 sh_sync_dma_for_device(sg_virt(s), s->length, dir); 45 sh_sync_dma_for_device(sg_virt(s), s->length, dir);
43 46
44 s->dma_address = sg_phys(s); 47 s->dma_address = sg_phys(s) - offset;
45 s->dma_length = s->length; 48 s->dma_length = s->length;
46 } 49 }
47 50
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:
255 mov.l @r8, r8 255 mov.l @r8, r8
256 jsr @r8 256 jsr @r8
257 nop 257 nop
258 bra __restore_all 258 bra ret_from_exception
259 nop 259 nop
260 CFI_ENDPROC 260 CFI_ENDPROC
261 261
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)
330 /* Let earlyprintk output early console messages */ 330 /* Let earlyprintk output early console messages */
331 early_platform_driver_probe("earlyprintk", 1, 1); 331 early_platform_driver_probe("earlyprintk", 1, 1);
332 332
333#ifdef CONFIG_OF_FLATTREE
334#ifdef CONFIG_USE_BUILTIN_DTB
335 unflatten_and_copy_device_tree();
336#else
337 unflatten_device_tree();
338#endif
339#endif
340
333 paging_init(); 341 paging_init();
334 342
335#ifdef CONFIG_DUMMY_CONSOLE 343#ifdef CONFIG_DUMMY_CONSOLE
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,
59 59
60 split_page(pfn_to_page(virt_to_phys(ret) >> PAGE_SHIFT), order); 60 split_page(pfn_to_page(virt_to_phys(ret) >> PAGE_SHIFT), order);
61 61
62 *dma_handle = virt_to_phys(ret); 62 *dma_handle = virt_to_phys(ret) - PFN_PHYS(dev->dma_pfn_offset);
63 63
64 return ret_nocache; 64 return ret_nocache;
65} 65}
@@ -69,7 +69,7 @@ void dma_generic_free_coherent(struct device *dev, size_t size,
69 unsigned long attrs) 69 unsigned long attrs)
70{ 70{
71 int order = get_order(size); 71 int order = get_order(size);
72 unsigned long pfn = dma_handle >> PAGE_SHIFT; 72 unsigned long pfn = (dma_handle >> PAGE_SHIFT) + dev->dma_pfn_offset;
73 int k; 73 int k;
74 74
75 for (k = 0; k < (1 << order); k++) 75 for (k = 0; k < (1 << order); k++)