aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/kernel/pci_iommu.c2
-rw-r--r--arch/arm/common/dmabounce.c2
-rw-r--r--arch/blackfin/kernel/dma-mapping.c3
-rw-r--r--arch/ia64/hp/common/sba_iommu.c2
-rw-r--r--arch/ia64/hp/sim/simscsi.c4
-rw-r--r--arch/ia64/kernel/efi.c4
-rw-r--r--arch/ia64/kernel/setup.c14
-rw-r--r--arch/ia64/sn/pci/pci_dma.c2
-rw-r--r--arch/m68k/kernel/dma.c2
-rw-r--r--arch/mips/Kconfig4
-rw-r--r--arch/mips/Kconfig.debug12
-rw-r--r--arch/mips/Makefile18
-rw-r--r--arch/mips/cobalt/Makefile2
-rw-r--r--arch/mips/cobalt/setup.c24
-rw-r--r--arch/mips/cobalt/time.c35
-rw-r--r--arch/mips/kernel/Makefile1
-rw-r--r--arch/mips/kernel/cevt-gt641xx.c144
-rw-r--r--arch/mips/kernel/cevt-r4k.c4
-rw-r--r--arch/mips/kernel/time.c4
-rw-r--r--arch/mips/mips-boards/generic/time.c13
-rw-r--r--arch/mips/mm/dma-default.c16
-rw-r--r--arch/mips/sgi-ip27/ip27-init.c2
-rw-r--r--arch/mips/sgi-ip27/ip27-timer.c134
-rw-r--r--arch/mips/sibyte/bcm1480/irq.c75
-rw-r--r--arch/mips/sibyte/bcm1480/smp.c4
-rw-r--r--arch/mips/sibyte/bcm1480/time.c117
-rw-r--r--arch/mips/sibyte/sb1250/irq.c35
-rw-r--r--arch/mips/sibyte/sb1250/smp.c4
-rw-r--r--arch/mips/sibyte/sb1250/time.c88
-rw-r--r--arch/powerpc/boot/dts/lite5200.dts26
-rw-r--r--arch/powerpc/boot/dts/lite5200b.dts26
-rw-r--r--arch/powerpc/kernel/dma_64.c3
-rw-r--r--arch/powerpc/kernel/ibmebus.c3
-rw-r--r--arch/powerpc/kernel/iommu.c2
-rw-r--r--arch/powerpc/platforms/52xx/lite5200.c4
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_common.c71
-rw-r--r--arch/powerpc/platforms/ps3/system-bus.c5
-rw-r--r--arch/powerpc/sysdev/bestcomm/bestcomm.c9
-rw-r--r--arch/sparc/kernel/ioport.c17
-rw-r--r--arch/sparc/mm/io-unit.c2
-rw-r--r--arch/sparc/mm/iommu.c8
-rw-r--r--arch/sparc/mm/sun4c.c2
-rw-r--r--arch/sparc64/Kconfig4
-rw-r--r--arch/sparc64/Makefile4
-rw-r--r--arch/sparc64/defconfig91
-rw-r--r--arch/sparc64/kernel/Makefile9
-rw-r--r--arch/sparc64/kernel/iommu.c7
-rw-r--r--arch/sparc64/kernel/iommu_common.c13
-rw-r--r--arch/sparc64/kernel/irq.c85
-rw-r--r--arch/sparc64/kernel/ldc.c2
-rw-r--r--arch/sparc64/kernel/pci.c3
-rw-r--r--arch/sparc64/kernel/pci_msi.c14
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c7
-rw-r--r--arch/sparc64/math-emu/Makefile2
-rw-r--r--arch/um/drivers/ubd_kern.c2
-rw-r--r--arch/x86/boot/compressed/head_32.S15
-rw-r--r--arch/x86/boot/compressed/misc_32.c3
-rw-r--r--arch/x86/boot/header.S7
-rw-r--r--arch/x86/kernel/asm-offsets_32.c7
-rw-r--r--arch/x86/kernel/e820_32.c18
-rw-r--r--arch/x86/kernel/e820_64.c22
-rw-r--r--arch/x86/kernel/efi_32.c4
-rw-r--r--arch/x86/kernel/head_32.S44
-rw-r--r--arch/x86/kernel/io_apic_64.c59
-rw-r--r--arch/x86/kernel/pci-calgary_64.c10
-rw-r--r--arch/x86/kernel/pci-dma_64.c5
-rw-r--r--arch/x86/kernel/pci-gart_64.c4
-rw-r--r--arch/x86/kernel/pci-nommu_64.c4
-rw-r--r--arch/x86/kernel/setup_32.c4
-rw-r--r--arch/x86/kernel/setup_64.c9
-rw-r--r--arch/x86/mm/pageattr_64.c6
-rw-r--r--arch/x86_64/Kconfig32
72 files changed, 904 insertions, 541 deletions
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index e1c470752ebc..ee07dceae1d4 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -465,7 +465,7 @@ EXPORT_SYMBOL(pci_free_consistent);
465 Write dma_length of each leader with the combined lengths of 465 Write dma_length of each leader with the combined lengths of
466 the mergable followers. */ 466 the mergable followers. */
467 467
468#define SG_ENT_VIRT_ADDRESS(SG) (page_address((SG)->page) + (SG)->offset) 468#define SG_ENT_VIRT_ADDRESS(SG) (sg_virt((SG)))
469#define SG_ENT_PHYS_ADDRESS(SG) __pa(SG_ENT_VIRT_ADDRESS(SG)) 469#define SG_ENT_PHYS_ADDRESS(SG) __pa(SG_ENT_VIRT_ADDRESS(SG))
470 470
471static void 471static void
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 44ab0dad4035..9d371e476552 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -442,7 +442,7 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
442 BUG_ON(dir == DMA_NONE); 442 BUG_ON(dir == DMA_NONE);
443 443
444 for (i = 0; i < nents; i++, sg++) { 444 for (i = 0; i < nents; i++, sg++) {
445 struct page *page = sg->page; 445 struct page *page = sg_page(sg);
446 unsigned int offset = sg->offset; 446 unsigned int offset = sg->offset;
447 unsigned int length = sg->length; 447 unsigned int length = sg->length;
448 void *ptr = page_address(page) + offset; 448 void *ptr = page_address(page) + offset;
diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c
index 94d7b119b71e..a16cb03c5291 100644
--- a/arch/blackfin/kernel/dma-mapping.c
+++ b/arch/blackfin/kernel/dma-mapping.c
@@ -160,8 +160,7 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
160 BUG_ON(direction == DMA_NONE); 160 BUG_ON(direction == DMA_NONE);
161 161
162 for (i = 0; i < nents; i++, sg++) { 162 for (i = 0; i < nents; i++, sg++) {
163 sg->dma_address = (dma_addr_t)(page_address(sg->page) + 163 sg->dma_address = (dma_addr_t) sg_virt(sg);
164 sg->offset);
165 164
166 invalidate_dcache_range(sg_dma_address(sg), 165 invalidate_dcache_range(sg_dma_address(sg),
167 sg_dma_address(sg) + 166 sg_dma_address(sg) +
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index 3c95f4184b99..bc859a311eaf 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -246,7 +246,7 @@ static int reserve_sba_gart = 1;
246static SBA_INLINE void sba_mark_invalid(struct ioc *, dma_addr_t, size_t); 246static SBA_INLINE void sba_mark_invalid(struct ioc *, dma_addr_t, size_t);
247static SBA_INLINE void sba_free_range(struct ioc *, dma_addr_t, size_t); 247static SBA_INLINE void sba_free_range(struct ioc *, dma_addr_t, size_t);
248 248
249#define sba_sg_address(sg) (page_address((sg)->page) + (sg)->offset) 249#define sba_sg_address(sg) sg_virt((sg))
250 250
251#ifdef FULL_VALID_PDIR 251#ifdef FULL_VALID_PDIR
252static u64 prefetch_spill_page; 252static u64 prefetch_spill_page;
diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c
index a3a558a06757..6ef9b5219930 100644
--- a/arch/ia64/hp/sim/simscsi.c
+++ b/arch/ia64/hp/sim/simscsi.c
@@ -131,7 +131,7 @@ simscsi_sg_readwrite (struct scsi_cmnd *sc, int mode, unsigned long offset)
131 stat.fd = desc[sc->device->id]; 131 stat.fd = desc[sc->device->id];
132 132
133 scsi_for_each_sg(sc, sl, scsi_sg_count(sc), i) { 133 scsi_for_each_sg(sc, sl, scsi_sg_count(sc), i) {
134 req.addr = __pa(page_address(sl->page) + sl->offset); 134 req.addr = __pa(sg_virt(sl));
135 req.len = sl->length; 135 req.len = sl->length;
136 if (DBG) 136 if (DBG)
137 printk("simscsi_sg_%s @ %lx (off %lx) use_sg=%d len=%d\n", 137 printk("simscsi_sg_%s @ %lx (off %lx) use_sg=%d len=%d\n",
@@ -212,7 +212,7 @@ static void simscsi_fillresult(struct scsi_cmnd *sc, char *buf, unsigned len)
212 if (!len) 212 if (!len)
213 break; 213 break;
214 thislen = min(len, slp->length); 214 thislen = min(len, slp->length);
215 memcpy(page_address(slp->page) + slp->offset, buf, thislen); 215 memcpy(sg_virt(slp), buf, thislen);
216 len -= thislen; 216 len -= thislen;
217 } 217 }
218} 218}
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index 8e4894b205e2..3f7ea13358e9 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -1090,7 +1090,8 @@ efi_memmap_init(unsigned long *s, unsigned long *e)
1090 1090
1091void 1091void
1092efi_initialize_iomem_resources(struct resource *code_resource, 1092efi_initialize_iomem_resources(struct resource *code_resource,
1093 struct resource *data_resource) 1093 struct resource *data_resource,
1094 struct resource *bss_resource)
1094{ 1095{
1095 struct resource *res; 1096 struct resource *res;
1096 void *efi_map_start, *efi_map_end, *p; 1097 void *efi_map_start, *efi_map_end, *p;
@@ -1171,6 +1172,7 @@ efi_initialize_iomem_resources(struct resource *code_resource,
1171 */ 1172 */
1172 insert_resource(res, code_resource); 1173 insert_resource(res, code_resource);
1173 insert_resource(res, data_resource); 1174 insert_resource(res, data_resource);
1175 insert_resource(res, bss_resource);
1174#ifdef CONFIG_KEXEC 1176#ifdef CONFIG_KEXEC
1175 insert_resource(res, &efi_memmap_res); 1177 insert_resource(res, &efi_memmap_res);
1176 insert_resource(res, &boot_param_res); 1178 insert_resource(res, &boot_param_res);
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index cbf67f1aa291..ae6c3c02e117 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -90,7 +90,12 @@ static struct resource code_resource = {
90 .name = "Kernel code", 90 .name = "Kernel code",
91 .flags = IORESOURCE_BUSY | IORESOURCE_MEM 91 .flags = IORESOURCE_BUSY | IORESOURCE_MEM
92}; 92};
93extern char _text[], _end[], _etext[]; 93
94static struct resource bss_resource = {
95 .name = "Kernel bss",
96 .flags = IORESOURCE_BUSY | IORESOURCE_MEM
97};
98extern char _text[], _end[], _etext[], _edata[], _bss[];
94 99
95unsigned long ia64_max_cacheline_size; 100unsigned long ia64_max_cacheline_size;
96 101
@@ -200,8 +205,11 @@ static int __init register_memory(void)
200 code_resource.start = ia64_tpa(_text); 205 code_resource.start = ia64_tpa(_text);
201 code_resource.end = ia64_tpa(_etext) - 1; 206 code_resource.end = ia64_tpa(_etext) - 1;
202 data_resource.start = ia64_tpa(_etext); 207 data_resource.start = ia64_tpa(_etext);
203 data_resource.end = ia64_tpa(_end) - 1; 208 data_resource.end = ia64_tpa(_edata) - 1;
204 efi_initialize_iomem_resources(&code_resource, &data_resource); 209 bss_resource.start = ia64_tpa(_bss);
210 bss_resource.end = ia64_tpa(_end) - 1;
211 efi_initialize_iomem_resources(&code_resource, &data_resource,
212 &bss_resource);
205 213
206 return 0; 214 return 0;
207} 215}
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index ecd8a52b9b9e..511db2fd7bff 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -16,7 +16,7 @@
16#include <asm/sn/pcidev.h> 16#include <asm/sn/pcidev.h>
17#include <asm/sn/sn_sal.h> 17#include <asm/sn/sn_sal.h>
18 18
19#define SG_ENT_VIRT_ADDRESS(sg) (page_address((sg)->page) + (sg)->offset) 19#define SG_ENT_VIRT_ADDRESS(sg) (sg_virt((sg)))
20#define SG_ENT_PHYS_ADDRESS(SG) virt_to_phys(SG_ENT_VIRT_ADDRESS(SG)) 20#define SG_ENT_PHYS_ADDRESS(SG) virt_to_phys(SG_ENT_VIRT_ADDRESS(SG))
21 21
22/** 22/**
diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
index 9d4e4b5b6bd8..ef490e1ce600 100644
--- a/arch/m68k/kernel/dma.c
+++ b/arch/m68k/kernel/dma.c
@@ -121,7 +121,7 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
121 int i; 121 int i;
122 122
123 for (i = 0; i < nents; sg++, i++) { 123 for (i = 0; i < nents; sg++, i++) {
124 sg->dma_address = page_to_phys(sg->page) + sg->offset; 124 sg->dma_address = sg_phys(sg);
125 dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir); 125 dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
126 } 126 }
127 return nents; 127 return nents;
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 3ecff5e9e4f3..61262c5f9c62 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -66,6 +66,7 @@ config BCM47XX
66config MIPS_COBALT 66config MIPS_COBALT
67 bool "Cobalt Server" 67 bool "Cobalt Server"
68 select CEVT_R4K 68 select CEVT_R4K
69 select CEVT_GT641XX
69 select DMA_NONCOHERENT 70 select DMA_NONCOHERENT
70 select HW_HAS_PCI 71 select HW_HAS_PCI
71 select I8253 72 select I8253
@@ -729,6 +730,9 @@ config ARCH_MAY_HAVE_PC_FDC
729config BOOT_RAW 730config BOOT_RAW
730 bool 731 bool
731 732
733config CEVT_GT641XX
734 bool
735
732config CEVT_R4K 736config CEVT_R4K
733 bool 737 bool
734 738
diff --git a/arch/mips/Kconfig.debug b/arch/mips/Kconfig.debug
index 3efe117721aa..fd7124c1b75a 100644
--- a/arch/mips/Kconfig.debug
+++ b/arch/mips/Kconfig.debug
@@ -6,18 +6,6 @@ config TRACE_IRQFLAGS_SUPPORT
6 6
7source "lib/Kconfig.debug" 7source "lib/Kconfig.debug"
8 8
9config CROSSCOMPILE
10 bool "Are you using a crosscompiler"
11 help
12 Say Y here if you are compiling the kernel on a different
13 architecture than the one it is intended to run on. This is just a
14 convenience option which will select the appropriate value for
15 the CROSS_COMPILE make variable which otherwise has to be passed on
16 the command line from mips-linux-, mipsel-linux-, mips64-linux- and
17 mips64el-linux- as appropriate for a particular kernel configuration.
18 You will have to pass the value for CROSS_COMPILE manually if the
19 name prefix for your tools is different.
20
21config CMDLINE 9config CMDLINE
22 string "Default kernel command string" 10 string "Default kernel command string"
23 default "" 11 default ""
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 14164c2b8791..23c17755eca0 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -18,15 +18,15 @@ cflags-y :=
18# Select the object file format to substitute into the linker script. 18# Select the object file format to substitute into the linker script.
19# 19#
20ifdef CONFIG_CPU_LITTLE_ENDIAN 20ifdef CONFIG_CPU_LITTLE_ENDIAN
2132bit-tool-prefix = mipsel-linux- 2132bit-tool-archpref = mipsel
2264bit-tool-prefix = mips64el-linux- 2264bit-tool-archpref = mips64el
2332bit-bfd = elf32-tradlittlemips 2332bit-bfd = elf32-tradlittlemips
2464bit-bfd = elf64-tradlittlemips 2464bit-bfd = elf64-tradlittlemips
2532bit-emul = elf32ltsmip 2532bit-emul = elf32ltsmip
2664bit-emul = elf64ltsmip 2664bit-emul = elf64ltsmip
27else 27else
2832bit-tool-prefix = mips-linux- 2832bit-tool-archpref = mips
2964bit-tool-prefix = mips64-linux- 2964bit-tool-archpref = mips64
3032bit-bfd = elf32-tradbigmips 3032bit-bfd = elf32-tradbigmips
3164bit-bfd = elf64-tradbigmips 3164bit-bfd = elf64-tradbigmips
3232bit-emul = elf32btsmip 3232bit-emul = elf32btsmip
@@ -34,16 +34,18 @@ else
34endif 34endif
35 35
36ifdef CONFIG_32BIT 36ifdef CONFIG_32BIT
37tool-prefix = $(32bit-tool-prefix) 37tool-archpref = $(32bit-tool-archpref)
38UTS_MACHINE := mips 38UTS_MACHINE := mips
39endif 39endif
40ifdef CONFIG_64BIT 40ifdef CONFIG_64BIT
41tool-prefix = $(64bit-tool-prefix) 41tool-archpref = $(64bit-tool-archpref)
42UTS_MACHINE := mips64 42UTS_MACHINE := mips64
43endif 43endif
44 44
45ifdef CONFIG_CROSSCOMPILE 45ifneq ($(SUBARCH),$(ARCH))
46CROSS_COMPILE := $(tool-prefix) 46 ifeq ($(CROSS_COMPILE),)
47 CROSS_COMPILE := $(call cc-cross-prefix, $(tool-archpref)-linux- $(tool-archpref)-gnu-linux- $(tool-archpref)-unknown-gnu-linux-)
48 endif
47endif 49endif
48 50
49ifdef CONFIG_32BIT 51ifdef CONFIG_32BIT
diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile
index 6b83f4ddc8fc..d73833b7c781 100644
--- a/arch/mips/cobalt/Makefile
+++ b/arch/mips/cobalt/Makefile
@@ -2,7 +2,7 @@
2# Makefile for the Cobalt micro systems family specific parts of the kernel 2# Makefile for the Cobalt micro systems family specific parts of the kernel
3# 3#
4 4
5obj-y := buttons.o irq.o led.o reset.o rtc.o serial.o setup.o 5obj-y := buttons.o irq.o led.o reset.o rtc.o serial.o setup.o time.o
6 6
7obj-$(CONFIG_PCI) += pci.o 7obj-$(CONFIG_PCI) += pci.o
8obj-$(CONFIG_EARLY_PRINTK) += console.o 8obj-$(CONFIG_EARLY_PRINTK) += console.o
diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c
index d11bb1bc7b6b..dd23beb8604f 100644
--- a/arch/mips/cobalt/setup.c
+++ b/arch/mips/cobalt/setup.c
@@ -9,19 +9,17 @@
9 * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv) 9 * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv)
10 * 10 *
11 */ 11 */
12#include <linux/interrupt.h>
13#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/interrupt.h>
14#include <linux/io.h>
15#include <linux/ioport.h>
14#include <linux/pm.h> 16#include <linux/pm.h>
15 17
16#include <asm/bootinfo.h> 18#include <asm/bootinfo.h>
17#include <asm/time.h>
18#include <asm/i8253.h>
19#include <asm/io.h>
20#include <asm/reboot.h> 19#include <asm/reboot.h>
21#include <asm/gt64120.h> 20#include <asm/gt64120.h>
22 21
23#include <cobalt.h> 22#include <cobalt.h>
24#include <irq.h>
25 23
26extern void cobalt_machine_restart(char *command); 24extern void cobalt_machine_restart(char *command);
27extern void cobalt_machine_halt(void); 25extern void cobalt_machine_halt(void);
@@ -41,17 +39,6 @@ const char *get_system_type(void)
41 return "MIPS Cobalt"; 39 return "MIPS Cobalt";
42} 40}
43 41
44void __init plat_timer_setup(struct irqaction *irq)
45{
46 /* Load timer value for HZ (TCLK is 50MHz) */
47 GT_WRITE(GT_TC0_OFS, 50*1000*1000 / HZ);
48
49 /* Enable timer0 */
50 GT_WRITE(GT_TC_CONTROL_OFS, GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
51
52 setup_irq(GT641XX_TIMER0_IRQ, irq);
53}
54
55/* 42/*
56 * Cobalt doesn't have PS/2 keyboard/mouse interfaces, 43 * Cobalt doesn't have PS/2 keyboard/mouse interfaces,
57 * keyboard conntroller is never used. 44 * keyboard conntroller is never used.
@@ -84,11 +71,6 @@ static struct resource cobalt_reserved_resources[] = {
84 }, 71 },
85}; 72};
86 73
87void __init plat_time_init(void)
88{
89 setup_pit_timer();
90}
91
92void __init plat_mem_setup(void) 74void __init plat_mem_setup(void)
93{ 75{
94 int i; 76 int i;
diff --git a/arch/mips/cobalt/time.c b/arch/mips/cobalt/time.c
new file mode 100644
index 000000000000..fa819fccd5db
--- /dev/null
+++ b/arch/mips/cobalt/time.c
@@ -0,0 +1,35 @@
1/*
2 * Cobalt time initialization.
3 *
4 * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20#include <linux/init.h>
21
22#include <asm/gt64120.h>
23#include <asm/i8253.h>
24#include <asm/time.h>
25
26#define GT641XX_BASE_CLOCK 50000000 /* 50MHz */
27
28void __init plat_time_init(void)
29{
30 setup_pit_timer();
31
32 gt641xx_set_base_clock(GT641XX_BASE_CLOCK);
33
34 mips_timer_state = gt641xx_timer0_state;
35}
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index a3afa39faae5..d7745c8976f6 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -9,6 +9,7 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
9 time.o topology.o traps.o unaligned.o 9 time.o topology.o traps.o unaligned.o
10 10
11obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o 11obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o
12obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o
12 13
13binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \ 14binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \
14 irix5sys.o sysirix.o 15 irix5sys.o sysirix.o
diff --git a/arch/mips/kernel/cevt-gt641xx.c b/arch/mips/kernel/cevt-gt641xx.c
new file mode 100644
index 000000000000..4c651b2680f9
--- /dev/null
+++ b/arch/mips/kernel/cevt-gt641xx.c
@@ -0,0 +1,144 @@
1/*
2 * GT641xx clockevent routines.
3 *
4 * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20#include <linux/clockchips.h>
21#include <linux/init.h>
22#include <linux/interrupt.h>
23#include <linux/spinlock.h>
24
25#include <asm/gt64120.h>
26#include <asm/time.h>
27
28#include <irq.h>
29
30static DEFINE_SPINLOCK(gt641xx_timer_lock);
31static unsigned int gt641xx_base_clock;
32
33void gt641xx_set_base_clock(unsigned int clock)
34{
35 gt641xx_base_clock = clock;
36}
37
38int gt641xx_timer0_state(void)
39{
40 if (GT_READ(GT_TC0_OFS))
41 return 0;
42
43 GT_WRITE(GT_TC0_OFS, gt641xx_base_clock / HZ);
44 GT_WRITE(GT_TC_CONTROL_OFS, GT_TC_CONTROL_ENTC0_MSK);
45
46 return 1;
47}
48
49static int gt641xx_timer0_set_next_event(unsigned long delta,
50 struct clock_event_device *evt)
51{
52 unsigned long flags;
53 u32 ctrl;
54
55 spin_lock_irqsave(&gt641xx_timer_lock, flags);
56
57 ctrl = GT_READ(GT_TC_CONTROL_OFS);
58 ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
59 ctrl |= GT_TC_CONTROL_ENTC0_MSK;
60
61 GT_WRITE(GT_TC0_OFS, delta);
62 GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
63
64 spin_unlock_irqrestore(&gt641xx_timer_lock, flags);
65
66 return 0;
67}
68
69static void gt641xx_timer0_set_mode(enum clock_event_mode mode,
70 struct clock_event_device *evt)
71{
72 unsigned long flags;
73 u32 ctrl;
74
75 spin_lock_irqsave(&gt641xx_timer_lock, flags);
76
77 ctrl = GT_READ(GT_TC_CONTROL_OFS);
78 ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
79
80 switch (mode) {
81 case CLOCK_EVT_MODE_PERIODIC:
82 ctrl |= GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK;
83 break;
84 case CLOCK_EVT_MODE_ONESHOT:
85 ctrl |= GT_TC_CONTROL_ENTC0_MSK;
86 break;
87 default:
88 break;
89 }
90
91 GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
92
93 spin_unlock_irqrestore(&gt641xx_timer_lock, flags);
94}
95
96static void gt641xx_timer0_event_handler(struct clock_event_device *dev)
97{
98}
99
100static struct clock_event_device gt641xx_timer0_clockevent = {
101 .name = "gt641xx-timer0",
102 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
103 .cpumask = CPU_MASK_CPU0,
104 .irq = GT641XX_TIMER0_IRQ,
105 .set_next_event = gt641xx_timer0_set_next_event,
106 .set_mode = gt641xx_timer0_set_mode,
107 .event_handler = gt641xx_timer0_event_handler,
108};
109
110static irqreturn_t gt641xx_timer0_interrupt(int irq, void *dev_id)
111{
112 struct clock_event_device *cd = &gt641xx_timer0_clockevent;
113
114 cd->event_handler(cd);
115
116 return IRQ_HANDLED;
117}
118
119static struct irqaction gt641xx_timer0_irqaction = {
120 .handler = gt641xx_timer0_interrupt,
121 .flags = IRQF_DISABLED | IRQF_PERCPU,
122 .name = "gt641xx_timer0",
123};
124
125static int __init gt641xx_timer0_clockevent_init(void)
126{
127 struct clock_event_device *cd;
128
129 if (!gt641xx_base_clock)
130 return 0;
131
132 GT_WRITE(GT_TC0_OFS, gt641xx_base_clock / HZ);
133
134 cd = &gt641xx_timer0_clockevent;
135 cd->rating = 200 + gt641xx_base_clock / 10000000;
136 cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
137 cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
138 clockevent_set_clock(cd, gt641xx_base_clock);
139
140 clockevents_register_device(&gt641xx_timer0_clockevent);
141
142 return setup_irq(GT641XX_TIMER0_IRQ, &gt641xx_timer0_irqaction);
143}
144arch_initcall(gt641xx_timer0_clockevent_init);
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
index a915e5693421..ae2984fff580 100644
--- a/arch/mips/kernel/cevt-r4k.c
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -186,7 +186,7 @@ static int c0_compare_int_usable(void)
186 * IP7 already pending? Try to clear it by acking the timer. 186 * IP7 already pending? Try to clear it by acking the timer.
187 */ 187 */
188 if (c0_compare_int_pending()) { 188 if (c0_compare_int_pending()) {
189 write_c0_compare(read_c0_compare()); 189 write_c0_compare(read_c0_count());
190 irq_disable_hazard(); 190 irq_disable_hazard();
191 if (c0_compare_int_pending()) 191 if (c0_compare_int_pending())
192 return 0; 192 return 0;
@@ -202,7 +202,7 @@ static int c0_compare_int_usable(void)
202 if (!c0_compare_int_pending()) 202 if (!c0_compare_int_pending())
203 return 0; 203 return 0;
204 204
205 write_c0_compare(read_c0_compare()); 205 write_c0_compare(read_c0_count());
206 irq_disable_hazard(); 206 irq_disable_hazard();
207 if (c0_compare_int_pending()) 207 if (c0_compare_int_pending())
208 return 0; 208 return 0;
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index c4e6866d5cbc..6c6849a8f136 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -195,8 +195,8 @@ void __cpuinit clockevent_set_clock(struct clock_event_device *cd,
195 195
196 /* Find a shift value */ 196 /* Find a shift value */
197 for (shift = 32; shift > 0; shift--) { 197 for (shift = 32; shift > 0; shift--) {
198 temp = (u64) NSEC_PER_SEC << shift; 198 temp = (u64) clock << shift;
199 do_div(temp, clock); 199 do_div(temp, NSEC_PER_SEC);
200 if ((temp >> 32) == 0) 200 if ((temp >> 32) == 0)
201 break; 201 break;
202 } 202 }
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c
index 1d00b778ff1e..9d6243a8c15a 100644
--- a/arch/mips/mips-boards/generic/time.c
+++ b/arch/mips/mips-boards/generic/time.c
@@ -147,21 +147,8 @@ void __init plat_time_init(void)
147#endif 147#endif
148} 148}
149 149
150//static irqreturn_t mips_perf_interrupt(int irq, void *dev_id)
151//{
152// return perf_irq();
153//}
154
155//static struct irqaction perf_irqaction = {
156// .handler = mips_perf_interrupt,
157// .flags = IRQF_DISABLED | IRQF_PERCPU,
158// .name = "performance",
159//};
160
161void __init plat_perf_setup(void) 150void __init plat_perf_setup(void)
162{ 151{
163// struct irqaction *irq = &perf_irqaction;
164
165 cp0_perfcount_irq = -1; 152 cp0_perfcount_irq = -1;
166 153
167#ifdef MSC01E_INT_BASE 154#ifdef MSC01E_INT_BASE
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 98b5e5bac02e..b0b034c4654f 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -165,12 +165,11 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
165 for (i = 0; i < nents; i++, sg++) { 165 for (i = 0; i < nents; i++, sg++) {
166 unsigned long addr; 166 unsigned long addr;
167 167
168 addr = (unsigned long) page_address(sg->page); 168 addr = (unsigned long) sg_virt(sg);
169 if (!plat_device_is_coherent(dev) && addr) 169 if (!plat_device_is_coherent(dev) && addr)
170 __dma_sync(addr + sg->offset, sg->length, direction); 170 __dma_sync(addr, sg->length, direction);
171 sg->dma_address = plat_map_dma_mem(dev, 171 sg->dma_address = plat_map_dma_mem(dev,
172 (void *)(addr + sg->offset), 172 (void *)addr, sg->length);
173 sg->length);
174 } 173 }
175 174
176 return nents; 175 return nents;
@@ -223,10 +222,9 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
223 for (i = 0; i < nhwentries; i++, sg++) { 222 for (i = 0; i < nhwentries; i++, sg++) {
224 if (!plat_device_is_coherent(dev) && 223 if (!plat_device_is_coherent(dev) &&
225 direction != DMA_TO_DEVICE) { 224 direction != DMA_TO_DEVICE) {
226 addr = (unsigned long) page_address(sg->page); 225 addr = (unsigned long) sg_virt(sg);
227 if (addr) 226 if (addr)
228 __dma_sync(addr + sg->offset, sg->length, 227 __dma_sync(addr, sg->length, direction);
229 direction);
230 } 228 }
231 plat_unmap_dma_mem(sg->dma_address); 229 plat_unmap_dma_mem(sg->dma_address);
232 } 230 }
@@ -304,7 +302,7 @@ void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
304 /* Make sure that gcc doesn't leave the empty loop body. */ 302 /* Make sure that gcc doesn't leave the empty loop body. */
305 for (i = 0; i < nelems; i++, sg++) { 303 for (i = 0; i < nelems; i++, sg++) {
306 if (cpu_is_noncoherent_r10000(dev)) 304 if (cpu_is_noncoherent_r10000(dev))
307 __dma_sync((unsigned long)page_address(sg->page), 305 __dma_sync((unsigned long)page_address(sg_page(sg)),
308 sg->length, direction); 306 sg->length, direction);
309 plat_unmap_dma_mem(sg->dma_address); 307 plat_unmap_dma_mem(sg->dma_address);
310 } 308 }
@@ -322,7 +320,7 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nele
322 /* Make sure that gcc doesn't leave the empty loop body. */ 320 /* Make sure that gcc doesn't leave the empty loop body. */
323 for (i = 0; i < nelems; i++, sg++) { 321 for (i = 0; i < nelems; i++, sg++) {
324 if (!plat_device_is_coherent(dev)) 322 if (!plat_device_is_coherent(dev))
325 __dma_sync((unsigned long)page_address(sg->page), 323 __dma_sync((unsigned long)page_address(sg_page(sg)),
326 sg->length, direction); 324 sg->length, direction);
327 plat_unmap_dma_mem(sg->dma_address); 325 plat_unmap_dma_mem(sg->dma_address);
328 } 326 }
diff --git a/arch/mips/sgi-ip27/ip27-init.c b/arch/mips/sgi-ip27/ip27-init.c
index 681b593071cb..3305fa9ae66d 100644
--- a/arch/mips/sgi-ip27/ip27-init.c
+++ b/arch/mips/sgi-ip27/ip27-init.c
@@ -110,7 +110,7 @@ static void __init per_hub_init(cnodeid_t cnode)
110 } 110 }
111} 111}
112 112
113void __init per_cpu_init(void) 113void __cpuinit per_cpu_init(void)
114{ 114{
115 int cpu = smp_processor_id(); 115 int cpu = smp_processor_id();
116 int slice = LOCAL_HUB_L(PI_CPU_NUM); 116 int slice = LOCAL_HUB_L(PI_CPU_NUM);
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
index d467bf4f6c3f..f5dccf01da11 100644
--- a/arch/mips/sgi-ip27/ip27-timer.c
+++ b/arch/mips/sgi-ip27/ip27-timer.c
@@ -111,8 +111,24 @@ unsigned long read_persistent_clock(void)
111 return mktime(year, month, date, hour, min, sec); 111 return mktime(year, month, date, hour, min, sec);
112} 112}
113 113
114static int rt_set_next_event(unsigned long delta, 114static void enable_rt_irq(unsigned int irq)
115 struct clock_event_device *evt) 115{
116}
117
118static void disable_rt_irq(unsigned int irq)
119{
120}
121
122static struct irq_chip rt_irq_type = {
123 .name = "SN HUB RT timer",
124 .ack = disable_rt_irq,
125 .mask = disable_rt_irq,
126 .mask_ack = disable_rt_irq,
127 .unmask = enable_rt_irq,
128 .eoi = enable_rt_irq,
129};
130
131static int rt_next_event(unsigned long delta, struct clock_event_device *evt)
116{ 132{
117 unsigned int cpu = smp_processor_id(); 133 unsigned int cpu = smp_processor_id();
118 int slice = cputoslice(cpu) == 0; 134 int slice = cputoslice(cpu) == 0;
@@ -129,50 +145,24 @@ static void rt_set_mode(enum clock_event_mode mode,
129 struct clock_event_device *evt) 145 struct clock_event_device *evt)
130{ 146{
131 switch (mode) { 147 switch (mode) {
132 case CLOCK_EVT_MODE_PERIODIC: 148 case CLOCK_EVT_MODE_ONESHOT:
133 /* The only mode supported */ 149 /* The only mode supported */
134 break; 150 break;
135 151
152 case CLOCK_EVT_MODE_PERIODIC:
136 case CLOCK_EVT_MODE_UNUSED: 153 case CLOCK_EVT_MODE_UNUSED:
137 case CLOCK_EVT_MODE_SHUTDOWN: 154 case CLOCK_EVT_MODE_SHUTDOWN:
138 case CLOCK_EVT_MODE_ONESHOT:
139 case CLOCK_EVT_MODE_RESUME: 155 case CLOCK_EVT_MODE_RESUME:
140 /* Nothing to do */ 156 /* Nothing to do */
141 break; 157 break;
142 } 158 }
143} 159}
144 160
145struct clock_event_device rt_clock_event_device = {
146 .name = "HUB-RT",
147 .features = CLOCK_EVT_FEAT_ONESHOT,
148
149 .rating = 300,
150 .set_next_event = rt_set_next_event,
151 .set_mode = rt_set_mode,
152};
153
154static void enable_rt_irq(unsigned int irq)
155{
156}
157
158static void disable_rt_irq(unsigned int irq)
159{
160}
161
162static struct irq_chip rt_irq_type = {
163 .name = "SN HUB RT timer",
164 .ack = disable_rt_irq,
165 .mask = disable_rt_irq,
166 .mask_ack = disable_rt_irq,
167 .unmask = enable_rt_irq,
168 .eoi = enable_rt_irq,
169};
170
171unsigned int rt_timer_irq; 161unsigned int rt_timer_irq;
172 162
173static irqreturn_t ip27_rt_timer_interrupt(int irq, void *dev_id) 163static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id)
174{ 164{
175 struct clock_event_device *cd = &rt_clock_event_device; 165 struct clock_event_device *cd = dev_id;
176 unsigned int cpu = smp_processor_id(); 166 unsigned int cpu = smp_processor_id();
177 int slice = cputoslice(cpu) == 0; 167 int slice = cputoslice(cpu) == 0;
178 168
@@ -182,11 +172,10 @@ static irqreturn_t ip27_rt_timer_interrupt(int irq, void *dev_id)
182 return IRQ_HANDLED; 172 return IRQ_HANDLED;
183} 173}
184 174
185static struct irqaction rt_irqaction = { 175struct irqaction hub_rt_irqaction = {
186 .handler = (irq_handler_t) ip27_rt_timer_interrupt, 176 .handler = hub_rt_counter_handler,
187 .flags = IRQF_DISABLED, 177 .flags = IRQF_DISABLED | IRQF_PERCPU,
188 .mask = CPU_MASK_NONE, 178 .name = "hub-rt",
189 .name = "timer"
190}; 179};
191 180
192/* 181/*
@@ -200,32 +189,48 @@ static struct irqaction rt_irqaction = {
200#define NSEC_PER_CYCLE 800 189#define NSEC_PER_CYCLE 800
201#define CYCLES_PER_SEC (NSEC_PER_SEC / NSEC_PER_CYCLE) 190#define CYCLES_PER_SEC (NSEC_PER_SEC / NSEC_PER_CYCLE)
202 191
203static void __init ip27_rt_clock_event_init(void) 192static DEFINE_PER_CPU(struct clock_event_device, hub_rt_clockevent);
193static DEFINE_PER_CPU(char [11], hub_rt_name);
194
195static void __cpuinit hub_rt_clock_event_init(void)
204{ 196{
205 struct clock_event_device *cd = &rt_clock_event_device;
206 unsigned int cpu = smp_processor_id(); 197 unsigned int cpu = smp_processor_id();
207 int irq = allocate_irqno(); 198 struct clock_event_device *cd = &per_cpu(hub_rt_clockevent, cpu);
208 199 unsigned char *name = per_cpu(hub_rt_name, cpu);
209 if (irq < 0) 200 int irq = rt_timer_irq;
210 panic("Can't allocate interrupt number for timer interrupt"); 201
211 202 sprintf(name, "hub-rt %d", cpu);
212 rt_timer_irq = irq; 203 cd->name = "HUB-RT",
213 204 cd->features = CLOCK_EVT_FEAT_ONESHOT,
205 clockevent_set_clock(cd, CYCLES_PER_SEC);
206 cd->max_delta_ns = clockevent_delta2ns(0xfffffffffffff, cd);
207 cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
208 cd->rating = 200,
214 cd->irq = irq, 209 cd->irq = irq,
215 cd->cpumask = cpumask_of_cpu(cpu), 210 cd->cpumask = cpumask_of_cpu(cpu),
216 211 cd->rating = 300,
217 /* 212 cd->set_next_event = rt_next_event,
218 * Calculate the min / max delta 213 cd->set_mode = rt_set_mode,
219 */
220 cd->mult =
221 div_sc((unsigned long) CYCLES_PER_SEC, NSEC_PER_SEC, 32);
222 cd->shift = 32;
223 cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
224 cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
225 clockevents_register_device(cd); 214 clockevents_register_device(cd);
215}
216
217static void __init hub_rt_clock_event_global_init(void)
218{
219 unsigned int irq;
220
221 do {
222 smp_wmb();
223 irq = rt_timer_irq;
224 if (irq)
225 break;
226
227 irq = allocate_irqno();
228 if (irq < 0)
229 panic("Allocation of irq number for timer failed");
230 } while (xchg(&rt_timer_irq, irq));
226 231
227 set_irq_chip_and_handler(irq, &rt_irq_type, handle_percpu_irq); 232 set_irq_chip_and_handler(irq, &rt_irq_type, handle_percpu_irq);
228 setup_irq(irq, &rt_irqaction); 233 setup_irq(irq, &hub_rt_irqaction);
229} 234}
230 235
231static cycle_t hub_rt_read(void) 236static cycle_t hub_rt_read(void)
@@ -233,27 +238,29 @@ static cycle_t hub_rt_read(void)
233 return REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT); 238 return REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT);
234} 239}
235 240
236struct clocksource ht_rt_clocksource = { 241struct clocksource hub_rt_clocksource = {
237 .name = "HUB-RT", 242 .name = "HUB-RT",
238 .rating = 200, 243 .rating = 200,
239 .read = hub_rt_read, 244 .read = hub_rt_read,
240 .mask = CLOCKSOURCE_MASK(52), 245 .mask = CLOCKSOURCE_MASK(52),
241 .shift = 32,
242 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 246 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
243}; 247};
244 248
245static void __init ip27_rt_clocksource_init(void) 249static void __init hub_rt_clocksource_init(void)
246{ 250{
247 clocksource_register(&ht_rt_clocksource); 251 struct clocksource *cs = &hub_rt_clocksource;
252
253 clocksource_set_clock(cs, CYCLES_PER_SEC);
254 clocksource_register(cs);
248} 255}
249 256
250void __init plat_time_init(void) 257void __init plat_time_init(void)
251{ 258{
252 ip27_rt_clock_event_init(); 259 hub_rt_clocksource_init();
253 ip27_rt_clocksource_init(); 260 hub_rt_clock_event_global_init();
254} 261}
255 262
256void __init cpu_time_init(void) 263void __cpuinit cpu_time_init(void)
257{ 264{
258 lboard_t *board; 265 lboard_t *board;
259 klcpu_t *cpu; 266 klcpu_t *cpu;
@@ -271,6 +278,7 @@ void __init cpu_time_init(void)
271 278
272 printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed); 279 printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed);
273 280
281 hub_rt_clock_event_init();
274 set_c0_status(SRB_TIMOCLK); 282 set_c0_status(SRB_TIMOCLK);
275} 283}
276 284
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
index 7aa79bf63c4a..10299bafeab7 100644
--- a/arch/mips/sibyte/bcm1480/irq.c
+++ b/arch/mips/sibyte/bcm1480/irq.c
@@ -452,6 +452,43 @@ static void bcm1480_kgdb_interrupt(void)
452 452
453extern void bcm1480_mailbox_interrupt(void); 453extern void bcm1480_mailbox_interrupt(void);
454 454
455static inline void dispatch_ip4(void)
456{
457 int cpu = smp_processor_id();
458 int irq = K_BCM1480_INT_TIMER_0 + cpu;
459
460 /* Reset the timer */
461 __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
462 IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
463
464 do_IRQ(irq);
465}
466
467static inline void dispatch_ip2(void)
468{
469 unsigned long long mask_h, mask_l;
470 unsigned int cpu = smp_processor_id();
471 unsigned long base;
472
473 /*
474 * Default...we've hit an IP[2] interrupt, which means we've got to
475 * check the 1480 interrupt registers to figure out what to do. Need
476 * to detect which CPU we're on, now that smp_affinity is supported.
477 */
478 base = A_BCM1480_IMR_MAPPER(cpu);
479 mask_h = __raw_readq(
480 IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H));
481 mask_l = __raw_readq(
482 IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L));
483
484 if (mask_h) {
485 if (mask_h ^ 1)
486 do_IRQ(fls64(mask_h) - 1);
487 else if (mask_l)
488 do_IRQ(63 + fls64(mask_l));
489 }
490}
491
455asmlinkage void plat_irq_dispatch(void) 492asmlinkage void plat_irq_dispatch(void)
456{ 493{
457 unsigned int pending; 494 unsigned int pending;
@@ -469,17 +506,8 @@ asmlinkage void plat_irq_dispatch(void)
469 else 506 else
470#endif 507#endif
471 508
472 if (pending & CAUSEF_IP4) { 509 if (pending & CAUSEF_IP4)
473 int cpu = smp_processor_id(); 510 dispatch_ip4();
474 int irq = K_BCM1480_INT_TIMER_0 + cpu;
475
476 /* Reset the timer */
477 __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
478 IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
479
480 do_IRQ(irq);
481 }
482
483#ifdef CONFIG_SMP 511#ifdef CONFIG_SMP
484 else if (pending & CAUSEF_IP3) 512 else if (pending & CAUSEF_IP3)
485 bcm1480_mailbox_interrupt(); 513 bcm1480_mailbox_interrupt();
@@ -490,27 +518,6 @@ asmlinkage void plat_irq_dispatch(void)
490 bcm1480_kgdb_interrupt(); /* KGDB (uart 1) */ 518 bcm1480_kgdb_interrupt(); /* KGDB (uart 1) */
491#endif 519#endif
492 520
493 else if (pending & CAUSEF_IP2) { 521 else if (pending & CAUSEF_IP2)
494 unsigned long long mask_h, mask_l; 522 dispatch_ip2();
495 unsigned long base;
496
497 /*
498 * Default...we've hit an IP[2] interrupt, which means we've
499 * got to check the 1480 interrupt registers to figure out what
500 * to do. Need to detect which CPU we're on, now that
501 * smp_affinity is supported.
502 */
503 base = A_BCM1480_IMR_MAPPER(smp_processor_id());
504 mask_h = __raw_readq(
505 IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H));
506 mask_l = __raw_readq(
507 IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L));
508
509 if (mask_h) {
510 if (mask_h ^ 1)
511 do_IRQ(fls64(mask_h) - 1);
512 else
513 do_IRQ(63 + fls64(mask_l));
514 }
515 }
516} 523}
diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c
index 02b266a31c46..436ba78359ab 100644
--- a/arch/mips/sibyte/bcm1480/smp.c
+++ b/arch/mips/sibyte/bcm1480/smp.c
@@ -58,7 +58,7 @@ static void *mailbox_0_regs[] = {
58/* 58/*
59 * SMP init and finish on secondary CPUs 59 * SMP init and finish on secondary CPUs
60 */ 60 */
61void bcm1480_smp_init(void) 61void __cpuinit bcm1480_smp_init(void)
62{ 62{
63 unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 | 63 unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
64 STATUSF_IP1 | STATUSF_IP0; 64 STATUSF_IP1 | STATUSF_IP0;
@@ -67,7 +67,7 @@ void bcm1480_smp_init(void)
67 change_c0_status(ST0_IM, imask); 67 change_c0_status(ST0_IM, imask);
68} 68}
69 69
70void bcm1480_smp_finish(void) 70void __cpuinit bcm1480_smp_finish(void)
71{ 71{
72 extern void sb1480_clockevent_init(void); 72 extern void sb1480_clockevent_init(void);
73 73
diff --git a/arch/mips/sibyte/bcm1480/time.c b/arch/mips/sibyte/bcm1480/time.c
index c730744aa474..610f0253954d 100644
--- a/arch/mips/sibyte/bcm1480/time.c
+++ b/arch/mips/sibyte/bcm1480/time.c
@@ -15,22 +15,12 @@
15 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */ 17 */
18
19/*
20 * These are routines to set up and handle interrupts from the
21 * bcm1480 general purpose timer 0. We're using the timer as a
22 * system clock, so we set it up to run at 100 Hz. On every
23 * interrupt, we update our idea of what the time of day is,
24 * then call do_timer() in the architecture-independent kernel
25 * code to do general bookkeeping (e.g. update jiffies, run
26 * bottom halves, etc.)
27 */
28#include <linux/clockchips.h> 18#include <linux/clockchips.h>
29#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/irq.h>
30#include <linux/percpu.h> 21#include <linux/percpu.h>
31#include <linux/spinlock.h> 22#include <linux/spinlock.h>
32 23
33#include <asm/irq.h>
34#include <asm/addrspace.h> 24#include <asm/addrspace.h>
35#include <asm/time.h> 25#include <asm/time.h>
36#include <asm/io.h> 26#include <asm/io.h>
@@ -47,33 +37,10 @@
47#define IMR_IP3_VAL K_BCM1480_INT_MAP_I1 37#define IMR_IP3_VAL K_BCM1480_INT_MAP_I1
48#define IMR_IP4_VAL K_BCM1480_INT_MAP_I2 38#define IMR_IP4_VAL K_BCM1480_INT_MAP_I2
49 39
50#ifdef CONFIG_SIMULATION
51#define BCM1480_HPT_VALUE 50000
52#else
53#define BCM1480_HPT_VALUE 1000000
54#endif
55
56extern int bcm1480_steal_irq(int irq); 40extern int bcm1480_steal_irq(int irq);
57 41
58void __init plat_time_init(void)
59{
60 unsigned int cpu = smp_processor_id();
61 unsigned int irq = K_BCM1480_INT_TIMER_0 + cpu;
62
63 BUG_ON(cpu > 3); /* Only have 4 general purpose timers */
64
65 bcm1480_mask_irq(cpu, irq);
66
67 /* Map the timer interrupt to ip[4] of this cpu */
68 __raw_writeq(IMR_IP4_VAL, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H)
69 + (irq<<3)));
70
71 bcm1480_unmask_irq(cpu, irq);
72 bcm1480_steal_irq(irq);
73}
74
75/* 42/*
76 * The general purpose timer ticks at 1 Mhz independent if 43 * The general purpose timer ticks at 1MHz independent if
77 * the rest of the system 44 * the rest of the system
78 */ 45 */
79static void sibyte_set_mode(enum clock_event_mode mode, 46static void sibyte_set_mode(enum clock_event_mode mode,
@@ -88,7 +55,7 @@ static void sibyte_set_mode(enum clock_event_mode mode,
88 switch (mode) { 55 switch (mode) {
89 case CLOCK_EVT_MODE_PERIODIC: 56 case CLOCK_EVT_MODE_PERIODIC:
90 __raw_writeq(0, timer_cfg); 57 __raw_writeq(0, timer_cfg);
91 __raw_writeq(BCM1480_HPT_VALUE / HZ - 1, timer_init); 58 __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, timer_init);
92 __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, 59 __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
93 timer_cfg); 60 timer_cfg);
94 break; 61 break;
@@ -121,80 +88,96 @@ static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd)
121 return res; 88 return res;
122} 89}
123 90
124static DEFINE_PER_CPU(struct clock_event_device, sibyte_hpt_clockevent);
125
126static irqreturn_t sibyte_counter_handler(int irq, void *dev_id) 91static irqreturn_t sibyte_counter_handler(int irq, void *dev_id)
127{ 92{
128 unsigned int cpu = smp_processor_id(); 93 unsigned int cpu = smp_processor_id();
129 struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu); 94 struct clock_event_device *cd = dev_id;
95 void __iomem *timer_cfg;
96
97 timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
130 98
131 /* Reset the timer */ 99 /* Reset the timer */
132 __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, 100 __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
133 IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); 101 timer_cfg);
134 cd->event_handler(cd); 102 cd->event_handler(cd);
135 103
136 return IRQ_HANDLED; 104 return IRQ_HANDLED;
137} 105}
138 106
139static struct irqaction sibyte_counter_irqaction = { 107static DEFINE_PER_CPU(struct clock_event_device, sibyte_hpt_clockevent);
140 .handler = sibyte_counter_handler, 108static DEFINE_PER_CPU(struct irqaction, sibyte_hpt_irqaction);
141 .flags = IRQF_DISABLED | IRQF_PERCPU, 109static DEFINE_PER_CPU(char [18], sibyte_hpt_name);
142 .name = "timer",
143};
144 110
145/*
146 * This interrupt is "special" in that it doesn't use the request_irq
147 * way to hook the irq line. The timer interrupt is initialized early
148 * enough to make this a major pain, and it's also firing enough to
149 * warrant a bit of special case code. bcm1480_timer_interrupt is
150 * called directly from irq_handler.S when IP[4] is set during an
151 * interrupt
152 */
153void __cpuinit sb1480_clockevent_init(void) 111void __cpuinit sb1480_clockevent_init(void)
154{ 112{
155 unsigned int cpu = smp_processor_id(); 113 unsigned int cpu = smp_processor_id();
156 unsigned int irq = K_BCM1480_INT_TIMER_0 + cpu; 114 unsigned int irq = K_BCM1480_INT_TIMER_0 + cpu;
115 struct irqaction *action = &per_cpu(sibyte_hpt_irqaction, cpu);
157 struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu); 116 struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu);
117 unsigned char *name = per_cpu(sibyte_hpt_name, cpu);
118
119 BUG_ON(cpu > 3); /* Only have 4 general purpose timers */
158 120
159 cd->name = "bcm1480-counter"; 121 sprintf(name, "bcm1480-counter %d", cpu);
122 cd->name = name;
160 cd->features = CLOCK_EVT_FEAT_PERIODIC | 123 cd->features = CLOCK_EVT_FEAT_PERIODIC |
161 CLOCK_EVT_MODE_ONESHOT; 124 CLOCK_EVT_MODE_ONESHOT;
125 clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
126 cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd);
127 cd->min_delta_ns = clockevent_delta2ns(1, cd);
128 cd->rating = 200;
129 cd->irq = irq;
130 cd->cpumask = cpumask_of_cpu(cpu);
162 cd->set_next_event = sibyte_next_event; 131 cd->set_next_event = sibyte_next_event;
163 cd->set_mode = sibyte_set_mode; 132 cd->set_mode = sibyte_set_mode;
164 cd->irq = irq; 133 clockevents_register_device(cd);
165 clockevent_set_clock(cd, BCM1480_HPT_VALUE); 134
135 bcm1480_mask_irq(cpu, irq);
136
137 /*
138 * Map timer interrupt to IP[4] of this cpu
139 */
140 __raw_writeq(IMR_IP4_VAL,
141 IOADDR(A_BCM1480_IMR_REGISTER(cpu,
142 R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) + (irq << 3)));
166 143
167 setup_irq(irq, &sibyte_counter_irqaction); 144 bcm1480_unmask_irq(cpu, irq);
145 bcm1480_steal_irq(irq);
146
147 action->handler = sibyte_counter_handler;
148 action->flags = IRQF_DISABLED | IRQF_PERCPU;
149 action->name = name;
150 action->dev_id = cd;
151 setup_irq(irq, action);
168} 152}
169 153
170static cycle_t bcm1480_hpt_read(void) 154static cycle_t bcm1480_hpt_read(void)
171{ 155{
172 /* We assume this function is called xtime_lock held. */ 156 return (cycle_t) __raw_readq(IOADDR(A_SCD_ZBBUS_CYCLE_COUNT));
173 unsigned long count =
174 __raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)));
175 return (jiffies + 1) * (BCM1480_HPT_VALUE / HZ) - count;
176} 157}
177 158
178struct clocksource bcm1480_clocksource = { 159struct clocksource bcm1480_clocksource = {
179 .name = "MIPS", 160 .name = "zbbus-cycles",
180 .rating = 200, 161 .rating = 200,
181 .read = bcm1480_hpt_read, 162 .read = bcm1480_hpt_read,
182 .mask = CLOCKSOURCE_MASK(32), 163 .mask = CLOCKSOURCE_MASK(64),
183 .shift = 32,
184 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 164 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
185}; 165};
186 166
187void __init sb1480_clocksource_init(void) 167void __init sb1480_clocksource_init(void)
188{ 168{
189 struct clocksource *cs = &bcm1480_clocksource; 169 struct clocksource *cs = &bcm1480_clocksource;
170 unsigned int plldiv;
171 unsigned long zbbus;
190 172
191 clocksource_set_clock(cs, BCM1480_HPT_VALUE); 173 plldiv = G_BCM1480_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
174 zbbus = ((plldiv >> 1) * 50000000) + ((plldiv & 1) * 25000000);
175 clocksource_set_clock(cs, zbbus);
192 clocksource_register(cs); 176 clocksource_register(cs);
193} 177}
194 178
195void __init bcm1480_hpt_setup(void) 179void __init plat_time_init(void)
196{ 180{
197 mips_hpt_frequency = BCM1480_HPT_VALUE;
198 sb1480_clocksource_init(); 181 sb1480_clocksource_init();
199 sb1480_clockevent_init(); 182 sb1480_clockevent_init();
200} 183}
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c
index 500d17e84c09..53780a179d1d 100644
--- a/arch/mips/sibyte/sb1250/irq.c
+++ b/arch/mips/sibyte/sb1250/irq.c
@@ -402,6 +402,22 @@ static void sb1250_kgdb_interrupt(void)
402 402
403extern void sb1250_mailbox_interrupt(void); 403extern void sb1250_mailbox_interrupt(void);
404 404
405static inline void dispatch_ip2(void)
406{
407 unsigned int cpu = smp_processor_id();
408 unsigned long long mask;
409
410 /*
411 * Default...we've hit an IP[2] interrupt, which means we've got to
412 * check the 1250 interrupt registers to figure out what to do. Need
413 * to detect which CPU we're on, now that smp_affinity is supported.
414 */
415 mask = __raw_readq(IOADDR(A_IMR_REGISTER(cpu,
416 R_IMR_INTERRUPT_STATUS_BASE)));
417 if (mask)
418 do_IRQ(fls64(mask) - 1);
419}
420
405asmlinkage void plat_irq_dispatch(void) 421asmlinkage void plat_irq_dispatch(void)
406{ 422{
407 unsigned int cpu = smp_processor_id(); 423 unsigned int cpu = smp_processor_id();
@@ -434,21 +450,8 @@ asmlinkage void plat_irq_dispatch(void)
434 sb1250_kgdb_interrupt(); 450 sb1250_kgdb_interrupt();
435#endif 451#endif
436 452
437 else if (pending & CAUSEF_IP2) { 453 else if (pending & CAUSEF_IP2)
438 unsigned long long mask; 454 dispatch_ip2();
439 455 else
440 /*
441 * Default...we've hit an IP[2] interrupt, which means we've
442 * got to check the 1250 interrupt registers to figure out what
443 * to do. Need to detect which CPU we're on, now that
444 * smp_affinity is supported.
445 */
446 mask = __raw_readq(IOADDR(A_IMR_REGISTER(smp_processor_id(),
447 R_IMR_INTERRUPT_STATUS_BASE)));
448 if (mask)
449 do_IRQ(fls64(mask) - 1);
450 else
451 spurious_interrupt();
452 } else
453 spurious_interrupt(); 456 spurious_interrupt();
454} 457}
diff --git a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c
index aaa4f30dda79..3f52c95a4eb8 100644
--- a/arch/mips/sibyte/sb1250/smp.c
+++ b/arch/mips/sibyte/sb1250/smp.c
@@ -46,7 +46,7 @@ static void *mailbox_regs[] = {
46/* 46/*
47 * SMP init and finish on secondary CPUs 47 * SMP init and finish on secondary CPUs
48 */ 48 */
49void sb1250_smp_init(void) 49void __cpuinit sb1250_smp_init(void)
50{ 50{
51 unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 | 51 unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
52 STATUSF_IP1 | STATUSF_IP0; 52 STATUSF_IP1 | STATUSF_IP0;
@@ -55,7 +55,7 @@ void sb1250_smp_init(void)
55 change_c0_status(ST0_IM, imask); 55 change_c0_status(ST0_IM, imask);
56} 56}
57 57
58void sb1250_smp_finish(void) 58void __cpuinit sb1250_smp_finish(void)
59{ 59{
60 extern void sb1250_clockevent_init(void); 60 extern void sb1250_clockevent_init(void);
61 61
diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c
index 9ef54628bc9c..a41e908bc218 100644
--- a/arch/mips/sibyte/sb1250/time.c
+++ b/arch/mips/sibyte/sb1250/time.c
@@ -52,26 +52,6 @@
52 52
53extern int sb1250_steal_irq(int irq); 53extern int sb1250_steal_irq(int irq);
54 54
55static cycle_t sb1250_hpt_read(void);
56
57void __init sb1250_hpt_setup(void)
58{
59 int cpu = smp_processor_id();
60
61 if (!cpu) {
62 /* Setup hpt using timer #3 but do not enable irq for it */
63 __raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CFG)));
64 __raw_writeq(SB1250_HPT_VALUE,
65 IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_INIT)));
66 __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
67 IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CFG)));
68
69 mips_hpt_frequency = V_SCD_TIMER_FREQ;
70 clocksource_mips.read = sb1250_hpt_read;
71 clocksource_mips.mask = M_SCD_TIMER_INIT;
72 }
73}
74
75/* 55/*
76 * The general purpose timer ticks at 1 Mhz independent if 56 * The general purpose timer ticks at 1 Mhz independent if
77 * the rest of the system 57 * the rest of the system
@@ -121,18 +101,14 @@ sibyte_next_event(unsigned long delta, struct clock_event_device *evt)
121 return 0; 101 return 0;
122} 102}
123 103
124struct clock_event_device sibyte_hpt_clockevent = {
125 .name = "sb1250-counter",
126 .features = CLOCK_EVT_FEAT_PERIODIC,
127 .set_mode = sibyte_set_mode,
128 .set_next_event = sibyte_next_event,
129 .shift = 32,
130 .irq = 0,
131};
132
133static irqreturn_t sibyte_counter_handler(int irq, void *dev_id) 104static irqreturn_t sibyte_counter_handler(int irq, void *dev_id)
134{ 105{
135 struct clock_event_device *cd = &sibyte_hpt_clockevent; 106 unsigned int cpu = smp_processor_id();
107 struct clock_event_device *cd = dev_id;
108
109 /* ACK interrupt */
110 ____raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
111 IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
136 112
137 cd->event_handler(cd); 113 cd->event_handler(cd);
138 114
@@ -145,15 +121,35 @@ static struct irqaction sibyte_irqaction = {
145 .name = "timer", 121 .name = "timer",
146}; 122};
147 123
124static DEFINE_PER_CPU(struct clock_event_device, sibyte_hpt_clockevent);
125static DEFINE_PER_CPU(struct irqaction, sibyte_hpt_irqaction);
126static DEFINE_PER_CPU(char [18], sibyte_hpt_name);
127
148void __cpuinit sb1250_clockevent_init(void) 128void __cpuinit sb1250_clockevent_init(void)
149{ 129{
150 struct clock_event_device *cd = &sibyte_hpt_clockevent;
151 unsigned int cpu = smp_processor_id(); 130 unsigned int cpu = smp_processor_id();
152 int irq = K_INT_TIMER_0 + cpu; 131 unsigned int irq = K_INT_TIMER_0 + cpu;
132 struct irqaction *action = &per_cpu(sibyte_hpt_irqaction, cpu);
133 struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu);
134 unsigned char *name = per_cpu(sibyte_hpt_name, cpu);
153 135
154 /* Only have 4 general purpose timers, and we use last one as hpt */ 136 /* Only have 4 general purpose timers, and we use last one as hpt */
155 BUG_ON(cpu > 2); 137 BUG_ON(cpu > 2);
156 138
139 sprintf(name, "bcm1480-counter %d", cpu);
140 cd->name = name;
141 cd->features = CLOCK_EVT_FEAT_PERIODIC |
142 CLOCK_EVT_MODE_ONESHOT;
143 clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
144 cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd);
145 cd->min_delta_ns = clockevent_delta2ns(1, cd);
146 cd->rating = 200;
147 cd->irq = irq;
148 cd->cpumask = cpumask_of_cpu(cpu);
149 cd->set_next_event = sibyte_next_event;
150 cd->set_mode = sibyte_set_mode;
151 clockevents_register_device(cd);
152
157 sb1250_mask_irq(cpu, irq); 153 sb1250_mask_irq(cpu, irq);
158 154
159 /* Map the timer interrupt to ip[4] of this cpu */ 155 /* Map the timer interrupt to ip[4] of this cpu */
@@ -165,17 +161,11 @@ void __cpuinit sb1250_clockevent_init(void)
165 sb1250_unmask_irq(cpu, irq); 161 sb1250_unmask_irq(cpu, irq);
166 sb1250_steal_irq(irq); 162 sb1250_steal_irq(irq);
167 163
168 /* 164 action->handler = sibyte_counter_handler;
169 * This interrupt is "special" in that it doesn't use the request_irq 165 action->flags = IRQF_DISABLED | IRQF_PERCPU;
170 * way to hook the irq line. The timer interrupt is initialized early 166 action->name = name;
171 * enough to make this a major pain, and it's also firing enough to 167 action->dev_id = cd;
172 * warrant a bit of special case code. sb1250_timer_interrupt is
173 * called directly from irq_handler.S when IP[4] is set during an
174 * interrupt
175 */
176 setup_irq(irq, &sibyte_irqaction); 168 setup_irq(irq, &sibyte_irqaction);
177
178 clockevents_register_device(cd);
179} 169}
180 170
181/* 171/*
@@ -195,8 +185,7 @@ struct clocksource bcm1250_clocksource = {
195 .name = "MIPS", 185 .name = "MIPS",
196 .rating = 200, 186 .rating = 200,
197 .read = sb1250_hpt_read, 187 .read = sb1250_hpt_read,
198 .mask = CLOCKSOURCE_MASK(32), 188 .mask = CLOCKSOURCE_MASK(23),
199 .shift = 32,
200 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 189 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
201}; 190};
202 191
@@ -204,6 +193,17 @@ void __init sb1250_clocksource_init(void)
204{ 193{
205 struct clocksource *cs = &bcm1250_clocksource; 194 struct clocksource *cs = &bcm1250_clocksource;
206 195
196 /* Setup hpt using timer #3 but do not enable irq for it */
197 __raw_writeq(0,
198 IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
199 R_SCD_TIMER_CFG)));
200 __raw_writeq(SB1250_HPT_VALUE,
201 IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
202 R_SCD_TIMER_INIT)));
203 __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
204 IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
205 R_SCD_TIMER_CFG)));
206
207 clocksource_set_clock(cs, V_SCD_TIMER_FREQ); 207 clocksource_set_clock(cs, V_SCD_TIMER_FREQ);
208 clocksource_register(cs); 208 clocksource_register(cs);
209} 209}
diff --git a/arch/powerpc/boot/dts/lite5200.dts b/arch/powerpc/boot/dts/lite5200.dts
index bc45f5fbb060..6731763f0282 100644
--- a/arch/powerpc/boot/dts/lite5200.dts
+++ b/arch/powerpc/boot/dts/lite5200.dts
@@ -70,18 +70,16 @@
70 }; 70 };
71 71
72 gpt@600 { // General Purpose Timer 72 gpt@600 { // General Purpose Timer
73 compatible = "mpc5200-gpt"; 73 compatible = "fsl,mpc5200-gpt";
74 device_type = "gpt";
75 cell-index = <0>; 74 cell-index = <0>;
76 reg = <600 10>; 75 reg = <600 10>;
77 interrupts = <1 9 0>; 76 interrupts = <1 9 0>;
78 interrupt-parent = <&mpc5200_pic>; 77 interrupt-parent = <&mpc5200_pic>;
79 has-wdt; 78 fsl,has-wdt;
80 }; 79 };
81 80
82 gpt@610 { // General Purpose Timer 81 gpt@610 { // General Purpose Timer
83 compatible = "mpc5200-gpt"; 82 compatible = "fsl,mpc5200-gpt";
84 device_type = "gpt";
85 cell-index = <1>; 83 cell-index = <1>;
86 reg = <610 10>; 84 reg = <610 10>;
87 interrupts = <1 a 0>; 85 interrupts = <1 a 0>;
@@ -89,8 +87,7 @@
89 }; 87 };
90 88
91 gpt@620 { // General Purpose Timer 89 gpt@620 { // General Purpose Timer
92 compatible = "mpc5200-gpt"; 90 compatible = "fsl,mpc5200-gpt";
93 device_type = "gpt";
94 cell-index = <2>; 91 cell-index = <2>;
95 reg = <620 10>; 92 reg = <620 10>;
96 interrupts = <1 b 0>; 93 interrupts = <1 b 0>;
@@ -98,8 +95,7 @@
98 }; 95 };
99 96
100 gpt@630 { // General Purpose Timer 97 gpt@630 { // General Purpose Timer
101 compatible = "mpc5200-gpt"; 98 compatible = "fsl,mpc5200-gpt";
102 device_type = "gpt";
103 cell-index = <3>; 99 cell-index = <3>;
104 reg = <630 10>; 100 reg = <630 10>;
105 interrupts = <1 c 0>; 101 interrupts = <1 c 0>;
@@ -107,8 +103,7 @@
107 }; 103 };
108 104
109 gpt@640 { // General Purpose Timer 105 gpt@640 { // General Purpose Timer
110 compatible = "mpc5200-gpt"; 106 compatible = "fsl,mpc5200-gpt";
111 device_type = "gpt";
112 cell-index = <4>; 107 cell-index = <4>;
113 reg = <640 10>; 108 reg = <640 10>;
114 interrupts = <1 d 0>; 109 interrupts = <1 d 0>;
@@ -116,8 +111,7 @@
116 }; 111 };
117 112
118 gpt@650 { // General Purpose Timer 113 gpt@650 { // General Purpose Timer
119 compatible = "mpc5200-gpt"; 114 compatible = "fsl,mpc5200-gpt";
120 device_type = "gpt";
121 cell-index = <5>; 115 cell-index = <5>;
122 reg = <650 10>; 116 reg = <650 10>;
123 interrupts = <1 e 0>; 117 interrupts = <1 e 0>;
@@ -125,8 +119,7 @@
125 }; 119 };
126 120
127 gpt@660 { // General Purpose Timer 121 gpt@660 { // General Purpose Timer
128 compatible = "mpc5200-gpt"; 122 compatible = "fsl,mpc5200-gpt";
129 device_type = "gpt";
130 cell-index = <6>; 123 cell-index = <6>;
131 reg = <660 10>; 124 reg = <660 10>;
132 interrupts = <1 f 0>; 125 interrupts = <1 f 0>;
@@ -134,8 +127,7 @@
134 }; 127 };
135 128
136 gpt@670 { // General Purpose Timer 129 gpt@670 { // General Purpose Timer
137 compatible = "mpc5200-gpt"; 130 compatible = "fsl,mpc5200-gpt";
138 device_type = "gpt";
139 cell-index = <7>; 131 cell-index = <7>;
140 reg = <670 10>; 132 reg = <670 10>;
141 interrupts = <1 10 0>; 133 interrupts = <1 10 0>;
diff --git a/arch/powerpc/boot/dts/lite5200b.dts b/arch/powerpc/boot/dts/lite5200b.dts
index 6582c9a39b27..b540388c608c 100644
--- a/arch/powerpc/boot/dts/lite5200b.dts
+++ b/arch/powerpc/boot/dts/lite5200b.dts
@@ -70,18 +70,16 @@
70 }; 70 };
71 71
72 gpt@600 { // General Purpose Timer 72 gpt@600 { // General Purpose Timer
73 compatible = "mpc5200b-gpt","mpc5200-gpt"; 73 compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
74 device_type = "gpt";
75 cell-index = <0>; 74 cell-index = <0>;
76 reg = <600 10>; 75 reg = <600 10>;
77 interrupts = <1 9 0>; 76 interrupts = <1 9 0>;
78 interrupt-parent = <&mpc5200_pic>; 77 interrupt-parent = <&mpc5200_pic>;
79 has-wdt; 78 fsl,has-wdt;
80 }; 79 };
81 80
82 gpt@610 { // General Purpose Timer 81 gpt@610 { // General Purpose Timer
83 compatible = "mpc5200b-gpt","mpc5200-gpt"; 82 compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
84 device_type = "gpt";
85 cell-index = <1>; 83 cell-index = <1>;
86 reg = <610 10>; 84 reg = <610 10>;
87 interrupts = <1 a 0>; 85 interrupts = <1 a 0>;
@@ -89,8 +87,7 @@
89 }; 87 };
90 88
91 gpt@620 { // General Purpose Timer 89 gpt@620 { // General Purpose Timer
92 compatible = "mpc5200b-gpt","mpc5200-gpt"; 90 compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
93 device_type = "gpt";
94 cell-index = <2>; 91 cell-index = <2>;
95 reg = <620 10>; 92 reg = <620 10>;
96 interrupts = <1 b 0>; 93 interrupts = <1 b 0>;
@@ -98,8 +95,7 @@
98 }; 95 };
99 96
100 gpt@630 { // General Purpose Timer 97 gpt@630 { // General Purpose Timer
101 compatible = "mpc5200b-gpt","mpc5200-gpt"; 98 compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
102 device_type = "gpt";
103 cell-index = <3>; 99 cell-index = <3>;
104 reg = <630 10>; 100 reg = <630 10>;
105 interrupts = <1 c 0>; 101 interrupts = <1 c 0>;
@@ -107,8 +103,7 @@
107 }; 103 };
108 104
109 gpt@640 { // General Purpose Timer 105 gpt@640 { // General Purpose Timer
110 compatible = "mpc5200b-gpt","mpc5200-gpt"; 106 compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
111 device_type = "gpt";
112 cell-index = <4>; 107 cell-index = <4>;
113 reg = <640 10>; 108 reg = <640 10>;
114 interrupts = <1 d 0>; 109 interrupts = <1 d 0>;
@@ -116,8 +111,7 @@
116 }; 111 };
117 112
118 gpt@650 { // General Purpose Timer 113 gpt@650 { // General Purpose Timer
119 compatible = "mpc5200b-gpt","mpc5200-gpt"; 114 compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
120 device_type = "gpt";
121 cell-index = <5>; 115 cell-index = <5>;
122 reg = <650 10>; 116 reg = <650 10>;
123 interrupts = <1 e 0>; 117 interrupts = <1 e 0>;
@@ -125,8 +119,7 @@
125 }; 119 };
126 120
127 gpt@660 { // General Purpose Timer 121 gpt@660 { // General Purpose Timer
128 compatible = "mpc5200b-gpt","mpc5200-gpt"; 122 compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
129 device_type = "gpt";
130 cell-index = <6>; 123 cell-index = <6>;
131 reg = <660 10>; 124 reg = <660 10>;
132 interrupts = <1 f 0>; 125 interrupts = <1 f 0>;
@@ -134,8 +127,7 @@
134 }; 127 };
135 128
136 gpt@670 { // General Purpose Timer 129 gpt@670 { // General Purpose Timer
137 compatible = "mpc5200b-gpt","mpc5200-gpt"; 130 compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
138 device_type = "gpt";
139 cell-index = <7>; 131 cell-index = <7>;
140 reg = <670 10>; 132 reg = <670 10>;
141 interrupts = <1 10 0>; 133 interrupts = <1 10 0>;
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
index 9001104b56b0..14206e3f0819 100644
--- a/arch/powerpc/kernel/dma_64.c
+++ b/arch/powerpc/kernel/dma_64.c
@@ -161,8 +161,7 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
161 int i; 161 int i;
162 162
163 for_each_sg(sgl, sg, nents, i) { 163 for_each_sg(sgl, sg, nents, i) {
164 sg->dma_address = (page_to_phys(sg->page) + sg->offset) | 164 sg->dma_address = sg_phys(sg) | dma_direct_offset;
165 dma_direct_offset;
166 sg->dma_length = sg->length; 165 sg->dma_length = sg->length;
167 } 166 }
168 167
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index 289d7e935918..72fd87156b24 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -102,8 +102,7 @@ static int ibmebus_map_sg(struct device *dev,
102 int i; 102 int i;
103 103
104 for_each_sg(sgl, sg, nents, i) { 104 for_each_sg(sgl, sg, nents, i) {
105 sg->dma_address = (dma_addr_t)page_address(sg->page) 105 sg->dma_address = (dma_addr_t) sg_virt(sg);
106 + sg->offset;
107 sg->dma_length = sg->length; 106 sg->dma_length = sg->length;
108 } 107 }
109 108
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 306a6f75b6c5..2d0c9ef555e9 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -307,7 +307,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
307 continue; 307 continue;
308 } 308 }
309 /* Allocate iommu entries for that segment */ 309 /* Allocate iommu entries for that segment */
310 vaddr = (unsigned long)page_address(s->page) + s->offset; 310 vaddr = (unsigned long) sg_virt(s);
311 npages = iommu_num_pages(vaddr, slen); 311 npages = iommu_num_pages(vaddr, slen);
312 entry = iommu_range_alloc(tbl, npages, &handle, mask >> IOMMU_PAGE_SHIFT, 0); 312 entry = iommu_range_alloc(tbl, npages, &handle, mask >> IOMMU_PAGE_SHIFT, 0);
313 313
diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c
index 65b7ae426238..25d2bfa3d9dc 100644
--- a/arch/powerpc/platforms/52xx/lite5200.c
+++ b/arch/powerpc/platforms/52xx/lite5200.c
@@ -145,6 +145,9 @@ static void __init lite5200_setup_arch(void)
145 /* Some mpc5200 & mpc5200b related configuration */ 145 /* Some mpc5200 & mpc5200b related configuration */
146 mpc5200_setup_xlb_arbiter(); 146 mpc5200_setup_xlb_arbiter();
147 147
148 /* Map wdt for mpc52xx_restart() */
149 mpc52xx_map_wdt();
150
148#ifdef CONFIG_PM 151#ifdef CONFIG_PM
149 mpc52xx_suspend.board_suspend_prepare = lite5200_suspend_prepare; 152 mpc52xx_suspend.board_suspend_prepare = lite5200_suspend_prepare;
150 mpc52xx_suspend.board_resume_finish = lite5200_resume_finish; 153 mpc52xx_suspend.board_resume_finish = lite5200_resume_finish;
@@ -183,5 +186,6 @@ define_machine(lite5200) {
183 .init = mpc52xx_declare_of_platform_devices, 186 .init = mpc52xx_declare_of_platform_devices,
184 .init_IRQ = mpc52xx_init_irq, 187 .init_IRQ = mpc52xx_init_irq,
185 .get_irq = mpc52xx_get_irq, 188 .get_irq = mpc52xx_get_irq,
189 .restart = mpc52xx_restart,
186 .calibrate_decr = generic_calibrate_decr, 190 .calibrate_decr = generic_calibrate_decr,
187}; 191};
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
index 3bc201e07e6b..9850685c5429 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
@@ -18,15 +18,20 @@
18#include <asm/prom.h> 18#include <asm/prom.h>
19#include <asm/mpc52xx.h> 19#include <asm/mpc52xx.h>
20 20
21/*
22 * This variable is mapped in mpc52xx_map_wdt() and used in mpc52xx_restart().
23 * Permanent mapping is required because mpc52xx_restart() can be called
24 * from interrupt context while node mapping (which calls ioremap())
25 * cannot be used at such point.
26 */
27static volatile struct mpc52xx_gpt *mpc52xx_wdt = NULL;
21 28
22void __iomem * 29static void __iomem *
23mpc52xx_find_and_map(const char *compatible) 30mpc52xx_map_node(struct device_node *ofn)
24{ 31{
25 struct device_node *ofn;
26 const u32 *regaddr_p; 32 const u32 *regaddr_p;
27 u64 regaddr64, size64; 33 u64 regaddr64, size64;
28 34
29 ofn = of_find_compatible_node(NULL, NULL, compatible);
30 if (!ofn) 35 if (!ofn)
31 return NULL; 36 return NULL;
32 37
@@ -42,8 +47,23 @@ mpc52xx_find_and_map(const char *compatible)
42 47
43 return ioremap((u32)regaddr64, (u32)size64); 48 return ioremap((u32)regaddr64, (u32)size64);
44} 49}
50
51void __iomem *
52mpc52xx_find_and_map(const char *compatible)
53{
54 return mpc52xx_map_node(
55 of_find_compatible_node(NULL, NULL, compatible));
56}
57
45EXPORT_SYMBOL(mpc52xx_find_and_map); 58EXPORT_SYMBOL(mpc52xx_find_and_map);
46 59
60void __iomem *
61mpc52xx_find_and_map_path(const char *path)
62{
63 return mpc52xx_map_node(of_find_node_by_path(path));
64}
65
66EXPORT_SYMBOL(mpc52xx_find_and_map_path);
47 67
48/** 68/**
49 * mpc52xx_find_ipb_freq - Find the IPB bus frequency for a device 69 * mpc52xx_find_ipb_freq - Find the IPB bus frequency for a device
@@ -113,3 +133,46 @@ mpc52xx_declare_of_platform_devices(void)
113 "Error while probing of_platform bus\n"); 133 "Error while probing of_platform bus\n");
114} 134}
115 135
136void __init
137mpc52xx_map_wdt(void)
138{
139 const void *has_wdt;
140 struct device_node *np;
141
142 /* mpc52xx_wdt is mapped here and used in mpc52xx_restart,
143 * possibly from a interrupt context. wdt is only implement
144 * on a gpt0, so check has-wdt property before mapping.
145 */
146 for_each_compatible_node(np, NULL, "fsl,mpc5200-gpt") {
147 has_wdt = of_get_property(np, "fsl,has-wdt", NULL);
148 if (has_wdt) {
149 mpc52xx_wdt = mpc52xx_map_node(np);
150 return;
151 }
152 }
153 for_each_compatible_node(np, NULL, "mpc5200-gpt") {
154 has_wdt = of_get_property(np, "has-wdt", NULL);
155 if (has_wdt) {
156 mpc52xx_wdt = mpc52xx_map_node(np);
157 return;
158 }
159 }
160}
161
162void
163mpc52xx_restart(char *cmd)
164{
165 local_irq_disable();
166
167 /* Turn on the watchdog and wait for it to expire.
168 * It effectively does a reset. */
169 if (mpc52xx_wdt) {
170 out_be32(&mpc52xx_wdt->mode, 0x00000000);
171 out_be32(&mpc52xx_wdt->count, 0x000000ff);
172 out_be32(&mpc52xx_wdt->mode, 0x00009004);
173 } else
174 printk("mpc52xx_restart: Can't access wdt. "
175 "Restart impossible, system halted.\n");
176
177 while (1);
178}
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 07e64b48e7fc..6405f4a36763 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -628,9 +628,8 @@ static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl,
628 int i; 628 int i;
629 629
630 for_each_sg(sgl, sg, nents, i) { 630 for_each_sg(sgl, sg, nents, i) {
631 int result = ps3_dma_map(dev->d_region, 631 int result = ps3_dma_map(dev->d_region, sg_phys(sg),
632 page_to_phys(sg->page) + sg->offset, sg->length, 632 sg->length, &sg->dma_address, 0);
633 &sg->dma_address, 0);
634 633
635 if (result) { 634 if (result) {
636 pr_debug("%s:%d: ps3_dma_map failed (%d)\n", 635 pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.c b/arch/powerpc/sysdev/bestcomm/bestcomm.c
index 48492a83e5a7..740ad73ce5cc 100644
--- a/arch/powerpc/sysdev/bestcomm/bestcomm.c
+++ b/arch/powerpc/sysdev/bestcomm/bestcomm.c
@@ -269,6 +269,7 @@ bcom_engine_init(void)
269 int task; 269 int task;
270 phys_addr_t tdt_pa, ctx_pa, var_pa, fdt_pa; 270 phys_addr_t tdt_pa, ctx_pa, var_pa, fdt_pa;
271 unsigned int tdt_size, ctx_size, var_size, fdt_size; 271 unsigned int tdt_size, ctx_size, var_size, fdt_size;
272 u16 regval;
272 273
273 /* Allocate & clear SRAM zones for FDT, TDTs, contexts and vars/incs */ 274 /* Allocate & clear SRAM zones for FDT, TDTs, contexts and vars/incs */
274 tdt_size = BCOM_MAX_TASKS * sizeof(struct bcom_tdt); 275 tdt_size = BCOM_MAX_TASKS * sizeof(struct bcom_tdt);
@@ -319,9 +320,11 @@ bcom_engine_init(void)
319 /* Init 'always' initiator */ 320 /* Init 'always' initiator */
320 out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ALWAYS], BCOM_IPR_ALWAYS); 321 out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ALWAYS], BCOM_IPR_ALWAYS);
321 322
322 /* Disable COMM Bus Prefetch, apparently it's not reliable yet */ 323 /* Disable COMM Bus Prefetch on the original 5200; it's broken */
323 /* FIXME: This should be done on 5200 and not 5200B ... */ 324 if ((mfspr(SPRN_SVR) & MPC5200_SVR_MASK) == MPC5200_SVR) {
324 out_be16(&bcom_eng->regs->PtdCntrl, in_be16(&bcom_eng->regs->PtdCntrl) | 1); 325 regval = in_be16(&bcom_eng->regs->PtdCntrl);
326 out_be16(&bcom_eng->regs->PtdCntrl, regval | 1);
327 }
325 328
326 /* Init lock */ 329 /* Init lock */
327 spin_lock_init(&bcom_eng->lock); 330 spin_lock_init(&bcom_eng->lock);
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 9c3ed88853f3..97aa50d1e4ae 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -727,9 +727,8 @@ int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents,
727 BUG_ON(direction == PCI_DMA_NONE); 727 BUG_ON(direction == PCI_DMA_NONE);
728 /* IIep is write-through, not flushing. */ 728 /* IIep is write-through, not flushing. */
729 for_each_sg(sgl, sg, nents, n) { 729 for_each_sg(sgl, sg, nents, n) {
730 BUG_ON(page_address(sg->page) == NULL); 730 BUG_ON(page_address(sg_page(sg)) == NULL);
731 sg->dvma_address = 731 sg->dvma_address = virt_to_phys(sg_virt(sg));
732 virt_to_phys(page_address(sg->page)) + sg->offset;
733 sg->dvma_length = sg->length; 732 sg->dvma_length = sg->length;
734 } 733 }
735 return nents; 734 return nents;
@@ -748,9 +747,9 @@ void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents,
748 BUG_ON(direction == PCI_DMA_NONE); 747 BUG_ON(direction == PCI_DMA_NONE);
749 if (direction != PCI_DMA_TODEVICE) { 748 if (direction != PCI_DMA_TODEVICE) {
750 for_each_sg(sgl, sg, nents, n) { 749 for_each_sg(sgl, sg, nents, n) {
751 BUG_ON(page_address(sg->page) == NULL); 750 BUG_ON(page_address(sg_page(sg)) == NULL);
752 mmu_inval_dma_area( 751 mmu_inval_dma_area(
753 (unsigned long) page_address(sg->page), 752 (unsigned long) page_address(sg_page(sg)),
754 (sg->length + PAGE_SIZE-1) & PAGE_MASK); 753 (sg->length + PAGE_SIZE-1) & PAGE_MASK);
755 } 754 }
756 } 755 }
@@ -798,9 +797,9 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sgl, int
798 BUG_ON(direction == PCI_DMA_NONE); 797 BUG_ON(direction == PCI_DMA_NONE);
799 if (direction != PCI_DMA_TODEVICE) { 798 if (direction != PCI_DMA_TODEVICE) {
800 for_each_sg(sgl, sg, nents, n) { 799 for_each_sg(sgl, sg, nents, n) {
801 BUG_ON(page_address(sg->page) == NULL); 800 BUG_ON(page_address(sg_page(sg)) == NULL);
802 mmu_inval_dma_area( 801 mmu_inval_dma_area(
803 (unsigned long) page_address(sg->page), 802 (unsigned long) page_address(sg_page(sg)),
804 (sg->length + PAGE_SIZE-1) & PAGE_MASK); 803 (sg->length + PAGE_SIZE-1) & PAGE_MASK);
805 } 804 }
806 } 805 }
@@ -814,9 +813,9 @@ void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sgl,
814 BUG_ON(direction == PCI_DMA_NONE); 813 BUG_ON(direction == PCI_DMA_NONE);
815 if (direction != PCI_DMA_TODEVICE) { 814 if (direction != PCI_DMA_TODEVICE) {
816 for_each_sg(sgl, sg, nents, n) { 815 for_each_sg(sgl, sg, nents, n) {
817 BUG_ON(page_address(sg->page) == NULL); 816 BUG_ON(page_address(sg_page(sg)) == NULL);
818 mmu_inval_dma_area( 817 mmu_inval_dma_area(
819 (unsigned long) page_address(sg->page), 818 (unsigned long) page_address(sg_page(sg)),
820 (sg->length + PAGE_SIZE-1) & PAGE_MASK); 819 (sg->length + PAGE_SIZE-1) & PAGE_MASK);
821 } 820 }
822 } 821 }
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c
index 375b4db63704..1666087c5b80 100644
--- a/arch/sparc/mm/io-unit.c
+++ b/arch/sparc/mm/io-unit.c
@@ -144,7 +144,7 @@ static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus
144 spin_lock_irqsave(&iounit->lock, flags); 144 spin_lock_irqsave(&iounit->lock, flags);
145 while (sz != 0) { 145 while (sz != 0) {
146 --sz; 146 --sz;
147 sg->dvma_address = iounit_get_area(iounit, (unsigned long)page_address(sg->page) + sg->offset, sg->length); 147 sg->dvma_address = iounit_get_area(iounit, sg_virt(sg), sg->length);
148 sg->dvma_length = sg->length; 148 sg->dvma_length = sg->length;
149 sg = sg_next(sg); 149 sg = sg_next(sg);
150 } 150 }
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
index 283656d9f6ea..4b934270f05e 100644
--- a/arch/sparc/mm/iommu.c
+++ b/arch/sparc/mm/iommu.c
@@ -238,7 +238,7 @@ static void iommu_get_scsi_sgl_noflush(struct scatterlist *sg, int sz, struct sb
238 while (sz != 0) { 238 while (sz != 0) {
239 --sz; 239 --sz;
240 n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; 240 n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
241 sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset; 241 sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset;
242 sg->dvma_length = (__u32) sg->length; 242 sg->dvma_length = (__u32) sg->length;
243 sg = sg_next(sg); 243 sg = sg_next(sg);
244 } 244 }
@@ -252,7 +252,7 @@ static void iommu_get_scsi_sgl_gflush(struct scatterlist *sg, int sz, struct sbu
252 while (sz != 0) { 252 while (sz != 0) {
253 --sz; 253 --sz;
254 n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; 254 n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
255 sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset; 255 sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset;
256 sg->dvma_length = (__u32) sg->length; 256 sg->dvma_length = (__u32) sg->length;
257 sg = sg_next(sg); 257 sg = sg_next(sg);
258 } 258 }
@@ -273,7 +273,7 @@ static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbu
273 * XXX Is this a good assumption? 273 * XXX Is this a good assumption?
274 * XXX What if someone else unmaps it here and races us? 274 * XXX What if someone else unmaps it here and races us?
275 */ 275 */
276 if ((page = (unsigned long) page_address(sg->page)) != 0) { 276 if ((page = (unsigned long) page_address(sg_page(sg))) != 0) {
277 for (i = 0; i < n; i++) { 277 for (i = 0; i < n; i++) {
278 if (page != oldpage) { /* Already flushed? */ 278 if (page != oldpage) { /* Already flushed? */
279 flush_page_for_dma(page); 279 flush_page_for_dma(page);
@@ -283,7 +283,7 @@ static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbu
283 } 283 }
284 } 284 }
285 285
286 sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset; 286 sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset;
287 sg->dvma_length = (__u32) sg->length; 287 sg->dvma_length = (__u32) sg->length;
288 sg = sg_next(sg); 288 sg = sg_next(sg);
289 } 289 }
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index ee6708fc4492..a2cc141291c7 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -1228,7 +1228,7 @@ static void sun4c_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *
1228{ 1228{
1229 while (sz != 0) { 1229 while (sz != 0) {
1230 --sz; 1230 --sz;
1231 sg->dvma_address = (__u32)sun4c_lockarea(page_address(sg->page) + sg->offset, sg->length); 1231 sg->dvma_address = (__u32)sun4c_lockarea(sg_virt(sg), sg->length);
1232 sg->dvma_length = sg->length; 1232 sg->dvma_length = sg->length;
1233 sg = sg_next(sg); 1233 sg = sg_next(sg);
1234 } 1234 }
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index c7a74e376985..03c4e5c1b94a 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -72,6 +72,10 @@ config ARCH_NO_VIRT_TO_BUS
72config OF 72config OF
73 def_bool y 73 def_bool y
74 74
75config GENERIC_HARDIRQS_NO__DO_IRQ
76 bool
77 def_bool y
78
75choice 79choice
76 prompt "Kernel page size" 80 prompt "Kernel page size"
77 default SPARC64_PAGE_SIZE_8KB 81 default SPARC64_PAGE_SIZE_8KB
diff --git a/arch/sparc64/Makefile b/arch/sparc64/Makefile
index 6c92a42efe76..01159cb5f16d 100644
--- a/arch/sparc64/Makefile
+++ b/arch/sparc64/Makefile
@@ -18,8 +18,6 @@ NEW_GCC := $(call cc-option-yn, -m64 -mcmodel=medlow)
18NEW_GAS := $(shell if $(LD) -V 2>&1 | grep 'elf64_sparc' > /dev/null; then echo y; else echo n; fi) 18NEW_GAS := $(shell if $(LD) -V 2>&1 | grep 'elf64_sparc' > /dev/null; then echo y; else echo n; fi)
19UNDECLARED_REGS := $(shell if $(CC) -c -x assembler /dev/null -Wa,--help | grep undeclared-regs > /dev/null; then echo y; else echo n; fi; ) 19UNDECLARED_REGS := $(shell if $(CC) -c -x assembler /dev/null -Wa,--help | grep undeclared-regs > /dev/null; then echo y; else echo n; fi; )
20 20
21export NEW_GCC
22
23ifneq ($(NEW_GAS),y) 21ifneq ($(NEW_GAS),y)
24AS = sparc64-linux-as 22AS = sparc64-linux-as
25LD = sparc64-linux-ld 23LD = sparc64-linux-ld
@@ -58,8 +56,6 @@ core-y += arch/sparc64/kernel/ arch/sparc64/mm/
58core-$(CONFIG_SOLARIS_EMUL) += arch/sparc64/solaris/ 56core-$(CONFIG_SOLARIS_EMUL) += arch/sparc64/solaris/
59core-y += arch/sparc64/math-emu/ 57core-y += arch/sparc64/math-emu/
60libs-y += arch/sparc64/prom/ arch/sparc64/lib/ 58libs-y += arch/sparc64/prom/ arch/sparc64/lib/
61
62# FIXME: is drivers- right?
63drivers-$(CONFIG_OPROFILE) += arch/sparc64/oprofile/ 59drivers-$(CONFIG_OPROFILE) += arch/sparc64/oprofile/
64 60
65boot := arch/sparc64/boot 61boot := arch/sparc64/boot
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 1aa2c4048e4b..e023d4b2fef4 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.23 3# Linux kernel version: 2.6.23
4# Sat Oct 13 21:53:54 2007 4# Sun Oct 21 19:57:44 2007
5# 5#
6CONFIG_SPARC=y 6CONFIG_SPARC=y
7CONFIG_SPARC64=y 7CONFIG_SPARC64=y
@@ -49,6 +49,10 @@ CONFIG_POSIX_MQUEUE=y
49# CONFIG_AUDIT is not set 49# CONFIG_AUDIT is not set
50# CONFIG_IKCONFIG is not set 50# CONFIG_IKCONFIG is not set
51CONFIG_LOG_BUF_SHIFT=18 51CONFIG_LOG_BUF_SHIFT=18
52# CONFIG_CGROUPS is not set
53CONFIG_FAIR_GROUP_SCHED=y
54CONFIG_FAIR_USER_SCHED=y
55# CONFIG_FAIR_CGROUP_SCHED is not set
52CONFIG_SYSFS_DEPRECATED=y 56CONFIG_SYSFS_DEPRECATED=y
53CONFIG_RELAY=y 57CONFIG_RELAY=y
54# CONFIG_BLK_DEV_INITRD is not set 58# CONFIG_BLK_DEV_INITRD is not set
@@ -145,7 +149,10 @@ CONFIG_SELECT_MEMORY_MODEL=y
145CONFIG_SPARSEMEM_MANUAL=y 149CONFIG_SPARSEMEM_MANUAL=y
146CONFIG_SPARSEMEM=y 150CONFIG_SPARSEMEM=y
147CONFIG_HAVE_MEMORY_PRESENT=y 151CONFIG_HAVE_MEMORY_PRESENT=y
148CONFIG_SPARSEMEM_STATIC=y 152# CONFIG_SPARSEMEM_STATIC is not set
153CONFIG_SPARSEMEM_EXTREME=y
154CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
155CONFIG_SPARSEMEM_VMEMMAP=y
149CONFIG_SPLIT_PTLOCK_CPUS=4 156CONFIG_SPLIT_PTLOCK_CPUS=4
150CONFIG_RESOURCES_64BIT=y 157CONFIG_RESOURCES_64BIT=y
151CONFIG_ZONE_DMA_FLAG=0 158CONFIG_ZONE_DMA_FLAG=0
@@ -275,10 +282,6 @@ CONFIG_VLAN_8021Q=m
275# CONFIG_LAPB is not set 282# CONFIG_LAPB is not set
276# CONFIG_ECONET is not set 283# CONFIG_ECONET is not set
277# CONFIG_WAN_ROUTER is not set 284# CONFIG_WAN_ROUTER is not set
278
279#
280# QoS and/or fair queueing
281#
282# CONFIG_NET_SCHED is not set 285# CONFIG_NET_SCHED is not set
283 286
284# 287#
@@ -372,8 +375,6 @@ CONFIG_IDEPCI_PCIBUS_ORDER=y
372# CONFIG_BLK_DEV_GENERIC is not set 375# CONFIG_BLK_DEV_GENERIC is not set
373# CONFIG_BLK_DEV_OPTI621 is not set 376# CONFIG_BLK_DEV_OPTI621 is not set
374CONFIG_BLK_DEV_IDEDMA_PCI=y 377CONFIG_BLK_DEV_IDEDMA_PCI=y
375# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
376CONFIG_IDEDMA_ONLYDISK=y
377# CONFIG_BLK_DEV_AEC62XX is not set 378# CONFIG_BLK_DEV_AEC62XX is not set
378CONFIG_BLK_DEV_ALI15X3=y 379CONFIG_BLK_DEV_ALI15X3=y
379# CONFIG_WDC_ALI15X3 is not set 380# CONFIG_WDC_ALI15X3 is not set
@@ -401,6 +402,7 @@ CONFIG_BLK_DEV_ALI15X3=y
401# CONFIG_BLK_DEV_TC86C001 is not set 402# CONFIG_BLK_DEV_TC86C001 is not set
402# CONFIG_IDE_ARM is not set 403# CONFIG_IDE_ARM is not set
403CONFIG_BLK_DEV_IDEDMA=y 404CONFIG_BLK_DEV_IDEDMA=y
405CONFIG_IDE_ARCH_OBSOLETE_INIT=y
404# CONFIG_BLK_DEV_HD is not set 406# CONFIG_BLK_DEV_HD is not set
405 407
406# 408#
@@ -441,6 +443,7 @@ CONFIG_SCSI_FC_ATTRS=y
441CONFIG_SCSI_ISCSI_ATTRS=m 443CONFIG_SCSI_ISCSI_ATTRS=m
442# CONFIG_SCSI_SAS_ATTRS is not set 444# CONFIG_SCSI_SAS_ATTRS is not set
443# CONFIG_SCSI_SAS_LIBSAS is not set 445# CONFIG_SCSI_SAS_LIBSAS is not set
446# CONFIG_SCSI_SRP_ATTRS is not set
444CONFIG_SCSI_LOWLEVEL=y 447CONFIG_SCSI_LOWLEVEL=y
445CONFIG_ISCSI_TCP=m 448CONFIG_ISCSI_TCP=m
446# CONFIG_BLK_DEV_3W_XXXX_RAID is not set 449# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
@@ -492,14 +495,8 @@ CONFIG_DM_MIRROR=m
492CONFIG_DM_ZERO=m 495CONFIG_DM_ZERO=m
493# CONFIG_DM_MULTIPATH is not set 496# CONFIG_DM_MULTIPATH is not set
494# CONFIG_DM_DELAY is not set 497# CONFIG_DM_DELAY is not set
495 498# CONFIG_DM_UEVENT is not set
496#
497# Fusion MPT device support
498#
499# CONFIG_FUSION is not set 499# CONFIG_FUSION is not set
500# CONFIG_FUSION_SPI is not set
501# CONFIG_FUSION_FC is not set
502# CONFIG_FUSION_SAS is not set
503 500
504# 501#
505# IEEE 1394 (FireWire) support 502# IEEE 1394 (FireWire) support
@@ -638,7 +635,6 @@ CONFIG_INPUT_MOUSEDEV_PSAUX=y
638CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 635CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
639CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 636CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
640# CONFIG_INPUT_JOYDEV is not set 637# CONFIG_INPUT_JOYDEV is not set
641# CONFIG_INPUT_TSDEV is not set
642CONFIG_INPUT_EVDEV=y 638CONFIG_INPUT_EVDEV=y
643# CONFIG_INPUT_EVBUG is not set 639# CONFIG_INPUT_EVBUG is not set
644 640
@@ -714,11 +710,9 @@ CONFIG_SERIAL_CORE_CONSOLE=y
714CONFIG_UNIX98_PTYS=y 710CONFIG_UNIX98_PTYS=y
715# CONFIG_LEGACY_PTYS is not set 711# CONFIG_LEGACY_PTYS is not set
716# CONFIG_IPMI_HANDLER is not set 712# CONFIG_IPMI_HANDLER is not set
717# CONFIG_WATCHDOG is not set
718# CONFIG_HW_RANDOM is not set 713# CONFIG_HW_RANDOM is not set
719# CONFIG_R3964 is not set 714# CONFIG_R3964 is not set
720# CONFIG_APPLICOM is not set 715# CONFIG_APPLICOM is not set
721# CONFIG_DRM is not set
722# CONFIG_RAW_DRIVER is not set 716# CONFIG_RAW_DRIVER is not set
723# CONFIG_TCG_TPM is not set 717# CONFIG_TCG_TPM is not set
724CONFIG_DEVPORT=y 718CONFIG_DEVPORT=y
@@ -786,8 +780,6 @@ CONFIG_I2C_ALGOBIT=y
786# CONFIG_POWER_SUPPLY is not set 780# CONFIG_POWER_SUPPLY is not set
787CONFIG_HWMON=y 781CONFIG_HWMON=y
788# CONFIG_HWMON_VID is not set 782# CONFIG_HWMON_VID is not set
789# CONFIG_SENSORS_ABITUGURU is not set
790# CONFIG_SENSORS_ABITUGURU3 is not set
791# CONFIG_SENSORS_AD7418 is not set 783# CONFIG_SENSORS_AD7418 is not set
792# CONFIG_SENSORS_ADM1021 is not set 784# CONFIG_SENSORS_ADM1021 is not set
793# CONFIG_SENSORS_ADM1025 is not set 785# CONFIG_SENSORS_ADM1025 is not set
@@ -795,12 +787,12 @@ CONFIG_HWMON=y
795# CONFIG_SENSORS_ADM1029 is not set 787# CONFIG_SENSORS_ADM1029 is not set
796# CONFIG_SENSORS_ADM1031 is not set 788# CONFIG_SENSORS_ADM1031 is not set
797# CONFIG_SENSORS_ADM9240 is not set 789# CONFIG_SENSORS_ADM9240 is not set
798# CONFIG_SENSORS_ASB100 is not set 790# CONFIG_SENSORS_ADT7470 is not set
799# CONFIG_SENSORS_ATXP1 is not set 791# CONFIG_SENSORS_ATXP1 is not set
800# CONFIG_SENSORS_DS1621 is not set 792# CONFIG_SENSORS_DS1621 is not set
801# CONFIG_SENSORS_F71805F is not set 793# CONFIG_SENSORS_F71805F is not set
802# CONFIG_SENSORS_FSCHER is not set 794# CONFIG_SENSORS_F71882FG is not set
803# CONFIG_SENSORS_FSCPOS is not set 795# CONFIG_SENSORS_F75375S is not set
804# CONFIG_SENSORS_GL518SM is not set 796# CONFIG_SENSORS_GL518SM is not set
805# CONFIG_SENSORS_GL520SM is not set 797# CONFIG_SENSORS_GL520SM is not set
806# CONFIG_SENSORS_IT87 is not set 798# CONFIG_SENSORS_IT87 is not set
@@ -836,6 +828,7 @@ CONFIG_HWMON=y
836# CONFIG_SENSORS_W83627HF is not set 828# CONFIG_SENSORS_W83627HF is not set
837# CONFIG_SENSORS_W83627EHF is not set 829# CONFIG_SENSORS_W83627EHF is not set
838# CONFIG_HWMON_DEBUG_CHIP is not set 830# CONFIG_HWMON_DEBUG_CHIP is not set
831# CONFIG_WATCHDOG is not set
839 832
840# 833#
841# Sonics Silicon Backplane 834# Sonics Silicon Backplane
@@ -858,12 +851,7 @@ CONFIG_SSB_POSSIBLE=y
858# 851#
859# Graphics support 852# Graphics support
860# 853#
861# CONFIG_BACKLIGHT_LCD_SUPPORT is not set 854# CONFIG_DRM is not set
862
863#
864# Display device support
865#
866# CONFIG_DISPLAY_SUPPORT is not set
867# CONFIG_VGASTATE is not set 855# CONFIG_VGASTATE is not set
868# CONFIG_VIDEO_OUTPUT_CONTROL is not set 856# CONFIG_VIDEO_OUTPUT_CONTROL is not set
869CONFIG_FB=y 857CONFIG_FB=y
@@ -872,6 +860,7 @@ CONFIG_FB_DDC=y
872CONFIG_FB_CFB_FILLRECT=y 860CONFIG_FB_CFB_FILLRECT=y
873CONFIG_FB_CFB_COPYAREA=y 861CONFIG_FB_CFB_COPYAREA=y
874CONFIG_FB_CFB_IMAGEBLIT=y 862CONFIG_FB_CFB_IMAGEBLIT=y
863# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
875# CONFIG_FB_SYS_FILLRECT is not set 864# CONFIG_FB_SYS_FILLRECT is not set
876# CONFIG_FB_SYS_COPYAREA is not set 865# CONFIG_FB_SYS_COPYAREA is not set
877# CONFIG_FB_SYS_IMAGEBLIT is not set 866# CONFIG_FB_SYS_IMAGEBLIT is not set
@@ -890,6 +879,7 @@ CONFIG_FB_TILEBLITTING=y
890# CONFIG_FB_PM2 is not set 879# CONFIG_FB_PM2 is not set
891# CONFIG_FB_ASILIANT is not set 880# CONFIG_FB_ASILIANT is not set
892# CONFIG_FB_IMSTT is not set 881# CONFIG_FB_IMSTT is not set
882# CONFIG_FB_UVESA is not set
893# CONFIG_FB_SBUS is not set 883# CONFIG_FB_SBUS is not set
894# CONFIG_FB_XVR500 is not set 884# CONFIG_FB_XVR500 is not set
895# CONFIG_FB_XVR2500 is not set 885# CONFIG_FB_XVR2500 is not set
@@ -915,6 +905,12 @@ CONFIG_FB_RADEON_I2C=y
915# CONFIG_FB_ARK is not set 905# CONFIG_FB_ARK is not set
916# CONFIG_FB_PM3 is not set 906# CONFIG_FB_PM3 is not set
917# CONFIG_FB_VIRTUAL is not set 907# CONFIG_FB_VIRTUAL is not set
908# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
909
910#
911# Display device support
912#
913# CONFIG_DISPLAY_SUPPORT is not set
918 914
919# 915#
920# Console display driver support 916# Console display driver support
@@ -1066,6 +1062,7 @@ CONFIG_AC97_BUS=m
1066CONFIG_HID_SUPPORT=y 1062CONFIG_HID_SUPPORT=y
1067CONFIG_HID=y 1063CONFIG_HID=y
1068# CONFIG_HID_DEBUG is not set 1064# CONFIG_HID_DEBUG is not set
1065# CONFIG_HIDRAW is not set
1069 1066
1070# 1067#
1071# USB Input Devices 1068# USB Input Devices
@@ -1187,19 +1184,6 @@ CONFIG_USB_STORAGE=m
1187# CONFIG_RTC_CLASS is not set 1184# CONFIG_RTC_CLASS is not set
1188 1185
1189# 1186#
1190# DMA Engine support
1191#
1192# CONFIG_DMA_ENGINE is not set
1193
1194#
1195# DMA Clients
1196#
1197
1198#
1199# DMA Devices
1200#
1201
1202#
1203# Userspace I/O 1187# Userspace I/O
1204# 1188#
1205# CONFIG_UIO is not set 1189# CONFIG_UIO is not set
@@ -1275,7 +1259,6 @@ CONFIG_TMPFS=y
1275# CONFIG_TMPFS_POSIX_ACL is not set 1259# CONFIG_TMPFS_POSIX_ACL is not set
1276CONFIG_HUGETLBFS=y 1260CONFIG_HUGETLBFS=y
1277CONFIG_HUGETLB_PAGE=y 1261CONFIG_HUGETLB_PAGE=y
1278CONFIG_RAMFS=y
1279# CONFIG_CONFIGFS_FS is not set 1262# CONFIG_CONFIGFS_FS is not set
1280 1263
1281# 1264#
@@ -1295,10 +1278,7 @@ CONFIG_RAMFS=y
1295# CONFIG_QNX4FS_FS is not set 1278# CONFIG_QNX4FS_FS is not set
1296# CONFIG_SYSV_FS is not set 1279# CONFIG_SYSV_FS is not set
1297# CONFIG_UFS_FS is not set 1280# CONFIG_UFS_FS is not set
1298 1281CONFIG_NETWORK_FILESYSTEMS=y
1299#
1300# Network File Systems
1301#
1302# CONFIG_NFS_FS is not set 1282# CONFIG_NFS_FS is not set
1303# CONFIG_NFSD is not set 1283# CONFIG_NFSD is not set
1304# CONFIG_SMB_FS is not set 1284# CONFIG_SMB_FS is not set
@@ -1313,10 +1293,6 @@ CONFIG_RAMFS=y
1313# CONFIG_PARTITION_ADVANCED is not set 1293# CONFIG_PARTITION_ADVANCED is not set
1314CONFIG_MSDOS_PARTITION=y 1294CONFIG_MSDOS_PARTITION=y
1315CONFIG_SUN_PARTITION=y 1295CONFIG_SUN_PARTITION=y
1316
1317#
1318# Native Language Support
1319#
1320CONFIG_NLS=m 1296CONFIG_NLS=m
1321CONFIG_NLS_DEFAULT="iso8859-1" 1297CONFIG_NLS_DEFAULT="iso8859-1"
1322# CONFIG_NLS_CODEPAGE_437 is not set 1298# CONFIG_NLS_CODEPAGE_437 is not set
@@ -1357,18 +1333,12 @@ CONFIG_NLS_DEFAULT="iso8859-1"
1357# CONFIG_NLS_KOI8_R is not set 1333# CONFIG_NLS_KOI8_R is not set
1358# CONFIG_NLS_KOI8_U is not set 1334# CONFIG_NLS_KOI8_U is not set
1359# CONFIG_NLS_UTF8 is not set 1335# CONFIG_NLS_UTF8 is not set
1360
1361#
1362# Distributed Lock Manager
1363#
1364# CONFIG_DLM is not set 1336# CONFIG_DLM is not set
1365 1337CONFIG_INSTRUMENTATION=y
1366#
1367# Instrumentation Support
1368#
1369CONFIG_PROFILING=y 1338CONFIG_PROFILING=y
1370CONFIG_OPROFILE=m 1339CONFIG_OPROFILE=m
1371CONFIG_KPROBES=y 1340CONFIG_KPROBES=y
1341# CONFIG_MARKERS is not set
1372 1342
1373# 1343#
1374# Kernel hacking 1344# Kernel hacking
@@ -1402,9 +1372,11 @@ CONFIG_DEBUG_BUGVERBOSE=y
1402# CONFIG_DEBUG_VM is not set 1372# CONFIG_DEBUG_VM is not set
1403# CONFIG_DEBUG_LIST is not set 1373# CONFIG_DEBUG_LIST is not set
1404CONFIG_FORCED_INLINING=y 1374CONFIG_FORCED_INLINING=y
1375# CONFIG_BOOT_PRINTK_DELAY is not set
1405# CONFIG_RCU_TORTURE_TEST is not set 1376# CONFIG_RCU_TORTURE_TEST is not set
1406# CONFIG_LKDTM is not set 1377# CONFIG_LKDTM is not set
1407# CONFIG_FAULT_INJECTION is not set 1378# CONFIG_FAULT_INJECTION is not set
1379# CONFIG_SAMPLES is not set
1408# CONFIG_DEBUG_STACK_USAGE is not set 1380# CONFIG_DEBUG_STACK_USAGE is not set
1409# CONFIG_DEBUG_DCFLUSH is not set 1381# CONFIG_DEBUG_DCFLUSH is not set
1410# CONFIG_STACK_DEBUG is not set 1382# CONFIG_STACK_DEBUG is not set
@@ -1417,6 +1389,7 @@ CONFIG_FORCED_INLINING=y
1417CONFIG_KEYS=y 1389CONFIG_KEYS=y
1418# CONFIG_KEYS_DEBUG_PROC_KEYS is not set 1390# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
1419# CONFIG_SECURITY is not set 1391# CONFIG_SECURITY is not set
1392# CONFIG_SECURITY_FILE_CAPABILITIES is not set
1420CONFIG_XOR_BLOCKS=m 1393CONFIG_XOR_BLOCKS=m
1421CONFIG_ASYNC_CORE=m 1394CONFIG_ASYNC_CORE=m
1422CONFIG_ASYNC_MEMCPY=m 1395CONFIG_ASYNC_MEMCPY=m
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
index 112c46e66578..ef50d217432f 100644
--- a/arch/sparc64/kernel/Makefile
+++ b/arch/sparc64/kernel/Makefile
@@ -39,12 +39,3 @@ else
39 obj-y += sys_sunos32.o sunos_ioctl32.o 39 obj-y += sys_sunos32.o sunos_ioctl32.o
40 endif 40 endif
41endif 41endif
42
43ifneq ($(NEW_GCC),y)
44 CMODEL_CFLAG := -mmedlow
45else
46 CMODEL_CFLAG := -m64 -mcmodel=medlow
47endif
48
49head.o: head.S ttable.S itlb_miss.S dtlb_miss.S ktlb.S tsb.S \
50 etrap.S rtrap.S winfixup.S entry.S
diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c
index 29af777d7ac9..070a4846c0cb 100644
--- a/arch/sparc64/kernel/iommu.c
+++ b/arch/sparc64/kernel/iommu.c
@@ -472,8 +472,7 @@ static void dma_4u_unmap_single(struct device *dev, dma_addr_t bus_addr,
472 spin_unlock_irqrestore(&iommu->lock, flags); 472 spin_unlock_irqrestore(&iommu->lock, flags);
473} 473}
474 474
475#define SG_ENT_PHYS_ADDRESS(SG) \ 475#define SG_ENT_PHYS_ADDRESS(SG) (__pa(sg_virt((SG))))
476 (__pa(page_address((SG)->page)) + (SG)->offset)
477 476
478static void fill_sg(iopte_t *iopte, struct scatterlist *sg, 477static void fill_sg(iopte_t *iopte, struct scatterlist *sg,
479 int nused, int nelems, 478 int nused, int nelems,
@@ -565,9 +564,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
565 /* Fast path single entry scatterlists. */ 564 /* Fast path single entry scatterlists. */
566 if (nelems == 1) { 565 if (nelems == 1) {
567 sglist->dma_address = 566 sglist->dma_address =
568 dma_4u_map_single(dev, 567 dma_4u_map_single(dev, sg_virt(sglist),
569 (page_address(sglist->page) +
570 sglist->offset),
571 sglist->length, direction); 568 sglist->length, direction);
572 if (unlikely(sglist->dma_address == DMA_ERROR_CODE)) 569 if (unlikely(sglist->dma_address == DMA_ERROR_CODE))
573 return 0; 570 return 0;
diff --git a/arch/sparc64/kernel/iommu_common.c b/arch/sparc64/kernel/iommu_common.c
index d7ca900ec51d..78e8277df655 100644
--- a/arch/sparc64/kernel/iommu_common.c
+++ b/arch/sparc64/kernel/iommu_common.c
@@ -73,7 +73,7 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,
73 73
74 daddr = dma_sg->dma_address; 74 daddr = dma_sg->dma_address;
75 sglen = sg->length; 75 sglen = sg->length;
76 sgaddr = (unsigned long) (page_address(sg->page) + sg->offset); 76 sgaddr = (unsigned long) sg_virt(sg);
77 while (dlen > 0) { 77 while (dlen > 0) {
78 unsigned long paddr; 78 unsigned long paddr;
79 79
@@ -123,7 +123,7 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,
123 sg = sg_next(sg); 123 sg = sg_next(sg);
124 if (--nents <= 0) 124 if (--nents <= 0)
125 break; 125 break;
126 sgaddr = (unsigned long) (page_address(sg->page) + sg->offset); 126 sgaddr = (unsigned long) sg_virt(sg);
127 sglen = sg->length; 127 sglen = sg->length;
128 } 128 }
129 if (dlen < 0) { 129 if (dlen < 0) {
@@ -191,7 +191,7 @@ void verify_sglist(struct scatterlist *sglist, int nents, iopte_t *iopte, int np
191 printk("sg(%d): page_addr(%p) off(%x) length(%x) " 191 printk("sg(%d): page_addr(%p) off(%x) length(%x) "
192 "dma_address[%016x] dma_length[%016x]\n", 192 "dma_address[%016x] dma_length[%016x]\n",
193 i, 193 i,
194 page_address(sg->page), sg->offset, 194 page_address(sg_page(sg)), sg->offset,
195 sg->length, 195 sg->length,
196 sg->dma_address, sg->dma_length); 196 sg->dma_address, sg->dma_length);
197 } 197 }
@@ -207,15 +207,14 @@ unsigned long prepare_sg(struct scatterlist *sg, int nents)
207 unsigned long prev; 207 unsigned long prev;
208 u32 dent_addr, dent_len; 208 u32 dent_addr, dent_len;
209 209
210 prev = (unsigned long) (page_address(sg->page) + sg->offset); 210 prev = (unsigned long) sg_virt(sg);
211 prev += (unsigned long) (dent_len = sg->length); 211 prev += (unsigned long) (dent_len = sg->length);
212 dent_addr = (u32) ((unsigned long)(page_address(sg->page) + sg->offset) 212 dent_addr = (u32) ((unsigned long)(sg_virt(sg)) & (IO_PAGE_SIZE - 1UL));
213 & (IO_PAGE_SIZE - 1UL));
214 while (--nents) { 213 while (--nents) {
215 unsigned long addr; 214 unsigned long addr;
216 215
217 sg = sg_next(sg); 216 sg = sg_next(sg);
218 addr = (unsigned long) (page_address(sg->page) + sg->offset); 217 addr = (unsigned long) sg_virt(sg);
219 if (! VCONTIG(prev, addr)) { 218 if (! VCONTIG(prev, addr)) {
220 dma_sg->dma_address = dent_addr; 219 dma_sg->dma_address = dent_addr;
221 dma_sg->dma_length = dent_len; 220 dma_sg->dma_length = dent_len;
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index 2c3bea228159..30431bd24e1e 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -257,8 +257,8 @@ struct irq_handler_data {
257 unsigned long imap; 257 unsigned long imap;
258 258
259 void (*pre_handler)(unsigned int, void *, void *); 259 void (*pre_handler)(unsigned int, void *, void *);
260 void *pre_handler_arg1; 260 void *arg1;
261 void *pre_handler_arg2; 261 void *arg2;
262}; 262};
263 263
264#ifdef CONFIG_SMP 264#ifdef CONFIG_SMP
@@ -346,7 +346,7 @@ static void sun4u_irq_disable(unsigned int virt_irq)
346 } 346 }
347} 347}
348 348
349static void sun4u_irq_end(unsigned int virt_irq) 349static void sun4u_irq_eoi(unsigned int virt_irq)
350{ 350{
351 struct irq_handler_data *data = get_irq_chip_data(virt_irq); 351 struct irq_handler_data *data = get_irq_chip_data(virt_irq);
352 struct irq_desc *desc = irq_desc + virt_irq; 352 struct irq_desc *desc = irq_desc + virt_irq;
@@ -401,7 +401,7 @@ static void sun4v_irq_disable(unsigned int virt_irq)
401 "err(%d)\n", ino, err); 401 "err(%d)\n", ino, err);
402} 402}
403 403
404static void sun4v_irq_end(unsigned int virt_irq) 404static void sun4v_irq_eoi(unsigned int virt_irq)
405{ 405{
406 unsigned int ino = virt_irq_table[virt_irq].dev_ino; 406 unsigned int ino = virt_irq_table[virt_irq].dev_ino;
407 struct irq_desc *desc = irq_desc + virt_irq; 407 struct irq_desc *desc = irq_desc + virt_irq;
@@ -478,7 +478,7 @@ static void sun4v_virq_disable(unsigned int virt_irq)
478 dev_handle, dev_ino, err); 478 dev_handle, dev_ino, err);
479} 479}
480 480
481static void sun4v_virq_end(unsigned int virt_irq) 481static void sun4v_virq_eoi(unsigned int virt_irq)
482{ 482{
483 struct irq_desc *desc = irq_desc + virt_irq; 483 struct irq_desc *desc = irq_desc + virt_irq;
484 unsigned long dev_handle, dev_ino; 484 unsigned long dev_handle, dev_ino;
@@ -498,33 +498,11 @@ static void sun4v_virq_end(unsigned int virt_irq)
498 dev_handle, dev_ino, err); 498 dev_handle, dev_ino, err);
499} 499}
500 500
501static void run_pre_handler(unsigned int virt_irq)
502{
503 struct irq_handler_data *data = get_irq_chip_data(virt_irq);
504 unsigned int ino;
505
506 ino = virt_irq_table[virt_irq].dev_ino;
507 if (likely(data->pre_handler)) {
508 data->pre_handler(ino,
509 data->pre_handler_arg1,
510 data->pre_handler_arg2);
511 }
512}
513
514static struct irq_chip sun4u_irq = { 501static struct irq_chip sun4u_irq = {
515 .typename = "sun4u", 502 .typename = "sun4u",
516 .enable = sun4u_irq_enable, 503 .enable = sun4u_irq_enable,
517 .disable = sun4u_irq_disable, 504 .disable = sun4u_irq_disable,
518 .end = sun4u_irq_end, 505 .eoi = sun4u_irq_eoi,
519 .set_affinity = sun4u_set_affinity,
520};
521
522static struct irq_chip sun4u_irq_ack = {
523 .typename = "sun4u+ack",
524 .enable = sun4u_irq_enable,
525 .disable = sun4u_irq_disable,
526 .ack = run_pre_handler,
527 .end = sun4u_irq_end,
528 .set_affinity = sun4u_set_affinity, 506 .set_affinity = sun4u_set_affinity,
529}; 507};
530 508
@@ -532,7 +510,7 @@ static struct irq_chip sun4v_irq = {
532 .typename = "sun4v", 510 .typename = "sun4v",
533 .enable = sun4v_irq_enable, 511 .enable = sun4v_irq_enable,
534 .disable = sun4v_irq_disable, 512 .disable = sun4v_irq_disable,
535 .end = sun4v_irq_end, 513 .eoi = sun4v_irq_eoi,
536 .set_affinity = sun4v_set_affinity, 514 .set_affinity = sun4v_set_affinity,
537}; 515};
538 516
@@ -540,31 +518,33 @@ static struct irq_chip sun4v_virq = {
540 .typename = "vsun4v", 518 .typename = "vsun4v",
541 .enable = sun4v_virq_enable, 519 .enable = sun4v_virq_enable,
542 .disable = sun4v_virq_disable, 520 .disable = sun4v_virq_disable,
543 .end = sun4v_virq_end, 521 .eoi = sun4v_virq_eoi,
544 .set_affinity = sun4v_virt_set_affinity, 522 .set_affinity = sun4v_virt_set_affinity,
545}; 523};
546 524
525static void fastcall pre_flow_handler(unsigned int virt_irq,
526 struct irq_desc *desc)
527{
528 struct irq_handler_data *data = get_irq_chip_data(virt_irq);
529 unsigned int ino = virt_irq_table[virt_irq].dev_ino;
530
531 data->pre_handler(ino, data->arg1, data->arg2);
532
533 handle_fasteoi_irq(virt_irq, desc);
534}
535
547void irq_install_pre_handler(int virt_irq, 536void irq_install_pre_handler(int virt_irq,
548 void (*func)(unsigned int, void *, void *), 537 void (*func)(unsigned int, void *, void *),
549 void *arg1, void *arg2) 538 void *arg1, void *arg2)
550{ 539{
551 struct irq_handler_data *data = get_irq_chip_data(virt_irq); 540 struct irq_handler_data *data = get_irq_chip_data(virt_irq);
552 struct irq_chip *chip = get_irq_chip(virt_irq); 541 struct irq_desc *desc = irq_desc + virt_irq;
553
554 if (WARN_ON(chip == &sun4v_irq || chip == &sun4v_virq)) {
555 printk(KERN_ERR "IRQ: Trying to install pre-handler on "
556 "sun4v irq %u\n", virt_irq);
557 return;
558 }
559 542
560 data->pre_handler = func; 543 data->pre_handler = func;
561 data->pre_handler_arg1 = arg1; 544 data->arg1 = arg1;
562 data->pre_handler_arg2 = arg2; 545 data->arg2 = arg2;
563
564 if (chip == &sun4u_irq_ack)
565 return;
566 546
567 set_irq_chip(virt_irq, &sun4u_irq_ack); 547 desc->handle_irq = pre_flow_handler;
568} 548}
569 549
570unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) 550unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap)
@@ -582,7 +562,10 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap)
582 if (!virt_irq) { 562 if (!virt_irq) {
583 virt_irq = virt_irq_alloc(0, ino); 563 virt_irq = virt_irq_alloc(0, ino);
584 bucket_set_virt_irq(__pa(bucket), virt_irq); 564 bucket_set_virt_irq(__pa(bucket), virt_irq);
585 set_irq_chip(virt_irq, &sun4u_irq); 565 set_irq_chip_and_handler_name(virt_irq,
566 &sun4u_irq,
567 handle_fasteoi_irq,
568 "IVEC");
586 } 569 }
587 570
588 data = get_irq_chip_data(virt_irq); 571 data = get_irq_chip_data(virt_irq);
@@ -617,7 +600,9 @@ static unsigned int sun4v_build_common(unsigned long sysino,
617 if (!virt_irq) { 600 if (!virt_irq) {
618 virt_irq = virt_irq_alloc(0, sysino); 601 virt_irq = virt_irq_alloc(0, sysino);
619 bucket_set_virt_irq(__pa(bucket), virt_irq); 602 bucket_set_virt_irq(__pa(bucket), virt_irq);
620 set_irq_chip(virt_irq, chip); 603 set_irq_chip_and_handler_name(virt_irq, chip,
604 handle_fasteoi_irq,
605 "IVEC");
621 } 606 }
622 607
623 data = get_irq_chip_data(virt_irq); 608 data = get_irq_chip_data(virt_irq);
@@ -665,7 +650,10 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
665 650
666 virt_irq = virt_irq_alloc(devhandle, devino); 651 virt_irq = virt_irq_alloc(devhandle, devino);
667 bucket_set_virt_irq(__pa(bucket), virt_irq); 652 bucket_set_virt_irq(__pa(bucket), virt_irq);
668 set_irq_chip(virt_irq, &sun4v_virq); 653
654 set_irq_chip_and_handler_name(virt_irq, &sun4v_virq,
655 handle_fasteoi_irq,
656 "IVEC");
669 657
670 data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); 658 data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC);
671 if (unlikely(!data)) 659 if (unlikely(!data))
@@ -724,6 +712,7 @@ void handler_irq(int irq, struct pt_regs *regs)
724 : "memory"); 712 : "memory");
725 713
726 while (bucket_pa) { 714 while (bucket_pa) {
715 struct irq_desc *desc;
727 unsigned long next_pa; 716 unsigned long next_pa;
728 unsigned int virt_irq; 717 unsigned int virt_irq;
729 718
@@ -731,7 +720,9 @@ void handler_irq(int irq, struct pt_regs *regs)
731 virt_irq = bucket_get_virt_irq(bucket_pa); 720 virt_irq = bucket_get_virt_irq(bucket_pa);
732 bucket_clear_chain_pa(bucket_pa); 721 bucket_clear_chain_pa(bucket_pa);
733 722
734 __do_IRQ(virt_irq); 723 desc = irq_desc + virt_irq;
724
725 desc->handle_irq(virt_irq, desc);
735 726
736 bucket_pa = next_pa; 727 bucket_pa = next_pa;
737 } 728 }
diff --git a/arch/sparc64/kernel/ldc.c b/arch/sparc64/kernel/ldc.c
index 85a2be0b0962..c8313cb60f0a 100644
--- a/arch/sparc64/kernel/ldc.c
+++ b/arch/sparc64/kernel/ldc.c
@@ -2057,7 +2057,7 @@ static void fill_cookies(struct cookie_state *sp, unsigned long pa,
2057 2057
2058static int sg_count_one(struct scatterlist *sg) 2058static int sg_count_one(struct scatterlist *sg)
2059{ 2059{
2060 unsigned long base = page_to_pfn(sg->page) << PAGE_SHIFT; 2060 unsigned long base = page_to_pfn(sg_page(sg)) << PAGE_SHIFT;
2061 long len = sg->length; 2061 long len = sg->length;
2062 2062
2063 if ((sg->offset | len) & (8UL - 1)) 2063 if ((sg->offset | len) & (8UL - 1))
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index 9b808640a193..63b3ebc0c3c2 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -207,8 +207,7 @@ static struct {
207 { "SUNW,sun4v-pci", sun4v_pci_init }, 207 { "SUNW,sun4v-pci", sun4v_pci_init },
208 { "pciex108e,80f0", fire_pci_init }, 208 { "pciex108e,80f0", fire_pci_init },
209}; 209};
210#define PCI_NUM_CONTROLLER_TYPES (sizeof(pci_controller_table) / \ 210#define PCI_NUM_CONTROLLER_TYPES ARRAY_SIZE(pci_controller_table)
211 sizeof(pci_controller_table[0]))
212 211
213static int __init pci_controller_init(const char *model_name, int namelen, struct device_node *dp) 212static int __init pci_controller_init(const char *model_name, int namelen, struct device_node *dp)
214{ 213{
diff --git a/arch/sparc64/kernel/pci_msi.c b/arch/sparc64/kernel/pci_msi.c
index 31a165fd3e48..d6d64b44af63 100644
--- a/arch/sparc64/kernel/pci_msi.c
+++ b/arch/sparc64/kernel/pci_msi.c
@@ -28,8 +28,15 @@ static irqreturn_t sparc64_msiq_interrupt(int irq, void *cookie)
28 unsigned long msi; 28 unsigned long msi;
29 29
30 err = ops->dequeue_msi(pbm, msiqid, &head, &msi); 30 err = ops->dequeue_msi(pbm, msiqid, &head, &msi);
31 if (likely(err > 0)) 31 if (likely(err > 0)) {
32 __do_IRQ(pbm->msi_irq_table[msi - pbm->msi_first]); 32 struct irq_desc *desc;
33 unsigned int virt_irq;
34
35 virt_irq = pbm->msi_irq_table[msi - pbm->msi_first];
36 desc = irq_desc + virt_irq;
37
38 desc->handle_irq(virt_irq, desc);
39 }
33 40
34 if (unlikely(err < 0)) 41 if (unlikely(err < 0))
35 goto err_dequeue; 42 goto err_dequeue;
@@ -128,7 +135,8 @@ int sparc64_setup_msi_irq(unsigned int *virt_irq_p,
128 if (!*virt_irq_p) 135 if (!*virt_irq_p)
129 goto out_err; 136 goto out_err;
130 137
131 set_irq_chip(*virt_irq_p, &msi_irq); 138 set_irq_chip_and_handler_name(*virt_irq_p, &msi_irq,
139 handle_simple_irq, "MSI");
132 140
133 err = alloc_msi(pbm); 141 err = alloc_msi(pbm);
134 if (unlikely(err < 0)) 142 if (unlikely(err < 0))
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index fe46ace3e59f..8c4875bdb4a8 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -365,8 +365,7 @@ static void dma_4v_unmap_single(struct device *dev, dma_addr_t bus_addr,
365 spin_unlock_irqrestore(&iommu->lock, flags); 365 spin_unlock_irqrestore(&iommu->lock, flags);
366} 366}
367 367
368#define SG_ENT_PHYS_ADDRESS(SG) \ 368#define SG_ENT_PHYS_ADDRESS(SG) (__pa(sg_virt((SG))))
369 (__pa(page_address((SG)->page)) + (SG)->offset)
370 369
371static long fill_sg(long entry, struct device *dev, 370static long fill_sg(long entry, struct device *dev,
372 struct scatterlist *sg, 371 struct scatterlist *sg,
@@ -477,9 +476,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
477 /* Fast path single entry scatterlists. */ 476 /* Fast path single entry scatterlists. */
478 if (nelems == 1) { 477 if (nelems == 1) {
479 sglist->dma_address = 478 sglist->dma_address =
480 dma_4v_map_single(dev, 479 dma_4v_map_single(dev, sg_virt(sglist),
481 (page_address(sglist->page) +
482 sglist->offset),
483 sglist->length, direction); 480 sglist->length, direction);
484 if (unlikely(sglist->dma_address == DMA_ERROR_CODE)) 481 if (unlikely(sglist->dma_address == DMA_ERROR_CODE))
485 return 0; 482 return 0;
diff --git a/arch/sparc64/math-emu/Makefile b/arch/sparc64/math-emu/Makefile
index a0b06fd29467..cc5cb9baf6aa 100644
--- a/arch/sparc64/math-emu/Makefile
+++ b/arch/sparc64/math-emu/Makefile
@@ -4,4 +4,4 @@
4 4
5obj-y := math.o 5obj-y := math.o
6 6
7EXTRA_CFLAGS = -I. -Iinclude/math-emu -w 7EXTRA_CFLAGS = -Iinclude/math-emu -w
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 25b248a02507..3a8cd3dfb51c 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -1115,7 +1115,7 @@ static void do_ubd_request(struct request_queue *q)
1115 } 1115 }
1116 prepare_request(req, io_req, 1116 prepare_request(req, io_req,
1117 (unsigned long long) req->sector << 9, 1117 (unsigned long long) req->sector << 9,
1118 sg->offset, sg->length, sg->page); 1118 sg->offset, sg->length, sg_page(sg));
1119 1119
1120 last_sectors = sg->length >> 9; 1120 last_sectors = sg->length >> 9;
1121 n = os_write_file(thread_fd, &io_req, 1121 n = os_write_file(thread_fd, &io_req,
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
index f35ea2237522..a0ae2e7f6cec 100644
--- a/arch/x86/boot/compressed/head_32.S
+++ b/arch/x86/boot/compressed/head_32.S
@@ -27,13 +27,22 @@
27#include <asm/segment.h> 27#include <asm/segment.h>
28#include <asm/page.h> 28#include <asm/page.h>
29#include <asm/boot.h> 29#include <asm/boot.h>
30#include <asm/asm-offsets.h>
30 31
31.section ".text.head","ax",@progbits 32.section ".text.head","ax",@progbits
32 .globl startup_32 33 .globl startup_32
33 34
34startup_32: 35startup_32:
35 cld 36 /* check to see if KEEP_SEGMENTS flag is meaningful */
36 cli 37 cmpw $0x207, BP_version(%esi)
38 jb 1f
39
40 /* test KEEP_SEGMENTS flag to see if the bootloader is asking
41 * us to not reload segments */
42 testb $(1<<6), BP_loadflags(%esi)
43 jnz 2f
44
451: cli
37 movl $(__BOOT_DS),%eax 46 movl $(__BOOT_DS),%eax
38 movl %eax,%ds 47 movl %eax,%ds
39 movl %eax,%es 48 movl %eax,%es
@@ -41,6 +50,8 @@ startup_32:
41 movl %eax,%gs 50 movl %eax,%gs
42 movl %eax,%ss 51 movl %eax,%ss
43 52
532: cld
54
44/* Calculate the delta between where we were compiled to run 55/* Calculate the delta between where we were compiled to run
45 * at and where we were actually loaded at. This can only be done 56 * at and where we were actually loaded at. This can only be done
46 * with a short local call on x86. Nothing else will tell us what 57 * with a short local call on x86. Nothing else will tell us what
diff --git a/arch/x86/boot/compressed/misc_32.c b/arch/x86/boot/compressed/misc_32.c
index 1dc1e19c0a9f..b74d60d1b2fa 100644
--- a/arch/x86/boot/compressed/misc_32.c
+++ b/arch/x86/boot/compressed/misc_32.c
@@ -247,6 +247,9 @@ static void putstr(const char *s)
247 int x,y,pos; 247 int x,y,pos;
248 char c; 248 char c;
249 249
250 if (RM_SCREEN_INFO.orig_video_mode == 0 && lines == 0 && cols == 0)
251 return;
252
250 x = RM_SCREEN_INFO.orig_x; 253 x = RM_SCREEN_INFO.orig_x;
251 y = RM_SCREEN_INFO.orig_y; 254 y = RM_SCREEN_INFO.orig_y;
252 255
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index f3140e596d40..8353c81c41c0 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -119,7 +119,7 @@ _start:
119 # Part 2 of the header, from the old setup.S 119 # Part 2 of the header, from the old setup.S
120 120
121 .ascii "HdrS" # header signature 121 .ascii "HdrS" # header signature
122 .word 0x0206 # header version number (>= 0x0105) 122 .word 0x0207 # header version number (>= 0x0105)
123 # or else old loadlin-1.5 will fail) 123 # or else old loadlin-1.5 will fail)
124 .globl realmode_swtch 124 .globl realmode_swtch
125realmode_swtch: .word 0, 0 # default_switch, SETUPSEG 125realmode_swtch: .word 0, 0 # default_switch, SETUPSEG
@@ -214,6 +214,11 @@ cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line,
214 #added with boot protocol 214 #added with boot protocol
215 #version 2.06 215 #version 2.06
216 216
217hardware_subarch: .long 0 # subarchitecture, added with 2.07
218 # default to 0 for normal x86 PC
219
220hardware_subarch_data: .quad 0
221
217# End of setup header ##################################################### 222# End of setup header #####################################################
218 223
219 .section ".inittext", "ax" 224 .section ".inittext", "ax"
diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
index f1b7cdda82b3..f8764716b0c0 100644
--- a/arch/x86/kernel/asm-offsets_32.c
+++ b/arch/x86/kernel/asm-offsets_32.c
@@ -15,6 +15,7 @@
15#include <asm/fixmap.h> 15#include <asm/fixmap.h>
16#include <asm/processor.h> 16#include <asm/processor.h>
17#include <asm/thread_info.h> 17#include <asm/thread_info.h>
18#include <asm/bootparam.h>
18#include <asm/elf.h> 19#include <asm/elf.h>
19 20
20#include <xen/interface/xen.h> 21#include <xen/interface/xen.h>
@@ -146,4 +147,10 @@ void foo(void)
146 OFFSET(LGUEST_PAGES_regs_errcode, lguest_pages, regs.errcode); 147 OFFSET(LGUEST_PAGES_regs_errcode, lguest_pages, regs.errcode);
147 OFFSET(LGUEST_PAGES_regs, lguest_pages, regs); 148 OFFSET(LGUEST_PAGES_regs, lguest_pages, regs);
148#endif 149#endif
150
151 BLANK();
152 OFFSET(BP_scratch, boot_params, scratch);
153 OFFSET(BP_loadflags, boot_params, hdr.loadflags);
154 OFFSET(BP_hardware_subarch, boot_params, hdr.hardware_subarch);
155 OFFSET(BP_version, boot_params, hdr.version);
149} 156}
diff --git a/arch/x86/kernel/e820_32.c b/arch/x86/kernel/e820_32.c
index 58fd54eb5577..18f500d185a2 100644
--- a/arch/x86/kernel/e820_32.c
+++ b/arch/x86/kernel/e820_32.c
@@ -51,6 +51,13 @@ struct resource code_resource = {
51 .flags = IORESOURCE_BUSY | IORESOURCE_MEM 51 .flags = IORESOURCE_BUSY | IORESOURCE_MEM
52}; 52};
53 53
54struct resource bss_resource = {
55 .name = "Kernel bss",
56 .start = 0,
57 .end = 0,
58 .flags = IORESOURCE_BUSY | IORESOURCE_MEM
59};
60
54static struct resource system_rom_resource = { 61static struct resource system_rom_resource = {
55 .name = "System ROM", 62 .name = "System ROM",
56 .start = 0xf0000, 63 .start = 0xf0000,
@@ -254,7 +261,9 @@ static void __init probe_roms(void)
254 * and also for regions reported as reserved by the e820. 261 * and also for regions reported as reserved by the e820.
255 */ 262 */
256static void __init 263static void __init
257legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource) 264legacy_init_iomem_resources(struct resource *code_resource,
265 struct resource *data_resource,
266 struct resource *bss_resource)
258{ 267{
259 int i; 268 int i;
260 269
@@ -287,6 +296,7 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
287 */ 296 */
288 request_resource(res, code_resource); 297 request_resource(res, code_resource);
289 request_resource(res, data_resource); 298 request_resource(res, data_resource);
299 request_resource(res, bss_resource);
290#ifdef CONFIG_KEXEC 300#ifdef CONFIG_KEXEC
291 if (crashk_res.start != crashk_res.end) 301 if (crashk_res.start != crashk_res.end)
292 request_resource(res, &crashk_res); 302 request_resource(res, &crashk_res);
@@ -307,9 +317,11 @@ static int __init request_standard_resources(void)
307 317
308 printk("Setting up standard PCI resources\n"); 318 printk("Setting up standard PCI resources\n");
309 if (efi_enabled) 319 if (efi_enabled)
310 efi_initialize_iomem_resources(&code_resource, &data_resource); 320 efi_initialize_iomem_resources(&code_resource,
321 &data_resource, &bss_resource);
311 else 322 else
312 legacy_init_iomem_resources(&code_resource, &data_resource); 323 legacy_init_iomem_resources(&code_resource,
324 &data_resource, &bss_resource);
313 325
314 /* EFI systems may still have VGA */ 326 /* EFI systems may still have VGA */
315 request_resource(&iomem_resource, &video_ram_resource); 327 request_resource(&iomem_resource, &video_ram_resource);
diff --git a/arch/x86/kernel/e820_64.c b/arch/x86/kernel/e820_64.c
index 57616865d8a0..04698e0b056c 100644
--- a/arch/x86/kernel/e820_64.c
+++ b/arch/x86/kernel/e820_64.c
@@ -47,7 +47,7 @@ unsigned long end_pfn_map;
47 */ 47 */
48static unsigned long __initdata end_user_pfn = MAXMEM>>PAGE_SHIFT; 48static unsigned long __initdata end_user_pfn = MAXMEM>>PAGE_SHIFT;
49 49
50extern struct resource code_resource, data_resource; 50extern struct resource code_resource, data_resource, bss_resource;
51 51
52/* Check for some hardcoded bad areas that early boot is not allowed to touch */ 52/* Check for some hardcoded bad areas that early boot is not allowed to touch */
53static inline int bad_addr(unsigned long *addrp, unsigned long size) 53static inline int bad_addr(unsigned long *addrp, unsigned long size)
@@ -225,6 +225,7 @@ void __init e820_reserve_resources(void)
225 */ 225 */
226 request_resource(res, &code_resource); 226 request_resource(res, &code_resource);
227 request_resource(res, &data_resource); 227 request_resource(res, &data_resource);
228 request_resource(res, &bss_resource);
228#ifdef CONFIG_KEXEC 229#ifdef CONFIG_KEXEC
229 if (crashk_res.start != crashk_res.end) 230 if (crashk_res.start != crashk_res.end)
230 request_resource(res, &crashk_res); 231 request_resource(res, &crashk_res);
@@ -729,3 +730,22 @@ __init void e820_setup_gap(void)
729 printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n", 730 printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
730 pci_mem_start, gapstart, gapsize); 731 pci_mem_start, gapstart, gapsize);
731} 732}
733
734int __init arch_get_ram_range(int slot, u64 *addr, u64 *size)
735{
736 int i;
737
738 if (slot < 0 || slot >= e820.nr_map)
739 return -1;
740 for (i = slot; i < e820.nr_map; i++) {
741 if (e820.map[i].type != E820_RAM)
742 continue;
743 break;
744 }
745 if (i == e820.nr_map || e820.map[i].addr > (max_pfn << PAGE_SHIFT))
746 return -1;
747 *addr = e820.map[i].addr;
748 *size = min_t(u64, e820.map[i].size + e820.map[i].addr,
749 max_pfn << PAGE_SHIFT) - *addr;
750 return i + 1;
751}
diff --git a/arch/x86/kernel/efi_32.c b/arch/x86/kernel/efi_32.c
index b42558c48e9d..e2be78f49399 100644
--- a/arch/x86/kernel/efi_32.c
+++ b/arch/x86/kernel/efi_32.c
@@ -603,7 +603,8 @@ void __init efi_enter_virtual_mode(void)
603 603
604void __init 604void __init
605efi_initialize_iomem_resources(struct resource *code_resource, 605efi_initialize_iomem_resources(struct resource *code_resource,
606 struct resource *data_resource) 606 struct resource *data_resource,
607 struct resource *bss_resource)
607{ 608{
608 struct resource *res; 609 struct resource *res;
609 efi_memory_desc_t *md; 610 efi_memory_desc_t *md;
@@ -675,6 +676,7 @@ efi_initialize_iomem_resources(struct resource *code_resource,
675 if (md->type == EFI_CONVENTIONAL_MEMORY) { 676 if (md->type == EFI_CONVENTIONAL_MEMORY) {
676 request_resource(res, code_resource); 677 request_resource(res, code_resource);
677 request_resource(res, data_resource); 678 request_resource(res, data_resource);
679 request_resource(res, bss_resource);
678#ifdef CONFIG_KEXEC 680#ifdef CONFIG_KEXEC
679 request_resource(res, &crashk_res); 681 request_resource(res, &crashk_res);
680#endif 682#endif
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index 39677965e161..00b1c2c56454 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -79,22 +79,30 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_
79 */ 79 */
80.section .text.head,"ax",@progbits 80.section .text.head,"ax",@progbits
81ENTRY(startup_32) 81ENTRY(startup_32)
82 /* check to see if KEEP_SEGMENTS flag is meaningful */
83 cmpw $0x207, BP_version(%esi)
84 jb 1f
85
86 /* test KEEP_SEGMENTS flag to see if the bootloader is asking
87 us to not reload segments */
88 testb $(1<<6), BP_loadflags(%esi)
89 jnz 2f
82 90
83/* 91/*
84 * Set segments to known values. 92 * Set segments to known values.
85 */ 93 */
86 cld 941: lgdt boot_gdt_descr - __PAGE_OFFSET
87 lgdt boot_gdt_descr - __PAGE_OFFSET
88 movl $(__BOOT_DS),%eax 95 movl $(__BOOT_DS),%eax
89 movl %eax,%ds 96 movl %eax,%ds
90 movl %eax,%es 97 movl %eax,%es
91 movl %eax,%fs 98 movl %eax,%fs
92 movl %eax,%gs 99 movl %eax,%gs
1002:
93 101
94/* 102/*
95 * Clear BSS first so that there are no surprises... 103 * Clear BSS first so that there are no surprises...
96 * No need to cld as DF is already clear from cld above...
97 */ 104 */
105 cld
98 xorl %eax,%eax 106 xorl %eax,%eax
99 movl $__bss_start - __PAGE_OFFSET,%edi 107 movl $__bss_start - __PAGE_OFFSET,%edi
100 movl $__bss_stop - __PAGE_OFFSET,%ecx 108 movl $__bss_stop - __PAGE_OFFSET,%ecx
@@ -128,6 +136,35 @@ ENTRY(startup_32)
128 movsl 136 movsl
1291: 1371:
130 138
139#ifdef CONFIG_PARAVIRT
140 cmpw $0x207, (boot_params + BP_version - __PAGE_OFFSET)
141 jb default_entry
142
143 /* Paravirt-compatible boot parameters. Look to see what architecture
144 we're booting under. */
145 movl (boot_params + BP_hardware_subarch - __PAGE_OFFSET), %eax
146 cmpl $num_subarch_entries, %eax
147 jae bad_subarch
148
149 movl subarch_entries - __PAGE_OFFSET(,%eax,4), %eax
150 subl $__PAGE_OFFSET, %eax
151 jmp *%eax
152
153bad_subarch:
154WEAK(lguest_entry)
155WEAK(xen_entry)
156 /* Unknown implementation; there's really
157 nothing we can do at this point. */
158 ud2a
159.data
160subarch_entries:
161 .long default_entry /* normal x86/PC */
162 .long lguest_entry /* lguest hypervisor */
163 .long xen_entry /* Xen hypervisor */
164num_subarch_entries = (. - subarch_entries) / 4
165.previous
166#endif /* CONFIG_PARAVIRT */
167
131/* 168/*
132 * Initialize page tables. This creates a PDE and a set of page 169 * Initialize page tables. This creates a PDE and a set of page
133 * tables, which are located immediately beyond _end. The variable 170 * tables, which are located immediately beyond _end. The variable
@@ -140,6 +177,7 @@ ENTRY(startup_32)
140 */ 177 */
141page_pde_offset = (__PAGE_OFFSET >> 20); 178page_pde_offset = (__PAGE_OFFSET >> 20);
142 179
180default_entry:
143 movl $(pg0 - __PAGE_OFFSET), %edi 181 movl $(pg0 - __PAGE_OFFSET), %edi
144 movl $(swapper_pg_dir - __PAGE_OFFSET), %edx 182 movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
145 movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */ 183 movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c
index b3c2d268d708..953328b55a30 100644
--- a/arch/x86/kernel/io_apic_64.c
+++ b/arch/x86/kernel/io_apic_64.c
@@ -31,6 +31,7 @@
31#include <linux/sysdev.h> 31#include <linux/sysdev.h>
32#include <linux/msi.h> 32#include <linux/msi.h>
33#include <linux/htirq.h> 33#include <linux/htirq.h>
34#include <linux/dmar.h>
34#ifdef CONFIG_ACPI 35#ifdef CONFIG_ACPI
35#include <acpi/acpi_bus.h> 36#include <acpi/acpi_bus.h>
36#endif 37#endif
@@ -2031,8 +2032,64 @@ void arch_teardown_msi_irq(unsigned int irq)
2031 destroy_irq(irq); 2032 destroy_irq(irq);
2032} 2033}
2033 2034
2034#endif /* CONFIG_PCI_MSI */ 2035#ifdef CONFIG_DMAR
2036#ifdef CONFIG_SMP
2037static void dmar_msi_set_affinity(unsigned int irq, cpumask_t mask)
2038{
2039 struct irq_cfg *cfg = irq_cfg + irq;
2040 struct msi_msg msg;
2041 unsigned int dest;
2042 cpumask_t tmp;
2043
2044 cpus_and(tmp, mask, cpu_online_map);
2045 if (cpus_empty(tmp))
2046 return;
2047
2048 if (assign_irq_vector(irq, mask))
2049 return;
2050
2051 cpus_and(tmp, cfg->domain, mask);
2052 dest = cpu_mask_to_apicid(tmp);
2053
2054 dmar_msi_read(irq, &msg);
2055
2056 msg.data &= ~MSI_DATA_VECTOR_MASK;
2057 msg.data |= MSI_DATA_VECTOR(cfg->vector);
2058 msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
2059 msg.address_lo |= MSI_ADDR_DEST_ID(dest);
2060
2061 dmar_msi_write(irq, &msg);
2062 irq_desc[irq].affinity = mask;
2063}
2064#endif /* CONFIG_SMP */
2065
2066struct irq_chip dmar_msi_type = {
2067 .name = "DMAR_MSI",
2068 .unmask = dmar_msi_unmask,
2069 .mask = dmar_msi_mask,
2070 .ack = ack_apic_edge,
2071#ifdef CONFIG_SMP
2072 .set_affinity = dmar_msi_set_affinity,
2073#endif
2074 .retrigger = ioapic_retrigger_irq,
2075};
2076
2077int arch_setup_dmar_msi(unsigned int irq)
2078{
2079 int ret;
2080 struct msi_msg msg;
2081
2082 ret = msi_compose_msg(NULL, irq, &msg);
2083 if (ret < 0)
2084 return ret;
2085 dmar_msi_write(irq, &msg);
2086 set_irq_chip_and_handler_name(irq, &dmar_msi_type, handle_edge_irq,
2087 "edge");
2088 return 0;
2089}
2090#endif
2035 2091
2092#endif /* CONFIG_PCI_MSI */
2036/* 2093/*
2037 * Hypertransport interrupt support 2094 * Hypertransport interrupt support
2038 */ 2095 */
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 5098f58063a5..1a20fe31338b 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -411,8 +411,10 @@ static int calgary_nontranslate_map_sg(struct device* dev,
411 int i; 411 int i;
412 412
413 for_each_sg(sg, s, nelems, i) { 413 for_each_sg(sg, s, nelems, i) {
414 BUG_ON(!s->page); 414 struct page *p = sg_page(s);
415 s->dma_address = virt_to_bus(page_address(s->page) +s->offset); 415
416 BUG_ON(!p);
417 s->dma_address = virt_to_bus(sg_virt(s));
416 s->dma_length = s->length; 418 s->dma_length = s->length;
417 } 419 }
418 return nelems; 420 return nelems;
@@ -432,9 +434,9 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
432 return calgary_nontranslate_map_sg(dev, sg, nelems, direction); 434 return calgary_nontranslate_map_sg(dev, sg, nelems, direction);
433 435
434 for_each_sg(sg, s, nelems, i) { 436 for_each_sg(sg, s, nelems, i) {
435 BUG_ON(!s->page); 437 BUG_ON(!sg_page(s));
436 438
437 vaddr = (unsigned long)page_address(s->page) + s->offset; 439 vaddr = (unsigned long) sg_virt(s);
438 npages = num_dma_pages(vaddr, s->length); 440 npages = num_dma_pages(vaddr, s->length);
439 441
440 entry = iommu_range_alloc(tbl, npages); 442 entry = iommu_range_alloc(tbl, npages);
diff --git a/arch/x86/kernel/pci-dma_64.c b/arch/x86/kernel/pci-dma_64.c
index afaf9f12c032..393e2725a6e3 100644
--- a/arch/x86/kernel/pci-dma_64.c
+++ b/arch/x86/kernel/pci-dma_64.c
@@ -7,6 +7,7 @@
7#include <linux/string.h> 7#include <linux/string.h>
8#include <linux/pci.h> 8#include <linux/pci.h>
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/dmar.h>
10#include <asm/io.h> 11#include <asm/io.h>
11#include <asm/iommu.h> 12#include <asm/iommu.h>
12#include <asm/calgary.h> 13#include <asm/calgary.h>
@@ -305,6 +306,8 @@ void __init pci_iommu_alloc(void)
305 detect_calgary(); 306 detect_calgary();
306#endif 307#endif
307 308
309 detect_intel_iommu();
310
308#ifdef CONFIG_SWIOTLB 311#ifdef CONFIG_SWIOTLB
309 pci_swiotlb_init(); 312 pci_swiotlb_init();
310#endif 313#endif
@@ -316,6 +319,8 @@ static int __init pci_iommu_init(void)
316 calgary_iommu_init(); 319 calgary_iommu_init();
317#endif 320#endif
318 321
322 intel_iommu_init();
323
319#ifdef CONFIG_IOMMU 324#ifdef CONFIG_IOMMU
320 gart_iommu_init(); 325 gart_iommu_init();
321#endif 326#endif
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index 5cdfab65e93f..c56e9ee64964 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -302,7 +302,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
302#endif 302#endif
303 303
304 for_each_sg(sg, s, nents, i) { 304 for_each_sg(sg, s, nents, i) {
305 unsigned long addr = page_to_phys(s->page) + s->offset; 305 unsigned long addr = sg_phys(s);
306 if (nonforced_iommu(dev, addr, s->length)) { 306 if (nonforced_iommu(dev, addr, s->length)) {
307 addr = dma_map_area(dev, addr, s->length, dir); 307 addr = dma_map_area(dev, addr, s->length, dir);
308 if (addr == bad_dma_address) { 308 if (addr == bad_dma_address) {
@@ -397,7 +397,7 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
397 start_sg = sgmap = sg; 397 start_sg = sgmap = sg;
398 ps = NULL; /* shut up gcc */ 398 ps = NULL; /* shut up gcc */
399 for_each_sg(sg, s, nents, i) { 399 for_each_sg(sg, s, nents, i) {
400 dma_addr_t addr = page_to_phys(s->page) + s->offset; 400 dma_addr_t addr = sg_phys(s);
401 s->dma_address = addr; 401 s->dma_address = addr;
402 BUG_ON(s->length == 0); 402 BUG_ON(s->length == 0);
403 403
diff --git a/arch/x86/kernel/pci-nommu_64.c b/arch/x86/kernel/pci-nommu_64.c
index e85d4360360c..faf70bdca335 100644
--- a/arch/x86/kernel/pci-nommu_64.c
+++ b/arch/x86/kernel/pci-nommu_64.c
@@ -62,8 +62,8 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
62 int i; 62 int i;
63 63
64 for_each_sg(sg, s, nents, i) { 64 for_each_sg(sg, s, nents, i) {
65 BUG_ON(!s->page); 65 BUG_ON(!sg_page(s));
66 s->dma_address = virt_to_bus(page_address(s->page) +s->offset); 66 s->dma_address = virt_to_bus(sg_virt(s));
67 if (!check_addr("map_sg", hwdev, s->dma_address, s->length)) 67 if (!check_addr("map_sg", hwdev, s->dma_address, s->length))
68 return 0; 68 return 0;
69 s->dma_length = s->length; 69 s->dma_length = s->length;
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c
index ba2e165a8a0f..cc0e91447b76 100644
--- a/arch/x86/kernel/setup_32.c
+++ b/arch/x86/kernel/setup_32.c
@@ -60,6 +60,7 @@
60#include <asm/vmi.h> 60#include <asm/vmi.h>
61#include <setup_arch.h> 61#include <setup_arch.h>
62#include <bios_ebda.h> 62#include <bios_ebda.h>
63#include <asm/cacheflush.h>
63 64
64/* This value is set up by the early boot code to point to the value 65/* This value is set up by the early boot code to point to the value
65 immediately after the boot time page tables. It contains a *physical* 66 immediately after the boot time page tables. It contains a *physical*
@@ -73,6 +74,7 @@ int disable_pse __devinitdata = 0;
73 */ 74 */
74extern struct resource code_resource; 75extern struct resource code_resource;
75extern struct resource data_resource; 76extern struct resource data_resource;
77extern struct resource bss_resource;
76 78
77/* cpu data as detected by the assembly code in head.S */ 79/* cpu data as detected by the assembly code in head.S */
78struct cpuinfo_x86 new_cpu_data __cpuinitdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; 80struct cpuinfo_x86 new_cpu_data __cpuinitdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
@@ -600,6 +602,8 @@ void __init setup_arch(char **cmdline_p)
600 code_resource.end = virt_to_phys(_etext)-1; 602 code_resource.end = virt_to_phys(_etext)-1;
601 data_resource.start = virt_to_phys(_etext); 603 data_resource.start = virt_to_phys(_etext);
602 data_resource.end = virt_to_phys(_edata)-1; 604 data_resource.end = virt_to_phys(_edata)-1;
605 bss_resource.start = virt_to_phys(&__bss_start);
606 bss_resource.end = virt_to_phys(&__bss_stop)-1;
603 607
604 parse_early_param(); 608 parse_early_param();
605 609
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c
index 31322d42eaae..e7a9e36bd52d 100644
--- a/arch/x86/kernel/setup_64.c
+++ b/arch/x86/kernel/setup_64.c
@@ -58,6 +58,7 @@
58#include <asm/numa.h> 58#include <asm/numa.h>
59#include <asm/sections.h> 59#include <asm/sections.h>
60#include <asm/dmi.h> 60#include <asm/dmi.h>
61#include <asm/cacheflush.h>
61 62
62/* 63/*
63 * Machine setup.. 64 * Machine setup..
@@ -133,6 +134,12 @@ struct resource code_resource = {
133 .end = 0, 134 .end = 0,
134 .flags = IORESOURCE_RAM, 135 .flags = IORESOURCE_RAM,
135}; 136};
137struct resource bss_resource = {
138 .name = "Kernel bss",
139 .start = 0,
140 .end = 0,
141 .flags = IORESOURCE_RAM,
142};
136 143
137#ifdef CONFIG_PROC_VMCORE 144#ifdef CONFIG_PROC_VMCORE
138/* elfcorehdr= specifies the location of elf core header 145/* elfcorehdr= specifies the location of elf core header
@@ -276,6 +283,8 @@ void __init setup_arch(char **cmdline_p)
276 code_resource.end = virt_to_phys(&_etext)-1; 283 code_resource.end = virt_to_phys(&_etext)-1;
277 data_resource.start = virt_to_phys(&_etext); 284 data_resource.start = virt_to_phys(&_etext);
278 data_resource.end = virt_to_phys(&_edata)-1; 285 data_resource.end = virt_to_phys(&_edata)-1;
286 bss_resource.start = virt_to_phys(&__bss_start);
287 bss_resource.end = virt_to_phys(&__bss_stop)-1;
279 288
280 early_identify_cpu(&boot_cpu_data); 289 early_identify_cpu(&boot_cpu_data);
281 290
diff --git a/arch/x86/mm/pageattr_64.c b/arch/x86/mm/pageattr_64.c
index c7b7dfe1d405..c40afbaaf93d 100644
--- a/arch/x86/mm/pageattr_64.c
+++ b/arch/x86/mm/pageattr_64.c
@@ -61,10 +61,10 @@ static struct page *split_large_page(unsigned long address, pgprot_t prot,
61 return base; 61 return base;
62} 62}
63 63
64static void cache_flush_page(void *adr) 64void clflush_cache_range(void *adr, int size)
65{ 65{
66 int i; 66 int i;
67 for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size) 67 for (i = 0; i < size; i += boot_cpu_data.x86_clflush_size)
68 clflush(adr+i); 68 clflush(adr+i);
69} 69}
70 70
@@ -80,7 +80,7 @@ static void flush_kernel_map(void *arg)
80 asm volatile("wbinvd" ::: "memory"); 80 asm volatile("wbinvd" ::: "memory");
81 else list_for_each_entry(pg, l, lru) { 81 else list_for_each_entry(pg, l, lru) {
82 void *adr = page_address(pg); 82 void *adr = page_address(pg);
83 cache_flush_page(adr); 83 clflush_cache_range(adr, PAGE_SIZE);
84 } 84 }
85 __flush_tlb_all(); 85 __flush_tlb_all();
86} 86}
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index aab25f3ba3ce..c2d24991bb2b 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -750,6 +750,38 @@ config PCI_DOMAINS
750 depends on PCI 750 depends on PCI
751 default y 751 default y
752 752
753config DMAR
754 bool "Support for DMA Remapping Devices (EXPERIMENTAL)"
755 depends on PCI_MSI && ACPI && EXPERIMENTAL
756 default y
757 help
758 DMA remapping (DMAR) devices support enables independent address
759 translations for Direct Memory Access (DMA) from devices.
760 These DMA remapping devices are reported via ACPI tables
761 and include PCI device scope covered by these DMA
762 remapping devices.
763
764config DMAR_GFX_WA
765 bool "Support for Graphics workaround"
766 depends on DMAR
767 default y
768 help
769 Current Graphics drivers tend to use physical address
770 for DMA and avoid using DMA APIs. Setting this config
771 option permits the IOMMU driver to set a unity map for
772 all the OS-visible memory. Hence the driver can continue
773 to use physical addresses for DMA.
774
775config DMAR_FLOPPY_WA
776 bool
777 depends on DMAR
778 default y
779 help
780 Floppy disk drivers are know to bypass DMA API calls
781 thereby failing to work when IOMMU is enabled. This
782 workaround will setup a 1:1 mapping for the first
783 16M to make floppy (an ISA device) work.
784
753source "drivers/pci/pcie/Kconfig" 785source "drivers/pci/pcie/Kconfig"
754 786
755source "drivers/pci/Kconfig" 787source "drivers/pci/Kconfig"