aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/boot/compressed/head.S46
-rw-r--r--arch/arm/common/rtctime.c15
-rw-r--r--arch/arm/configs/at91rm9200dk_defconfig1009
-rw-r--r--arch/arm/configs/at91rm9200ek_defconfig998
-rw-r--r--arch/arm/configs/csb337_defconfig1136
-rw-r--r--arch/arm/configs/csb637_defconfig1116
-rw-r--r--arch/arm/kernel/ecard.c7
-rw-r--r--arch/arm/kernel/fiq.c4
-rw-r--r--arch/arm/kernel/setup.c15
-rw-r--r--arch/arm/lib/csumpartialcopy.S6
-rw-r--r--arch/arm/lib/csumpartialcopygeneric.S6
-rw-r--r--arch/arm/lib/csumpartialcopyuser.S8
-rw-r--r--arch/arm/mach-aaec2000/clock.c15
-rw-r--r--arch/arm/mach-at91rm9200/Makefile8
-rw-r--r--arch/arm/mach-at91rm9200/board-csb337.c143
-rw-r--r--arch/arm/mach-at91rm9200/board-csb637.c116
-rw-r--r--arch/arm/mach-at91rm9200/board-dk.c138
-rw-r--r--arch/arm/mach-at91rm9200/board-ek.c131
-rw-r--r--arch/arm/mach-integrator/clock.c15
-rw-r--r--arch/arm/mach-pxa/ssp.c17
-rw-r--r--arch/arm/mach-realview/clock.c15
-rw-r--r--arch/arm/mach-s3c2410/clock.c11
-rw-r--r--arch/arm/mach-versatile/clock.c15
-rw-r--r--arch/arm/mm/consistent.c53
-rw-r--r--arch/arm/plat-omap/clock.c15
-rw-r--r--arch/powerpc/kernel/Makefile6
-rw-r--r--arch/powerpc/kernel/pci_64.c5
-rw-r--r--arch/powerpc/kernel/process.c8
-rw-r--r--arch/powerpc/kernel/prom.c28
-rw-r--r--arch/powerpc/kernel/prom_init.c8
-rw-r--r--arch/powerpc/kernel/signal_32.c21
-rw-r--r--arch/powerpc/kernel/signal_64.c20
-rw-r--r--arch/powerpc/platforms/cell/pervasive.c2
-rw-r--r--arch/powerpc/platforms/cell/setup.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/syscalls.c4
-rw-r--r--arch/powerpc/platforms/iseries/Makefile4
-rw-r--r--arch/powerpc/platforms/iseries/iommu.c2
-rw-r--r--arch/powerpc/platforms/iseries/iommu.h35
-rw-r--r--arch/powerpc/platforms/iseries/irq.c19
-rw-r--r--arch/powerpc/platforms/iseries/lpardata.c5
-rw-r--r--arch/powerpc/platforms/iseries/lpevents.c12
-rw-r--r--arch/powerpc/platforms/iseries/mf.c16
-rw-r--r--arch/powerpc/platforms/iseries/pci.c1
-rw-r--r--arch/powerpc/platforms/iseries/vio.c2
-rw-r--r--arch/powerpc/platforms/iseries/viopath.c12
-rw-r--r--arch/powerpc/platforms/powermac/setup.c2
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c5
-rw-r--r--arch/powerpc/platforms/pseries/hvcserver.c4
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c2
-rw-r--r--arch/powerpc/platforms/pseries/scanlog.c4
-rw-r--r--arch/powerpc/platforms/pseries/setup.c2
-rw-r--r--arch/powerpc/platforms/pseries/smp.c4
-rw-r--r--arch/powerpc/platforms/pseries/xics.c2
-rw-r--r--arch/powerpc/sysdev/dart_iommu.c1
-rw-r--r--arch/powerpc/xmon/xmon.c14
-rw-r--r--arch/ppc/kernel/Makefile1
-rw-r--r--arch/ppc/kernel/process.c851
-rw-r--r--drivers/block/viodasd.c32
-rw-r--r--drivers/cdrom/viocd.c6
-rw-r--r--drivers/char/drm/Makefile4
-rw-r--r--drivers/char/drm/ati_pcigart.c23
-rw-r--r--drivers/char/drm/drm.h4
-rw-r--r--drivers/char/drm/drmP.h122
-rw-r--r--drivers/char/drm/drm_agpsupport.c133
-rw-r--r--drivers/char/drm/drm_bufs.c49
-rw-r--r--drivers/char/drm/drm_context.c2
-rw-r--r--drivers/char/drm/drm_core.h4
-rw-r--r--drivers/char/drm/drm_drv.c152
-rw-r--r--drivers/char/drm/drm_fops.c317
-rw-r--r--drivers/char/drm/drm_init.c53
-rw-r--r--drivers/char/drm/drm_ioctl.c27
-rw-r--r--drivers/char/drm/drm_lock.c1
-rw-r--r--drivers/char/drm/drm_memory.c8
-rw-r--r--drivers/char/drm/drm_memory_debug.h269
-rw-r--r--drivers/char/drm/drm_os_linux.h1
-rw-r--r--drivers/char/drm/drm_pciids.h12
-rw-r--r--drivers/char/drm/drm_proc.c16
-rw-r--r--drivers/char/drm/drm_stub.c63
-rw-r--r--drivers/char/drm/drm_sysfs.c68
-rw-r--r--drivers/char/drm/i810_dma.c49
-rw-r--r--drivers/char/drm/i810_drv.c60
-rw-r--r--drivers/char/drm/i810_drv.h10
-rw-r--r--drivers/char/drm/i830_dma.c47
-rw-r--r--drivers/char/drm/i830_drv.c57
-rw-r--r--drivers/char/drm/i830_drv.h8
-rw-r--r--drivers/char/drm/i915_dma.c52
-rw-r--r--drivers/char/drm/i915_drm.h6
-rw-r--r--drivers/char/drm/i915_drv.c66
-rw-r--r--drivers/char/drm/i915_drv.h44
-rw-r--r--drivers/char/drm/i915_irq.c48
-rw-r--r--drivers/char/drm/i915_mem.c5
-rw-r--r--drivers/char/drm/mga_dma.c158
-rw-r--r--drivers/char/drm/mga_drv.c58
-rw-r--r--drivers/char/drm/mga_drv.h14
-rw-r--r--drivers/char/drm/mga_state.c26
-rw-r--r--drivers/char/drm/r128_cce.c15
-rw-r--r--drivers/char/drm/r128_drm.h4
-rw-r--r--drivers/char/drm/r128_drv.c48
-rw-r--r--drivers/char/drm/r128_drv.h8
-rw-r--r--drivers/char/drm/r128_irq.c4
-rw-r--r--drivers/char/drm/r128_state.c42
-rw-r--r--drivers/char/drm/r300_cmdbuf.c38
-rw-r--r--drivers/char/drm/r300_reg.h1
-rw-r--r--drivers/char/drm/radeon_cp.c106
-rw-r--r--drivers/char/drm/radeon_drm.h6
-rw-r--r--drivers/char/drm/radeon_drv.c62
-rw-r--r--drivers/char/drm/radeon_drv.h41
-rw-r--r--drivers/char/drm/radeon_state.c246
-rw-r--r--drivers/char/drm/savage_bci.c81
-rw-r--r--drivers/char/drm/savage_drv.c50
-rw-r--r--drivers/char/drm/savage_drv.h29
-rw-r--r--drivers/char/drm/savage_state.c324
-rw-r--r--drivers/char/drm/sis_drm.h25
-rw-r--r--drivers/char/drm/sis_drv.c42
-rw-r--r--drivers/char/drm/sis_drv.h4
-rw-r--r--drivers/char/drm/sis_ds.h7
-rw-r--r--drivers/char/drm/sis_mm.c30
-rw-r--r--drivers/char/drm/tdfx_drv.c42
-rw-r--r--drivers/char/drm/tdfx_drv.h7
-rw-r--r--drivers/char/drm/via_dma.c38
-rw-r--r--drivers/char/drm/via_dmablit.c805
-rw-r--r--drivers/char/drm/via_dmablit.h140
-rw-r--r--drivers/char/drm/via_drm.h60
-rw-r--r--drivers/char/drm/via_drv.c63
-rw-r--r--drivers/char/drm/via_drv.h56
-rw-r--r--drivers/char/drm/via_ds.c9
-rw-r--r--drivers/char/drm/via_irq.c53
-rw-r--r--drivers/char/drm/via_map.c47
-rw-r--r--drivers/char/drm/via_mm.c20
-rw-r--r--drivers/char/drm/via_verifier.c6
-rw-r--r--drivers/char/drm/via_verifier.h4
-rw-r--r--drivers/char/drm/via_video.c7
-rw-r--r--drivers/char/mem.c8
-rw-r--r--drivers/char/viocons.c31
-rw-r--r--drivers/i2c/busses/i2c-pxa.c10
-rw-r--r--drivers/ide/ide-io.c34
-rw-r--r--drivers/ide/ide-probe.c2
-rw-r--r--drivers/mfd/ucb1x00-core.c27
-rw-r--r--drivers/mmc/mmc_block.c11
-rw-r--r--drivers/net/iseries_veth.c4
-rw-r--r--drivers/pcmcia/pxa2xx_mainstone.c15
-rw-r--r--drivers/pcmcia/pxa2xx_sharpsl.c19
-rw-r--r--drivers/serial/8250.c11
-rw-r--r--drivers/serial/Kconfig34
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/at91_serial.c894
-rw-r--r--drivers/serial/crisv10.c11
-rw-r--r--drivers/serial/pmac_zilog.c23
-rw-r--r--drivers/serial/serial_core.c15
-rw-r--r--drivers/serial/serial_txx9.c11
-rw-r--r--include/asm-arm/arch-at91rm9200/at91rm9200_pdc.h36
-rw-r--r--include/asm-arm/arch-at91rm9200/at91rm9200_usart.h123
-rw-r--r--include/asm-arm/byteorder.h11
-rw-r--r--include/asm-arm/mach/serial_at91rm9200.h36
-rw-r--r--include/asm-arm/memory.h9
-rw-r--r--include/asm-powerpc/iommu.h19
-rw-r--r--include/asm-powerpc/iseries/hv_call.h4
-rw-r--r--include/asm-powerpc/iseries/hv_call_event.h134
-rw-r--r--include/asm-powerpc/iseries/hv_call_sc.h1
-rw-r--r--include/asm-powerpc/iseries/hv_lp_config.h1
-rw-r--r--include/asm-powerpc/iseries/hv_lp_event.h42
-rw-r--r--include/asm-powerpc/iseries/hv_types.h1
-rw-r--r--include/asm-powerpc/iseries/iseries_io.h14
-rw-r--r--include/asm-powerpc/iseries/it_exp_vpd_panel.h1
-rw-r--r--include/asm-powerpc/iseries/it_lp_naca.h22
-rw-r--r--include/asm-powerpc/iseries/it_lp_queue.h1
-rw-r--r--include/asm-powerpc/iseries/it_lp_reg_save.h3
-rw-r--r--include/asm-powerpc/iseries/lpar_map.h1
-rw-r--r--include/asm-powerpc/iseries/mf.h1
-rw-r--r--include/asm-powerpc/iseries/vio.h1
-rw-r--r--include/asm-powerpc/pci-bridge.h2
-rw-r--r--include/asm-powerpc/system.h8
-rw-r--r--include/asm-ppc/system.h12
-rw-r--r--include/linux/hrtimer.h12
-rw-r--r--include/linux/ide.h1
-rw-r--r--include/linux/ktime.h4
-rw-r--r--include/linux/serial_core.h3
-rw-r--r--kernel/hrtimer.c34
178 files changed, 9290 insertions, 3214 deletions
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 6abafb6f1844d..aaa47400eb9c1 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -84,7 +84,7 @@
kputc #'\n'
kphex r5, 8 /* decompressed kernel start */
kputc #'-'
- kphex r8, 8 /* decompressed kernel end */
+ kphex r9, 8 /* decompressed kernel end */
kputc #'>'
kphex r4, 8 /* kernel execution address */
kputc #'\n'
@@ -116,7 +116,7 @@ start:
.word start @ absolute load/run zImage address
.word _edata @ zImage end address
1: mov r7, r1 @ save architecture ID
- mov r8, #0 @ save r0
+ mov r8, r2 @ save atags pointer
#ifndef __ARM_ARCH_2__
/*
@@ -144,7 +144,7 @@ not_angel:
/*
* some architecture specific code can be inserted
- * by the linker here, but it should preserve r7 and r8.
+ * by the linker here, but it should preserve r7, r8, and r9.
*/
.text
@@ -249,16 +249,17 @@ not_relocated: mov r0, #0
* r5 = decompressed kernel start
* r6 = processor ID
* r7 = architecture ID
- * r8-r14 = unused
+ * r8 = atags pointer
+ * r9-r14 = corrupted
*/
add r1, r5, r0 @ end of decompressed kernel
adr r2, reloc_start
ldr r3, LC1
add r3, r2, r3
-1: ldmia r2!, {r8 - r13} @ copy relocation code
- stmia r1!, {r8 - r13}
- ldmia r2!, {r8 - r13}
- stmia r1!, {r8 - r13}
+1: ldmia r2!, {r9 - r14} @ copy relocation code
+ stmia r1!, {r9 - r14}
+ ldmia r2!, {r9 - r14}
+ stmia r1!, {r9 - r14}
cmp r2, r3
blo 1b
@@ -308,11 +309,12 @@ params: ldr r0, =params_phys
* r4 = kernel execution address
* r6 = processor ID
* r7 = architecture number
- * r8 = run-time address of "start"
+ * r8 = atags pointer
+ * r9 = run-time address of "start" (???)
* On exit,
- * r1, r2, r3, r8, r9, r12 corrupted
+ * r1, r2, r3, r9, r10, r12 corrupted
* This routine must preserve:
- * r4, r5, r6, r7
+ * r4, r5, r6, r7, r8
*/
.align 5
cache_on: mov r3, #8 @ cache_on function
@@ -326,15 +328,15 @@ __setup_mmu: sub r3, r4, #16384 @ Page directory size
* bits for the RAM area only.
*/
mov r0, r3
- mov r8, r0, lsr #18
- mov r8, r8, lsl #18 @ start of RAM
- add r9, r8, #0x10000000 @ a reasonable RAM size
+ mov r9, r0, lsr #18
+ mov r9, r9, lsl #18 @ start of RAM
+ add r10, r9, #0x10000000 @ a reasonable RAM size
mov r1, #0x12
orr r1, r1, #3 << 10
add r2, r3, #16384
1: cmp r1, r8 @ if virt > start of RAM
orrhs r1, r1, #0x0c @ set cacheable, bufferable
- cmp r1, r9 @ if virt > end of RAM
+ cmp r1, r10 @ if virt > end of RAM
bichs r1, r1, #0x0c @ clear cacheable, bufferable
str r1, [r0], #4 @ 1:1 mapping
add r1, r1, #1048576
@@ -403,26 +405,28 @@ __common_cache_on:
* r5 = decompressed kernel start
* r6 = processor ID
* r7 = architecture ID
- * r8-r14 = unused
+ * r8 = atags pointer
+ * r9-r14 = corrupted
*/
.align 5
-reloc_start: add r8, r5, r0
+reloc_start: add r9, r5, r0
debug_reloc_start
mov r1, r4
1:
.rept 4
- ldmia r5!, {r0, r2, r3, r9 - r13} @ relocate kernel
- stmia r1!, {r0, r2, r3, r9 - r13}
+ ldmia r5!, {r0, r2, r3, r10 - r14} @ relocate kernel
+ stmia r1!, {r0, r2, r3, r10 - r14}
.endr
- cmp r5, r8
+ cmp r5, r9
blo 1b
debug_reloc_end
call_kernel: bl cache_clean_flush
bl cache_off
- mov r0, #0
+ mov r0, #0 @ must be zero
mov r1, r7 @ restore architecture number
+ mov r2, r8 @ restore atags pointer
mov pc, r4 @ call kernel
/*
diff --git a/arch/arm/common/rtctime.c b/arch/arm/common/rtctime.c
index ffb82d5bedefa..48b1e19b131f9 100644
--- a/arch/arm/common/rtctime.c
+++ b/arch/arm/common/rtctime.c
@@ -19,6 +19,7 @@
#include <linux/spinlock.h>
#include <linux/capability.h>
#include <linux/device.h>
+#include <linux/mutex.h>
#include <asm/rtc.h>
#include <asm/semaphore.h>
@@ -35,7 +36,7 @@ static unsigned long rtc_irq_data;
/*
* rtc_sem protects rtc_inuse and rtc_ops
*/
-static DECLARE_MUTEX(rtc_sem);
+static DEFINE_MUTEX(rtc_mutex);
static unsigned long rtc_inuse;
static struct rtc_ops *rtc_ops;
@@ -356,7 +357,7 @@ static int rtc_open(struct inode *inode, struct file *file)
{
int ret;
- down(&rtc_sem);
+ mutex_lock(&rtc_mutex);
if (rtc_inuse) {
ret = -EBUSY;
@@ -374,7 +375,7 @@ static int rtc_open(struct inode *inode, struct file *file)
rtc_inuse = 1;
}
}
- up(&rtc_sem);
+ mutex_unlock(&rtc_mutex);
return ret;
}
@@ -480,7 +481,7 @@ int register_rtc(struct rtc_ops *ops)
{
int ret = -EBUSY;
- down(&rtc_sem);
+ mutex_lock(&rtc_mutex);
if (rtc_ops == NULL) {
rtc_ops = ops;
@@ -489,7 +490,7 @@ int register_rtc(struct rtc_ops *ops)
create_proc_read_entry("driver/rtc", 0, NULL,
rtc_read_proc, ops);
}
- up(&rtc_sem);
+ mutex_unlock(&rtc_mutex);
return ret;
}
@@ -497,12 +498,12 @@ EXPORT_SYMBOL(register_rtc);
void unregister_rtc(struct rtc_ops *rtc)
{
- down(&rtc_sem);
+ mutex_lock(&rtc_mutex);
if (rtc == rtc_ops) {
remove_proc_entry("driver/rtc", NULL);
misc_deregister(&rtc_miscdev);
rtc_ops = NULL;
}
- up(&rtc_sem);
+ mutex_unlock(&rtc_mutex);
}
EXPORT_SYMBOL(unregister_rtc);
diff --git a/arch/arm/configs/at91rm9200dk_defconfig b/arch/arm/configs/at91rm9200dk_defconfig
new file mode 100644
index 0000000000000..5cdd13acf8ff1
--- /dev/null
+++ b/arch/arm/configs/at91rm9200dk_defconfig
@@ -0,0 +1,1009 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.15
+# Mon Jan 9 20:54:30 2006
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# System Type
+#
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+CONFIG_ARCH_AT91RM9200=y
+
+#
+# AT91RM9200 Implementations
+#
+
+#
+# AT91RM9200 Board Type
+#
+CONFIG_ARCH_AT91RM9200DK=y
+# CONFIG_MACH_AT91RM9200EK is not set
+# CONFIG_MACH_CSB337 is not set
+# CONFIG_MACH_CSB637 is not set
+# CONFIG_MACH_CARMEVA is not set
+# CONFIG_MACH_KB9200 is not set
+# CONFIG_MACH_ATEB9200 is not set
+
+#
+# AT91RM9200 Feature Selections
+#
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_32v4=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+
+#
+# Bus support
+#
+CONFIG_ISA_DMA_API=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+
+#
+# PC-card bridges
+#
+CONFIG_AT91_CF=y
+
+#
+# Kernel Features
+#
+# CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+# CONFIG_LEDS_CPU is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20410000,3145728 root=/dev/ram0 rw"
+# CONFIG_XIP_KERNEL is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_AMDSTD_RETRY=0
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_XIP is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x10000000
+CONFIG_MTD_PHYSMAP_LEN=0x200000
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_AT91_DATAFLASH=y
+CONFIG_MTD_AT91_DATAFLASH_CARD=y
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_ARM_AT91_ETHER=y
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AT91=y
+CONFIG_SERIAL_AT91_CONSOLE=y
+# CONFIG_SERIAL_AT91_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AT91_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_AT91_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+CONFIG_AT91_SPI=y
+CONFIG_AT91_SPIDEV=y
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_AT91=y
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_RTC_X1205_I2C is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+# CONFIG_USB_STORAGE is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+CONFIG_USB_GADGET_AT91=y
+CONFIG_USB_AT91=y
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=y
+# CONFIG_MMC_WBSD is not set
+CONFIG_MMC_AT91RM9200=y
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_ERRORS is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
diff --git a/arch/arm/configs/at91rm9200ek_defconfig b/arch/arm/configs/at91rm9200ek_defconfig
new file mode 100644
index 0000000000000..20838ccf1da7f
--- /dev/null
+++ b/arch/arm/configs/at91rm9200ek_defconfig
@@ -0,0 +1,998 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.15
+# Mon Jan 9 20:57:31 2006
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# System Type
+#
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+CONFIG_ARCH_AT91RM9200=y
+
+#
+# AT91RM9200 Implementations
+#
+
+#
+# AT91RM9200 Board Type
+#
+# CONFIG_ARCH_AT91RM9200DK is not set
+CONFIG_MACH_AT91RM9200EK=y
+# CONFIG_MACH_CSB337 is not set
+# CONFIG_MACH_CSB637 is not set
+# CONFIG_MACH_CARMEVA is not set
+# CONFIG_MACH_KB9200 is not set
+# CONFIG_MACH_ATEB9200 is not set
+
+#
+# AT91RM9200 Feature Selections
+#
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_32v4=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+
+#
+# Bus support
+#
+CONFIG_ISA_DMA_API=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20410000,3145728 root=/dev/ram0 rw"
+# CONFIG_XIP_KERNEL is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_AMDSTD_RETRY=0
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_XIP is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x10000000
+CONFIG_MTD_PHYSMAP_LEN=0x800000
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_AT91_DATAFLASH=y
+CONFIG_MTD_AT91_DATAFLASH_CARD=y
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_ARM_AT91_ETHER=y
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AT91=y
+CONFIG_SERIAL_AT91_CONSOLE=y
+# CONFIG_SERIAL_AT91_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AT91_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_AT91_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+CONFIG_AT91_SPI=y
+CONFIG_AT91_SPIDEV=y
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_AT91=y
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_RTC_X1205_I2C is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+CONFIG_FB_S1D13XXX=y
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+# CONFIG_USB_STORAGE is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+CONFIG_USB_GADGET_AT91=y
+CONFIG_USB_AT91=y
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=y
+# CONFIG_MMC_WBSD is not set
+CONFIG_MMC_AT91RM9200=y
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_ERRORS is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
diff --git a/arch/arm/configs/csb337_defconfig b/arch/arm/configs/csb337_defconfig
new file mode 100644
index 0000000000000..885a3184830ad
--- /dev/null
+++ b/arch/arm/configs/csb337_defconfig
@@ -0,0 +1,1136 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.15
+# Mon Jan 9 21:51:31 2006
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# System Type
+#
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+CONFIG_ARCH_AT91RM9200=y
+
+#
+# AT91RM9200 Implementations
+#
+
+#
+# AT91RM9200 Board Type
+#
+# CONFIG_ARCH_AT91RM9200DK is not set
+# CONFIG_MACH_AT91RM9200EK is not set
+CONFIG_MACH_CSB337=y
+# CONFIG_MACH_CSB637 is not set
+# CONFIG_MACH_CARMEVA is not set
+# CONFIG_MACH_KB9200 is not set
+# CONFIG_MACH_ATEB9200 is not set
+
+#
+# AT91RM9200 Feature Selections
+#
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_32v4=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+
+#
+# Bus support
+#
+CONFIG_ISA_DMA_API=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+
+#
+# PC-card bridges
+#
+CONFIG_AT91_CF=y
+
+#
+# Kernel Features
+#
+# CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=32M console=ttyS0,38400 initrd=0x20410000,3145728 root=/dev/ram0 rw"
+# CONFIG_XIP_KERNEL is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_XIP is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PLATRAM is not set
+CONFIG_MTD_CSB337=y
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_AT91_DATAFLASH is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+# CONFIG_BLK_DEV_SD is not set
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_AHA152X is not set
+# CONFIG_PCMCIA_FDOMAIN is not set
+# CONFIG_PCMCIA_NINJA_SCSI is not set
+# CONFIG_PCMCIA_QLOGIC is not set
+# CONFIG_PCMCIA_SYM53C500 is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_ARM_AT91_ETHER=y
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AT91=y
+CONFIG_SERIAL_AT91_CONSOLE=y
+# CONFIG_SERIAL_AT91_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AT91_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+# CONFIG_NVRAM is not set
+CONFIG_RTC=y
+# CONFIG_AT91_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+CONFIG_AT91_SPI=y
+CONFIG_AT91_SPIDEV=y
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_AT91=y
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_RTC_X1205_I2C is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_CONSOLE=y
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRPRIME is not set
+# CONFIG_USB_SERIAL_ANYDATA is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP2101 is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+CONFIG_USB_SERIAL_FTDI_SIO=y
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+CONFIG_USB_SERIAL_KEYSPAN=y
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+CONFIG_USB_SERIAL_MCT_U232=y
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+CONFIG_USB_GADGET_AT91=y
+CONFIG_USB_AT91=y
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=y
+# CONFIG_MMC_WBSD is not set
+CONFIG_MMC_AT91RM9200=y
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_ERRORS is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
diff --git a/arch/arm/configs/csb637_defconfig b/arch/arm/configs/csb637_defconfig
new file mode 100644
index 0000000000000..95a96a5462a0c
--- /dev/null
+++ b/arch/arm/configs/csb637_defconfig
@@ -0,0 +1,1116 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.15
+# Mon Jan 9 21:52:00 2006
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# System Type
+#
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+CONFIG_ARCH_AT91RM9200=y
+
+#
+# AT91RM9200 Implementations
+#
+
+#
+# AT91RM9200 Board Type
+#
+# CONFIG_ARCH_AT91RM9200DK is not set
+# CONFIG_MACH_AT91RM9200EK is not set
+# CONFIG_MACH_CSB337 is not set
+CONFIG_MACH_CSB637=y
+# CONFIG_MACH_CARMEVA is not set
+# CONFIG_MACH_KB9200 is not set
+# CONFIG_MACH_ATEB9200 is not set
+
+#
+# AT91RM9200 Feature Selections
+#
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_32v4=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+
+#
+# Bus support
+#
+CONFIG_ISA_DMA_API=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+
+#
+# PC-card bridges
+#
+CONFIG_AT91_CF=y
+
+#
+# Kernel Features
+#
+# CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=32M console=ttyS0,38400 initrd=0x20410000,3145728 root=/dev/ram0 rw"
+# CONFIG_XIP_KERNEL is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_XIP is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PLATRAM is not set
+CONFIG_MTD_CSB637=y
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_AT91_DATAFLASH is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+# CONFIG_BLK_DEV_SD is not set
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_AHA152X is not set
+# CONFIG_PCMCIA_FDOMAIN is not set
+# CONFIG_PCMCIA_NINJA_SCSI is not set
+# CONFIG_PCMCIA_QLOGIC is not set
+# CONFIG_PCMCIA_SYM53C500 is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_ARM_AT91_ETHER=y
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AT91=y
+CONFIG_SERIAL_AT91_CONSOLE=y
+# CONFIG_SERIAL_AT91_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AT91_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+# CONFIG_NVRAM is not set
+CONFIG_RTC=y
+# CONFIG_AT91_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+CONFIG_AT91_SPI=y
+CONFIG_AT91_SPIDEV=y
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_AT91=y
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_RTC_X1205_I2C is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_CONSOLE=y
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRPRIME is not set
+# CONFIG_USB_SERIAL_ANYDATA is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP2101 is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+CONFIG_USB_SERIAL_FTDI_SIO=y
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+CONFIG_USB_SERIAL_KEYSPAN=y
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+CONFIG_USB_SERIAL_MCT_U232=y
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_ERRORS is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index dceb826bd216e..96fd91926c9bd 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -40,6 +40,7 @@
#include <linux/proc_fs.h>
#include <linux/device.h>
#include <linux/init.h>
+#include <linux/mutex.h>
#include <asm/dma.h>
#include <asm/ecard.h>
@@ -206,7 +207,7 @@ static void ecard_task_readbytes(struct ecard_request *req)
static DECLARE_WAIT_QUEUE_HEAD(ecard_wait);
static struct ecard_request *ecard_req;
-static DECLARE_MUTEX(ecard_sem);
+static DEFINE_MUTEX(ecard_mutex);
/*
* Set up the expansion card daemon's page tables.
@@ -299,7 +300,7 @@ static void ecard_call(struct ecard_request *req)
req->complete = &completion;
- down(&ecard_sem);
+ mutex_lock(&ecard_mutex);
ecard_req = req;
wake_up(&ecard_wait);
@@ -307,7 +308,7 @@ static void ecard_call(struct ecard_request *req)
* Now wait for kecardd to run.
*/
wait_for_completion(&completion);
- up(&ecard_sem);
+ mutex_unlock(&ecard_mutex);
}
/* ======================= Mid-level card control ===================== */
diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
index 9299dfc256982..1ec3f7faa259e 100644
--- a/arch/arm/kernel/fiq.c
+++ b/arch/arm/kernel/fiq.c
@@ -101,7 +101,7 @@ void __attribute__((naked)) set_fiq_regs(struct pt_regs *regs)
ldmia %1, {r8 - r14}\n\
msr cpsr_c, %0 @ return to SVC mode\n\
mov r0, r0\n\
- ldmea fp, {fp, sp, pc}"
+ ldmfd sp, {fp, sp, pc}"
: "=&r" (tmp)
: "r" (&regs->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE));
}
@@ -119,7 +119,7 @@ void __attribute__((naked)) get_fiq_regs(struct pt_regs *regs)
stmia %1, {r8 - r14}\n\
msr cpsr_c, %0 @ return to SVC mode\n\
mov r0, r0\n\
- ldmea fp, {fp, sp, pc}"
+ ldmfd sp, {fp, sp, pc}"
: "=&r" (tmp)
: "r" (&regs->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE));
}
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 2cab741ad0f8e..c45d10d07bde9 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -205,7 +205,7 @@ static const char *proc_arch[] = {
"5TE",
"5TEJ",
"6TEJ",
- "?(10)",
+ "7",
"?(11)",
"?(12)",
"?(13)",
@@ -258,14 +258,17 @@ int cpu_architecture(void)
{
int cpu_arch;
- if ((processor_id & 0x0000f000) == 0) {
+ if ((processor_id & 0x0008f000) == 0) {
cpu_arch = CPU_ARCH_UNKNOWN;
- } else if ((processor_id & 0x0000f000) == 0x00007000) {
+ } else if ((processor_id & 0x0008f000) == 0x00007000) {
cpu_arch = (processor_id & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3;
- } else {
+ } else if ((processor_id & 0x00080000) == 0x00000000) {
cpu_arch = (processor_id >> 16) & 7;
if (cpu_arch)
cpu_arch += CPU_ARCH_ARMv3;
+ } else {
+ /* the revised CPUID */
+ cpu_arch = ((processor_id >> 12) & 0xf) - 0xb + CPU_ARCH_ARMv6;
}
return cpu_arch;
@@ -863,11 +866,11 @@ static int c_show(struct seq_file *m, void *v)
seq_printf(m, "\nCPU implementer\t: 0x%02x\n", processor_id >> 24);
seq_printf(m, "CPU architecture: %s\n", proc_arch[cpu_architecture()]);
- if ((processor_id & 0x0000f000) == 0x00000000) {
+ if ((processor_id & 0x0008f000) == 0x00000000) {
/* pre-ARM7 */
seq_printf(m, "CPU part\t\t: %07x\n", processor_id >> 4);
} else {
- if ((processor_id & 0x0000f000) == 0x00007000) {
+ if ((processor_id & 0x0008f000) == 0x00007000) {
/* ARM7 */
seq_printf(m, "CPU variant\t: 0x%02x\n",
(processor_id >> 16) & 127);
diff --git a/arch/arm/lib/csumpartialcopy.S b/arch/arm/lib/csumpartialcopy.S
index 990ee63b24655..21effe0dbf97e 100644
--- a/arch/arm/lib/csumpartialcopy.S
+++ b/arch/arm/lib/csumpartialcopy.S
@@ -18,11 +18,13 @@
*/
.macro save_regs
+ mov ip, sp
stmfd sp!, {r1, r4 - r8, fp, ip, lr, pc}
+ sub fp, ip, #4
.endm
- .macro load_regs,flags
- LOADREGS(\flags,fp,{r1, r4 - r8, fp, sp, pc})
+ .macro load_regs
+ ldmfd sp, {r1, r4 - r8, fp, sp, pc}
.endm
.macro load1b, reg1
diff --git a/arch/arm/lib/csumpartialcopygeneric.S b/arch/arm/lib/csumpartialcopygeneric.S
index 4a4609c19095f..c50e8f5285d17 100644
--- a/arch/arm/lib/csumpartialcopygeneric.S
+++ b/arch/arm/lib/csumpartialcopygeneric.S
@@ -23,7 +23,7 @@ len .req r2
sum .req r3
.Lzero: mov r0, sum
- load_regs ea
+ load_regs
/*
* Align an unaligned destination pointer. We know that
@@ -87,9 +87,7 @@ sum .req r3
b .Ldone
FN_ENTRY
- mov ip, sp
save_regs
- sub fp, ip, #4
cmp len, #8 @ Ensure that we have at least
blo .Lless8 @ 8 bytes to copy.
@@ -163,7 +161,7 @@ FN_ENTRY
ldr sum, [sp, #0] @ dst
tst sum, #1
movne r0, r0, ror #8
- load_regs ea
+ load_regs
.Lsrc_not_aligned:
adc sum, sum, #0 @ include C from dst alignment
diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S
index 333bca292de93..c3b93e22ea25a 100644
--- a/arch/arm/lib/csumpartialcopyuser.S
+++ b/arch/arm/lib/csumpartialcopyuser.S
@@ -18,11 +18,13 @@
.text
.macro save_regs
+ mov ip, sp
stmfd sp!, {r1 - r2, r4 - r8, fp, ip, lr, pc}
+ sub fp, ip, #4
.endm
- .macro load_regs,flags
- ldm\flags fp, {r1, r2, r4-r8, fp, sp, pc}
+ .macro load_regs
+ ldmfd sp, {r1, r2, r4-r8, fp, sp, pc}
.endm
.macro load1b, reg1
@@ -100,5 +102,5 @@
6002: teq r2, r1
strneb r0, [r1], #1
bne 6002b
- load_regs ea
+ load_regs
.previous
diff --git a/arch/arm/mach-aaec2000/clock.c b/arch/arm/mach-aaec2000/clock.c
index 1c84c60941e1b..74aa7a39bb68d 100644
--- a/arch/arm/mach-aaec2000/clock.c
+++ b/arch/arm/mach-aaec2000/clock.c
@@ -16,26 +16,27 @@
#include <linux/err.h>
#include <linux/string.h>
#include <linux/clk.h>
+#include <linux/mutex.h>
#include <asm/semaphore.h>
#include "clock.h"
static LIST_HEAD(clocks);
-static DECLARE_MUTEX(clocks_sem);
+static DEFINE_MUTEX(clocks_mutex);
struct clk *clk_get(struct device *dev, const char *id)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
- down(&clocks_sem);
+ mutex_lock(&clocks_mutex);
list_for_each_entry(p, &clocks, node) {
if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
clk = p;
break;
}
}
- up(&clocks_sem);
+ mutex_unlock(&clocks_mutex);
return clk;
}
@@ -78,18 +79,18 @@ EXPORT_SYMBOL(clk_set_rate);
int clk_register(struct clk *clk)
{
- down(&clocks_sem);
+ mutex_lock(&clocks_mutex);
list_add(&clk->node, &clocks);
- up(&clocks_sem);
+ mutex_unlock(&clocks_mutex);
return 0;
}
EXPORT_SYMBOL(clk_register);
void clk_unregister(struct clk *clk)
{
- down(&clocks_sem);
+ mutex_lock(&clocks_mutex);
list_del(&clk->node);
- up(&clocks_sem);
+ mutex_unlock(&clocks_mutex);
}
EXPORT_SYMBOL(clk_unregister);
diff --git a/arch/arm/mach-at91rm9200/Makefile b/arch/arm/mach-at91rm9200/Makefile
index 1f2805ca6e21d..75e6ee318dedc 100644
--- a/arch/arm/mach-at91rm9200/Makefile
+++ b/arch/arm/mach-at91rm9200/Makefile
@@ -8,10 +8,10 @@ obj-n :=
obj- :=
# Board-specific support
-#obj-$(CONFIG_ARCH_AT91RM9200DK) += board-dk.o
-#obj-$(CONFIG_MACH_AT91RM9200EK) += board-ek.o
-#obj-$(CONFIG_MACH_CSB337) += board-csb337.o
-#obj-$(CONFIG_MACH_CSB637) += board-csb637.o
+obj-$(CONFIG_ARCH_AT91RM9200DK) += board-dk.o
+obj-$(CONFIG_MACH_AT91RM9200EK) += board-ek.o
+obj-$(CONFIG_MACH_CSB337) += board-csb337.o
+obj-$(CONFIG_MACH_CSB637) += board-csb637.o
#obj-$(CONFIG_MACH_CARMEVA) += board-carmeva.o
#obj-$(CONFIG_MACH_KB9200) += board-kb9202.o
diff --git a/arch/arm/mach-at91rm9200/board-csb337.c b/arch/arm/mach-at91rm9200/board-csb337.c
new file mode 100644
index 0000000000000..4aec834ee47fa
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/board-csb337.c
@@ -0,0 +1,143 @@
+/*
+ * linux/arch/arm/mach-at91rm9200/board-csb337.c
+ *
+ * Copyright (C) 2005 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/mach/serial_at91rm9200.h>
+#include <asm/arch/board.h>
+
+#include "generic.h"
+
+static void __init csb337_init_irq(void)
+{
+ /* Initialize AIC controller */
+ at91rm9200_init_irq(NULL);
+
+ /* Set up the GPIO interrupts */
+ at91_gpio_irq_setup(BGA_GPIO_BANKS);
+}
+
+/*
+ * Serial port configuration.
+ * 0 .. 3 = USART0 .. USART3
+ * 4 = DBGU
+ */
+#define CSB337_UART_MAP { 4, 1, -1, -1, -1 } /* ttyS0, ..., ttyS4 */
+#define CSB337_SERIAL_CONSOLE 0 /* ttyS0 */
+
+static void __init csb337_map_io(void)
+{
+ int serial[AT91_NR_UART] = CSB337_UART_MAP;
+ int i;
+
+ at91rm9200_map_io();
+
+ /* Initialize clocks: 3.6864 MHz crystal */
+ at91_clock_init(3686400);
+
+#ifdef CONFIG_SERIAL_AT91
+ at91_console_port = CSB337_SERIAL_CONSOLE;
+ memcpy(at91_serial_map, serial, sizeof(serial));
+
+ /* Register UARTs */
+ for (i = 0; i < AT91_NR_UART; i++) {
+ if (serial[i] >= 0)
+ at91_register_uart(i, serial[i]);
+ }
+#endif
+}
+
+static struct at91_eth_data __initdata csb337_eth_data = {
+ .phy_irq_pin = AT91_PIN_PC2,
+ .is_rmii = 0,
+};
+
+static struct at91_usbh_data __initdata csb337_usbh_data = {
+ .ports = 2,
+};
+
+static struct at91_udc_data __initdata csb337_udc_data = {
+ // this has no VBUS sensing pin
+ .pullup_pin = AT91_PIN_PA24,
+};
+
+static struct at91_cf_data __initdata csb337_cf_data = {
+ /*
+ * connector P4 on the CSB 337 mates to
+ * connector P8 on the CSB 300CF
+ */
+
+ /* CSB337 specific */
+ .det_pin = AT91_PIN_PC3,
+
+ /* CSB300CF specific */
+ .irq_pin = AT91_PIN_PA19,
+ .vcc_pin = AT91_PIN_PD0,
+ .rst_pin = AT91_PIN_PD2,
+};
+
+static struct at91_mmc_data __initdata csb337_mmc_data = {
+ .det_pin = AT91_PIN_PD5,
+ .is_b = 0,
+ .wire4 = 1,
+ .wp_pin = AT91_PIN_PD6,
+};
+
+static void __init csb337_board_init(void)
+{
+ /* Ethernet */
+ at91_add_device_eth(&csb337_eth_data);
+ /* USB Host */
+ at91_add_device_usbh(&csb337_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&csb337_udc_data);
+ /* Compact Flash */
+ at91_set_gpio_input(AT91_PIN_PB22, 1); /* IOIS16 */
+ at91_add_device_cf(&csb337_cf_data);
+ /* MMC */
+ at91_add_device_mmc(&csb337_mmc_data);
+}
+
+MACHINE_START(CSB337, "Cogent CSB337")
+ /* Maintainer: Bill Gatliff */
+ .phys_ram = AT91_SDRAM_BASE,
+ .phys_io = AT91_BASE_SYS,
+ .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+ .boot_params = AT91_SDRAM_BASE + 0x100,
+ .timer = &at91rm9200_timer,
+ .map_io = csb337_map_io,
+ .init_irq = csb337_init_irq,
+ .init_machine = csb337_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91rm9200/board-csb637.c b/arch/arm/mach-at91rm9200/board-csb637.c
new file mode 100644
index 0000000000000..23e4cc21481a5
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/board-csb637.c
@@ -0,0 +1,116 @@
+/*
+ * linux/arch/arm/mach-at91rm9200/board-csb637.c
+ *
+ * Copyright (C) 2005 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/mach/serial_at91rm9200.h>
+#include <asm/arch/board.h>
+
+#include "generic.h"
+
+static void __init csb637_init_irq(void)
+{
+ /* Initialize AIC controller */
+ at91rm9200_init_irq(NULL);
+
+ /* Set up the GPIO interrupts */
+ at91_gpio_irq_setup(BGA_GPIO_BANKS);
+}
+
+/*
+ * Serial port configuration.
+ * 0 .. 3 = USART0 .. USART3
+ * 4 = DBGU
+ */
+#define CSB637_UART_MAP { 4, 1, -1, -1, -1 } /* ttyS0, ..., ttyS4 */
+#define CSB637_SERIAL_CONSOLE 0 /* ttyS0 */
+
+static void __init csb637_map_io(void)
+{
+ int serial[AT91_NR_UART] = CSB637_UART_MAP;
+ int i;
+
+ at91rm9200_map_io();
+
+ /* Initialize clocks: 3.6864 MHz crystal */
+ at91_clock_init(3686400);
+
+#ifdef CONFIG_SERIAL_AT91
+ at91_console_port = CSB637_SERIAL_CONSOLE;
+ memcpy(at91_serial_map, serial, sizeof(serial));
+
+ /* Register UARTs */
+ for (i = 0; i < AT91_NR_UART; i++) {
+ if (serial[i] >= 0)
+ at91_register_uart(i, serial[i]);
+ }
+#endif
+}
+
+static struct at91_eth_data __initdata csb637_eth_data = {
+ .phy_irq_pin = AT91_PIN_PC0,
+ .is_rmii = 0,
+};
+
+static struct at91_usbh_data __initdata csb637_usbh_data = {
+ .ports = 2,
+};
+
+static struct at91_udc_data __initdata csb637_udc_data = {
+ .vbus_pin = AT91_PIN_PB28,
+ .pullup_pin = AT91_PIN_PB1,
+};
+
+static void __init csb637_board_init(void)
+{
+ /* Ethernet */
+ at91_add_device_eth(&csb637_eth_data);
+ /* USB Host */
+ at91_add_device_usbh(&csb637_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&csb637_udc_data);
+}
+
+MACHINE_START(CSB637, "Cogent CSB637")
+ /* Maintainer: Bill Gatliff */
+ .phys_ram = AT91_SDRAM_BASE,
+ .phys_io = AT91_BASE_SYS,
+ .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+ .boot_params = AT91_SDRAM_BASE + 0x100,
+ .timer = &at91rm9200_timer,
+ .map_io = csb637_map_io,
+ .init_irq = csb637_init_irq,
+ .init_machine = csb637_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91rm9200/board-dk.c b/arch/arm/mach-at91rm9200/board-dk.c
new file mode 100644
index 0000000000000..8c747a31b95aa
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/board-dk.c
@@ -0,0 +1,138 @@
+/*
+ * linux/arch/arm/mach-at91rm9200/board-dk.c
+ *
+ * Copyright (C) 2005 SAN People
+ *
+ * Epson S1D framebuffer glue code is:
+ * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/mach/serial_at91rm9200.h>
+#include <asm/arch/board.h>
+
+#include "generic.h"
+
+static void __init dk_init_irq(void)
+{
+ /* Initialize AIC controller */
+ at91rm9200_init_irq(NULL);
+
+ /* Set up the GPIO interrupts */
+ at91_gpio_irq_setup(BGA_GPIO_BANKS);
+}
+
+/*
+ * Serial port configuration.
+ * 0 .. 3 = USART0 .. USART3
+ * 4 = DBGU
+ */
+#define DK_UART_MAP { 4, 1, -1, -1, -1 } /* ttyS0, ..., ttyS4 */
+#define DK_SERIAL_CONSOLE 0 /* ttyS0 */
+
+static void __init dk_map_io(void)
+{
+ int serial[AT91_NR_UART] = DK_UART_MAP;
+ int i;
+
+ at91rm9200_map_io();
+
+ /* Initialize clocks: 18.432 MHz crystal */
+ at91_clock_init(18432000);
+
+#ifdef CONFIG_SERIAL_AT91
+ at91_console_port = DK_SERIAL_CONSOLE;
+ memcpy(at91_serial_map, serial, sizeof(serial));
+
+ /* Register UARTs */
+ for (i = 0; i < AT91_NR_UART; i++) {
+ if (at91_serial_map[i] >= 0)
+ at91_register_uart(i, at91_serial_map[i]);
+ }
+#endif
+}
+
+static struct at91_eth_data __initdata dk_eth_data = {
+ .phy_irq_pin = AT91_PIN_PC4,
+ .is_rmii = 1,
+};
+
+static struct at91_usbh_data __initdata dk_usbh_data = {
+ .ports = 2,
+};
+
+static struct at91_udc_data __initdata dk_udc_data = {
+ .vbus_pin = AT91_PIN_PD4,
+ .pullup_pin = AT91_PIN_PD5,
+};
+
+static struct at91_cf_data __initdata dk_cf_data = {
+ .det_pin = AT91_PIN_PB0,
+ .rst_pin = AT91_PIN_PC5,
+ // .irq_pin = ... not connected
+ // .vcc_pin = ... always powered
+};
+
+static struct at91_mmc_data __initdata dk_mmc_data = {
+ .is_b = 0,
+ .wire4 = 1,
+};
+
+static void __init dk_board_init(void)
+{
+ /* Ethernet */
+ at91_add_device_eth(&dk_eth_data);
+ /* USB Host */
+ at91_add_device_usbh(&dk_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&dk_udc_data);
+ /* Compact Flash */
+ at91_add_device_cf(&dk_cf_data);
+ /* MMC */
+ at91_set_gpio_output(AT91_PIN_PB7, 1); /* this MMC card slot can optionally use SPI signaling (CS3). default: MMC */
+ at91_add_device_mmc(&dk_mmc_data);
+ /* VGA */
+// dk_add_device_video();
+}
+
+MACHINE_START(AT91RM9200DK, "Atmel AT91RM9200-DK")
+ /* Maintainer: SAN People/Atmel */
+ .phys_ram = AT91_SDRAM_BASE,
+ .phys_io = AT91_BASE_SYS,
+ .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+ .boot_params = AT91_SDRAM_BASE + 0x100,
+ .timer = &at91rm9200_timer,
+ .map_io = dk_map_io,
+ .init_irq = dk_init_irq,
+ .init_machine = dk_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91rm9200/board-ek.c b/arch/arm/mach-at91rm9200/board-ek.c
new file mode 100644
index 0000000000000..d140645711bea
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/board-ek.c
@@ -0,0 +1,131 @@
+/*
+ * linux/arch/arm/mach-at91rm9200/board-ek.c
+ *
+ * Copyright (C) 2005 SAN People
+ *
+ * Epson S1D framebuffer glue code is:
+ * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/mach/serial_at91rm9200.h>
+#include <asm/arch/board.h>
+
+#include "generic.h"
+
+static void __init ek_init_irq(void)
+{
+ /* Initialize AIC controller */
+ at91rm9200_init_irq(NULL);
+
+ /* Set up the GPIO interrupts */
+ at91_gpio_irq_setup(BGA_GPIO_BANKS);
+}
+
+/*
+ * Serial port configuration.
+ * 0 .. 3 = USART0 .. USART3
+ * 4 = DBGU
+ */
+#define EK_UART_MAP { 4, 1, -1, -1, -1 } /* ttyS0, ..., ttyS4 */
+#define EK_SERIAL_CONSOLE 0 /* ttyS0 */
+
+static void __init ek_map_io(void)
+{
+ int serial[AT91_NR_UART] = EK_UART_MAP;
+ int i;
+
+ at91rm9200_map_io();
+
+ /* Initialize clocks: 18.432 MHz crystal */
+ at91_clock_init(18432000);
+
+#ifdef CONFIG_SERIAL_AT91
+ at91_console_port = EK_SERIAL_CONSOLE;
+ memcpy(at91_serial_map, serial, sizeof(serial));
+
+ /* Register UARTs */
+ for (i = 0; i < AT91_NR_UART; i++) {
+ if (serial[i] >= 0)
+ at91_register_uart(i, serial[i]);
+ }
+#endif
+}
+
+static struct at91_eth_data __initdata ek_eth_data = {
+ .phy_irq_pin = AT91_PIN_PC4,
+ .is_rmii = 1,
+};
+
+static struct at91_usbh_data __initdata ek_usbh_data = {
+ .ports = 2,
+};
+
+static struct at91_udc_data __initdata ek_udc_data = {
+ .vbus_pin = AT91_PIN_PD4,
+ .pullup_pin = AT91_PIN_PD5,
+};
+
+static struct at91_mmc_data __initdata ek_mmc_data = {
+ .det_pin = AT91_PIN_PB27,
+ .is_b = 0,
+ .wire4 = 1,
+ .wp_pin = AT91_PIN_PA17,
+};
+
+static void __init ek_board_init(void)
+{
+ /* Ethernet */
+ at91_add_device_eth(&ek_eth_data);
+ /* USB Host */
+ at91_add_device_usbh(&ek_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&ek_udc_data);
+ /* MMC */
+ at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). default: MMC */
+ at91_add_device_mmc(&ek_mmc_data);
+ /* VGA */
+// ek_add_device_video();
+}
+
+MACHINE_START(AT91RM9200EK, "Atmel AT91RM9200-EK")
+ /* Maintainer: SAN People/Atmel */
+ .phys_ram = AT91_SDRAM_BASE,
+ .phys_io = AT91_BASE_SYS,
+ .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+ .boot_params = AT91_SDRAM_BASE + 0x100,
+ .timer = &at91rm9200_timer,
+ .map_io = ek_map_io,
+ .init_irq = ek_init_irq,
+ .init_machine = ek_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-integrator/clock.c b/arch/arm/mach-integrator/clock.c
index 40684e01e865a..95a1e263f7fa5 100644
--- a/arch/arm/mach-integrator/clock.c
+++ b/arch/arm/mach-integrator/clock.c
@@ -15,6 +15,7 @@
#include <linux/err.h>
#include <linux/string.h>
#include <linux/clk.h>
+#include <linux/mutex.h>
#include <asm/semaphore.h>
#include <asm/hardware/icst525.h>
@@ -22,20 +23,20 @@
#include "clock.h"
static LIST_HEAD(clocks);
-static DECLARE_MUTEX(clocks_sem);
+static DEFINE_MUTEX(clocks_mutex);
struct clk *clk_get(struct device *dev, const char *id)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
- down(&clocks_sem);
+ mutex_lock(&clocks_mutex);
list_for_each_entry(p, &clocks, node) {
if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
clk = p;
break;
}
}
- up(&clocks_sem);
+ mutex_unlock(&clocks_mutex);
return clk;
}
@@ -107,18 +108,18 @@ static struct clk uart_clk = {
int clk_register(struct clk *clk)
{
- down(&clocks_sem);
+ mutex_lock(&clocks_mutex);
list_add(&clk->node, &clocks);
- up(&clocks_sem);
+ mutex_unlock(&clocks_mutex);
return 0;
}
EXPORT_SYMBOL(clk_register);
void clk_unregister(struct clk *clk)
{
- down(&clocks_sem);
+ mutex_lock(&clocks_mutex);
list_del(&clk->node);
- up(&clocks_sem);
+ mutex_unlock(&clocks_mutex);
}
EXPORT_SYMBOL(clk_unregister);
diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c
index a68b30eff4d26..93096befd0173 100644
--- a/arch/arm/mach-pxa/ssp.c
+++ b/arch/arm/mach-pxa/ssp.c
@@ -31,6 +31,7 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/init.h>
+#include <linux/mutex.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/hardware.h>
@@ -59,7 +60,7 @@ static const struct ssp_info_ ssp_info[PXA_SSP_PORTS] = {
#endif
};
-static DECLARE_MUTEX(sem);
+static DEFINE_MUTEX(mutex);
static int use_count[PXA_SSP_PORTS] = {0, 0, 0};
static irqreturn_t ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
@@ -239,16 +240,16 @@ int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags)
if (port > PXA_SSP_PORTS || port == 0)
return -ENODEV;
- down(&sem);
+ mutex_lock(&mutex);
if (use_count[port - 1]) {
- up(&sem);
+ mutex_unlock(&mutex);
return -EBUSY;
}
use_count[port - 1]++;
if (!request_mem_region(__PREG(SSCR0_P(port)), 0x2c, "SSP")) {
use_count[port - 1]--;
- up(&sem);
+ mutex_unlock(&mutex);
return -EBUSY;
}
dev->port = port;
@@ -265,13 +266,13 @@ int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags)
/* turn on SSP port clock */
pxa_set_cken(ssp_info[port-1].clock, 1);
- up(&sem);
+ mutex_unlock(&mutex);
return 0;
out_region:
release_mem_region(__PREG(SSCR0_P(port)), 0x2c);
use_count[port - 1]--;
- up(&sem);
+ mutex_unlock(&mutex);
return ret;
}
@@ -282,7 +283,7 @@ out_region:
*/
void ssp_exit(struct ssp_dev *dev)
{
- down(&sem);
+ mutex_lock(&mutex);
SSCR0_P(dev->port) &= ~SSCR0_SSE;
if (dev->port > PXA_SSP_PORTS || dev->port == 0) {
@@ -295,7 +296,7 @@ void ssp_exit(struct ssp_dev *dev)
free_irq(dev->irq, dev);
release_mem_region(__PREG(SSCR0_P(dev->port)), 0x2c);
use_count[dev->port - 1]--;
- up(&sem);
+ mutex_unlock(&mutex);
}
EXPORT_SYMBOL(ssp_write_word);
diff --git a/arch/arm/mach-realview/clock.c b/arch/arm/mach-realview/clock.c
index ec3f7e798623f..21325a4da9da6 100644
--- a/arch/arm/mach-realview/clock.c
+++ b/arch/arm/mach-realview/clock.c
@@ -14,6 +14,7 @@
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/clk.h>
+#include <linux/mutex.h>
#include <asm/semaphore.h>
#include <asm/hardware/icst307.h>
@@ -21,20 +22,20 @@
#include "clock.h"
static LIST_HEAD(clocks);
-static DECLARE_MUTEX(clocks_sem);
+static DEFINE_MUTEX(clocks_mutex);
struct clk *clk_get(struct device *dev, const char *id)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
- down(&clocks_sem);
+ mutex_lock(&clocks_mutex);
list_for_each_entry(p, &clocks, node) {
if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
clk = p;
break;
}
}
- up(&clocks_sem);
+ mutex_unlock(&clocks_mutex);
return clk;
}
@@ -109,18 +110,18 @@ static struct clk mmci_clk = {
int clk_register(struct clk *clk)
{
- down(&clocks_sem);
+ mutex_lock(&clocks_mutex);
list_add(&clk->node, &clocks);
- up(&clocks_sem);
+ mutex_unlock(&clocks_mutex);
return 0;
}
EXPORT_SYMBOL(clk_register);
void clk_unregister(struct clk *clk)
{
- down(&clocks_sem);
+ mutex_lock(&clocks_mutex);
list_del(&clk->node);
- up(&clocks_sem);
+ mutex_unlock(&clocks_mutex);
}
EXPORT_SYMBOL(clk_unregister);
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
index fc09ba92d66a4..af2f3d52b61b8 100644
--- a/arch/arm/mach-s3c2410/clock.c
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -37,6 +37,7 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/clk.h>
+#include <linux/mutex.h>
#include <asm/hardware.h>
#include <asm/atomic.h>
@@ -51,7 +52,7 @@
/* clock information */
static LIST_HEAD(clocks);
-static DECLARE_MUTEX(clocks_sem);
+static DEFINE_MUTEX(clocks_mutex);
/* old functions */
@@ -102,7 +103,7 @@ struct clk *clk_get(struct device *dev, const char *id)
else
idno = to_platform_device(dev)->id;
- down(&clocks_sem);
+ mutex_lock(&clocks_mutex);
list_for_each_entry(p, &clocks, list) {
if (p->id == idno &&
@@ -126,7 +127,7 @@ struct clk *clk_get(struct device *dev, const char *id)
}
}
- up(&clocks_sem);
+ mutex_unlock(&clocks_mutex);
return clk;
}
@@ -362,9 +363,9 @@ int s3c24xx_register_clock(struct clk *clk)
/* add to the list of available clocks */
- down(&clocks_sem);
+ mutex_lock(&clocks_mutex);
list_add(&clk->list, &clocks);
- up(&clocks_sem);
+ mutex_unlock(&clocks_mutex);
return 0;
}
diff --git a/arch/arm/mach-versatile/clock.c b/arch/arm/mach-versatile/clock.c
index dcf10014f5cd3..9858c96560e24 100644
--- a/arch/arm/mach-versatile/clock.c
+++ b/arch/arm/mach-versatile/clock.c
@@ -15,6 +15,7 @@
#include <linux/err.h>
#include <linux/string.h>
#include <linux/clk.h>
+#include <linux/mutex.h>
#include <asm/semaphore.h>
#include <asm/hardware/icst307.h>
@@ -22,20 +23,20 @@
#include "clock.h"
static LIST_HEAD(clocks);
-static DECLARE_MUTEX(clocks_sem);
+static DEFINE_MUTEX(clocks_mutex);
struct clk *clk_get(struct device *dev, const char *id)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
- down(&clocks_sem);
+ mutex_lock(&clocks_mutex);
list_for_each_entry(p, &clocks, node) {
if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
clk = p;
break;
}
}
- up(&clocks_sem);
+ mutex_unlock(&clocks_mutex);
return clk;
}
@@ -110,18 +111,18 @@ static struct clk mmci_clk = {
int clk_register(struct clk *clk)
{
- down(&clocks_sem);
+ mutex_lock(&clocks_mutex);
list_add(&clk->node, &clocks);
- up(&clocks_sem);
+ mutex_unlock(&clocks_mutex);
return 0;
}
EXPORT_SYMBOL(clk_register);
void clk_unregister(struct clk *clk)
{
- down(&clocks_sem);
+ mutex_lock(&clocks_mutex);
list_del(&clk->node);
- up(&clocks_sem);
+ mutex_unlock(&clocks_mutex);
}
EXPORT_SYMBOL(clk_unregister);
diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c
index 0513ed1b2fcf8..c2ee18d2075e7 100644
--- a/arch/arm/mm/consistent.c
+++ b/arch/arm/mm/consistent.c
@@ -20,15 +20,25 @@
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
+#include <asm/sizes.h>
+
+/* Sanity check size */
+#if (CONSISTENT_DMA_SIZE % SZ_2M)
+#error "CONSISTENT_DMA_SIZE must be multiple of 2MiB"
+#endif
-#define CONSISTENT_BASE (0xffc00000)
#define CONSISTENT_END (0xffe00000)
+#define CONSISTENT_BASE (CONSISTENT_END - CONSISTENT_DMA_SIZE)
+
#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT)
+#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT)
+#define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT)
+
/*
- * This is the page table (2MB) covering uncached, DMA consistent allocations
+ * These are the page tables (2MB each) covering uncached, DMA consistent allocations
*/
-static pte_t *consistent_pte;
+static pte_t *consistent_pte[NUM_CONSISTENT_PTES];
static DEFINE_SPINLOCK(consistent_lock);
/*
@@ -142,7 +152,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
unsigned long order;
u64 mask = ISA_DMA_THRESHOLD, limit;
- if (!consistent_pte) {
+ if (!consistent_pte[0]) {
printk(KERN_ERR "%s: not initialised\n", __func__);
dump_stack();
return NULL;
@@ -205,9 +215,12 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
c = vm_region_alloc(&consistent_head, size,
gfp & ~(__GFP_DMA | __GFP_HIGHMEM));
if (c) {
- pte_t *pte = consistent_pte + CONSISTENT_OFFSET(c->vm_start);
+ pte_t *pte;
struct page *end = page + (1 << order);
+ int idx = CONSISTENT_PTE_INDEX(c->vm_start);
+ u32 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
+ pte = consistent_pte[idx] + off;
c->vm_pages = page;
/*
@@ -226,6 +239,11 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
set_pte(pte, mk_pte(page, prot));
page++;
pte++;
+ off++;
+ if (off >= PTRS_PER_PTE) {
+ off = 0;
+ pte = consistent_pte[++idx];
+ }
} while (size -= PAGE_SIZE);
/*
@@ -327,6 +345,8 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr
struct vm_region *c;
unsigned long flags, addr;
pte_t *ptep;
+ int idx;
+ u32 off;
WARN_ON(irqs_disabled());
@@ -347,7 +367,9 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr
size = c->vm_end - c->vm_start;
}
- ptep = consistent_pte + CONSISTENT_OFFSET(c->vm_start);
+ idx = CONSISTENT_PTE_INDEX(c->vm_start);
+ off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
+ ptep = consistent_pte[idx] + off;
addr = c->vm_start;
do {
pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep);
@@ -355,6 +377,11 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr
ptep++;
addr += PAGE_SIZE;
+ off++;
+ if (off >= PTRS_PER_PTE) {
+ off = 0;
+ ptep = consistent_pte[++idx];
+ }
if (!pte_none(pte) && pte_present(pte)) {
pfn = pte_pfn(pte);
@@ -401,11 +428,12 @@ static int __init consistent_init(void)
pgd_t *pgd;
pmd_t *pmd;
pte_t *pte;
- int ret = 0;
+ int ret = 0, i = 0;
+ u32 base = CONSISTENT_BASE;
do {
- pgd = pgd_offset(&init_mm, CONSISTENT_BASE);
- pmd = pmd_alloc(&init_mm, pgd, CONSISTENT_BASE);
+ pgd = pgd_offset(&init_mm, base);
+ pmd = pmd_alloc(&init_mm, pgd, base);
if (!pmd) {
printk(KERN_ERR "%s: no pmd tables\n", __func__);
ret = -ENOMEM;
@@ -413,15 +441,16 @@ static int __init consistent_init(void)
}
WARN_ON(!pmd_none(*pmd));
- pte = pte_alloc_kernel(pmd, CONSISTENT_BASE);
+ pte = pte_alloc_kernel(pmd, base);
if (!pte) {
printk(KERN_ERR "%s: no pte tables\n", __func__);
ret = -ENOMEM;
break;
}
- consistent_pte = pte;
- } while (0);
+ consistent_pte[i++] = pte;
+ base += (1 << PGDIR_SHIFT);
+ } while (base < CONSISTENT_END);
return ret;
}
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 84fd65656fcfa..7ebc5a29db8d6 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -20,6 +20,7 @@
#include <linux/err.h>
#include <linux/string.h>
#include <linux/clk.h>
+#include <linux/mutex.h>
#include <asm/io.h>
#include <asm/semaphore.h>
@@ -27,7 +28,7 @@
#include <asm/arch/clock.h>
LIST_HEAD(clocks);
-static DECLARE_MUTEX(clocks_sem);
+static DEFINE_MUTEX(clocks_mutex);
DEFINE_SPINLOCK(clockfw_lock);
static struct clk_functions *arch_clock;
@@ -40,14 +41,14 @@ struct clk * clk_get(struct device *dev, const char *id)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
- down(&clocks_sem);
+ mutex_lock(&clocks_mutex);
list_for_each_entry(p, &clocks, node) {
if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
clk = p;
break;
}
}
- up(&clocks_sem);
+ mutex_unlock(&clocks_mutex);
return clk;
}
@@ -249,11 +250,11 @@ void propagate_rate(struct clk * tclk)
int clk_register(struct clk *clk)
{
- down(&clocks_sem);
+ mutex_lock(&clocks_mutex);
list_add(&clk->node, &clocks);
if (clk->init)
clk->init(clk);
- up(&clocks_sem);
+ mutex_unlock(&clocks_mutex);
return 0;
}
@@ -261,9 +262,9 @@ EXPORT_SYMBOL(clk_register);
void clk_unregister(struct clk *clk)
{
- down(&clocks_sem);
+ mutex_lock(&clocks_mutex);
list_del(&clk->node);
- up(&clocks_sem);
+ mutex_unlock(&clocks_mutex);
}
EXPORT_SYMBOL(clk_unregister);
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index bbfa1bdceb4d1..a94699d8dc52b 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -11,7 +11,8 @@ CFLAGS_btext.o += -fPIC
endif
obj-y := semaphore.o cputable.o ptrace.o syscalls.o \
- irq.o align.o signal_32.o pmc.o vdso.o
+ irq.o align.o signal_32.o pmc.o vdso.o \
+ init_task.o process.o
obj-y += vdso32/
obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
signal_64.o ptrace32.o systbl.o \
@@ -44,8 +45,7 @@ extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o
extra-$(CONFIG_8xx) := head_8xx.o
extra-y += vmlinux.lds
-obj-y += process.o init_task.o time.o \
- prom.o traps.o setup-common.o udbg.o
+obj-y += time.o prom.o traps.o setup-common.o udbg.o
obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o systbl.o
obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o
obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 24fe70f40b665..c367520bc1c38 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -53,6 +53,7 @@ EXPORT_SYMBOL(io_page_mask);
#ifdef CONFIG_PPC_MULTIPLATFORM
static void fixup_resource(struct resource *res, struct pci_dev *dev);
static void do_bus_setup(struct pci_bus *bus);
+static void phbs_remap_io(void);
#endif
/* pci_io_base -- the base address from which io bars are offsets.
@@ -251,6 +252,7 @@ void pcibios_free_controller(struct pci_controller *phb)
kfree(phb);
}
+#ifndef CONFIG_PPC_ISERIES
void __devinit pcibios_claim_one_bus(struct pci_bus *b)
{
struct pci_dev *dev;
@@ -275,7 +277,6 @@ void __devinit pcibios_claim_one_bus(struct pci_bus *b)
EXPORT_SYMBOL_GPL(pcibios_claim_one_bus);
#endif
-#ifndef CONFIG_PPC_ISERIES
static void __init pcibios_claim_of_setup(void)
{
struct pci_bus *b;
@@ -1218,7 +1219,7 @@ int remap_bus_range(struct pci_bus *bus)
}
EXPORT_SYMBOL(remap_bus_range);
-void phbs_remap_io(void)
+static void phbs_remap_io(void)
{
struct pci_controller *hose, *tmp;
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 1f816f0d7740e..57703994a0635 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -201,13 +201,13 @@ int dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs)
}
#endif /* CONFIG_SPE */
+#ifndef CONFIG_SMP
/*
* If we are doing lazy switching of CPU state (FP, altivec or SPE),
* and the current task has some state, discard it.
*/
-static inline void discard_lazy_cpu_state(void)
+void discard_lazy_cpu_state(void)
{
-#ifndef CONFIG_SMP
preempt_disable();
if (last_task_used_math == current)
last_task_used_math = NULL;
@@ -220,9 +220,10 @@ static inline void discard_lazy_cpu_state(void)
last_task_used_spe = NULL;
#endif
preempt_enable();
-#endif /* CONFIG_SMP */
}
+#endif /* CONFIG_SMP */
+#ifdef CONFIG_PPC_MERGE /* XXX for now */
int set_dabr(unsigned long dabr)
{
if (ppc_md.set_dabr)
@@ -231,6 +232,7 @@ int set_dabr(unsigned long dabr)
mtspr(SPRN_DABR, dabr);
return 0;
}
+#endif
#ifdef CONFIG_PPC64
DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array);
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 34ab0daec3a7d..02e2115323e49 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -1100,17 +1100,37 @@ static int __init early_init_dt_scan_memory(unsigned long node,
static void __init early_reserve_mem(void)
{
- unsigned long base, size;
- unsigned long *reserve_map;
+ u64 base, size;
+ u64 *reserve_map;
- reserve_map = (unsigned long *)(((unsigned long)initial_boot_params) +
+ reserve_map = (u64 *)(((unsigned long)initial_boot_params) +
initial_boot_params->off_mem_rsvmap);
+#ifdef CONFIG_PPC32
+ /*
+ * Handle the case where we might be booting from an old kexec
+ * image that setup the mem_rsvmap as pairs of 32-bit values
+ */
+ if (*reserve_map > 0xffffffffull) {
+ u32 base_32, size_32;
+ u32 *reserve_map_32 = (u32 *)reserve_map;
+
+ while (1) {
+ base_32 = *(reserve_map_32++);
+ size_32 = *(reserve_map_32++);
+ if (size_32 == 0)
+ break;
+ DBG("reserving: %lx -> %lx\n", base_32, size_32);
+ lmb_reserve(base_32, size_32);
+ }
+ return;
+ }
+#endif
while (1) {
base = *(reserve_map++);
size = *(reserve_map++);
if (size == 0)
break;
- DBG("reserving: %lx -> %lx\n", base, size);
+ DBG("reserving: %llx -> %llx\n", base, size);
lmb_reserve(base, size);
}
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index e381f2fc121c5..d963a12ec6400 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -137,8 +137,8 @@ struct prom_t {
};
struct mem_map_entry {
- unsigned long base;
- unsigned long size;
+ u64 base;
+ u64 size;
};
typedef u32 cell_t;
@@ -897,9 +897,9 @@ static unsigned long __init prom_next_cell(int s, cell_t **cellp)
* If problems seem to show up, it would be a good start to track
* them down.
*/
-static void reserve_mem(unsigned long base, unsigned long size)
+static void reserve_mem(u64 base, u64 size)
{
- unsigned long top = base + size;
+ u64 top = base + size;
unsigned long cnt = RELOC(mem_reserve_cnt);
if (size == 0)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index d3f0b6d452fb7..177bba78fb0b6 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -497,6 +497,15 @@ static long restore_user_regs(struct pt_regs *regs,
if (err)
return 1;
+ /*
+ * Do this before updating the thread state in
+ * current->thread.fpr/vr/evr. That way, if we get preempted
+ * and another task grabs the FPU/Altivec/SPE, it won't be
+ * tempted to save the current CPU state into the thread_struct
+ * and corrupt what we are writing there.
+ */
+ discard_lazy_cpu_state();
+
/* force the process to reload the FP registers from
current->thread when it next does FP instructions */
regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
@@ -538,18 +547,6 @@ static long restore_user_regs(struct pt_regs *regs,
return 1;
#endif /* CONFIG_SPE */
-#ifndef CONFIG_SMP
- preempt_disable();
- if (last_task_used_math == current)
- last_task_used_math = NULL;
- if (last_task_used_altivec == current)
- last_task_used_altivec = NULL;
-#ifdef CONFIG_SPE
- if (last_task_used_spe == current)
- last_task_used_spe = NULL;
-#endif
- preempt_enable();
-#endif
return 0;
}
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 5462bef898f61..7b9d999e21150 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -207,10 +207,20 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
if (!sig)
regs->gpr[13] = save_r13;
- err |= __copy_from_user(&current->thread.fpr, &sc->fp_regs, FP_REGS_SIZE);
if (set != NULL)
err |= __get_user(set->sig[0], &sc->oldmask);
+ /*
+ * Do this before updating the thread state in
+ * current->thread.fpr/vr. That way, if we get preempted
+ * and another task grabs the FPU/Altivec, it won't be
+ * tempted to save the current CPU state into the thread_struct
+ * and corrupt what we are writing there.
+ */
+ discard_lazy_cpu_state();
+
+ err |= __copy_from_user(&current->thread.fpr, &sc->fp_regs, FP_REGS_SIZE);
+
#ifdef CONFIG_ALTIVEC
err |= __get_user(v_regs, &sc->v_regs);
err |= __get_user(msr, &sc->gp_regs[PT_MSR]);
@@ -229,14 +239,6 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
current->thread.vrsave = 0;
#endif /* CONFIG_ALTIVEC */
-#ifndef CONFIG_SMP
- preempt_disable();
- if (last_task_used_math == current)
- last_task_used_math = NULL;
- if (last_task_used_altivec == current)
- last_task_used_altivec = NULL;
- preempt_enable();
-#endif
/* Force reload of FP/VEC */
regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1 | MSR_VEC);
diff --git a/arch/powerpc/platforms/cell/pervasive.c b/arch/powerpc/platforms/cell/pervasive.c
index 85152544c1530..e0e051c675dd1 100644
--- a/arch/powerpc/platforms/cell/pervasive.c
+++ b/arch/powerpc/platforms/cell/pervasive.c
@@ -142,7 +142,7 @@ static void cbe_idle(void)
}
}
-int cbe_system_reset_exception(struct pt_regs *regs)
+static int cbe_system_reset_exception(struct pt_regs *regs)
{
switch (regs->msr & SRR1_WAKEMASK) {
case SRR1_WAKEEE:
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index 18e25e65c04b2..b33a4443f5a93 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -57,7 +57,7 @@
#define DBG(fmt...)
#endif
-void cell_show_cpuinfo(struct seq_file *m)
+static void cell_show_cpuinfo(struct seq_file *m)
{
struct device_node *root;
const char *model = "";
diff --git a/arch/powerpc/platforms/cell/spufs/syscalls.c b/arch/powerpc/platforms/cell/spufs/syscalls.c
index d549aa7ebea61..e6565a949ddc7 100644
--- a/arch/powerpc/platforms/cell/spufs/syscalls.c
+++ b/arch/powerpc/platforms/cell/spufs/syscalls.c
@@ -29,7 +29,9 @@
* value of the spu_status register after the SPU has stopped.
*
*/
-long do_spu_run(struct file *filp, __u32 __user *unpc, __u32 __user *ustatus)
+static long do_spu_run(struct file *filp,
+ __u32 __user *unpc,
+ __u32 __user *ustatus)
{
long ret;
struct spufs_inode_info *i;
diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile
index 127b465308be8..ce8c0b943fa0f 100644
--- a/arch/powerpc/platforms/iseries/Makefile
+++ b/arch/powerpc/platforms/iseries/Makefile
@@ -1,8 +1,8 @@
EXTRA_CFLAGS += -mno-minimal-toc
obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \
- hvcall.o proc.o htab.o iommu.o misc.o
-obj-$(CONFIG_PCI) += pci.o irq.o vpdinfo.o
+ hvcall.o proc.o htab.o iommu.o misc.o irq.o
+obj-$(CONFIG_PCI) += pci.o vpdinfo.o
obj-$(CONFIG_IBMVIO) += vio.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_VIOPATH) += viopath.o
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index 2b54eeb2c8997..bea0b703f4095 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -34,6 +34,8 @@
#include <asm/pci-bridge.h>
#include <asm/iseries/hv_call_xm.h>
+#include "iommu.h"
+
extern struct list_head iSeries_Global_Device_List;
diff --git a/arch/powerpc/platforms/iseries/iommu.h b/arch/powerpc/platforms/iseries/iommu.h
new file mode 100644
index 0000000000000..cb5658fbe6572
--- /dev/null
+++ b/arch/powerpc/platforms/iseries/iommu.h
@@ -0,0 +1,35 @@
+#ifndef _PLATFORMS_ISERIES_IOMMU_H
+#define _PLATFORMS_ISERIES_IOMMU_H
+
+/*
+ * Copyright (C) 2005 Stephen Rothwell, IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the:
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307 USA
+ */
+
+struct device_node;
+struct iommu_table;
+
+/* Creates table for an individual device node */
+extern void iommu_devnode_init_iSeries(struct device_node *dn);
+
+/* Get table parameters from HV */
+extern void iommu_table_getparms_iSeries(unsigned long busno,
+ unsigned char slotno, unsigned char virtbus,
+ struct iommu_table *tbl);
+
+#endif /* _PLATFORMS_ISERIES_IOMMU_H */
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index 42e978e4897a9..83442ea77476a 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -48,6 +48,8 @@
extern void iSeries_smp_message_recv(struct pt_regs *);
#endif
+#ifdef CONFIG_PCI
+
enum pci_event_type {
pe_bus_created = 0, /* PHB has been created */
pe_bus_error = 1, /* PHB has failed */
@@ -147,20 +149,11 @@ static void int_received(struct pci_event *event, struct pt_regs *regs)
static void pci_event_handler(struct HvLpEvent *event, struct pt_regs *regs)
{
if (event && (event->xType == HvLpEvent_Type_PciIo)) {
- switch (event->xFlags.xFunction) {
- case HvLpEvent_Function_Int:
+ if (hvlpevent_is_int(event))
int_received((struct pci_event *)event, regs);
- break;
- case HvLpEvent_Function_Ack:
+ else
printk(KERN_ERR
"pci_event_handler: unexpected ack received\n");
- break;
- default:
- printk(KERN_ERR
- "pci_event_handler: unexpected event function %d\n",
- (int)event->xFlags.xFunction);
- break;
- }
} else if (event)
printk(KERN_ERR
"pci_event_handler: Unrecognized PCI event type 0x%x\n",
@@ -334,6 +327,8 @@ int __init iSeries_allocate_IRQ(HvBusNumber bus,
return virtirq;
}
+#endif /* CONFIG_PCI */
+
/*
* Get the next pending IRQ.
*/
@@ -353,6 +348,7 @@ int iSeries_get_irq(struct pt_regs *regs)
if (hvlpevent_is_pending())
process_hvlpevents(regs);
+#ifdef CONFIG_PCI
if (num_pending_irqs) {
spin_lock(&pending_irqs_lock);
for (irq = 0; irq < NR_IRQS; irq++) {
@@ -366,6 +362,7 @@ int iSeries_get_irq(struct pt_regs *regs)
if (irq >= NR_IRQS)
irq = -2;
}
+#endif
return irq;
}
diff --git a/arch/powerpc/platforms/iseries/lpardata.c b/arch/powerpc/platforms/iseries/lpardata.c
index ea72385aaf0a9..438e2dba63b59 100644
--- a/arch/powerpc/platforms/iseries/lpardata.c
+++ b/arch/powerpc/platforms/iseries/lpardata.c
@@ -93,10 +93,7 @@ struct ItLpNaca itLpNaca = {
.xPirEnvironMode = 0, /* Piranha stuff */
.xPirConsoleMode = 0,
.xPirDasdMode = 0,
- .xLparInstalled = 0,
- .xSysPartitioned = 0,
- .xHwSyncedTBs = 0,
- .xIntProcUtilHmt = 0,
+ .flags = 0,
.xSpVpdFormat = 0,
.xIntProcRatio = 0,
.xPlicVrmIndex = 0, /* VRM index of PLIC */
diff --git a/arch/powerpc/platforms/iseries/lpevents.c b/arch/powerpc/platforms/iseries/lpevents.c
index e9fb98bf895f4..0b885300d1d1a 100644
--- a/arch/powerpc/platforms/iseries/lpevents.c
+++ b/arch/powerpc/platforms/iseries/lpevents.c
@@ -53,7 +53,7 @@ static struct HvLpEvent * get_next_hvlpevent(void)
struct HvLpEvent * event;
event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr;
- if (event->xFlags.xValid) {
+ if (hvlpevent_is_valid(event)) {
/* rmb() needed only for weakly consistent machines (regatta) */
rmb();
/* Set pointer to next potential event */
@@ -84,7 +84,7 @@ int hvlpevent_is_pending(void)
next_event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr;
- return next_event->xFlags.xValid |
+ return hvlpevent_is_valid(next_event) ||
hvlpevent_queue.xPlicOverflowIntPending;
}
@@ -101,18 +101,18 @@ static void hvlpevent_clear_valid(struct HvLpEvent * event)
switch (extra) {
case 3:
tmp = (struct HvLpEvent*)((char*)event + 3 * LpEventAlign);
- tmp->xFlags.xValid = 0;
+ hvlpevent_invalidate(tmp);
case 2:
tmp = (struct HvLpEvent*)((char*)event + 2 * LpEventAlign);
- tmp->xFlags.xValid = 0;
+ hvlpevent_invalidate(tmp);
case 1:
tmp = (struct HvLpEvent*)((char*)event + 1 * LpEventAlign);
- tmp->xFlags.xValid = 0;
+ hvlpevent_invalidate(tmp);
}
mb();
- event->xFlags.xValid = 0;
+ hvlpevent_invalidate(event);
}
void process_hvlpevents(struct pt_regs *regs)
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c
index 49e7e4b858475..a41d8b78c0cd6 100644
--- a/arch/powerpc/platforms/iseries/mf.c
+++ b/arch/powerpc/platforms/iseries/mf.c
@@ -251,10 +251,7 @@ static struct pending_event *new_pending_event(void)
}
memset(ev, 0, sizeof(struct pending_event));
hev = &ev->event.hp_lp_event;
- hev->xFlags.xValid = 1;
- hev->xFlags.xAckType = HvLpEvent_AckType_ImmediateAck;
- hev->xFlags.xAckInd = HvLpEvent_AckInd_DoAck;
- hev->xFlags.xFunction = HvLpEvent_Function_Int;
+ hev->flags = HV_LP_EVENT_VALID | HV_LP_EVENT_DO_ACK | HV_LP_EVENT_INT;
hev->xType = HvLpEvent_Type_MachineFac;
hev->xSourceLp = HvLpConfig_getLpIndex();
hev->xTargetLp = primary_lp;
@@ -518,17 +515,10 @@ static void handle_ack(struct io_mf_lp_event *event)
static void hv_handler(struct HvLpEvent *event, struct pt_regs *regs)
{
if ((event != NULL) && (event->xType == HvLpEvent_Type_MachineFac)) {
- switch(event->xFlags.xFunction) {
- case HvLpEvent_Function_Ack:
+ if (hvlpevent_is_ack(event))
handle_ack((struct io_mf_lp_event *)event);
- break;
- case HvLpEvent_Function_Int:
+ else
handle_int((struct io_mf_lp_event *)event);
- break;
- default:
- printk(KERN_ERR "mf.c: non ack/int event received\n");
- break;
- }
} else
printk(KERN_ERR "mf.c: alien event received\n");
}
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index dafc518fbb833..a19833b880e40 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -43,6 +43,7 @@
#include "irq.h"
#include "pci.h"
#include "call_pci.h"
+#include "iommu.h"
extern unsigned long io_page_mask;
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
index 384360ee06ec6..ad36ab0639f04 100644
--- a/arch/powerpc/platforms/iseries/vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -22,6 +22,8 @@
#include <asm/iseries/hv_lp_config.h>
#include <asm/iseries/hv_call_xm.h>
+#include "iommu.h"
+
struct device *iSeries_vio_dev = &vio_bus_device.dev;
EXPORT_SYMBOL(iSeries_vio_dev);
diff --git a/arch/powerpc/platforms/iseries/viopath.c b/arch/powerpc/platforms/iseries/viopath.c
index 842672695598e..622a30149b48b 100644
--- a/arch/powerpc/platforms/iseries/viopath.c
+++ b/arch/powerpc/platforms/iseries/viopath.c
@@ -270,7 +270,7 @@ static void handleMonitorEvent(struct HvLpEvent *event)
* First see if this is just a normal monitor message from the
* other partition
*/
- if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
+ if (hvlpevent_is_int(event)) {
remoteLp = event->xSourceLp;
if (!viopathStatus[remoteLp].isActive)
sendMonMsg(remoteLp);
@@ -331,13 +331,12 @@ static void handleConfig(struct HvLpEvent *event)
{
if (!event)
return;
- if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
+ if (hvlpevent_is_int(event)) {
printk(VIOPATH_KERN_WARN
"unexpected config request from partition %d",
event->xSourceLp);
- if ((event->xFlags.xFunction == HvLpEvent_Function_Int) &&
- (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck)) {
+ if (hvlpevent_need_ack(event)) {
event->xRc = HvLpEvent_Rc_InvalidSubtype;
HvCallEvent_ackLpEvent(event);
}
@@ -377,7 +376,7 @@ static void vio_handleEvent(struct HvLpEvent *event, struct pt_regs *regs)
int subtype = (event->xSubtype & VIOMAJOR_SUBTYPE_MASK)
>> VIOMAJOR_SUBTYPE_SHIFT;
- if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
+ if (hvlpevent_is_int(event)) {
remoteLp = event->xSourceLp;
/*
* The isActive is checked because if the hosting partition
@@ -436,8 +435,7 @@ static void vio_handleEvent(struct HvLpEvent *event, struct pt_regs *regs)
"unexpected virtual io event subtype %d from partition %d\n",
event->xSubtype, remoteLp);
/* No handler. Ack if necessary */
- if ((event->xFlags.xFunction == HvLpEvent_Function_Int) &&
- (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck)) {
+ if (hvlpevent_is_int(event) && hvlpevent_need_ack(event)) {
event->xRc = HvLpEvent_Rc_InvalidSubtype;
HvCallEvent_ackLpEvent(event);
}
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 3b1a9d4fcbc6c..89c4c36361610 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -278,7 +278,7 @@ static void __init l2cr_init(void)
}
#endif
-void __init pmac_setup_arch(void)
+static void __init pmac_setup_arch(void)
{
struct device_node *cpu, *ic;
int *fp;
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 17cea7f2afd3a..83578313ee7e7 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -208,10 +208,11 @@ static void __eeh_mark_slot (struct device_node *dn, int mode_flag)
{
while (dn) {
if (PCI_DN(dn)) {
- PCI_DN(dn)->eeh_mode |= mode_flag;
-
/* Mark the pci device driver too */
struct pci_dev *dev = PCI_DN(dn)->pcidev;
+
+ PCI_DN(dn)->eeh_mode |= mode_flag;
+
if (dev && dev->driver)
dev->error_state = pci_channel_io_frozen;
diff --git a/arch/powerpc/platforms/pseries/hvcserver.c b/arch/powerpc/platforms/pseries/hvcserver.c
index 4d584172055a6..22bfb5c89db9f 100644
--- a/arch/powerpc/platforms/pseries/hvcserver.c
+++ b/arch/powerpc/platforms/pseries/hvcserver.c
@@ -40,7 +40,7 @@ MODULE_VERSION(HVCS_ARCH_VERSION);
* functions aren't performance sensitive, so this conversion isn't an
* issue.
*/
-int hvcs_convert(long to_convert)
+static int hvcs_convert(long to_convert)
{
switch (to_convert) {
case H_Success:
@@ -91,7 +91,7 @@ int hvcs_free_partner_info(struct list_head *head)
EXPORT_SYMBOL(hvcs_free_partner_info);
/* Helper function for hvcs_get_partner_info */
-int hvcs_next_partner(uint32_t unit_address,
+static int hvcs_next_partner(uint32_t unit_address,
unsigned long last_p_partition_ID,
unsigned long last_p_unit_address, unsigned long *pi_buff)
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 169f9148789c7..48cfbfc43f992 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -51,8 +51,6 @@
#define DBG(fmt...)
-extern int is_python(struct device_node *);
-
static void tce_build_pSeries(struct iommu_table *tbl, long index,
long npages, unsigned long uaddr,
enum dma_data_direction direction)
diff --git a/arch/powerpc/platforms/pseries/scanlog.c b/arch/powerpc/platforms/pseries/scanlog.c
index 2edc947f7c44b..50643496eb635 100644
--- a/arch/powerpc/platforms/pseries/scanlog.c
+++ b/arch/powerpc/platforms/pseries/scanlog.c
@@ -192,7 +192,7 @@ struct file_operations scanlog_fops = {
.release = scanlog_release,
};
-int __init scanlog_init(void)
+static int __init scanlog_init(void)
{
struct proc_dir_entry *ent;
@@ -222,7 +222,7 @@ int __init scanlog_init(void)
return 0;
}
-void __exit scanlog_cleanup(void)
+static void __exit scanlog_cleanup(void)
{
if (proc_ppc64_scan_log_dump) {
kfree(proc_ppc64_scan_log_dump->data);
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 8903cf63236a2..68b7f086d63db 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -86,7 +86,7 @@ static void pseries_dedicated_idle(void);
struct mpic *pSeries_mpic;
-void pSeries_show_cpuinfo(struct seq_file *m)
+static void pSeries_show_cpuinfo(struct seq_file *m)
{
struct device_node *root;
const char *model = "";
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index 2f543cea97879..8e6b1ed1396e4 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -93,7 +93,7 @@ static int query_cpu_stopped(unsigned int pcpu)
return cpu_status;
}
-int pSeries_cpu_disable(void)
+static int pSeries_cpu_disable(void)
{
int cpu = smp_processor_id();
@@ -109,7 +109,7 @@ int pSeries_cpu_disable(void)
return 0;
}
-void pSeries_cpu_die(unsigned int cpu)
+static void pSeries_cpu_die(unsigned int cpu)
{
int tries;
int cpu_status;
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 0c0cfa32eb58f..fd823c7c9ac88 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -381,7 +381,7 @@ int xics_get_irq(struct pt_regs *regs)
#ifdef CONFIG_SMP
-irqreturn_t xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
{
int cpu = smp_processor_id();
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index e00b46b9514ed..977de9db87547 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -139,7 +139,6 @@ static void dart_build(struct iommu_table *tbl, long index,
*(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK);
- rpn++;
uaddr += DART_PAGE_SIZE;
}
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 22612ed5379c4..7d02fa2a89902 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -311,7 +311,7 @@ static void release_output_lock(void)
}
#endif
-int xmon_core(struct pt_regs *regs, int fromipi)
+static int xmon_core(struct pt_regs *regs, int fromipi)
{
int cmd = 0;
unsigned long msr;
@@ -528,7 +528,7 @@ xmon_irq(int irq, void *d, struct pt_regs *regs)
return IRQ_HANDLED;
}
-int xmon_bpt(struct pt_regs *regs)
+static int xmon_bpt(struct pt_regs *regs)
{
struct bpt *bp;
unsigned long offset;
@@ -554,7 +554,7 @@ int xmon_bpt(struct pt_regs *regs)
return 1;
}
-int xmon_sstep(struct pt_regs *regs)
+static int xmon_sstep(struct pt_regs *regs)
{
if (user_mode(regs))
return 0;
@@ -562,7 +562,7 @@ int xmon_sstep(struct pt_regs *regs)
return 1;
}
-int xmon_dabr_match(struct pt_regs *regs)
+static int xmon_dabr_match(struct pt_regs *regs)
{
if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
return 0;
@@ -572,7 +572,7 @@ int xmon_dabr_match(struct pt_regs *regs)
return 1;
}
-int xmon_iabr_match(struct pt_regs *regs)
+static int xmon_iabr_match(struct pt_regs *regs)
{
if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
return 0;
@@ -582,7 +582,7 @@ int xmon_iabr_match(struct pt_regs *regs)
return 1;
}
-int xmon_ipi(struct pt_regs *regs)
+static int xmon_ipi(struct pt_regs *regs)
{
#ifdef CONFIG_SMP
if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
@@ -591,7 +591,7 @@ int xmon_ipi(struct pt_regs *regs)
return 0;
}
-int xmon_fault_handler(struct pt_regs *regs)
+static int xmon_fault_handler(struct pt_regs *regs)
{
struct bpt *bp;
unsigned long offset;
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index e6c1d615bb860..ca02013008682 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -13,7 +13,6 @@ extra-$(CONFIG_POWER4) += idle_power4.o
extra-y += vmlinux.lds
obj-y := entry.o traps.o idle.o time.o misc.o \
- process.o \
setup.o \
ppc_htab.o
obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o
diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c
deleted file mode 100644
index a76b504299ca0..0000000000000
--- a/arch/ppc/kernel/process.c
+++ /dev/null
@@ -1,851 +0,0 @@
-/*
- * arch/ppc/kernel/process.c
- *
- * Derived from "arch/i386/kernel/process.c"
- * Copyright (C) 1995 Linus Torvalds
- *
- * Updated and modified by Cort Dougan (cort@cs.nmt.edu) and
- * Paul Mackerras (paulus@cs.anu.edu.au)
- *
- * PowerPC version
- * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- */
-
-#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/user.h>
-#include <linux/elf.h>
-#include <linux/init.h>
-#include <linux/prctl.h>
-#include <linux/init_task.h>
-#include <linux/module.h>
-#include <linux/kallsyms.h>
-#include <linux/mqueue.h>
-#include <linux/hardirq.h>
-
-#include <asm/pgtable.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/processor.h>
-#include <asm/mmu.h>
-#include <asm/prom.h>
-
-extern unsigned long _get_SP(void);
-
-struct task_struct *last_task_used_math = NULL;
-struct task_struct *last_task_used_altivec = NULL;
-struct task_struct *last_task_used_spe = NULL;
-
-static struct fs_struct init_fs = INIT_FS;
-static struct files_struct init_files = INIT_FILES;
-static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
-static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
-struct mm_struct init_mm = INIT_MM(init_mm);
-EXPORT_SYMBOL(init_mm);
-
-/* this is 8kB-aligned so we can get to the thread_info struct
- at the base of it from the stack pointer with 1 integer instruction. */
-union thread_union init_thread_union
- __attribute__((__section__(".data.init_task"))) =
-{ INIT_THREAD_INFO(init_task) };
-
-/* initial task structure */
-struct task_struct init_task = INIT_TASK(init_task);
-EXPORT_SYMBOL(init_task);
-
-/* only used to get secondary processor up */
-struct task_struct *current_set[NR_CPUS] = {&init_task, };
-
-#undef SHOW_TASK_SWITCHES
-#undef CHECK_STACK
-
-#if defined(CHECK_STACK)
-unsigned long
-kernel_stack_top(struct task_struct *tsk)
-{
- return ((unsigned long)tsk) + sizeof(union task_union);
-}
-
-unsigned long
-task_top(struct task_struct *tsk)
-{
- return ((unsigned long)tsk) + sizeof(struct thread_info);
-}
-
-/* check to make sure the kernel stack is healthy */
-int check_stack(struct task_struct *tsk)
-{
- unsigned long stack_top = kernel_stack_top(tsk);
- unsigned long tsk_top = task_top(tsk);
- int ret = 0;
-
-#if 0
- /* check thread magic */
- if ( tsk->thread.magic != THREAD_MAGIC )
- {
- ret |= 1;
- printk("thread.magic bad: %08x\n", tsk->thread.magic);
- }
-#endif
-
- if ( !tsk )
- printk("check_stack(): tsk bad tsk %p\n",tsk);
-
- /* check if stored ksp is bad */
- if ( (tsk->thread.ksp > stack_top) || (tsk->thread.ksp < tsk_top) )
- {
- printk("stack out of bounds: %s/%d\n"
- " tsk_top %08lx ksp %08lx stack_top %08lx\n",
- tsk->comm,tsk->pid,
- tsk_top, tsk->thread.ksp, stack_top);
- ret |= 2;
- }
-
- /* check if stack ptr RIGHT NOW is bad */
- if ( (tsk == current) && ((_get_SP() > stack_top ) || (_get_SP() < tsk_top)) )
- {
- printk("current stack ptr out of bounds: %s/%d\n"
- " tsk_top %08lx sp %08lx stack_top %08lx\n",
- current->comm,current->pid,
- tsk_top, _get_SP(), stack_top);
- ret |= 4;
- }
-
-#if 0
- /* check amount of free stack */
- for ( i = (unsigned long *)task_top(tsk) ; i < kernel_stack_top(tsk) ; i++ )
- {
- if ( !i )
- printk("check_stack(): i = %p\n", i);
- if ( *i != 0 )
- {
- /* only notify if it's less than 900 bytes */
- if ( (i - (unsigned long *)task_top(tsk)) < 900 )
- printk("%d bytes free on stack\n",
- i - task_top(tsk));
- break;
- }
- }
-#endif
-
- if (ret)
- {
- panic("bad kernel stack");
- }
- return(ret);
-}
-#endif /* defined(CHECK_STACK) */
-
-/*
- * Make sure the floating-point register state in the
- * the thread_struct is up to date for task tsk.
- */
-void flush_fp_to_thread(struct task_struct *tsk)
-{
- if (tsk->thread.regs) {
- /*
- * We need to disable preemption here because if we didn't,
- * another process could get scheduled after the regs->msr
- * test but before we have finished saving the FP registers
- * to the thread_struct. That process could take over the
- * FPU, and then when we get scheduled again we would store
- * bogus values for the remaining FP registers.
- */
- preempt_disable();
- if (tsk->thread.regs->msr & MSR_FP) {
-#ifdef CONFIG_SMP
- /*
- * This should only ever be called for current or
- * for a stopped child process. Since we save away
- * the FP register state on context switch on SMP,
- * there is something wrong if a stopped child appears
- * to still have its FP state in the CPU registers.
- */
- BUG_ON(tsk != current);
-#endif
- giveup_fpu(current);
- }
- preempt_enable();
- }
-}
-
-void enable_kernel_fp(void)
-{
- WARN_ON(preemptible());
-
-#ifdef CONFIG_SMP
- if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
- giveup_fpu(current);
- else
- giveup_fpu(NULL); /* just enables FP for kernel */
-#else
- giveup_fpu(last_task_used_math);
-#endif /* CONFIG_SMP */
-}
-EXPORT_SYMBOL(enable_kernel_fp);
-
-int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
-{
- preempt_disable();
- if (tsk->thread.regs && (tsk->thread.regs->msr & MSR_FP))
- giveup_fpu(tsk);
- preempt_enable();
- memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs));
- return 1;
-}
-
-#ifdef CONFIG_ALTIVEC
-void enable_kernel_altivec(void)
-{
- WARN_ON(preemptible());
-
-#ifdef CONFIG_SMP
- if (current->thread.regs && (current->thread.regs->msr & MSR_VEC))
- giveup_altivec(current);
- else
- giveup_altivec(NULL); /* just enable AltiVec for kernel - force */
-#else
- giveup_altivec(last_task_used_altivec);
-#endif /* __SMP __ */
-}
-EXPORT_SYMBOL(enable_kernel_altivec);
-
-/*
- * Make sure the VMX/Altivec register state in the
- * the thread_struct is up to date for task tsk.
- */
-void flush_altivec_to_thread(struct task_struct *tsk)
-{
- if (tsk->thread.regs) {
- preempt_disable();
- if (tsk->thread.regs->msr & MSR_VEC) {
-#ifdef CONFIG_SMP
- BUG_ON(tsk != current);
-#endif
- giveup_altivec(current);
- }
- preempt_enable();
- }
-}
-
-int dump_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
-{
- if (regs->msr & MSR_VEC)
- giveup_altivec(current);
- memcpy(vrregs, &current->thread.vr[0], sizeof(*vrregs));
- return 1;
-}
-#endif /* CONFIG_ALTIVEC */
-
-#ifdef CONFIG_SPE
-void
-enable_kernel_spe(void)
-{
- WARN_ON(preemptible());
-
-#ifdef CONFIG_SMP
- if (current->thread.regs && (current->thread.regs->msr & MSR_SPE))
- giveup_spe(current);
- else
- giveup_spe(NULL); /* just enable SPE for kernel - force */
-#else
- giveup_spe(last_task_used_spe);
-#endif /* __SMP __ */
-}
-EXPORT_SYMBOL(enable_kernel_spe);
-
-void flush_spe_to_thread(struct task_struct *tsk)
-{
- if (tsk->thread.regs) {
- preempt_disable();
- if (tsk->thread.regs->msr & MSR_SPE) {
-#ifdef CONFIG_SMP
- BUG_ON(tsk != current);
-#endif
- giveup_spe(current);
- }
- preempt_enable();
- }
-}
-
-int dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs)
-{
- if (regs->msr & MSR_SPE)
- giveup_spe(current);
- /* We copy u32 evr[32] + u64 acc + u32 spefscr -> 35 */
- memcpy(evrregs, &current->thread.evr[0], sizeof(u32) * 35);
- return 1;
-}
-#endif /* CONFIG_SPE */
-
-struct task_struct *__switch_to(struct task_struct *prev,
- struct task_struct *new)
-{
- struct thread_struct *new_thread, *old_thread;
- unsigned long s;
- struct task_struct *last;
-
- local_irq_save(s);
-#ifdef CHECK_STACK
- check_stack(prev);
- check_stack(new);
-#endif
-
-#ifdef CONFIG_SMP
- /* avoid complexity of lazy save/restore of fpu
- * by just saving it every time we switch out if
- * this task used the fpu during the last quantum.
- *
- * If it tries to use the fpu again, it'll trap and
- * reload its fp regs. So we don't have to do a restore
- * every switch, just a save.
- * -- Cort
- */
- if (prev->thread.regs && (prev->thread.regs->msr & MSR_FP))
- giveup_fpu(prev);
-#ifdef CONFIG_ALTIVEC
- /*
- * If the previous thread used altivec in the last quantum
- * (thus changing altivec regs) then save them.
- * We used to check the VRSAVE register but not all apps
- * set it, so we don't rely on it now (and in fact we need
- * to save & restore VSCR even if VRSAVE == 0). -- paulus
- *
- * On SMP we always save/restore altivec regs just to avoid the
- * complexity of changing processors.
- * -- Cort
- */
- if ((prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)))
- giveup_altivec(prev);
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_SPE
- /*
- * If the previous thread used spe in the last quantum
- * (thus changing spe regs) then save them.
- *
- * On SMP we always save/restore spe regs just to avoid the
- * complexity of changing processors.
- */
- if ((prev->thread.regs && (prev->thread.regs->msr & MSR_SPE)))
- giveup_spe(prev);
-#endif /* CONFIG_SPE */
-#endif /* CONFIG_SMP */
-
-#ifdef CONFIG_ALTIVEC
- /* Avoid the trap. On smp this this never happens since
- * we don't set last_task_used_altivec -- Cort
- */
- if (new->thread.regs && last_task_used_altivec == new)
- new->thread.regs->msr |= MSR_VEC;
-#endif
-#ifdef CONFIG_SPE
- /* Avoid the trap. On smp this this never happens since
- * we don't set last_task_used_spe
- */
- if (new->thread.regs && last_task_used_spe == new)
- new->thread.regs->msr |= MSR_SPE;
-#endif /* CONFIG_SPE */
- new_thread = &new->thread;
- old_thread = &current->thread;
- last = _switch(old_thread, new_thread);
- local_irq_restore(s);
- return last;
-}
-
-void show_regs(struct pt_regs * regs)
-{
- int i, trap;
-
- printk("NIP: %08lX LR: %08lX SP: %08lX REGS: %p TRAP: %04lx %s\n",
- regs->nip, regs->link, regs->gpr[1], regs, regs->trap,
- print_tainted());
- printk("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
- regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
- regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
- regs->msr&MSR_IR ? 1 : 0,
- regs->msr&MSR_DR ? 1 : 0);
- trap = TRAP(regs);
- if (trap == 0x300 || trap == 0x600)
- printk("DAR: %08lX, DSISR: %08lX\n", regs->dar, regs->dsisr);
- printk("TASK = %p[%d] '%s' THREAD: %p\n",
- current, current->pid, current->comm, task_thread_info(current));
- printk("Last syscall: %ld ", current->thread.last_syscall);
-
-#ifdef CONFIG_SMP
- printk(" CPU: %d", smp_processor_id());
-#endif /* CONFIG_SMP */
-
- for (i = 0; i < 32; i++) {
- long r;
- if ((i % 8) == 0)
- printk("\n" KERN_INFO "GPR%02d: ", i);
- if (__get_user(r, &regs->gpr[i]))
- break;
- printk("%08lX ", r);
- if (i == 12 && !FULL_REGS(regs))
- break;
- }
- printk("\n");
-#ifdef CONFIG_KALLSYMS
- /*
- * Lookup NIP late so we have the best change of getting the
- * above info out without failing
- */
- printk("NIP [%08lx] ", regs->nip);
- print_symbol("%s\n", regs->nip);
- printk("LR [%08lx] ", regs->link);
- print_symbol("%s\n", regs->link);
-#endif
- show_stack(current, (unsigned long *) regs->gpr[1]);
-}
-
-void exit_thread(void)
-{
- preempt_disable();
- if (last_task_used_math == current)
- last_task_used_math = NULL;
- if (last_task_used_altivec == current)
- last_task_used_altivec = NULL;
-#ifdef CONFIG_SPE
- if (last_task_used_spe == current)
- last_task_used_spe = NULL;
-#endif
- preempt_enable();
-}
-
-void flush_thread(void)
-{
- preempt_disable();
- if (last_task_used_math == current)
- last_task_used_math = NULL;
- if (last_task_used_altivec == current)
- last_task_used_altivec = NULL;
-#ifdef CONFIG_SPE
- if (last_task_used_spe == current)
- last_task_used_spe = NULL;
-#endif
- preempt_enable();
-}
-
-void
-release_thread(struct task_struct *t)
-{
-}
-
-/*
- * This gets called before we allocate a new thread and copy
- * the current task into it.
- */
-void prepare_to_copy(struct task_struct *tsk)
-{
- struct pt_regs *regs = tsk->thread.regs;
-
- if (regs == NULL)
- return;
- preempt_disable();
- if (regs->msr & MSR_FP)
- giveup_fpu(current);
-#ifdef CONFIG_ALTIVEC
- if (regs->msr & MSR_VEC)
- giveup_altivec(current);
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_SPE
- if (regs->msr & MSR_SPE)
- giveup_spe(current);
-#endif /* CONFIG_SPE */
- preempt_enable();
-}
-
-/*
- * Copy a thread..
- */
-int
-copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
- unsigned long unused,
- struct task_struct *p, struct pt_regs *regs)
-{
- struct pt_regs *childregs, *kregs;
- extern void ret_from_fork(void);
- unsigned long sp = (unsigned long)task_stack_page(p) + THREAD_SIZE;
- unsigned long childframe;
-
- CHECK_FULL_REGS(regs);
- /* Copy registers */
- sp -= sizeof(struct pt_regs);
- childregs = (struct pt_regs *) sp;
- *childregs = *regs;
- if ((childregs->msr & MSR_PR) == 0) {
- /* for kernel thread, set `current' and stackptr in new task */
- childregs->gpr[1] = sp + sizeof(struct pt_regs);
- childregs->gpr[2] = (unsigned long) p;
- p->thread.regs = NULL; /* no user register state */
- } else {
- childregs->gpr[1] = usp;
- p->thread.regs = childregs;
- if (clone_flags & CLONE_SETTLS)
- childregs->gpr[2] = childregs->gpr[6];
- }
- childregs->gpr[3] = 0; /* Result from fork() */
- sp -= STACK_FRAME_OVERHEAD;
- childframe = sp;
-
- /*
- * The way this works is that at some point in the future
- * some task will call _switch to switch to the new task.
- * That will pop off the stack frame created below and start
- * the new task running at ret_from_fork. The new task will
- * do some house keeping and then return from the fork or clone
- * system call, using the stack frame created above.
- */
- sp -= sizeof(struct pt_regs);
- kregs = (struct pt_regs *) sp;
- sp -= STACK_FRAME_OVERHEAD;
- p->thread.ksp = sp;
- kregs->nip = (unsigned long)ret_from_fork;
-
- p->thread.last_syscall = -1;
-
- return 0;
-}
-
-/*
- * Set up a thread for executing a new program
- */
-void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp)
-{
- set_fs(USER_DS);
- memset(regs->gpr, 0, sizeof(regs->gpr));
- regs->ctr = 0;
- regs->link = 0;
- regs->xer = 0;
- regs->ccr = 0;
- regs->mq = 0;
- regs->nip = nip;
- regs->gpr[1] = sp;
- regs->msr = MSR_USER;
- preempt_disable();
- if (last_task_used_math == current)
- last_task_used_math = NULL;
- if (last_task_used_altivec == current)
- last_task_used_altivec = NULL;
-#ifdef CONFIG_SPE
- if (last_task_used_spe == current)
- last_task_used_spe = NULL;
-#endif
- preempt_enable();
- memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
- current->thread.fpscr.val = 0;
-#ifdef CONFIG_ALTIVEC
- memset(current->thread.vr, 0, sizeof(current->thread.vr));
- memset(&current->thread.vscr, 0, sizeof(current->thread.vscr));
- current->thread.vrsave = 0;
- current->thread.used_vr = 0;
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_SPE
- memset(current->thread.evr, 0, sizeof(current->thread.evr));
- current->thread.acc = 0;
- current->thread.spefscr = 0;
- current->thread.used_spe = 0;
-#endif /* CONFIG_SPE */
-}
-
-#define PR_FP_ALL_EXCEPT (PR_FP_EXC_DIV | PR_FP_EXC_OVF | PR_FP_EXC_UND \
- | PR_FP_EXC_RES | PR_FP_EXC_INV)
-
-int set_fpexc_mode(struct task_struct *tsk, unsigned int val)
-{
- struct pt_regs *regs = tsk->thread.regs;
-
- /* This is a bit hairy. If we are an SPE enabled processor
- * (have embedded fp) we store the IEEE exception enable flags in
- * fpexc_mode. fpexc_mode is also used for setting FP exception
- * mode (asyn, precise, disabled) for 'Classic' FP. */
- if (val & PR_FP_EXC_SW_ENABLE) {
-#ifdef CONFIG_SPE
- tsk->thread.fpexc_mode = val &
- (PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT);
-#else
- return -EINVAL;
-#endif
- } else {
- /* on a CONFIG_SPE this does not hurt us. The bits that
- * __pack_fe01 use do not overlap with bits used for
- * PR_FP_EXC_SW_ENABLE. Additionally, the MSR[FE0,FE1] bits
- * on CONFIG_SPE implementations are reserved so writing to
- * them does not change anything */
- if (val > PR_FP_EXC_PRECISE)
- return -EINVAL;
- tsk->thread.fpexc_mode = __pack_fe01(val);
- if (regs != NULL && (regs->msr & MSR_FP) != 0)
- regs->msr = (regs->msr & ~(MSR_FE0|MSR_FE1))
- | tsk->thread.fpexc_mode;
- }
- return 0;
-}
-
-int get_fpexc_mode(struct task_struct *tsk, unsigned long adr)
-{
- unsigned int val;
-
- if (tsk->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE)
-#ifdef CONFIG_SPE
- val = tsk->thread.fpexc_mode;
-#else
- return -EINVAL;
-#endif
- else
- val = __unpack_fe01(tsk->thread.fpexc_mode);
- return put_user(val, (unsigned int __user *) adr);
-}
-
-int sys_clone(unsigned long clone_flags, unsigned long usp,
- int __user *parent_tidp, void __user *child_threadptr,
- int __user *child_tidp, int p6,
- struct pt_regs *regs)
-{
- CHECK_FULL_REGS(regs);
- if (usp == 0)
- usp = regs->gpr[1]; /* stack pointer for child */
- return do_fork(clone_flags, usp, regs, 0, parent_tidp, child_tidp);
-}
-
-int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
- unsigned long p4, unsigned long p5, unsigned long p6,
- struct pt_regs *regs)
-{
- CHECK_FULL_REGS(regs);
- return do_fork(SIGCHLD, regs->gpr[1], regs, 0, NULL, NULL);
-}
-
-int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
- unsigned long p4, unsigned long p5, unsigned long p6,
- struct pt_regs *regs)
-{
- CHECK_FULL_REGS(regs);
- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1],
- regs, 0, NULL, NULL);
-}
-
-int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
- unsigned long a3, unsigned long a4, unsigned long a5,
- struct pt_regs *regs)
-{
- int error;
- char * filename;
-
- filename = getname((char __user *) a0);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- goto out;
- preempt_disable();
- if (regs->msr & MSR_FP)
- giveup_fpu(current);
-#ifdef CONFIG_ALTIVEC
- if (regs->msr & MSR_VEC)
- giveup_altivec(current);
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_SPE
- if (regs->msr & MSR_SPE)
- giveup_spe(current);
-#endif /* CONFIG_SPE */
- preempt_enable();
- error = do_execve(filename, (char __user *__user *) a1,
- (char __user *__user *) a2, regs);
- if (error == 0) {
- task_lock(current);
- current->ptrace &= ~PT_DTRACE;
- task_unlock(current);
- }
- putname(filename);
-out:
- return error;
-}
-
-void dump_stack(void)
-{
- show_stack(current, NULL);
-}
-
-EXPORT_SYMBOL(dump_stack);
-
-void show_stack(struct task_struct *tsk, unsigned long *stack)
-{
- unsigned long sp, stack_top, prev_sp, ret;
- int count = 0;
- unsigned long next_exc = 0;
- struct pt_regs *regs;
- extern char ret_from_except, ret_from_except_full, ret_from_syscall;
-
- sp = (unsigned long) stack;
- if (tsk == NULL)
- tsk = current;
- if (sp == 0) {
- if (tsk == current)
- asm("mr %0,1" : "=r" (sp));
- else
- sp = tsk->thread.ksp;
- }
-
- prev_sp = (unsigned long) end_of_stack(tsk);
- stack_top = (unsigned long) task_stack_page(tsk) + THREAD_SIZE;
- while (count < 16 && sp > prev_sp && sp < stack_top && (sp & 3) == 0) {
- if (count == 0) {
- printk("Call trace:");
-#ifdef CONFIG_KALLSYMS
- printk("\n");
-#endif
- } else {
- if (next_exc) {
- ret = next_exc;
- next_exc = 0;
- } else
- ret = *(unsigned long *)(sp + 4);
- printk(" [%08lx] ", ret);
-#ifdef CONFIG_KALLSYMS
- print_symbol("%s", ret);
- printk("\n");
-#endif
- if (ret == (unsigned long) &ret_from_except
- || ret == (unsigned long) &ret_from_except_full
- || ret == (unsigned long) &ret_from_syscall) {
- /* sp + 16 points to an exception frame */
- regs = (struct pt_regs *) (sp + 16);
- if (sp + 16 + sizeof(*regs) <= stack_top)
- next_exc = regs->nip;
- }
- }
- ++count;
- sp = *(unsigned long *)sp;
- }
-#ifndef CONFIG_KALLSYMS
- if (count > 0)
- printk("\n");
-#endif
-}
-
-#if 0
-/*
- * Low level print for debugging - Cort
- */
-int __init ll_printk(const char *fmt, ...)
-{
- va_list args;
- char buf[256];
- int i;
-
- va_start(args, fmt);
- i=vsprintf(buf,fmt,args);
- ll_puts(buf);
- va_end(args);
- return i;
-}
-
-int lines = 24, cols = 80;
-int orig_x = 0, orig_y = 0;
-
-void puthex(unsigned long val)
-{
- unsigned char buf[10];
- int i;
- for (i = 7; i >= 0; i--)
- {
- buf[i] = "0123456789ABCDEF"[val & 0x0F];
- val >>= 4;
- }
- buf[8] = '\0';
- prom_print(buf);
-}
-
-void __init ll_puts(const char *s)
-{
- int x,y;
- char *vidmem = (char *)/*(_ISA_MEM_BASE + 0xB8000) */0xD00B8000;
- char c;
- extern int mem_init_done;
-
- if ( mem_init_done ) /* assume this means we can printk */
- {
- printk(s);
- return;
- }
-
-#if 0
- if ( have_of )
- {
- prom_print(s);
- return;
- }
-#endif
-
- /*
- * can't ll_puts on chrp without openfirmware yet.
- * vidmem just needs to be setup for it.
- * -- Cort
- */
- if ( _machine != _MACH_prep )
- return;
- x = orig_x;
- y = orig_y;
-
- while ( ( c = *s++ ) != '\0' ) {
- if ( c == '\n' ) {
- x = 0;
- if ( ++y >= lines ) {
- /*scroll();*/
- /*y--;*/
- y = 0;
- }
- } else {
- vidmem [ ( x + cols * y ) * 2 ] = c;
- if ( ++x >= cols ) {
- x = 0;
- if ( ++y >= lines ) {
- /*scroll();*/
- /*y--;*/
- y = 0;
- }
- }
- }
- }
-
- orig_x = x;
- orig_y = y;
-}
-#endif
-
-unsigned long get_wchan(struct task_struct *p)
-{
- unsigned long ip, sp;
- unsigned long stack_page = (unsigned long) task_stack_page(p);
- int count = 0;
- if (!p || p == current || p->state == TASK_RUNNING)
- return 0;
- sp = p->thread.ksp;
- do {
- sp = *(unsigned long *)sp;
- if (sp < stack_page || sp >= stack_page + 8188)
- return 0;
- if (count > 0) {
- ip = *(unsigned long *)(sp + 4);
- if (!in_sched_functions(ip))
- return ip;
- }
- } while (count++ < 16);
- return 0;
-}
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index d1aaf31bd97e8..f63e07bd9f9c4 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -293,6 +293,7 @@ static int send_request(struct request *req)
u16 viocmd;
HvLpEvent_Rc hvrc;
struct vioblocklpevent *bevent;
+ struct HvLpEvent *hev;
struct scatterlist sg[VIOMAXBLOCKDMA];
int sgindex;
int statindex;
@@ -347,22 +348,19 @@ static int send_request(struct request *req)
* token so we can match the response up later
*/
memset(bevent, 0, sizeof(struct vioblocklpevent));
- bevent->event.xFlags.xValid = 1;
- bevent->event.xFlags.xFunction = HvLpEvent_Function_Int;
- bevent->event.xFlags.xAckInd = HvLpEvent_AckInd_DoAck;
- bevent->event.xFlags.xAckType = HvLpEvent_AckType_ImmediateAck;
- bevent->event.xType = HvLpEvent_Type_VirtualIo;
- bevent->event.xSubtype = viocmd;
- bevent->event.xSourceLp = HvLpConfig_getLpIndex();
- bevent->event.xTargetLp = viopath_hostLp;
- bevent->event.xSizeMinus1 =
+ hev = &bevent->event;
+ hev->flags = HV_LP_EVENT_VALID | HV_LP_EVENT_DO_ACK |
+ HV_LP_EVENT_INT;
+ hev->xType = HvLpEvent_Type_VirtualIo;
+ hev->xSubtype = viocmd;
+ hev->xSourceLp = HvLpConfig_getLpIndex();
+ hev->xTargetLp = viopath_hostLp;
+ hev->xSizeMinus1 =
offsetof(struct vioblocklpevent, u.rw_data.dma_info) +
(sizeof(bevent->u.rw_data.dma_info[0]) * nsg) - 1;
- bevent->event.xSourceInstanceId =
- viopath_sourceinst(viopath_hostLp);
- bevent->event.xTargetInstanceId =
- viopath_targetinst(viopath_hostLp);
- bevent->event.xCorrelationToken = (u64)req;
+ hev->xSourceInstanceId = viopath_sourceinst(viopath_hostLp);
+ hev->xTargetInstanceId = viopath_targetinst(viopath_hostLp);
+ hev->xCorrelationToken = (u64)req;
bevent->version = VIOVERSION;
bevent->disk = DEVICE_NO(d);
bevent->u.rw_data.offset = start;
@@ -649,10 +647,10 @@ static void handle_block_event(struct HvLpEvent *event)
/* Notification that a partition went away! */
return;
/* First, we should NEVER get an int here...only acks */
- if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
+ if (hvlpevent_is_int(event)) {
printk(VIOD_KERN_WARNING
"Yikes! got an int in viodasd event handler!\n");
- if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) {
+ if (hvlpevent_need_ack(event)) {
event->xRc = HvLpEvent_Rc_InvalidSubtype;
HvCallEvent_ackLpEvent(event);
}
@@ -695,7 +693,7 @@ static void handle_block_event(struct HvLpEvent *event)
default:
printk(VIOD_KERN_WARNING "invalid subtype!");
- if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) {
+ if (hvlpevent_need_ack(event)) {
event->xRc = HvLpEvent_Rc_InvalidSubtype;
HvCallEvent_ackLpEvent(event);
}
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index b5191780ecca4..193446e6a08a8 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -542,10 +542,10 @@ static void vio_handle_cd_event(struct HvLpEvent *event)
/* Notification that a partition went away! */
return;
/* First, we should NEVER get an int here...only acks */
- if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
+ if (hvlpevent_is_int(event)) {
printk(VIOCD_KERN_WARNING
"Yikes! got an int in viocd event handler!\n");
- if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) {
+ if (hvlpevent_need_ack(event)) {
event->xRc = HvLpEvent_Rc_InvalidSubtype;
HvCallEvent_ackLpEvent(event);
}
@@ -616,7 +616,7 @@ return_complete:
printk(VIOCD_KERN_WARNING
"message with invalid subtype %0x04X!\n",
event->xSubtype & VIOMINOR_SUBTYPE_MASK);
- if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) {
+ if (hvlpevent_need_ack(event)) {
event->xRc = HvLpEvent_Rc_InvalidSubtype;
HvCallEvent_ackLpEvent(event);
}
diff --git a/drivers/char/drm/Makefile b/drivers/char/drm/Makefile
index e41060c76226c..9d180c42816cb 100644
--- a/drivers/char/drm/Makefile
+++ b/drivers/char/drm/Makefile
@@ -3,7 +3,7 @@
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
drm-objs := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \
- drm_drv.o drm_fops.o drm_init.o drm_ioctl.o drm_irq.o \
+ drm_drv.o drm_fops.o drm_ioctl.o drm_irq.o \
drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
drm_sysfs.o
@@ -18,7 +18,7 @@ radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o
ffb-objs := ffb_drv.o ffb_context.o
sis-objs := sis_drv.o sis_ds.o sis_mm.o
savage-objs := savage_drv.o savage_bci.o savage_state.o
-via-objs := via_irq.o via_drv.o via_ds.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o
+via-objs := via_irq.o via_drv.o via_ds.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o via_dmablit.o
ifeq ($(CONFIG_COMPAT),y)
drm-objs += drm_ioc32.o
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c
index efff0eec618c2..5485382cadec8 100644
--- a/drivers/char/drm/ati_pcigart.c
+++ b/drivers/char/drm/ati_pcigart.c
@@ -52,7 +52,7 @@
# define ATI_MAX_PCIGART_PAGES 8192 /**< 32 MB aperture, 4K pages */
# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */
-static unsigned long drm_ati_alloc_pcigart_table(void)
+static void *drm_ati_alloc_pcigart_table(void)
{
unsigned long address;
struct page *page;
@@ -72,27 +72,26 @@ static unsigned long drm_ati_alloc_pcigart_table(void)
}
DRM_DEBUG("%s: returning 0x%08lx\n", __FUNCTION__, address);
- return address;
+ return (void *)address;
}
-static void drm_ati_free_pcigart_table(unsigned long address)
+static void drm_ati_free_pcigart_table(void *address)
{
struct page *page;
int i;
DRM_DEBUG("%s\n", __FUNCTION__);
- page = virt_to_page(address);
+ page = virt_to_page((unsigned long)address);
for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) {
__put_page(page);
ClearPageReserved(page);
}
- free_pages(address, ATI_PCIGART_TABLE_ORDER);
+ free_pages((unsigned long)address, ATI_PCIGART_TABLE_ORDER);
}
-int drm_ati_pcigart_cleanup(drm_device_t * dev,
- drm_ati_pcigart_info * gart_info)
+int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
{
drm_sg_mem_t *entry = dev->sg;
unsigned long pages;
@@ -136,10 +135,10 @@ int drm_ati_pcigart_cleanup(drm_device_t * dev,
EXPORT_SYMBOL(drm_ati_pcigart_cleanup);
-int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info * gart_info)
+int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
{
drm_sg_mem_t *entry = dev->sg;
- unsigned long address = 0;
+ void *address = NULL;
unsigned long pages;
u32 *pci_gart, page_base, bus_address = 0;
int i, j, ret = 0;
@@ -163,7 +162,7 @@ int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info * gart_info)
goto done;
}
- bus_address = pci_map_single(dev->pdev, (void *)address,
+ bus_address = pci_map_single(dev->pdev, address,
ATI_PCIGART_TABLE_PAGES *
PAGE_SIZE, PCI_DMA_TODEVICE);
if (bus_address == 0) {
@@ -176,7 +175,7 @@ int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info * gart_info)
address = gart_info->addr;
bus_address = gart_info->bus_addr;
DRM_DEBUG("PCI: Gart Table: VRAM %08X mapped at %08lX\n",
- bus_address, address);
+ bus_address, (unsigned long)address);
}
pci_gart = (u32 *) address;
@@ -195,7 +194,7 @@ int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info * gart_info)
if (entry->busaddr[i] == 0) {
DRM_ERROR("unable to map PCIGART pages!\n");
drm_ati_pcigart_cleanup(dev, gart_info);
- address = 0;
+ address = NULL;
bus_address = 0;
goto done;
}
diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h
index 64d6237fdd0ba..9da0ddb892b58 100644
--- a/drivers/char/drm/drm.h
+++ b/drivers/char/drm/drm.h
@@ -90,8 +90,8 @@
#define DRM_MAX_ORDER 22 /**< Up to 2^22 bytes = 4MB */
#define DRM_RAM_PERCENT 10 /**< How much system ram can we lock? */
-#define _DRM_LOCK_HELD 0x80000000 /**< Hardware lock is held */
-#define _DRM_LOCK_CONT 0x40000000 /**< Hardware lock is contended */
+#define _DRM_LOCK_HELD 0x80000000U /**< Hardware lock is held */
+#define _DRM_LOCK_CONT 0x40000000U /**< Hardware lock is contended */
#define _DRM_LOCK_IS_HELD(lock) ((lock) & _DRM_LOCK_HELD)
#define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT)
#define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT))
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 3dc3c9d79ae42..54b561e694862 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -144,20 +144,6 @@
/** \name Backward compatibility section */
/*@{*/
-#ifndef MODULE_LICENSE
-#define MODULE_LICENSE(x)
-#endif
-
-#ifndef preempt_disable
-#define preempt_disable()
-#define preempt_enable()
-#endif
-
-#ifndef pte_offset_map
-#define pte_offset_map pte_offset
-#define pte_unmap(pte)
-#endif
-
#define DRM_RPR_ARG(vma) vma,
#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT)
@@ -286,10 +272,13 @@ typedef int drm_ioctl_t(struct inode *inode, struct file *filp,
typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
unsigned long arg);
+#define DRM_AUTH 0x1
+#define DRM_MASTER 0x2
+#define DRM_ROOT_ONLY 0x4
+
typedef struct drm_ioctl_desc {
drm_ioctl_t *func;
- int auth_needed;
- int root_only;
+ int flags;
} drm_ioctl_desc_t;
typedef struct drm_devstate {
@@ -384,6 +373,7 @@ typedef struct drm_buf_entry {
/** File private data */
typedef struct drm_file {
int authenticated;
+ int master;
int minor;
pid_t pid;
uid_t uid;
@@ -532,8 +522,9 @@ typedef struct drm_vbl_sig {
typedef struct ati_pcigart_info {
int gart_table_location;
int is_pcie;
- unsigned long addr;
+ void *addr;
dma_addr_t bus_addr;
+ drm_local_map_t mapping;
} drm_ati_pcigart_info;
/**
@@ -544,16 +535,14 @@ typedef struct ati_pcigart_info {
struct drm_device;
struct drm_driver {
- int (*preinit) (struct drm_device *, unsigned long flags);
- void (*prerelease) (struct drm_device *, struct file * filp);
- void (*pretakedown) (struct drm_device *);
- int (*postcleanup) (struct drm_device *);
- int (*presetup) (struct drm_device *);
- int (*postsetup) (struct drm_device *);
+ int (*load) (struct drm_device *, unsigned long flags);
+ int (*firstopen) (struct drm_device *);
+ int (*open) (struct drm_device *, drm_file_t *);
+ void (*preclose) (struct drm_device *, struct file * filp);
+ void (*postclose) (struct drm_device *, drm_file_t *);
+ void (*lastclose) (struct drm_device *);
+ int (*unload) (struct drm_device *);
int (*dma_ioctl) (DRM_IOCTL_ARGS);
- int (*open_helper) (struct drm_device *, drm_file_t *);
- void (*free_filp_priv) (struct drm_device *, drm_file_t *);
- void (*release) (struct drm_device *, struct file * filp);
void (*dma_ready) (struct drm_device *);
int (*dma_quiescent) (struct drm_device *);
int (*context_ctor) (struct drm_device * dev, int context);
@@ -561,8 +550,9 @@ struct drm_driver {
int (*kernel_context_switch) (struct drm_device * dev, int old,
int new);
void (*kernel_context_switch_unlock) (struct drm_device * dev,
- drm_lock_t * lock);
+ drm_lock_t *lock);
int (*vblank_wait) (struct drm_device * dev, unsigned int *sequence);
+ int (*dri_library_name) (struct drm_device *dev, char *buf);
/**
* Called by \c drm_device_is_agp. Typically used to determine if a
@@ -579,16 +569,24 @@ struct drm_driver {
/* these have to be filled in */
- int (*postinit) (struct drm_device *, unsigned long flags);
- irqreturn_t(*irq_handler) (DRM_IRQ_ARGS);
+ irqreturn_t(*irq_handler) (DRM_IRQ_ARGS);
void (*irq_preinstall) (struct drm_device * dev);
void (*irq_postinstall) (struct drm_device * dev);
void (*irq_uninstall) (struct drm_device * dev);
void (*reclaim_buffers) (struct drm_device * dev, struct file * filp);
+ void (*reclaim_buffers_locked) (struct drm_device *dev,
+ struct file *filp);
unsigned long (*get_map_ofs) (drm_map_t * map);
unsigned long (*get_reg_ofs) (struct drm_device * dev);
void (*set_version) (struct drm_device * dev, drm_set_version_t * sv);
- int (*version) (drm_version_t * version);
+
+ int major;
+ int minor;
+ int patchlevel;
+ char *name;
+ char *desc;
+ char *date;
+
u32 driver_features;
int dev_priv_size;
drm_ioctl_desc_t *ioctls;
@@ -752,19 +750,43 @@ static inline int drm_core_has_MTRR(struct drm_device *dev)
{
return drm_core_check_feature(dev, DRIVER_USE_MTRR);
}
+
+#define DRM_MTRR_WC MTRR_TYPE_WRCOMB
+
+static inline int drm_mtrr_add(unsigned long offset, unsigned long size,
+ unsigned int flags)
+{
+ return mtrr_add(offset, size, flags, 1);
+}
+
+static inline int drm_mtrr_del(int handle, unsigned long offset,
+ unsigned long size, unsigned int flags)
+{
+ return mtrr_del(handle, offset, size);
+}
+
#else
#define drm_core_has_MTRR(dev) (0)
+
+#define DRM_MTRR_WC 0
+
+static inline int drm_mtrr_add(unsigned long offset, unsigned long size,
+ unsigned int flags)
+{
+ return 0;
+}
+
+static inline int drm_mtrr_del(int handle, unsigned long offset,
+ unsigned long size, unsigned int flags)
+{
+ return 0;
+}
#endif
/******************************************************************/
/** \name Internal function definitions */
/*@{*/
- /* Misc. support (drm_init.h) */
-extern int drm_flags;
-extern void drm_parse_options(char *s);
-extern int drm_cpu_valid(void);
-
/* Driver support (drm_drv.h) */
extern int drm_init(struct drm_driver *driver);
extern void drm_exit(struct drm_driver *driver);
@@ -772,12 +794,11 @@ extern int drm_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern long drm_compat_ioctl(struct file *filp,
unsigned int cmd, unsigned long arg);
-extern int drm_takedown(drm_device_t * dev);
+extern int drm_lastclose(drm_device_t *dev);
/* Device support (drm_fops.h) */
extern int drm_open(struct inode *inode, struct file *filp);
extern int drm_stub_open(struct inode *inode, struct file *filp);
-extern int drm_flush(struct file *filp);
extern int drm_fasync(int fd, struct file *filp, int on);
extern int drm_release(struct inode *inode, struct file *filp);
@@ -819,6 +840,8 @@ extern int drm_getstats(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int drm_setversion(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
+extern int drm_noop(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
/* Context IOCTL support (drm_context.h) */
extern int drm_resctx(struct inode *inode, struct file *filp,
@@ -857,10 +880,6 @@ extern int drm_getmagic(struct inode *inode, struct file *filp,
extern int drm_authmagic(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
- /* Placeholder for ioctls past */
-extern int drm_noop(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-
/* Locking IOCTL support (drm_lock.h) */
extern int drm_lock(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
@@ -873,6 +892,7 @@ extern int drm_lock_free(drm_device_t * dev,
/* Buffer management support (drm_bufs.h) */
extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request);
extern int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request);
+extern int drm_addbufs_fb(drm_device_t *dev, drm_buf_desc_t *request);
extern int drm_addmap(drm_device_t * dev, unsigned int offset,
unsigned int size, drm_map_type_t type,
drm_map_flags_t flags, drm_local_map_t ** map_ptr);
@@ -908,8 +928,8 @@ extern void drm_core_reclaim_buffers(drm_device_t * dev, struct file *filp);
/* IRQ support (drm_irq.h) */
extern int drm_control(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
-extern int drm_irq_uninstall(drm_device_t * dev);
extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS);
+extern int drm_irq_uninstall(drm_device_t * dev);
extern void drm_driver_irq_preinstall(drm_device_t * dev);
extern void drm_driver_irq_postinstall(drm_device_t * dev);
extern void drm_driver_irq_uninstall(drm_device_t * dev);
@@ -933,13 +953,17 @@ extern int drm_agp_enable_ioctl(struct inode *inode, struct file *filp,
extern int drm_agp_info(drm_device_t * dev, drm_agp_info_t * info);
extern int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
-extern int drm_agp_alloc(struct inode *inode, struct file *filp,
+extern int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request);
+extern int drm_agp_alloc_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
-extern int drm_agp_free(struct inode *inode, struct file *filp,
+extern int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request);
+extern int drm_agp_free_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
-extern int drm_agp_unbind(struct inode *inode, struct file *filp,
+extern int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request);
+extern int drm_agp_unbind_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
-extern int drm_agp_bind(struct inode *inode, struct file *filp,
+extern int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request);
+extern int drm_agp_bind_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge,
size_t pages, u32 type);
@@ -991,10 +1015,8 @@ extern struct drm_sysfs_class *drm_sysfs_create(struct module *owner,
char *name);
extern void drm_sysfs_destroy(struct drm_sysfs_class *cs);
extern struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs,
- dev_t dev,
- struct device *device,
- const char *fmt, ...);
-extern void drm_sysfs_device_remove(dev_t dev);
+ drm_head_t *head);
+extern void drm_sysfs_device_remove(struct class_device *class_dev);
/* Inline replacements for DRM_IOREMAP macros */
static __inline__ void drm_core_ioremap(struct drm_map *map,
diff --git a/drivers/char/drm/drm_agpsupport.c b/drivers/char/drm/drm_agpsupport.c
index 2b6453a9ffce6..fabc930c67a23 100644
--- a/drivers/char/drm/drm_agpsupport.c
+++ b/drivers/char/drm/drm_agpsupport.c
@@ -1,5 +1,5 @@
/**
- * \file drm_agpsupport.h
+ * \file drm_agpsupport.c
* DRM support for AGP/GART backend
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
@@ -91,7 +91,7 @@ int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
/**
* Acquire the AGP device.
*
- * \param dev DRM device that is to acquire AGP
+ * \param dev DRM device that is to acquire AGP.
* \return zero on success or a negative number on failure.
*
* Verifies the AGP device hasn't been acquired before and calls
@@ -134,7 +134,7 @@ int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp,
/**
* Release the AGP device.
*
- * \param dev DRM device that is to release AGP
+ * \param dev DRM device that is to release AGP.
* \return zero on success or a negative number on failure.
*
* Verifies the AGP device has been acquired and calls \c agp_backend_release.
@@ -147,7 +147,6 @@ int drm_agp_release(drm_device_t * dev)
dev->agp->acquired = 0;
return 0;
}
-
EXPORT_SYMBOL(drm_agp_release);
int drm_agp_release_ioctl(struct inode *inode, struct file *filp,
@@ -208,30 +207,22 @@ int drm_agp_enable_ioctl(struct inode *inode, struct file *filp,
* Verifies the AGP device is present and has been acquired, allocates the
* memory via alloc_agp() and creates a drm_agp_mem entry for it.
*/
-int drm_agp_alloc(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_agp_buffer_t request;
drm_agp_mem_t *entry;
DRM_AGP_MEM *memory;
unsigned long pages;
u32 type;
- drm_agp_buffer_t __user *argp = (void __user *)arg;
if (!dev->agp || !dev->agp->acquired)
return -EINVAL;
- if (copy_from_user(&request, argp, sizeof(request)))
- return -EFAULT;
if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS)))
return -ENOMEM;
memset(entry, 0, sizeof(*entry));
- pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
- type = (u32) request.type;
-
+ pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE;
+ type = (u32) request->type;
if (!(memory = drm_alloc_agp(dev, pages, type))) {
drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
return -ENOMEM;
@@ -247,16 +238,39 @@ int drm_agp_alloc(struct inode *inode, struct file *filp,
dev->agp->memory->prev = entry;
dev->agp->memory = entry;
- request.handle = entry->handle;
- request.physical = memory->physical;
+ request->handle = entry->handle;
+ request->physical = memory->physical;
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_agp_alloc);
+
+int drm_agp_alloc_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
+ drm_agp_buffer_t request;
+ drm_agp_buffer_t __user *argp = (void __user *)arg;
+ int err;
+
+ if (copy_from_user(&request, argp, sizeof(request)))
+ return -EFAULT;
+
+ err = drm_agp_alloc(dev, &request);
+ if (err)
+ return err;
if (copy_to_user(argp, &request, sizeof(request))) {
+ drm_agp_mem_t *entry = dev->agp->memory;
+
dev->agp->memory = entry->next;
dev->agp->memory->prev = NULL;
- drm_free_agp(memory, pages);
+ drm_free_agp(entry->memory, entry->pages);
drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
return -EFAULT;
}
+
return 0;
}
@@ -293,21 +307,14 @@ static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t * dev,
* Verifies the AGP device is present and acquired, looks-up the AGP memory
* entry and passes it to the unbind_agp() function.
*/
-int drm_agp_unbind(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_agp_binding_t request;
drm_agp_mem_t *entry;
int ret;
if (!dev->agp || !dev->agp->acquired)
return -EINVAL;
- if (copy_from_user
- (&request, (drm_agp_binding_t __user *) arg, sizeof(request)))
- return -EFAULT;
- if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
+ if (!(entry = drm_agp_lookup_entry(dev, request->handle)))
return -EINVAL;
if (!entry->bound)
return -EINVAL;
@@ -316,6 +323,21 @@ int drm_agp_unbind(struct inode *inode, struct file *filp,
entry->bound = 0;
return ret;
}
+EXPORT_SYMBOL(drm_agp_unbind);
+
+int drm_agp_unbind_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
+ drm_agp_binding_t request;
+
+ if (copy_from_user
+ (&request, (drm_agp_binding_t __user *) arg, sizeof(request)))
+ return -EFAULT;
+
+ return drm_agp_unbind(dev, &request);
+}
/**
* Bind AGP memory into the GATT (ioctl)
@@ -330,26 +352,19 @@ int drm_agp_unbind(struct inode *inode, struct file *filp,
* is currently bound into the GATT. Looks-up the AGP memory entry and passes
* it to bind_agp() function.
*/
-int drm_agp_bind(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_agp_binding_t request;
drm_agp_mem_t *entry;
int retcode;
int page;
if (!dev->agp || !dev->agp->acquired)
return -EINVAL;
- if (copy_from_user
- (&request, (drm_agp_binding_t __user *) arg, sizeof(request)))
- return -EFAULT;
- if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
+ if (!(entry = drm_agp_lookup_entry(dev, request->handle)))
return -EINVAL;
if (entry->bound)
return -EINVAL;
- page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE;
+ page = (request->offset + PAGE_SIZE - 1) / PAGE_SIZE;
if ((retcode = drm_bind_agp(entry->memory, page)))
return retcode;
entry->bound = dev->agp->base + (page << PAGE_SHIFT);
@@ -357,6 +372,21 @@ int drm_agp_bind(struct inode *inode, struct file *filp,
dev->agp->base, entry->bound);
return 0;
}
+EXPORT_SYMBOL(drm_agp_bind);
+
+int drm_agp_bind_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
+ drm_agp_binding_t request;
+
+ if (copy_from_user
+ (&request, (drm_agp_binding_t __user *) arg, sizeof(request)))
+ return -EFAULT;
+
+ return drm_agp_bind(dev, &request);
+}
/**
* Free AGP memory (ioctl).
@@ -372,20 +402,13 @@ int drm_agp_bind(struct inode *inode, struct file *filp,
* unbind_agp(). Frees it via free_agp() as well as the entry itself
* and unlinks from the doubly linked list it's inserted in.
*/
-int drm_agp_free(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_agp_buffer_t request;
drm_agp_mem_t *entry;
if (!dev->agp || !dev->agp->acquired)
return -EINVAL;
- if (copy_from_user
- (&request, (drm_agp_buffer_t __user *) arg, sizeof(request)))
- return -EFAULT;
- if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
+ if (!(entry = drm_agp_lookup_entry(dev, request->handle)))
return -EINVAL;
if (entry->bound)
drm_unbind_agp(entry->memory);
@@ -402,12 +425,30 @@ int drm_agp_free(struct inode *inode, struct file *filp,
drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
return 0;
}
+EXPORT_SYMBOL(drm_agp_free);
+
+int drm_agp_free_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
+ drm_agp_buffer_t request;
+
+ if (copy_from_user
+ (&request, (drm_agp_buffer_t __user *) arg, sizeof(request)))
+ return -EFAULT;
+
+ return drm_agp_free(dev, &request);
+}
/**
* Initialize the AGP resources.
*
* \return pointer to a drm_agp_head structure.
*
+ * Gets the drm_agp_t structure which is made available by the agpgart module
+ * via the inter_module_* functions. Creates and initializes a drm_agp_head
+ * structure.
*/
drm_agp_head_t *drm_agp_init(drm_device_t * dev)
{
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index 319bdea8de8a6..1db12dcb6802f 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -36,22 +36,21 @@
#include <linux/vmalloc.h>
#include "drmP.h"
-unsigned long drm_get_resource_start(drm_device_t * dev, unsigned int resource)
+unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource)
{
return pci_resource_start(dev->pdev, resource);
}
-
EXPORT_SYMBOL(drm_get_resource_start);
-unsigned long drm_get_resource_len(drm_device_t * dev, unsigned int resource)
+unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource)
{
return pci_resource_len(dev->pdev, resource);
}
EXPORT_SYMBOL(drm_get_resource_len);
-static drm_map_list_t *drm_find_matching_map(drm_device_t * dev,
- drm_local_map_t * map)
+static drm_map_list_t *drm_find_matching_map(drm_device_t *dev,
+ drm_local_map_t *map)
{
struct list_head *list;
@@ -74,7 +73,7 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t * dev,
#ifdef _LP64
static __inline__ unsigned int HandleID(unsigned long lhandle,
- drm_device_t * dev)
+ drm_device_t *dev)
{
static unsigned int map32_handle = START_RANGE;
unsigned int hash;
@@ -155,7 +154,7 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
case _DRM_REGISTERS:
case _DRM_FRAME_BUFFER:
#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__)
- if (map->offset + map->size < map->offset ||
+ if (map->offset + (map->size-1) < map->offset ||
map->offset < virt_to_phys(high_memory)) {
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
return -EINVAL;
@@ -301,6 +300,9 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
return -EFAULT;
}
+ if (!(capable(CAP_SYS_ADMIN) || map.type == _DRM_AGP))
+ return -EPERM;
+
err = drm_addmap_core(dev, map.offset, map.size, map.type, map.flags,
&maplist);
@@ -332,7 +334,7 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
*
* \sa drm_addmap
*/
-int drm_rmmap_locked(drm_device_t * dev, drm_local_map_t * map)
+int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)
{
struct list_head *list;
drm_map_list_t *r_list = NULL;
@@ -384,10 +386,9 @@ int drm_rmmap_locked(drm_device_t * dev, drm_local_map_t * map)
return 0;
}
-
EXPORT_SYMBOL(drm_rmmap_locked);
-int drm_rmmap(drm_device_t * dev, drm_local_map_t * map)
+int drm_rmmap(drm_device_t *dev, drm_local_map_t *map)
{
int ret;
@@ -397,7 +398,6 @@ int drm_rmmap(drm_device_t * dev, drm_local_map_t * map)
return ret;
}
-
EXPORT_SYMBOL(drm_rmmap);
/* The rmmap ioctl appears to be unnecessary. All mappings are torn down on
@@ -548,7 +548,7 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
DRM_DEBUG("count: %d\n", count);
DRM_DEBUG("order: %d\n", order);
DRM_DEBUG("size: %d\n", size);
- DRM_DEBUG("agp_offset: %lu\n", agp_offset);
+ DRM_DEBUG("agp_offset: %lx\n", agp_offset);
DRM_DEBUG("alignment: %d\n", alignment);
DRM_DEBUG("page_order: %d\n", page_order);
DRM_DEBUG("total: %d\n", total);
@@ -649,6 +649,8 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
}
dma->buf_count += entry->buf_count;
+ dma->seg_count += entry->seg_count;
+ dma->page_count += byte_count >> PAGE_SHIFT;
dma->byte_count += byte_count;
DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
@@ -664,7 +666,6 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
atomic_dec(&dev->buf_alloc);
return 0;
}
-
EXPORT_SYMBOL(drm_addbufs_agp);
#endif /* __OS_HAS_AGP */
@@ -689,9 +690,13 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
if (!drm_core_check_feature(dev, DRIVER_PCI_DMA))
return -EINVAL;
+
if (!dma)
return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
count = request->count;
order = drm_order(request->size);
size = 1 << order;
@@ -882,7 +887,6 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
return 0;
}
-
EXPORT_SYMBOL(drm_addbufs_pci);
static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
@@ -908,6 +912,9 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
if (!dma)
return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
count = request->count;
order = drm_order(request->size);
size = 1 << order;
@@ -1026,6 +1033,8 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
}
dma->buf_count += entry->buf_count;
+ dma->seg_count += entry->seg_count;
+ dma->page_count += byte_count >> PAGE_SHIFT;
dma->byte_count += byte_count;
DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
@@ -1042,7 +1051,7 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
return 0;
}
-static int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
+int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
{
drm_device_dma_t *dma = dev->dma;
drm_buf_entry_t *entry;
@@ -1065,6 +1074,9 @@ static int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
if (!dma)
return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
count = request->count;
order = drm_order(request->size);
size = 1 << order;
@@ -1181,6 +1193,8 @@ static int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
}
dma->buf_count += entry->buf_count;
+ dma->seg_count += entry->seg_count;
+ dma->page_count += byte_count >> PAGE_SHIFT;
dma->byte_count += byte_count;
DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
@@ -1196,6 +1210,8 @@ static int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
atomic_dec(&dev->buf_alloc);
return 0;
}
+EXPORT_SYMBOL(drm_addbufs_fb);
+
/**
* Add buffers for DMA transfers (ioctl).
@@ -1577,5 +1593,6 @@ int drm_order(unsigned long size)
return order;
}
-
EXPORT_SYMBOL(drm_order);
+
+
diff --git a/drivers/char/drm/drm_context.c b/drivers/char/drm/drm_context.c
index bd958d69a2ac2..f842545269495 100644
--- a/drivers/char/drm/drm_context.c
+++ b/drivers/char/drm/drm_context.c
@@ -433,7 +433,7 @@ int drm_addctx(struct inode *inode, struct file *filp,
if (ctx.handle != DRM_KERNEL_CONTEXT) {
if (dev->driver->context_ctor)
if (!dev->driver->context_ctor(dev, ctx.handle)) {
- DRM_DEBUG( "Running out of ctxs or memory.\n");
+ DRM_DEBUG("Running out of ctxs or memory.\n");
return -ENOMEM;
}
}
diff --git a/drivers/char/drm/drm_core.h b/drivers/char/drm/drm_core.h
index cc97bb906dda2..f4f9db6c7ed4c 100644
--- a/drivers/char/drm/drm_core.h
+++ b/drivers/char/drm/drm_core.h
@@ -24,11 +24,11 @@
#define CORE_NAME "drm"
#define CORE_DESC "DRM shared core routines"
-#define CORE_DATE "20040925"
+#define CORE_DATE "20051102"
#define DRM_IF_MAJOR 1
#define DRM_IF_MINOR 2
#define CORE_MAJOR 1
#define CORE_MINOR 0
-#define CORE_PATCHLEVEL 0
+#define CORE_PATCHLEVEL 1
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index 4dff7554eb083..c4fa5a29582b5 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -56,66 +56,66 @@ static int drm_version(struct inode *inode, struct file *filp,
/** Ioctl table */
static drm_ioctl_desc_t drm_ioctls[] = {
- [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = {drm_version, 0, 0},
- [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = {drm_getunique, 0, 0},
- [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = {drm_getmagic, 0, 0},
- [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = {drm_irq_by_busid, 0, 1},
- [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = {drm_getmap, 0, 0},
- [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = {drm_getclient, 0, 0},
- [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = {drm_getstats, 0, 0},
- [DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = {drm_setversion, 0, 1},
-
- [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = {drm_setunique, 1, 1},
- [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = {drm_noop, 1, 1},
- [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = {drm_noop, 1, 1},
- [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = {drm_authmagic, 1, 1},
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = {drm_addmap_ioctl, 1, 1},
- [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = {drm_rmmap_ioctl, 1, 0},
-
- [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = {drm_setsareactx, 1, 1},
- [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = {drm_getsareactx, 1, 0},
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = {drm_addctx, 1, 1},
- [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = {drm_rmctx, 1, 1},
- [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = {drm_modctx, 1, 1},
- [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = {drm_getctx, 1, 0},
- [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = {drm_switchctx, 1, 1},
- [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = {drm_newctx, 1, 1},
- [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = {drm_resctx, 1, 0},
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = {drm_adddraw, 1, 1},
- [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = {drm_rmdraw, 1, 1},
-
- [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = {drm_lock, 1, 0},
- [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = {drm_unlock, 1, 0},
-
- [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = {drm_noop, 1, 0},
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = {drm_addbufs, 1, 1},
- [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = {drm_markbufs, 1, 1},
- [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = {drm_infobufs, 1, 0},
- [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = {drm_mapbufs, 1, 0},
- [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = {drm_freebufs, 1, 0},
+ [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = {drm_version, 0},
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = {drm_getunique, 0},
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = {drm_getmagic, 0},
+ [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = {drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = {drm_getmap, 0},
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = {drm_getclient, 0},
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = {drm_getstats, 0},
+ [DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = {drm_setversion, DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = {drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = {drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = {drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = {drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = {drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = {drm_rmmap_ioctl, DRM_AUTH},
+
+ [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = {drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = {drm_getsareactx, DRM_AUTH},
+
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = {drm_addctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = {drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = {drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = {drm_getctx, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = {drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = {drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = {drm_resctx, DRM_AUTH},
+
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = {drm_adddraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = {drm_rmdraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+
+ [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = {drm_lock, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = {drm_unlock, DRM_AUTH},
+
+ [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = {drm_noop, DRM_AUTH},
+
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = {drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = {drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = {drm_infobufs, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = {drm_mapbufs, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = {drm_freebufs, DRM_AUTH},
/* The DRM_IOCTL_DMA ioctl should be defined by the driver. */
+ [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = {NULL, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = {drm_control, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = {drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
#if __OS_HAS_AGP
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire_ioctl, 1, 1},
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release_ioctl, 1, 1},
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable_ioctl, 1, 1},
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info_ioctl, 1, 0},
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc, 1, 1},
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free, 1, 1},
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_bind, 1, 1},
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info_ioctl, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
#endif
- [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc, 1, 1},
- [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = {drm_sg_free, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = {drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0, 0},
+ [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0},
};
#define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( drm_ioctls )
@@ -129,7 +129,7 @@ static drm_ioctl_desc_t drm_ioctls[] = {
*
* \sa drm_device
*/
-int drm_takedown(drm_device_t * dev)
+int drm_lastclose(drm_device_t * dev)
{
drm_magic_entry_t *pt, *next;
drm_map_list_t *r_list;
@@ -138,9 +138,9 @@ int drm_takedown(drm_device_t * dev)
DRM_DEBUG("\n");
- if (dev->driver->pretakedown)
- dev->driver->pretakedown(dev);
- DRM_DEBUG("driver pretakedown completed\n");
+ if (dev->driver->lastclose)
+ dev->driver->lastclose(dev);
+ DRM_DEBUG("driver lastclose completed\n");
if (dev->unique) {
drm_free(dev->unique, strlen(dev->unique) + 1, DRM_MEM_DRIVER);
@@ -233,7 +233,7 @@ int drm_takedown(drm_device_t * dev)
}
up(&dev->struct_sem);
- DRM_DEBUG("takedown completed\n");
+ DRM_DEBUG("lastclose completed\n");
return 0;
}
@@ -281,7 +281,7 @@ EXPORT_SYMBOL(drm_init);
/**
* Called via cleanup_module() at module unload time.
*
- * Cleans up all DRM device, calling takedown().
+ * Cleans up all DRM device, calling drm_lastclose().
*
* \sa drm_init
*/
@@ -294,7 +294,7 @@ static void drm_cleanup(drm_device_t * dev)
return;
}
- drm_takedown(dev);
+ drm_lastclose(dev);
if (dev->maplist) {
drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
@@ -317,8 +317,8 @@ static void drm_cleanup(drm_device_t * dev)
dev->agp = NULL;
}
- if (dev->driver->postcleanup)
- dev->driver->postcleanup(dev);
+ if (dev->driver->unload)
+ dev->driver->unload(dev);
drm_put_head(&dev->primary);
if (drm_put_dev(dev))
@@ -342,12 +342,12 @@ void drm_exit(struct drm_driver *driver)
if (head->dev->driver != driver)
continue;
dev = head->dev;
- }
- if (dev) {
- /* release the pci driver */
- if (dev->pdev)
- pci_dev_put(dev->pdev);
- drm_cleanup(dev);
+ if (dev) {
+ /* release the pci driver */
+ if (dev->pdev)
+ pci_dev_put(dev->pdev);
+ drm_cleanup(dev);
+ }
}
DRM_INFO("Module unloaded\n");
}
@@ -432,14 +432,17 @@ static int drm_version(struct inode *inode, struct file *filp,
drm_device_t *dev = priv->head->dev;
drm_version_t __user *argp = (void __user *)arg;
drm_version_t version;
- int ret;
+ int len;
if (copy_from_user(&version, argp, sizeof(version)))
return -EFAULT;
- /* version is a required function to return the personality module version */
- if ((ret = dev->driver->version(&version)))
- return ret;
+ version.version_major = dev->driver->major;
+ version.version_minor = dev->driver->minor;
+ version.version_patchlevel = dev->driver->patchlevel;
+ DRM_COPY(version.name, dev->driver->name);
+ DRM_COPY(version.date, dev->driver->date);
+ DRM_COPY(version.desc, dev->driver->desc);
if (copy_to_user(argp, &version, sizeof(version)))
return -EFAULT;
@@ -493,8 +496,9 @@ int drm_ioctl(struct inode *inode, struct file *filp,
if (!func) {
DRM_DEBUG("no function\n");
retcode = -EINVAL;
- } else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN)) ||
- (ioctl->auth_needed && !priv->authenticated)) {
+ } else if (((ioctl->flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)) ||
+ ((ioctl->flags & DRM_AUTH) && !priv->authenticated) ||
+ ((ioctl->flags & DRM_MASTER) && !priv->master)) {
retcode = -EACCES;
} else {
retcode = func(inode, filp, cmd, arg);
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c
index bf0a740122bf8..403f44a1bf016 100644
--- a/drivers/char/drm/drm_fops.c
+++ b/drivers/char/drm/drm_fops.c
@@ -35,6 +35,7 @@
*/
#include "drmP.h"
+#include "drm_sarea.h"
#include <linux/poll.h>
static int drm_open_helper(struct inode *inode, struct file *filp,
@@ -42,15 +43,21 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
static int drm_setup(drm_device_t * dev)
{
+ drm_local_map_t *map;
int i;
int ret;
- if (dev->driver->presetup) {
- ret = dev->driver->presetup(dev);
+ if (dev->driver->firstopen) {
+ ret = dev->driver->firstopen(dev);
if (ret != 0)
return ret;
}
+ /* prebuild the SAREA */
+ i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, _DRM_CONTAINS_LOCK, &map);
+ if (i != 0)
+ return i;
+
atomic_set(&dev->ioctl_count, 0);
atomic_set(&dev->vma_count, 0);
dev->buf_use = 0;
@@ -109,8 +116,6 @@ static int drm_setup(drm_device_t * dev)
* drm_select_queue fails between the time the interrupt is
* initialized and the time the queues are initialized.
*/
- if (dev->driver->postsetup)
- dev->driver->postsetup(dev);
return 0;
}
@@ -154,10 +159,168 @@ int drm_open(struct inode *inode, struct file *filp)
return retcode;
}
-
EXPORT_SYMBOL(drm_open);
/**
+ * File \c open operation.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ *
+ * Puts the dev->fops corresponding to the device minor number into
+ * \p filp, call the \c open method, and restore the file operations.
+ */
+int drm_stub_open(struct inode *inode, struct file *filp)
+{
+ drm_device_t *dev = NULL;
+ int minor = iminor(inode);
+ int err = -ENODEV;
+ struct file_operations *old_fops;
+
+ DRM_DEBUG("\n");
+
+ if (!((minor >= 0) && (minor < drm_cards_limit)))
+ return -ENODEV;
+
+ if (!drm_heads[minor])
+ return -ENODEV;
+
+ if (!(dev = drm_heads[minor]->dev))
+ return -ENODEV;
+
+ old_fops = filp->f_op;
+ filp->f_op = fops_get(&dev->driver->fops);
+ if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) {
+ fops_put(filp->f_op);
+ filp->f_op = fops_get(old_fops);
+ }
+ fops_put(old_fops);
+
+ return err;
+}
+
+/**
+ * Check whether DRI will run on this CPU.
+ *
+ * \return non-zero if the DRI will run on this CPU, or zero otherwise.
+ */
+static int drm_cpu_valid(void)
+{
+#if defined(__i386__)
+ if (boot_cpu_data.x86 == 3)
+ return 0; /* No cmpxchg on a 386 */
+#endif
+#if defined(__sparc__) && !defined(__sparc_v9__)
+ return 0; /* No cmpxchg before v9 sparc. */
+#endif
+ return 1;
+}
+
+/**
+ * Called whenever a process opens /dev/drm.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param dev device.
+ * \return zero on success or a negative number on failure.
+ *
+ * Creates and initializes a drm_file structure for the file private data in \p
+ * filp and add it into the double linked list in \p dev.
+ */
+static int drm_open_helper(struct inode *inode, struct file *filp,
+ drm_device_t * dev)
+{
+ int minor = iminor(inode);
+ drm_file_t *priv;
+ int ret;
+
+ if (filp->f_flags & O_EXCL)
+ return -EBUSY; /* No exclusive opens */
+ if (!drm_cpu_valid())
+ return -EINVAL;
+
+ DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);
+
+ priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
+ if (!priv)
+ return -ENOMEM;
+
+ memset(priv, 0, sizeof(*priv));
+ filp->private_data = priv;
+ priv->uid = current->euid;
+ priv->pid = current->pid;
+ priv->minor = minor;
+ priv->head = drm_heads[minor];
+ priv->ioctl_count = 0;
+ /* for compatibility root is always authenticated */
+ priv->authenticated = capable(CAP_SYS_ADMIN);
+ priv->lock_count = 0;
+
+ if (dev->driver->open) {
+ ret = dev->driver->open(dev, priv);
+ if (ret < 0)
+ goto out_free;
+ }
+
+ down(&dev->struct_sem);
+ if (!dev->file_last) {
+ priv->next = NULL;
+ priv->prev = NULL;
+ dev->file_first = priv;
+ dev->file_last = priv;
+ /* first opener automatically becomes master */
+ priv->master = 1;
+ } else {
+ priv->next = NULL;
+ priv->prev = dev->file_last;
+ dev->file_last->next = priv;
+ dev->file_last = priv;
+ }
+ up(&dev->struct_sem);
+
+#ifdef __alpha__
+ /*
+ * Default the hose
+ */
+ if (!dev->hose) {
+ struct pci_dev *pci_dev;
+ pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL);
+ if (pci_dev) {
+ dev->hose = pci_dev->sysdata;
+ pci_dev_put(pci_dev);
+ }
+ if (!dev->hose) {
+ struct pci_bus *b = pci_bus_b(pci_root_buses.next);
+ if (b)
+ dev->hose = b->sysdata;
+ }
+ }
+#endif
+
+ return 0;
+ out_free:
+ drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
+ filp->private_data = NULL;
+ return ret;
+}
+
+/** No-op. */
+int drm_fasync(int fd, struct file *filp, int on)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
+ int retcode;
+
+ DRM_DEBUG("fd = %d, device = 0x%lx\n", fd,
+ (long)old_encode_dev(priv->head->device));
+ retcode = fasync_helper(fd, filp, on, &dev->buf_async);
+ if (retcode < 0)
+ return retcode;
+ return 0;
+}
+EXPORT_SYMBOL(drm_fasync);
+
+/**
* Release file.
*
* \param inode device inode
@@ -167,7 +330,7 @@ EXPORT_SYMBOL(drm_open);
* If the hardware lock is held then free it, and take it again for the kernel
* context since it's necessary to reclaim buffers. Unlink the file private
* data from its list and free it. Decreases the open count and if it reaches
- * zero calls takedown().
+ * zero calls drm_lastclose().
*/
int drm_release(struct inode *inode, struct file *filp)
{
@@ -180,8 +343,8 @@ int drm_release(struct inode *inode, struct file *filp)
DRM_DEBUG("open_count = %d\n", dev->open_count);
- if (dev->driver->prerelease)
- dev->driver->prerelease(dev, filp);
+ if (dev->driver->preclose)
+ dev->driver->preclose(dev, filp);
/* ========================================================
* Begin inline drm_release
@@ -197,8 +360,8 @@ int drm_release(struct inode *inode, struct file *filp)
DRM_DEBUG("File %p released, freeing lock for context %d\n",
filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
- if (dev->driver->release)
- dev->driver->release(dev, filp);
+ if (dev->driver->reclaim_buffers_locked)
+ dev->driver->reclaim_buffers_locked(dev, filp);
drm_lock_free(dev, &dev->lock.hw_lock->lock,
_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
@@ -207,7 +370,7 @@ int drm_release(struct inode *inode, struct file *filp)
hardware at this point, possibly
processed via a callback to the X
server. */
- } else if (dev->driver->release && priv->lock_count
+ } else if (dev->driver->reclaim_buffers_locked && priv->lock_count
&& dev->lock.hw_lock) {
/* The lock is required to reclaim buffers */
DECLARE_WAITQUEUE(entry, current);
@@ -237,15 +400,14 @@ int drm_release(struct inode *inode, struct file *filp)
__set_current_state(TASK_RUNNING);
remove_wait_queue(&dev->lock.lock_queue, &entry);
if (!retcode) {
- if (dev->driver->release)
- dev->driver->release(dev, filp);
+ dev->driver->reclaim_buffers_locked(dev, filp);
drm_lock_free(dev, &dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT);
}
}
- if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)
- && !dev->driver->release) {
+ if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) &&
+ !dev->driver->reclaim_buffers_locked) {
dev->driver->reclaim_buffers(dev, filp);
}
@@ -292,9 +454,8 @@ int drm_release(struct inode *inode, struct file *filp)
}
up(&dev->struct_sem);
- if (dev->driver->free_filp_priv)
- dev->driver->free_filp_priv(dev, priv);
-
+ if (dev->driver->postclose)
+ dev->driver->postclose(dev, priv);
drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
/* ========================================================
@@ -313,7 +474,7 @@ int drm_release(struct inode *inode, struct file *filp)
}
spin_unlock(&dev->count_lock);
unlock_kernel();
- return drm_takedown(dev);
+ return drm_lastclose(dev);
}
spin_unlock(&dev->count_lock);
@@ -321,129 +482,11 @@ int drm_release(struct inode *inode, struct file *filp)
return retcode;
}
-
EXPORT_SYMBOL(drm_release);
-/**
- * Called whenever a process opens /dev/drm.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param dev device.
- * \return zero on success or a negative number on failure.
- *
- * Creates and initializes a drm_file structure for the file private data in \p
- * filp and add it into the double linked list in \p dev.
- */
-static int drm_open_helper(struct inode *inode, struct file *filp,
- drm_device_t * dev)
-{
- int minor = iminor(inode);
- drm_file_t *priv;
- int ret;
-
- if (filp->f_flags & O_EXCL)
- return -EBUSY; /* No exclusive opens */
- if (!drm_cpu_valid())
- return -EINVAL;
-
- DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);
-
- priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
- if (!priv)
- return -ENOMEM;
-
- memset(priv, 0, sizeof(*priv));
- filp->private_data = priv;
- priv->uid = current->euid;
- priv->pid = current->pid;
- priv->minor = minor;
- priv->head = drm_heads[minor];
- priv->ioctl_count = 0;
- priv->authenticated = capable(CAP_SYS_ADMIN);
- priv->lock_count = 0;
-
- if (dev->driver->open_helper) {
- ret = dev->driver->open_helper(dev, priv);
- if (ret < 0)
- goto out_free;
- }
-
- down(&dev->struct_sem);
- if (!dev->file_last) {
- priv->next = NULL;
- priv->prev = NULL;
- dev->file_first = priv;
- dev->file_last = priv;
- } else {
- priv->next = NULL;
- priv->prev = dev->file_last;
- dev->file_last->next = priv;
- dev->file_last = priv;
- }
- up(&dev->struct_sem);
-
-#ifdef __alpha__
- /*
- * Default the hose
- */
- if (!dev->hose) {
- struct pci_dev *pci_dev;
- pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL);
- if (pci_dev) {
- dev->hose = pci_dev->sysdata;
- pci_dev_put(pci_dev);
- }
- if (!dev->hose) {
- struct pci_bus *b = pci_bus_b(pci_root_buses.next);
- if (b)
- dev->hose = b->sysdata;
- }
- }
-#endif
-
- return 0;
- out_free:
- drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
- filp->private_data = NULL;
- return ret;
-}
-
-/** No-op. */
-int drm_flush(struct file *filp)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
-
- DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
- current->pid, (long)old_encode_dev(priv->head->device),
- dev->open_count);
- return 0;
-}
-
-EXPORT_SYMBOL(drm_flush);
-
-/** No-op. */
-int drm_fasync(int fd, struct file *filp, int on)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- int retcode;
-
- DRM_DEBUG("fd = %d, device = 0x%lx\n", fd,
- (long)old_encode_dev(priv->head->device));
- retcode = fasync_helper(fd, filp, on, &dev->buf_async);
- if (retcode < 0)
- return retcode;
- return 0;
-}
-
-EXPORT_SYMBOL(drm_fasync);
-
/** No-op. */
unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait)
{
return 0;
}
-
EXPORT_SYMBOL(drm_poll);
diff --git a/drivers/char/drm/drm_init.c b/drivers/char/drm/drm_init.c
deleted file mode 100644
index 754b934715c40..0000000000000
--- a/drivers/char/drm/drm_init.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * \file drm_init.c
- * Setup/Cleanup for DRM
- *
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Mon Jan 4 08:58:31 1999 by faith@valinux.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "drmP.h"
-
-/**
- * Check whether DRI will run on this CPU.
- *
- * \return non-zero if the DRI will run on this CPU, or zero otherwise.
- */
-int drm_cpu_valid(void)
-{
-#if defined(__i386__)
- if (boot_cpu_data.x86 == 3)
- return 0; /* No cmpxchg on a 386 */
-#endif
-#if defined(__sparc__) && !defined(__sparc_v9__)
- return 0; /* No cmpxchg before v9 sparc. */
-#endif
- return 1;
-}
diff --git a/drivers/char/drm/drm_ioctl.c b/drivers/char/drm/drm_ioctl.c
index 9b0feba6b063e..bcd4e604d3ecd 100644
--- a/drivers/char/drm/drm_ioctl.c
+++ b/drivers/char/drm/drm_ioctl.c
@@ -137,17 +137,22 @@ int drm_setunique(struct inode *inode, struct file *filp,
static int drm_set_busid(drm_device_t * dev)
{
+ int len;
+
if (dev->unique != NULL)
return EBUSY;
- dev->unique_len = 20;
+ dev->unique_len = 40;
dev->unique = drm_alloc(dev->unique_len + 1, DRM_MEM_DRIVER);
if (dev->unique == NULL)
return ENOMEM;
- snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d",
+ len = snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d",
dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func);
+ if (len > dev->unique_len)
+ DRM_ERROR("Unique buffer overflowed\n");
+
dev->devname =
drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len +
2, DRM_MEM_DRIVER);
@@ -239,7 +244,7 @@ int drm_getclient(struct inode *inode, struct file *filp,
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
- drm_client_t __user *argp = (void __user *)arg;
+ drm_client_t __user *argp = (drm_client_t __user *)arg;
drm_client_t client;
drm_file_t *pt;
int idx;
@@ -262,7 +267,7 @@ int drm_getclient(struct inode *inode, struct file *filp,
client.iocs = pt->ioctl_count;
up(&dev->struct_sem);
- if (copy_to_user((drm_client_t __user *) arg, &client, sizeof(client)))
+ if (copy_to_user(argp, &client, sizeof(client)))
return -EFAULT;
return 0;
}
@@ -325,17 +330,13 @@ int drm_setversion(DRM_IOCTL_ARGS)
drm_set_version_t retv;
int if_version;
drm_set_version_t __user *argp = (void __user *)data;
- drm_version_t version;
DRM_COPY_FROM_USER_IOCTL(sv, argp, sizeof(sv));
- memset(&version, 0, sizeof(version));
-
- dev->driver->version(&version);
retv.drm_di_major = DRM_IF_MAJOR;
retv.drm_di_minor = DRM_IF_MINOR;
- retv.drm_dd_major = version.version_major;
- retv.drm_dd_minor = version.version_minor;
+ retv.drm_dd_major = dev->driver->major;
+ retv.drm_dd_minor = dev->driver->minor;
DRM_COPY_TO_USER_IOCTL(argp, retv, sizeof(sv));
@@ -343,7 +344,7 @@ int drm_setversion(DRM_IOCTL_ARGS)
if (sv.drm_di_major != DRM_IF_MAJOR ||
sv.drm_di_minor < 0 || sv.drm_di_minor > DRM_IF_MINOR)
return EINVAL;
- if_version = DRM_IF_VERSION(sv.drm_di_major, sv.drm_dd_minor);
+ if_version = DRM_IF_VERSION(sv.drm_di_major, sv.drm_di_minor);
dev->if_version = DRM_MAX(if_version, dev->if_version);
if (sv.drm_di_minor >= 1) {
/*
@@ -354,9 +355,9 @@ int drm_setversion(DRM_IOCTL_ARGS)
}
if (sv.drm_dd_major != -1) {
- if (sv.drm_dd_major != version.version_major ||
+ if (sv.drm_dd_major != dev->driver->major ||
sv.drm_dd_minor < 0
- || sv.drm_dd_minor > version.version_minor)
+ || sv.drm_dd_minor > dev->driver->minor)
return EINVAL;
if (dev->driver->set_version)
diff --git a/drivers/char/drm/drm_lock.c b/drivers/char/drm/drm_lock.c
index b48a595d54eca..f9e45303498dd 100644
--- a/drivers/char/drm/drm_lock.c
+++ b/drivers/char/drm/drm_lock.c
@@ -130,7 +130,6 @@ int drm_lock(struct inode *inode, struct file *filp,
/* dev->driver->kernel_context_switch isn't used by any of the x86
* drivers but is used by the Sparc driver.
*/
-
if (dev->driver->kernel_context_switch &&
dev->last_context != lock.context) {
dev->driver->kernel_context_switch(dev, dev->last_context,
diff --git a/drivers/char/drm/drm_memory.c b/drivers/char/drm/drm_memory.c
index abef2acf99f59..8074771e348fd 100644
--- a/drivers/char/drm/drm_memory.c
+++ b/drivers/char/drm/drm_memory.c
@@ -145,30 +145,22 @@ DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type)
return drm_agp_allocate_memory(dev->agp->bridge, pages, type);
}
-EXPORT_SYMBOL(drm_alloc_agp);
-
/** Wrapper around agp_free_memory() */
int drm_free_agp(DRM_AGP_MEM * handle, int pages)
{
return drm_agp_free_memory(handle) ? 0 : -EINVAL;
}
-EXPORT_SYMBOL(drm_free_agp);
-
/** Wrapper around agp_bind_memory() */
int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start)
{
return drm_agp_bind_memory(handle, start);
}
-EXPORT_SYMBOL(drm_bind_agp);
-
/** Wrapper around agp_unbind_memory() */
int drm_unbind_agp(DRM_AGP_MEM * handle)
{
return drm_agp_unbind_memory(handle);
}
-
-EXPORT_SYMBOL(drm_unbind_agp);
#endif /* agp */
#endif /* debug_memory */
diff --git a/drivers/char/drm/drm_memory_debug.h b/drivers/char/drm/drm_memory_debug.h
index b370aca718d27..e84605fc54af0 100644
--- a/drivers/char/drm/drm_memory_debug.h
+++ b/drivers/char/drm/drm_memory_debug.h
@@ -1,5 +1,5 @@
/**
- * \file drm_memory.h
+ * \file drm_memory_debug.h
* Memory management wrappers for DRM.
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
@@ -43,42 +43,41 @@ typedef struct drm_mem_stats {
unsigned long bytes_freed;
} drm_mem_stats_t;
-static DEFINE_SPINLOCK(DRM(mem_lock));
-static unsigned long DRM(ram_available) = 0; /* In pages */
-static unsigned long DRM(ram_used) = 0;
-static drm_mem_stats_t DRM(mem_stats)[] =
+static spinlock_t drm_mem_lock = SPIN_LOCK_UNLOCKED;
+static unsigned long drm_ram_available = 0; /* In pages */
+static unsigned long drm_ram_used = 0;
+static drm_mem_stats_t drm_mem_stats[] =
{
- [DRM_MEM_DMA] = {
- "dmabufs"},[DRM_MEM_SAREA] = {
- "sareas"},[DRM_MEM_DRIVER] = {
- "driver"},[DRM_MEM_MAGIC] = {
- "magic"},[DRM_MEM_IOCTLS] = {
- "ioctltab"},[DRM_MEM_MAPS] = {
- "maplist"},[DRM_MEM_VMAS] = {
- "vmalist"},[DRM_MEM_BUFS] = {
- "buflist"},[DRM_MEM_SEGS] = {
- "seglist"},[DRM_MEM_PAGES] = {
- "pagelist"},[DRM_MEM_FILES] = {
- "files"},[DRM_MEM_QUEUES] = {
- "queues"},[DRM_MEM_CMDS] = {
- "commands"},[DRM_MEM_MAPPINGS] = {
- "mappings"},[DRM_MEM_BUFLISTS] = {
- "buflists"},[DRM_MEM_AGPLISTS] = {
- "agplist"},[DRM_MEM_SGLISTS] = {
- "sglist"},[DRM_MEM_TOTALAGP] = {
- "totalagp"},[DRM_MEM_BOUNDAGP] = {
- "boundagp"},[DRM_MEM_CTXBITMAP] = {
- "ctxbitmap"},[DRM_MEM_CTXLIST] = {
- "ctxlist"},[DRM_MEM_STUB] = {
- "stub"}, {
- NULL, 0,} /* Last entry must be null */
+ [DRM_MEM_DMA] = {"dmabufs"},
+ [DRM_MEM_SAREA] = {"sareas"},
+ [DRM_MEM_DRIVER] = {"driver"},
+ [DRM_MEM_MAGIC] = {"magic"},
+ [DRM_MEM_IOCTLS] = {"ioctltab"},
+ [DRM_MEM_MAPS] = {"maplist"},
+ [DRM_MEM_VMAS] = {"vmalist"},
+ [DRM_MEM_BUFS] = {"buflist"},
+ [DRM_MEM_SEGS] = {"seglist"},
+ [DRM_MEM_PAGES] = {"pagelist"},
+ [DRM_MEM_FILES] = {"files"},
+ [DRM_MEM_QUEUES] = {"queues"},
+ [DRM_MEM_CMDS] = {"commands"},
+ [DRM_MEM_MAPPINGS] = {"mappings"},
+ [DRM_MEM_BUFLISTS] = {"buflists"},
+ [DRM_MEM_AGPLISTS] = {"agplist"},
+ [DRM_MEM_SGLISTS] = {"sglist"},
+ [DRM_MEM_TOTALAGP] = {"totalagp"},
+ [DRM_MEM_BOUNDAGP] = {"boundagp"},
+ [DRM_MEM_CTXBITMAP] = {"ctxbitmap"},
+ [DRM_MEM_CTXLIST] = {"ctxlist"},
+ [DRM_MEM_STUB] = {"stub"},
+ {NULL, 0,} /* Last entry must be null */
};
-void DRM(mem_init) (void) {
+void drm_mem_init (void) {
drm_mem_stats_t *mem;
struct sysinfo si;
- for (mem = DRM(mem_stats); mem->name; ++mem) {
+ for (mem = drm_mem_stats; mem->name; ++mem) {
mem->succeed_count = 0;
mem->free_count = 0;
mem->fail_count = 0;
@@ -87,13 +86,13 @@ void DRM(mem_init) (void) {
}
si_meminfo(&si);
- DRM(ram_available) = si.totalram;
- DRM(ram_used) = 0;
+ drm_ram_available = si.totalram;
+ drm_ram_used = 0;
}
/* drm_mem_info is called whenever a process reads /dev/drm/mem. */
-static int DRM(_mem_info) (char *buf, char **start, off_t offset,
+static int drm__mem_info (char *buf, char **start, off_t offset,
int request, int *eof, void *data) {
drm_mem_stats_t *pt;
int len = 0;
@@ -112,11 +111,11 @@ static int DRM(_mem_info) (char *buf, char **start, off_t offset,
" | allocs bytes\n\n");
DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n",
"system", 0, 0, 0,
- DRM(ram_available) << (PAGE_SHIFT - 10));
+ drm_ram_available << (PAGE_SHIFT - 10));
DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n",
- "locked", 0, 0, 0, DRM(ram_used) >> 10);
+ "locked", 0, 0, 0, drm_ram_used >> 10);
DRM_PROC_PRINT("\n");
- for (pt = DRM(mem_stats); pt->name; pt++) {
+ for (pt = drm_mem_stats; pt->name; pt++) {
DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n",
pt->name,
pt->succeed_count,
@@ -135,17 +134,17 @@ static int DRM(_mem_info) (char *buf, char **start, off_t offset,
return len - offset;
}
-int DRM(mem_info) (char *buf, char **start, off_t offset,
+int drm_mem_info (char *buf, char **start, off_t offset,
int len, int *eof, void *data) {
int ret;
- spin_lock(&DRM(mem_lock));
- ret = DRM(_mem_info) (buf, start, offset, len, eof, data);
- spin_unlock(&DRM(mem_lock));
+ spin_lock(&drm_mem_lock);
+ ret = drm__mem_info (buf, start, offset, len, eof, data);
+ spin_unlock(&drm_mem_lock);
return ret;
}
-void *DRM(alloc) (size_t size, int area) {
+void *drm_alloc (size_t size, int area) {
void *pt;
if (!size) {
@@ -154,41 +153,41 @@ void *DRM(alloc) (size_t size, int area) {
}
if (!(pt = kmalloc(size, GFP_KERNEL))) {
- spin_lock(&DRM(mem_lock));
- ++DRM(mem_stats)[area].fail_count;
- spin_unlock(&DRM(mem_lock));
+ spin_lock(&drm_mem_lock);
+ ++drm_mem_stats[area].fail_count;
+ spin_unlock(&drm_mem_lock);
return NULL;
}
- spin_lock(&DRM(mem_lock));
- ++DRM(mem_stats)[area].succeed_count;
- DRM(mem_stats)[area].bytes_allocated += size;
- spin_unlock(&DRM(mem_lock));
+ spin_lock(&drm_mem_lock);
+ ++drm_mem_stats[area].succeed_count;
+ drm_mem_stats[area].bytes_allocated += size;
+ spin_unlock(&drm_mem_lock);
return pt;
}
-void *DRM(calloc) (size_t nmemb, size_t size, int area) {
+void *drm_calloc (size_t nmemb, size_t size, int area) {
void *addr;
- addr = DRM(alloc) (nmemb * size, area);
+ addr = drm_alloc (nmemb * size, area);
if (addr != NULL)
memset((void *)addr, 0, size * nmemb);
return addr;
}
-void *DRM(realloc) (void *oldpt, size_t oldsize, size_t size, int area) {
+void *drm_realloc (void *oldpt, size_t oldsize, size_t size, int area) {
void *pt;
- if (!(pt = DRM(alloc) (size, area)))
+ if (!(pt = drm_alloc (size, area)))
return NULL;
if (oldpt && oldsize) {
memcpy(pt, oldpt, oldsize);
- DRM(free) (oldpt, oldsize, area);
+ drm_free (oldpt, oldsize, area);
}
return pt;
}
-void DRM(free) (void *pt, size_t size, int area) {
+void drm_free (void *pt, size_t size, int area) {
int alloc_count;
int free_count;
@@ -196,43 +195,43 @@ void DRM(free) (void *pt, size_t size, int area) {
DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
else
kfree(pt);
- spin_lock(&DRM(mem_lock));
- DRM(mem_stats)[area].bytes_freed += size;
- free_count = ++DRM(mem_stats)[area].free_count;
- alloc_count = DRM(mem_stats)[area].succeed_count;
- spin_unlock(&DRM(mem_lock));
+ spin_lock(&drm_mem_lock);
+ drm_mem_stats[area].bytes_freed += size;
+ free_count = ++drm_mem_stats[area].free_count;
+ alloc_count = drm_mem_stats[area].succeed_count;
+ spin_unlock(&drm_mem_lock);
if (free_count > alloc_count) {
DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n",
free_count, alloc_count);
}
}
-unsigned long DRM(alloc_pages) (int order, int area) {
+unsigned long drm_alloc_pages (int order, int area) {
unsigned long address;
unsigned long bytes = PAGE_SIZE << order;
unsigned long addr;
unsigned int sz;
- spin_lock(&DRM(mem_lock));
- if ((DRM(ram_used) >> PAGE_SHIFT)
- > (DRM_RAM_PERCENT * DRM(ram_available)) / 100) {
- spin_unlock(&DRM(mem_lock));
+ spin_lock(&drm_mem_lock);
+ if ((drm_ram_used >> PAGE_SHIFT)
+ > (DRM_RAM_PERCENT * drm_ram_available) / 100) {
+ spin_unlock(&drm_mem_lock);
return 0;
}
- spin_unlock(&DRM(mem_lock));
+ spin_unlock(&drm_mem_lock);
address = __get_free_pages(GFP_KERNEL|__GFP_COMP, order);
if (!address) {
- spin_lock(&DRM(mem_lock));
- ++DRM(mem_stats)[area].fail_count;
- spin_unlock(&DRM(mem_lock));
+ spin_lock(&drm_mem_lock);
+ ++drm_mem_stats[area].fail_count;
+ spin_unlock(&drm_mem_lock);
return 0;
}
- spin_lock(&DRM(mem_lock));
- ++DRM(mem_stats)[area].succeed_count;
- DRM(mem_stats)[area].bytes_allocated += bytes;
- DRM(ram_used) += bytes;
- spin_unlock(&DRM(mem_lock));
+ spin_lock(&drm_mem_lock);
+ ++drm_mem_stats[area].succeed_count;
+ drm_mem_stats[area].bytes_allocated += bytes;
+ drm_ram_used += bytes;
+ spin_unlock(&drm_mem_lock);
/* Zero outside the lock */
memset((void *)address, 0, bytes);
@@ -246,7 +245,7 @@ unsigned long DRM(alloc_pages) (int order, int area) {
return address;
}
-void DRM(free_pages) (unsigned long address, int order, int area) {
+void drm_free_pages (unsigned long address, int order, int area) {
unsigned long bytes = PAGE_SIZE << order;
int alloc_count;
int free_count;
@@ -264,12 +263,12 @@ void DRM(free_pages) (unsigned long address, int order, int area) {
free_pages(address, order);
}
- spin_lock(&DRM(mem_lock));
- free_count = ++DRM(mem_stats)[area].free_count;
- alloc_count = DRM(mem_stats)[area].succeed_count;
- DRM(mem_stats)[area].bytes_freed += bytes;
- DRM(ram_used) -= bytes;
- spin_unlock(&DRM(mem_lock));
+ spin_lock(&drm_mem_lock);
+ free_count = ++drm_mem_stats[area].free_count;
+ alloc_count = drm_mem_stats[area].succeed_count;
+ drm_mem_stats[area].bytes_freed += bytes;
+ drm_ram_used -= bytes;
+ spin_unlock(&drm_mem_lock);
if (free_count > alloc_count) {
DRM_MEM_ERROR(area,
"Excess frees: %d frees, %d allocs\n",
@@ -277,7 +276,7 @@ void DRM(free_pages) (unsigned long address, int order, int area) {
}
}
-void *DRM(ioremap) (unsigned long offset, unsigned long size,
+void *drm_ioremap (unsigned long offset, unsigned long size,
drm_device_t * dev) {
void *pt;
@@ -288,19 +287,19 @@ void *DRM(ioremap) (unsigned long offset, unsigned long size,
}
if (!(pt = drm_ioremap(offset, size, dev))) {
- spin_lock(&DRM(mem_lock));
- ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
- spin_unlock(&DRM(mem_lock));
+ spin_lock(&drm_mem_lock);
+ ++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count;
+ spin_unlock(&drm_mem_lock);
return NULL;
}
- spin_lock(&DRM(mem_lock));
- ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
- DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size;
- spin_unlock(&DRM(mem_lock));
+ spin_lock(&drm_mem_lock);
+ ++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
+ drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size;
+ spin_unlock(&drm_mem_lock);
return pt;
}
-void *DRM(ioremap_nocache) (unsigned long offset, unsigned long size,
+void *drm_ioremap_nocache (unsigned long offset, unsigned long size,
drm_device_t * dev) {
void *pt;
@@ -311,19 +310,19 @@ void *DRM(ioremap_nocache) (unsigned long offset, unsigned long size,
}
if (!(pt = drm_ioremap_nocache(offset, size, dev))) {
- spin_lock(&DRM(mem_lock));
- ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
- spin_unlock(&DRM(mem_lock));
+ spin_lock(&drm_mem_lock);
+ ++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count;
+ spin_unlock(&drm_mem_lock);
return NULL;
}
- spin_lock(&DRM(mem_lock));
- ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
- DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size;
- spin_unlock(&DRM(mem_lock));
+ spin_lock(&drm_mem_lock);
+ ++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
+ drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size;
+ spin_unlock(&drm_mem_lock);
return pt;
}
-void DRM(ioremapfree) (void *pt, unsigned long size, drm_device_t * dev) {
+void drm_ioremapfree (void *pt, unsigned long size, drm_device_t * dev) {
int alloc_count;
int free_count;
@@ -333,11 +332,11 @@ void DRM(ioremapfree) (void *pt, unsigned long size, drm_device_t * dev) {
else
drm_ioremapfree(pt, size, dev);
- spin_lock(&DRM(mem_lock));
- DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += size;
- free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count;
- alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
- spin_unlock(&DRM(mem_lock));
+ spin_lock(&drm_mem_lock);
+ drm_mem_stats[DRM_MEM_MAPPINGS].bytes_freed += size;
+ free_count = ++drm_mem_stats[DRM_MEM_MAPPINGS].free_count;
+ alloc_count = drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
+ spin_unlock(&drm_mem_lock);
if (free_count > alloc_count) {
DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
"Excess frees: %d frees, %d allocs\n",
@@ -347,7 +346,7 @@ void DRM(ioremapfree) (void *pt, unsigned long size, drm_device_t * dev) {
#if __OS_HAS_AGP
-DRM_AGP_MEM *DRM(alloc_agp) (int pages, u32 type) {
+DRM_AGP_MEM *drm_alloc_agp (drm_device_t *dev, int pages, u32 type) {
DRM_AGP_MEM *handle;
if (!pages) {
@@ -355,21 +354,21 @@ DRM_AGP_MEM *DRM(alloc_agp) (int pages, u32 type) {
return NULL;
}
- if ((handle = DRM(agp_allocate_memory) (pages, type))) {
- spin_lock(&DRM(mem_lock));
- ++DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
- DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_allocated
+ if ((handle = drm_agp_allocate_memory (pages, type))) {
+ spin_lock(&drm_mem_lock);
+ ++drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count;
+ drm_mem_stats[DRM_MEM_TOTALAGP].bytes_allocated
+= pages << PAGE_SHIFT;
- spin_unlock(&DRM(mem_lock));
+ spin_unlock(&drm_mem_lock);
return handle;
}
- spin_lock(&DRM(mem_lock));
- ++DRM(mem_stats)[DRM_MEM_TOTALAGP].fail_count;
- spin_unlock(&DRM(mem_lock));
+ spin_lock(&drm_mem_lock);
+ ++drm_mem_stats[DRM_MEM_TOTALAGP].fail_count;
+ spin_unlock(&drm_mem_lock);
return NULL;
}
-int DRM(free_agp) (DRM_AGP_MEM * handle, int pages) {
+int drm_free_agp (DRM_AGP_MEM * handle, int pages) {
int alloc_count;
int free_count;
int retval = -EINVAL;
@@ -380,13 +379,13 @@ int DRM(free_agp) (DRM_AGP_MEM * handle, int pages) {
return retval;
}
- if (DRM(agp_free_memory) (handle)) {
- spin_lock(&DRM(mem_lock));
- free_count = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count;
- alloc_count = DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
- DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_freed
+ if (drm_agp_free_memory (handle)) {
+ spin_lock(&drm_mem_lock);
+ free_count = ++drm_mem_stats[DRM_MEM_TOTALAGP].free_count;
+ alloc_count = drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count;
+ drm_mem_stats[DRM_MEM_TOTALAGP].bytes_freed
+= pages << PAGE_SHIFT;
- spin_unlock(&DRM(mem_lock));
+ spin_unlock(&drm_mem_lock);
if (free_count > alloc_count) {
DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
"Excess frees: %d frees, %d allocs\n",
@@ -397,7 +396,7 @@ int DRM(free_agp) (DRM_AGP_MEM * handle, int pages) {
return retval;
}
-int DRM(bind_agp) (DRM_AGP_MEM * handle, unsigned int start) {
+int drm_bind_agp (DRM_AGP_MEM * handle, unsigned int start) {
int retcode = -EINVAL;
if (!handle) {
@@ -406,21 +405,21 @@ int DRM(bind_agp) (DRM_AGP_MEM * handle, unsigned int start) {
return retcode;
}
- if (!(retcode = DRM(agp_bind_memory) (handle, start))) {
- spin_lock(&DRM(mem_lock));
- ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
- DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_allocated
+ if (!(retcode = drm_agp_bind_memory (handle, start))) {
+ spin_lock(&drm_mem_lock);
+ ++drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count;
+ drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_allocated
+= handle->page_count << PAGE_SHIFT;
- spin_unlock(&DRM(mem_lock));
+ spin_unlock(&drm_mem_lock);
return retcode;
}
- spin_lock(&DRM(mem_lock));
- ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].fail_count;
- spin_unlock(&DRM(mem_lock));
+ spin_lock(&drm_mem_lock);
+ ++drm_mem_stats[DRM_MEM_BOUNDAGP].fail_count;
+ spin_unlock(&drm_mem_lock);
return retcode;
}
-int DRM(unbind_agp) (DRM_AGP_MEM * handle) {
+int drm_unbind_agp (DRM_AGP_MEM * handle) {
int alloc_count;
int free_count;
int retcode = -EINVAL;
@@ -431,14 +430,14 @@ int DRM(unbind_agp) (DRM_AGP_MEM * handle) {
return retcode;
}
- if ((retcode = DRM(agp_unbind_memory) (handle)))
+ if ((retcode = drm_agp_unbind_memory (handle)))
return retcode;
- spin_lock(&DRM(mem_lock));
- free_count = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count;
- alloc_count = DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
- DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_freed
+ spin_lock(&drm_mem_lock);
+ free_count = ++drm_mem_stats[DRM_MEM_BOUNDAGP].free_count;
+ alloc_count = drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count;
+ drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_freed
+= handle->page_count << PAGE_SHIFT;
- spin_unlock(&DRM(mem_lock));
+ spin_unlock(&drm_mem_lock);
if (free_count > alloc_count) {
DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
"Excess frees: %d frees, %d allocs\n",
diff --git a/drivers/char/drm/drm_os_linux.h b/drivers/char/drm/drm_os_linux.h
index d51aeb4966f48..695115d703822 100644
--- a/drivers/char/drm/drm_os_linux.h
+++ b/drivers/char/drm/drm_os_linux.h
@@ -13,6 +13,7 @@
#define DRM_ERR(d) -(d)
/** Current process ID */
#define DRM_CURRENTPID current->pid
+#define DRM_SUSER(p) capable(CAP_SYS_ADMIN)
#define DRM_UDELAY(d) udelay(d)
/** Read a byte from a MMIO region */
#define DRM_READ8(map, offset) readb(((void __iomem *)(map)->handle) + (offset))
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
index d66dc55e29a07..5b1d3a04458d0 100644
--- a/drivers/char/drm/drm_pciids.h
+++ b/drivers/char/drm/drm_pciids.h
@@ -46,6 +46,7 @@
{0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
{0x1002, 0x4E51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
{0x1002, 0x4E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
+ {0x1002, 0x4E56, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
{0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
{0x1002, 0x5145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
{0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
@@ -69,6 +70,7 @@
{0x1002, 0x516B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
{0x1002, 0x516C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
{0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
+ {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
{0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \
{0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \
{0x1002, 0x5836, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \
@@ -82,10 +84,13 @@
{0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
{0x1002, 0x596A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x596B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
+ {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
{0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \
{0x1002, 0x5c62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \
{0x1002, 0x5c64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
+ {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
+ {0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420}, \
{0, 0, 0}
#define r128_PCI_IDS \
@@ -176,7 +181,7 @@
#define viadrv_PCI_IDS \
{0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
- {0x1106, 0x3118, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ {0x1106, 0x3118, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \
{0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
@@ -196,6 +201,10 @@
{0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
+#define gamma_PCI_IDS \
+ {0x3d3d, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ {0, 0, 0}
+
#define savage_PCI_IDS \
{0x5333, 0x8a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \
{0x5333, 0x8a21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \
@@ -234,3 +243,4 @@
{0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
+
diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c
index 3f452f763f0fa..6f943e3309ef9 100644
--- a/drivers/char/drm/drm_proc.c
+++ b/drivers/char/drm/drm_proc.c
@@ -61,16 +61,14 @@ static struct drm_proc_list {
const char *name; /**< file name */
int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/
} drm_proc_list[] = {
- {
- "name", drm_name_info}, {
- "mem", drm_mem_info}, {
- "vm", drm_vm_info}, {
- "clients", drm_clients_info}, {
- "queues", drm_queues_info}, {
- "bufs", drm_bufs_info},
+ {"name", drm_name_info},
+ {"mem", drm_mem_info},
+ {"vm", drm_vm_info},
+ {"clients", drm_clients_info},
+ {"queues", drm_queues_info},
+ {"bufs", drm_bufs_info},
#if DRM_DEBUG_CODE
- {
- "vma", drm_vma_info},
+ {"vma", drm_vma_info},
#endif
};
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c
index 60b6f8e8bf693..42d766359caa9 100644
--- a/drivers/char/drm/drm_stub.c
+++ b/drivers/char/drm/drm_stub.c
@@ -93,8 +93,8 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
dev->driver = driver;
- if (dev->driver->preinit)
- if ((retcode = dev->driver->preinit(dev, ent->driver_data)))
+ if (dev->driver->load)
+ if ((retcode = dev->driver->load(dev, ent->driver_data)))
goto error_out_unreg;
if (drm_core_has_AGP(dev)) {
@@ -124,47 +124,10 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
return 0;
error_out_unreg:
- drm_takedown(dev);
+ drm_lastclose(dev);
return retcode;
}
-/**
- * File \c open operation.
- *
- * \param inode device inode.
- * \param filp file pointer.
- *
- * Puts the dev->fops corresponding to the device minor number into
- * \p filp, call the \c open method, and restore the file operations.
- */
-int drm_stub_open(struct inode *inode, struct file *filp)
-{
- drm_device_t *dev = NULL;
- int minor = iminor(inode);
- int err = -ENODEV;
- struct file_operations *old_fops;
-
- DRM_DEBUG("\n");
-
- if (!((minor >= 0) && (minor < drm_cards_limit)))
- return -ENODEV;
-
- if (!drm_heads[minor])
- return -ENODEV;
-
- if (!(dev = drm_heads[minor]->dev))
- return -ENODEV;
-
- old_fops = filp->f_op;
- filp->f_op = fops_get(&dev->driver->fops);
- if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) {
- fops_put(filp->f_op);
- filp->f_op = fops_get(old_fops);
- }
- fops_put(old_fops);
-
- return err;
-}
/**
* Get a secondary minor number.
@@ -200,11 +163,7 @@ static int drm_get_head(drm_device_t * dev, drm_head_t * head)
goto err_g1;
}
- head->dev_class = drm_sysfs_device_add(drm_class,
- MKDEV(DRM_MAJOR,
- minor),
- &dev->pdev->dev,
- "card%d", minor);
+ head->dev_class = drm_sysfs_device_add(drm_class, head);
if (IS_ERR(head->dev_class)) {
printk(KERN_ERR
"DRM: Error sysfs_device_add.\n");
@@ -258,11 +217,10 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
}
if ((ret = drm_get_head(dev, &dev->primary)))
goto err_g1;
-
- /* postinit is a required function to display the signon banner */
- /* drivers add secondary heads here if needed */
- if ((ret = dev->driver->postinit(dev, ent->driver_data)))
- goto err_g1;
+
+ DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
+ driver->name, driver->major, driver->minor, driver->patchlevel,
+ driver->date, dev->primary.minor);
return 0;
@@ -318,10 +276,9 @@ int drm_put_head(drm_head_t * head)
DRM_DEBUG("release secondary minor %d\n", minor);
drm_proc_cleanup(minor, drm_proc_root, head->dev_root);
- drm_sysfs_device_remove(MKDEV(DRM_MAJOR, head->minor));
+ drm_sysfs_device_remove(head->dev_class);
- *head = (drm_head_t) {
- .dev = NULL};
+ *head = (drm_head_t) {.dev = NULL};
drm_heads[minor] = NULL;
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c
index 6d3449761914c..68e43ddc16aea 100644
--- a/drivers/char/drm/drm_sysfs.c
+++ b/drivers/char/drm/drm_sysfs.c
@@ -15,8 +15,6 @@
#include <linux/device.h>
#include <linux/kdev_t.h>
#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/string.h>
#include "drm_core.h"
#include "drmP.h"
@@ -28,15 +26,11 @@ struct drm_sysfs_class {
#define to_drm_sysfs_class(d) container_of(d, struct drm_sysfs_class, class)
struct simple_dev {
- struct list_head node;
dev_t dev;
struct class_device class_dev;
};
#define to_simple_dev(d) container_of(d, struct simple_dev, class_dev)
-static LIST_HEAD(simple_dev_list);
-static DEFINE_SPINLOCK(simple_dev_list_lock);
-
static void release_simple_dev(struct class_device *class_dev)
{
struct simple_dev *s_dev = to_simple_dev(class_dev);
@@ -124,6 +118,18 @@ void drm_sysfs_destroy(struct drm_sysfs_class *cs)
class_unregister(&cs->class);
}
+static ssize_t show_dri(struct class_device *class_device, char *buf)
+{
+ drm_device_t * dev = ((drm_head_t *)class_get_devdata(class_device))->dev;
+ if (dev->driver->dri_library_name)
+ return dev->driver->dri_library_name(dev, buf);
+ return snprintf(buf, PAGE_SIZE, "%s\n", dev->driver->pci_driver.name);
+}
+
+static struct class_device_attribute class_device_attrs[] = {
+ __ATTR(dri_library_name, S_IRUGO, show_dri, NULL),
+};
+
/**
* drm_sysfs_device_add - adds a class device to sysfs for a character driver
* @cs: pointer to the struct drm_sysfs_class that this device should be registered to.
@@ -138,13 +144,11 @@ void drm_sysfs_destroy(struct drm_sysfs_class *cs)
* Note: the struct drm_sysfs_class passed to this function must have previously been
* created with a call to drm_sysfs_create().
*/
-struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, dev_t dev,
- struct device *device,
- const char *fmt, ...)
+struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs,
+ drm_head_t *head)
{
- va_list args;
struct simple_dev *s_dev = NULL;
- int retval;
+ int i, retval;
if ((cs == NULL) || (IS_ERR(cs))) {
retval = -ENODEV;
@@ -158,26 +162,23 @@ struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, dev_t dev,
}
memset(s_dev, 0x00, sizeof(*s_dev));
- s_dev->dev = dev;
- s_dev->class_dev.dev = device;
+ s_dev->dev = MKDEV(DRM_MAJOR, head->minor);
+ s_dev->class_dev.dev = &(head->dev->pdev)->dev;
s_dev->class_dev.class = &cs->class;
- va_start(args, fmt);
- vsnprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, fmt, args);
- va_end(args);
+ snprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, "card%d", head->minor);
retval = class_device_register(&s_dev->class_dev);
if (retval)
goto error;
class_device_create_file(&s_dev->class_dev, &cs->attr);
+ class_set_devdata(&s_dev->class_dev, head);
- spin_lock(&simple_dev_list_lock);
- list_add(&s_dev->node, &simple_dev_list);
- spin_unlock(&simple_dev_list_lock);
-
+ for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
+ class_device_create_file(&s_dev->class_dev, &class_device_attrs[i]);
return &s_dev->class_dev;
- error:
+error:
kfree(s_dev);
return ERR_PTR(retval);
}
@@ -189,23 +190,12 @@ struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, dev_t dev,
* This call unregisters and cleans up a class device that was created with a
* call to drm_sysfs_device_add()
*/
-void drm_sysfs_device_remove(dev_t dev)
+void drm_sysfs_device_remove(struct class_device *class_dev)
{
- struct simple_dev *s_dev = NULL;
- int found = 0;
-
- spin_lock(&simple_dev_list_lock);
- list_for_each_entry(s_dev, &simple_dev_list, node) {
- if (s_dev->dev == dev) {
- found = 1;
- break;
- }
- }
- if (found) {
- list_del(&s_dev->node);
- spin_unlock(&simple_dev_list_lock);
- class_device_unregister(&s_dev->class_dev);
- } else {
- spin_unlock(&simple_dev_list_lock);
- }
+ struct simple_dev *s_dev = to_simple_dev(class_dev);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
+ class_device_remove_file(&s_dev->class_dev, &class_device_attrs[i]);
+ class_device_unregister(&s_dev->class_dev);
}
diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c
index dba502373da10..cc1b89086876b 100644
--- a/drivers/char/drm/i810_dma.c
+++ b/drivers/char/drm/i810_dma.c
@@ -114,7 +114,6 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
static struct file_operations i810_buffer_fops = {
.open = drm_open,
- .flush = drm_flush,
.release = drm_release,
.ioctl = drm_ioctl,
.mmap = i810_mmap_buffers,
@@ -1319,12 +1318,24 @@ static int i810_flip_bufs(struct inode *inode, struct file *filp,
return 0;
}
-void i810_driver_pretakedown(drm_device_t * dev)
+int i810_driver_load(drm_device_t *dev, unsigned long flags)
+{
+ /* i810 has 4 more counters */
+ dev->counters += 4;
+ dev->types[6] = _DRM_STAT_IRQ;
+ dev->types[7] = _DRM_STAT_PRIMARY;
+ dev->types[8] = _DRM_STAT_SECONDARY;
+ dev->types[9] = _DRM_STAT_DMA;
+
+ return 0;
+}
+
+void i810_driver_lastclose(drm_device_t * dev)
{
i810_dma_cleanup(dev);
}
-void i810_driver_prerelease(drm_device_t * dev, DRMFILE filp)
+void i810_driver_preclose(drm_device_t * dev, DRMFILE filp)
{
if (dev->dev_private) {
drm_i810_private_t *dev_priv = dev->dev_private;
@@ -1334,7 +1345,7 @@ void i810_driver_prerelease(drm_device_t * dev, DRMFILE filp)
}
}
-void i810_driver_release(drm_device_t * dev, struct file *filp)
+void i810_driver_reclaim_buffers_locked(drm_device_t * dev, struct file *filp)
{
i810_reclaim_buffers(dev, filp);
}
@@ -1346,21 +1357,21 @@ int i810_driver_dma_quiescent(drm_device_t * dev)
}
drm_ioctl_desc_t i810_ioctls[] = {
- [DRM_IOCTL_NR(DRM_I810_INIT)] = {i810_dma_init, 1, 1},
- [DRM_IOCTL_NR(DRM_I810_VERTEX)] = {i810_dma_vertex, 1, 0},
- [DRM_IOCTL_NR(DRM_I810_CLEAR)] = {i810_clear_bufs, 1, 0},
- [DRM_IOCTL_NR(DRM_I810_FLUSH)] = {i810_flush_ioctl, 1, 0},
- [DRM_IOCTL_NR(DRM_I810_GETAGE)] = {i810_getage, 1, 0},
- [DRM_IOCTL_NR(DRM_I810_GETBUF)] = {i810_getbuf, 1, 0},
- [DRM_IOCTL_NR(DRM_I810_SWAP)] = {i810_swap_bufs, 1, 0},
- [DRM_IOCTL_NR(DRM_I810_COPY)] = {i810_copybuf, 1, 0},
- [DRM_IOCTL_NR(DRM_I810_DOCOPY)] = {i810_docopy, 1, 0},
- [DRM_IOCTL_NR(DRM_I810_OV0INFO)] = {i810_ov0_info, 1, 0},
- [DRM_IOCTL_NR(DRM_I810_FSTATUS)] = {i810_fstatus, 1, 0},
- [DRM_IOCTL_NR(DRM_I810_OV0FLIP)] = {i810_ov0_flip, 1, 0},
- [DRM_IOCTL_NR(DRM_I810_MC)] = {i810_dma_mc, 1, 1},
- [DRM_IOCTL_NR(DRM_I810_RSTATUS)] = {i810_rstatus, 1, 0},
- [DRM_IOCTL_NR(DRM_I810_FLIP)] = {i810_flip_bufs, 1, 0}
+ [DRM_IOCTL_NR(DRM_I810_INIT)] = {i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_I810_VERTEX)] = {i810_dma_vertex, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I810_CLEAR)] = {i810_clear_bufs, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I810_FLUSH)] = {i810_flush_ioctl, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I810_GETAGE)] = {i810_getage, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I810_GETBUF)] = {i810_getbuf, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I810_SWAP)] = {i810_swap_bufs, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I810_COPY)] = {i810_copybuf, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I810_DOCOPY)] = {i810_docopy, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I810_OV0INFO)] = {i810_ov0_info, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I810_FSTATUS)] = {i810_fstatus, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I810_OV0FLIP)] = {i810_ov0_flip, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I810_MC)] = {i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_I810_RSTATUS)] = {i810_rstatus, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I810_FLIP)] = {i810_flip_bufs, DRM_AUTH}
};
int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls);
diff --git a/drivers/char/drm/i810_drv.c b/drivers/char/drm/i810_drv.c
index 070cef6c2b46c..dfe6ad2b6a6e2 100644
--- a/drivers/char/drm/i810_drv.c
+++ b/drivers/char/drm/i810_drv.c
@@ -38,38 +38,6 @@
#include "drm_pciids.h"
-static int postinit(struct drm_device *dev, unsigned long flags)
-{
- /* i810 has 4 more counters */
- dev->counters += 4;
- dev->types[6] = _DRM_STAT_IRQ;
- dev->types[7] = _DRM_STAT_PRIMARY;
- dev->types[8] = _DRM_STAT_SECONDARY;
- dev->types[9] = _DRM_STAT_DMA;
-
- DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
- DRIVER_NAME,
- DRIVER_MAJOR,
- DRIVER_MINOR,
- DRIVER_PATCHLEVEL,
- DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
- );
- return 0;
-}
-
-static int version(drm_version_t * version)
-{
- int len;
-
- version->version_major = DRIVER_MAJOR;
- version->version_minor = DRIVER_MINOR;
- version->version_patchlevel = DRIVER_PATCHLEVEL;
- DRM_COPY(version->name, DRIVER_NAME);
- DRM_COPY(version->date, DRIVER_DATE);
- DRM_COPY(version->desc, DRIVER_DESC);
- return 0;
-}
-
static struct pci_device_id pciidlist[] = {
i810_PCI_IDS
};
@@ -79,16 +47,14 @@ static struct drm_driver driver = {
DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE,
.dev_priv_size = sizeof(drm_i810_buf_priv_t),
- .pretakedown = i810_driver_pretakedown,
- .prerelease = i810_driver_prerelease,
+ .load = i810_driver_load,
+ .lastclose = i810_driver_lastclose,
+ .preclose = i810_driver_preclose,
.device_is_agp = i810_driver_device_is_agp,
- .release = i810_driver_release,
+ .reclaim_buffers_locked = i810_driver_reclaim_buffers_locked,
.dma_quiescent = i810_driver_dma_quiescent,
- .reclaim_buffers = i810_reclaim_buffers,
.get_map_ofs = drm_core_get_map_ofs,
.get_reg_ofs = drm_core_get_reg_ofs,
- .postinit = postinit,
- .version = version,
.ioctls = i810_ioctls,
.fops = {
.owner = THIS_MODULE,
@@ -98,13 +64,19 @@ static struct drm_driver driver = {
.mmap = drm_mmap,
.poll = drm_poll,
.fasync = drm_fasync,
- }
- ,
+ },
+
.pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
- }
- ,
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ },
+
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESC,
+ .date = DRIVER_DATE,
+ .major = DRIVER_MAJOR,
+ .minor = DRIVER_MINOR,
+ .patchlevel = DRIVER_PATCHLEVEL,
};
static int __init i810_init(void)
diff --git a/drivers/char/drm/i810_drv.h b/drivers/char/drm/i810_drv.h
index c78f36aaa2f06..a18b80d91920b 100644
--- a/drivers/char/drm/i810_drv.h
+++ b/drivers/char/drm/i810_drv.h
@@ -116,9 +116,13 @@ typedef struct drm_i810_private {
extern void i810_reclaim_buffers(drm_device_t * dev, struct file *filp);
extern int i810_driver_dma_quiescent(drm_device_t * dev);
-extern void i810_driver_release(drm_device_t * dev, struct file *filp);
-extern void i810_driver_pretakedown(drm_device_t * dev);
-extern void i810_driver_prerelease(drm_device_t * dev, DRMFILE filp);
+extern void i810_driver_reclaim_buffers_locked(drm_device_t * dev,
+ struct file *filp);
+extern int i810_driver_load(struct drm_device *, unsigned long flags);
+extern void i810_driver_lastclose(drm_device_t * dev);
+extern void i810_driver_preclose(drm_device_t * dev, DRMFILE filp);
+extern void i810_driver_reclaim_buffers_locked(drm_device_t * dev,
+ struct file *filp);
extern int i810_driver_device_is_agp(drm_device_t * dev);
extern drm_ioctl_desc_t i810_ioctls[];
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
index dc94f1914425b..4fea32aed6d24 100644
--- a/drivers/char/drm/i830_dma.c
+++ b/drivers/char/drm/i830_dma.c
@@ -116,7 +116,6 @@ static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
static struct file_operations i830_buffer_fops = {
.open = drm_open,
- .flush = drm_flush,
.release = drm_release,
.ioctl = drm_ioctl,
.mmap = i830_mmap_buffers,
@@ -1517,12 +1516,24 @@ static int i830_setparam(struct inode *inode, struct file *filp,
return 0;
}
-void i830_driver_pretakedown(drm_device_t * dev)
+int i830_driver_load(drm_device_t *dev, unsigned long flags)
+{
+ /* i830 has 4 more counters */
+ dev->counters += 4;
+ dev->types[6] = _DRM_STAT_IRQ;
+ dev->types[7] = _DRM_STAT_PRIMARY;
+ dev->types[8] = _DRM_STAT_SECONDARY;
+ dev->types[9] = _DRM_STAT_DMA;
+
+ return 0;
+}
+
+void i830_driver_lastclose(drm_device_t * dev)
{
i830_dma_cleanup(dev);
}
-void i830_driver_prerelease(drm_device_t * dev, DRMFILE filp)
+void i830_driver_preclose(drm_device_t * dev, DRMFILE filp)
{
if (dev->dev_private) {
drm_i830_private_t *dev_priv = dev->dev_private;
@@ -1532,7 +1543,7 @@ void i830_driver_prerelease(drm_device_t * dev, DRMFILE filp)
}
}
-void i830_driver_release(drm_device_t * dev, struct file *filp)
+void i830_driver_reclaim_buffers_locked(drm_device_t * dev, struct file *filp)
{
i830_reclaim_buffers(dev, filp);
}
@@ -1544,20 +1555,20 @@ int i830_driver_dma_quiescent(drm_device_t * dev)
}
drm_ioctl_desc_t i830_ioctls[] = {
- [DRM_IOCTL_NR(DRM_I830_INIT)] = {i830_dma_init, 1, 1},
- [DRM_IOCTL_NR(DRM_I830_VERTEX)] = {i830_dma_vertex, 1, 0},
- [DRM_IOCTL_NR(DRM_I830_CLEAR)] = {i830_clear_bufs, 1, 0},
- [DRM_IOCTL_NR(DRM_I830_FLUSH)] = {i830_flush_ioctl, 1, 0},
- [DRM_IOCTL_NR(DRM_I830_GETAGE)] = {i830_getage, 1, 0},
- [DRM_IOCTL_NR(DRM_I830_GETBUF)] = {i830_getbuf, 1, 0},
- [DRM_IOCTL_NR(DRM_I830_SWAP)] = {i830_swap_bufs, 1, 0},
- [DRM_IOCTL_NR(DRM_I830_COPY)] = {i830_copybuf, 1, 0},
- [DRM_IOCTL_NR(DRM_I830_DOCOPY)] = {i830_docopy, 1, 0},
- [DRM_IOCTL_NR(DRM_I830_FLIP)] = {i830_flip_bufs, 1, 0},
- [DRM_IOCTL_NR(DRM_I830_IRQ_EMIT)] = {i830_irq_emit, 1, 0},
- [DRM_IOCTL_NR(DRM_I830_IRQ_WAIT)] = {i830_irq_wait, 1, 0},
- [DRM_IOCTL_NR(DRM_I830_GETPARAM)] = {i830_getparam, 1, 0},
- [DRM_IOCTL_NR(DRM_I830_SETPARAM)] = {i830_setparam, 1, 0}
+ [DRM_IOCTL_NR(DRM_I830_INIT)] = {i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_I830_VERTEX)] = {i830_dma_vertex, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I830_CLEAR)] = {i830_clear_bufs, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I830_FLUSH)] = {i830_flush_ioctl, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I830_GETAGE)] = {i830_getage, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I830_GETBUF)] = {i830_getbuf, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I830_SWAP)] = {i830_swap_bufs, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I830_COPY)] = {i830_copybuf, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I830_DOCOPY)] = {i830_docopy, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I830_FLIP)] = {i830_flip_bufs, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I830_IRQ_EMIT)] = {i830_irq_emit, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I830_IRQ_WAIT)] = {i830_irq_wait, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I830_GETPARAM)] = {i830_getparam, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I830_SETPARAM)] = {i830_setparam, DRM_AUTH}
};
int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls);
diff --git a/drivers/char/drm/i830_drv.c b/drivers/char/drm/i830_drv.c
index acd821e8fe4d3..722658188f5f4 100644
--- a/drivers/char/drm/i830_drv.c
+++ b/drivers/char/drm/i830_drv.c
@@ -40,37 +40,6 @@
#include "drm_pciids.h"
-static int postinit(struct drm_device *dev, unsigned long flags)
-{
- dev->counters += 4;
- dev->types[6] = _DRM_STAT_IRQ;
- dev->types[7] = _DRM_STAT_PRIMARY;
- dev->types[8] = _DRM_STAT_SECONDARY;
- dev->types[9] = _DRM_STAT_DMA;
-
- DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
- DRIVER_NAME,
- DRIVER_MAJOR,
- DRIVER_MINOR,
- DRIVER_PATCHLEVEL,
- DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
- );
- return 0;
-}
-
-static int version(drm_version_t * version)
-{
- int len;
-
- version->version_major = DRIVER_MAJOR;
- version->version_minor = DRIVER_MINOR;
- version->version_patchlevel = DRIVER_PATCHLEVEL;
- DRM_COPY(version->name, DRIVER_NAME);
- DRM_COPY(version->date, DRIVER_DATE);
- DRM_COPY(version->desc, DRIVER_DESC);
- return 0;
-}
-
static struct pci_device_id pciidlist[] = {
i830_PCI_IDS
};
@@ -83,12 +52,12 @@ static struct drm_driver driver = {
.driver_features |= DRIVER_HAVE_IRQ | DRIVER_SHARED_IRQ,
#endif
.dev_priv_size = sizeof(drm_i830_buf_priv_t),
- .pretakedown = i830_driver_pretakedown,
- .prerelease = i830_driver_prerelease,
+ .load = i830_driver_load,
+ .lastclose = i830_driver_lastclose,
+ .preclose = i830_driver_preclose,
.device_is_agp = i830_driver_device_is_agp,
- .release = i830_driver_release,
+ .reclaim_buffers_locked = i830_driver_reclaim_buffers_locked,
.dma_quiescent = i830_driver_dma_quiescent,
- .reclaim_buffers = i830_reclaim_buffers,
.get_map_ofs = drm_core_get_map_ofs,
.get_reg_ofs = drm_core_get_reg_ofs,
#if USE_IRQS
@@ -97,8 +66,6 @@ static struct drm_driver driver = {
.irq_uninstall = i830_driver_irq_uninstall,
.irq_handler = i830_driver_irq_handler,
#endif
- .postinit = postinit,
- .version = version,
.ioctls = i830_ioctls,
.fops = {
.owner = THIS_MODULE,
@@ -108,13 +75,19 @@ static struct drm_driver driver = {
.mmap = drm_mmap,
.poll = drm_poll,
.fasync = drm_fasync,
- }
- ,
+ },
+
.pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
- }
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ },
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESC,
+ .date = DRIVER_DATE,
+ .major = DRIVER_MAJOR,
+ .minor = DRIVER_MINOR,
+ .patchlevel = DRIVER_PATCHLEVEL,
};
static int __init i830_init(void)
diff --git a/drivers/char/drm/i830_drv.h b/drivers/char/drm/i830_drv.h
index bc4bd49fb0ccb..bf9075b576bdd 100644
--- a/drivers/char/drm/i830_drv.h
+++ b/drivers/char/drm/i830_drv.h
@@ -136,10 +136,12 @@ extern irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS);
extern void i830_driver_irq_preinstall(drm_device_t * dev);
extern void i830_driver_irq_postinstall(drm_device_t * dev);
extern void i830_driver_irq_uninstall(drm_device_t * dev);
-extern void i830_driver_pretakedown(drm_device_t * dev);
-extern void i830_driver_release(drm_device_t * dev, struct file *filp);
+extern int i830_driver_load(struct drm_device *, unsigned long flags);
+extern void i830_driver_preclose(drm_device_t * dev, DRMFILE filp);
+extern void i830_driver_lastclose(drm_device_t * dev);
+extern void i830_driver_reclaim_buffers_locked(drm_device_t * dev,
+ struct file *filp);
extern int i830_driver_dma_quiescent(drm_device_t * dev);
-extern void i830_driver_prerelease(drm_device_t * dev, DRMFILE filp);
extern int i830_driver_device_is_agp(drm_device_t * dev);
#define I830_READ(reg) DRM_READ32(dev_priv->mmio_map, reg)
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index f3aa0c3701270..9140703da1ba0 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -1,7 +1,6 @@
/* i915_dma.c -- DMA support for the I915 -*- linux-c -*-
*/
-/**************************************************************************
- *
+/*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
@@ -25,7 +24,7 @@
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
- **************************************************************************/
+ */
#include "drmP.h"
#include "drm.h"
@@ -196,7 +195,7 @@ static int i915_initialize(drm_device_t * dev,
return 0;
}
-static int i915_resume(drm_device_t * dev)
+static int i915_dma_resume(drm_device_t * dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -253,7 +252,7 @@ static int i915_dma_init(DRM_IOCTL_ARGS)
retcode = i915_dma_cleanup(dev);
break;
case I915_RESUME_DMA:
- retcode = i915_resume(dev);
+ retcode = i915_dma_resume(dev);
break;
default:
retcode = -EINVAL;
@@ -654,6 +653,9 @@ static int i915_getparam(DRM_IOCTL_ARGS)
case I915_PARAM_ALLOW_BATCHBUFFER:
value = dev_priv->allow_batchbuffer ? 1 : 0;
break;
+ case I915_PARAM_LAST_DISPATCH:
+ value = READ_BREADCRUMB(dev_priv);
+ break;
default:
DRM_ERROR("Unkown parameter %d\n", param.param);
return DRM_ERR(EINVAL);
@@ -699,7 +701,19 @@ static int i915_setparam(DRM_IOCTL_ARGS)
return 0;
}
-void i915_driver_pretakedown(drm_device_t * dev)
+int i915_driver_load(drm_device_t *dev, unsigned long flags)
+{
+ /* i915 has 4 more counters */
+ dev->counters += 4;
+ dev->types[6] = _DRM_STAT_IRQ;
+ dev->types[7] = _DRM_STAT_PRIMARY;
+ dev->types[8] = _DRM_STAT_SECONDARY;
+ dev->types[9] = _DRM_STAT_DMA;
+
+ return 0;
+}
+
+void i915_driver_lastclose(drm_device_t * dev)
{
if (dev->dev_private) {
drm_i915_private_t *dev_priv = dev->dev_private;
@@ -708,7 +722,7 @@ void i915_driver_pretakedown(drm_device_t * dev)
i915_dma_cleanup(dev);
}
-void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp)
+void i915_driver_preclose(drm_device_t * dev, DRMFILE filp)
{
if (dev->dev_private) {
drm_i915_private_t *dev_priv = dev->dev_private;
@@ -717,18 +731,18 @@ void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp)
}
drm_ioctl_desc_t i915_ioctls[] = {
- [DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, 1, 1},
- [DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, 1, 0},
- [DRM_IOCTL_NR(DRM_I915_FLIP)] = {i915_flip_bufs, 1, 0},
- [DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = {i915_batchbuffer, 1, 0},
- [DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] = {i915_irq_emit, 1, 0},
- [DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] = {i915_irq_wait, 1, 0},
- [DRM_IOCTL_NR(DRM_I915_GETPARAM)] = {i915_getparam, 1, 0},
- [DRM_IOCTL_NR(DRM_I915_SETPARAM)] = {i915_setparam, 1, 1},
- [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, 1, 0},
- [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, 1, 0},
- [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, 1, 1},
- [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, 1, 0}
+ [DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I915_FLIP)] = {i915_flip_bufs, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = {i915_batchbuffer, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] = {i915_irq_emit, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] = {i915_irq_wait, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I915_GETPARAM)] = {i915_getparam, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I915_SETPARAM)] = {i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, DRM_AUTH}
};
int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
diff --git a/drivers/char/drm/i915_drm.h b/drivers/char/drm/i915_drm.h
index 23e027d290806..77412ddac0076 100644
--- a/drivers/char/drm/i915_drm.h
+++ b/drivers/char/drm/i915_drm.h
@@ -1,5 +1,4 @@
-/**************************************************************************
- *
+/*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
@@ -23,7 +22,7 @@
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
- **************************************************************************/
+ */
#ifndef _I915_DRM_H_
#define _I915_DRM_H_
@@ -152,6 +151,7 @@ typedef struct drm_i915_irq_wait {
*/
#define I915_PARAM_IRQ_ACTIVE 1
#define I915_PARAM_ALLOW_BATCHBUFFER 2
+#define I915_PARAM_LAST_DISPATCH 3
typedef struct drm_i915_getparam {
int param;
diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c
index 0508240f4e3be..8e2e6095c4b3f 100644
--- a/drivers/char/drm/i915_drv.c
+++ b/drivers/char/drm/i915_drv.c
@@ -1,6 +1,6 @@
/* i915_drv.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*-
*/
-/**************************************************************************
+/*
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
@@ -25,7 +25,7 @@
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
- **************************************************************************/
+ */
#include "drmP.h"
#include "drm.h"
@@ -34,48 +34,22 @@
#include "drm_pciids.h"
-static int postinit(struct drm_device *dev, unsigned long flags)
-{
- dev->counters += 4;
- dev->types[6] = _DRM_STAT_IRQ;
- dev->types[7] = _DRM_STAT_PRIMARY;
- dev->types[8] = _DRM_STAT_SECONDARY;
- dev->types[9] = _DRM_STAT_DMA;
-
- DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
- DRIVER_NAME,
- DRIVER_MAJOR,
- DRIVER_MINOR,
- DRIVER_PATCHLEVEL,
- DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
- );
- return 0;
-}
-
-static int version(drm_version_t * version)
-{
- int len;
-
- version->version_major = DRIVER_MAJOR;
- version->version_minor = DRIVER_MINOR;
- version->version_patchlevel = DRIVER_PATCHLEVEL;
- DRM_COPY(version->name, DRIVER_NAME);
- DRM_COPY(version->date, DRIVER_DATE);
- DRM_COPY(version->desc, DRIVER_DESC);
- return 0;
-}
-
static struct pci_device_id pciidlist[] = {
i915_PCI_IDS
};
static struct drm_driver driver = {
+ /* don't use mtrr's here, the Xserver or user space app should
+ * deal with them for intel hardware.
+ */
.driver_features =
- DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
- DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
- .pretakedown = i915_driver_pretakedown,
- .prerelease = i915_driver_prerelease,
+ DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/
+ DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
+ .load = i915_driver_load,
+ .lastclose = i915_driver_lastclose,
+ .preclose = i915_driver_preclose,
.device_is_agp = i915_driver_device_is_agp,
+ .vblank_wait = i915_driver_vblank_wait,
.irq_preinstall = i915_driver_irq_preinstall,
.irq_postinstall = i915_driver_irq_postinstall,
.irq_uninstall = i915_driver_irq_uninstall,
@@ -83,8 +57,6 @@ static struct drm_driver driver = {
.reclaim_buffers = drm_core_reclaim_buffers,
.get_map_ofs = drm_core_get_map_ofs,
.get_reg_ofs = drm_core_get_reg_ofs,
- .postinit = postinit,
- .version = version,
.ioctls = i915_ioctls,
.fops = {
.owner = THIS_MODULE,
@@ -97,11 +69,19 @@ static struct drm_driver driver = {
#ifdef CONFIG_COMPAT
.compat_ioctl = i915_compat_ioctl,
#endif
- },
+ },
+
.pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
- }
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ },
+
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESC,
+ .date = DRIVER_DATE,
+ .major = DRIVER_MAJOR,
+ .minor = DRIVER_MINOR,
+ .patchlevel = DRIVER_PATCHLEVEL,
};
static int __init i915_init(void)
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
index 17e457c73dc77..c6c71b45f1013 100644
--- a/drivers/char/drm/i915_drv.h
+++ b/drivers/char/drm/i915_drv.h
@@ -1,6 +1,6 @@
/* i915_drv.h -- Private header for the I915 driver -*- linux-c -*-
*/
-/**************************************************************************
+/*
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
@@ -25,7 +25,7 @@
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
- **************************************************************************/
+ */
#ifndef _I915_DRV_H_
#define _I915_DRV_H_
@@ -37,21 +37,18 @@
#define DRIVER_NAME "i915"
#define DRIVER_DESC "Intel Graphics"
-#define DRIVER_DATE "20040405"
+#define DRIVER_DATE "20051209"
/* Interface history:
*
* 1.1: Original.
+ * 1.2: Add Power Management
+ * 1.3: Add vblank support
*/
#define DRIVER_MAJOR 1
-#define DRIVER_MINOR 1
+#define DRIVER_MINOR 3
#define DRIVER_PATCHLEVEL 0
-/* We use our own dma mechanisms, not the drm template code. However,
- * the shared IRQ code is useful to us:
- */
-#define __HAVE_PM 1
-
typedef struct _drm_i915_ring_buffer {
int tail_mask;
unsigned long Start;
@@ -97,6 +94,7 @@ typedef struct drm_i915_private {
int tex_lru_log_granularity;
int allow_batchbuffer;
struct mem_block *agp_heap;
+ unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
} drm_i915_private_t;
extern drm_ioctl_desc_t i915_ioctls[];
@@ -104,14 +102,18 @@ extern int i915_max_ioctl;
/* i915_dma.c */
extern void i915_kernel_lost_context(drm_device_t * dev);
-extern void i915_driver_pretakedown(drm_device_t * dev);
-extern void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp);
+extern int i915_driver_load(struct drm_device *, unsigned long flags);
+extern void i915_driver_lastclose(drm_device_t * dev);
+extern void i915_driver_preclose(drm_device_t * dev, DRMFILE filp);
extern int i915_driver_device_is_agp(drm_device_t * dev);
+extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
+ unsigned long arg);
/* i915_irq.c */
extern int i915_irq_emit(DRM_IOCTL_ARGS);
extern int i915_irq_wait(DRM_IOCTL_ARGS);
+extern int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence);
extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
extern void i915_driver_irq_preinstall(drm_device_t * dev);
extern void i915_driver_irq_postinstall(drm_device_t * dev);
@@ -125,13 +127,10 @@ extern void i915_mem_takedown(struct mem_block **heap);
extern void i915_mem_release(drm_device_t * dev,
DRMFILE filp, struct mem_block *heap);
-extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
- unsigned long arg);
-
-#define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, reg)
-#define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, reg, val)
-#define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, reg)
-#define I915_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, reg, val)
+#define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg))
+#define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val))
+#define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg))
+#define I915_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, (reg), (val))
#define I915_VERBOSE 0
@@ -195,6 +194,13 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller);
#define PPCR 0x61204
#define PPCR_ON (1<<0)
+#define DVOB 0x61140
+#define DVOB_ON (1<<31)
+#define DVOC 0x61160
+#define DVOC_ON (1<<31)
+#define LVDS 0x61180
+#define LVDS_ON (1<<31)
+
#define ADPA 0x61100
#define ADPA_DPMS_MASK (~(3<<10))
#define ADPA_DPMS_ON (0<<10)
@@ -258,4 +264,6 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller);
#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
+#define READ_BREADCRUMB(dev_priv) (((u32 *)(dev_priv->hw_status_page))[5])
+
#endif
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
index 4fa448ee846b5..a1381c61aa631 100644
--- a/drivers/char/drm/i915_irq.c
+++ b/drivers/char/drm/i915_irq.c
@@ -1,7 +1,6 @@
-/* i915_dma.c -- DMA support for the I915 -*- linux-c -*-
+/* i915_irq.c -- IRQ support for the I915 -*- linux-c -*-
*/
-/**************************************************************************
- *
+/*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
@@ -25,16 +24,18 @@
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
- **************************************************************************/
+ */
#include "drmP.h"
#include "drm.h"
#include "i915_drm.h"
#include "i915_drv.h"
-#define USER_INT_FLAG 0x2
+#define USER_INT_FLAG (1<<1)
+#define VSYNC_PIPEB_FLAG (1<<5)
+#define VSYNC_PIPEA_FLAG (1<<7)
+
#define MAX_NOPID ((u32)~0)
-#define READ_BREADCRUMB(dev_priv) (((u32*)(dev_priv->hw_status_page))[5])
irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
{
@@ -43,7 +44,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
u16 temp;
temp = I915_READ16(I915REG_INT_IDENTITY_R);
- temp &= USER_INT_FLAG;
+ temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG);
DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp);
@@ -51,7 +52,15 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
return IRQ_NONE;
I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
- DRM_WAKEUP(&dev_priv->irq_queue);
+
+ if (temp & USER_INT_FLAG)
+ DRM_WAKEUP(&dev_priv->irq_queue);
+
+ if (temp & VSYNC_PIPEA_FLAG) {
+ atomic_inc(&dev->vbl_received);
+ DRM_WAKEUP(&dev->vbl_queue);
+ drm_vbl_send_signals(dev);
+ }
return IRQ_HANDLED;
}
@@ -102,6 +111,27 @@ static int i915_wait_irq(drm_device_t * dev, int irq_nr)
return ret;
}
+int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ unsigned int cur_vblank;
+ int ret = 0;
+
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ return DRM_ERR(EINVAL);
+ }
+
+ DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
+ (((cur_vblank = atomic_read(&dev->vbl_received))
+ - *sequence) <= (1<<23)));
+
+ *sequence = cur_vblank;
+
+ return ret;
+}
+
+
/* Needs the lock as it touches the ring.
*/
int i915_irq_emit(DRM_IOCTL_ARGS)
@@ -165,7 +195,7 @@ void i915_driver_irq_postinstall(drm_device_t * dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
- I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG);
+ I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | VSYNC_PIPEA_FLAG);
DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
}
diff --git a/drivers/char/drm/i915_mem.c b/drivers/char/drm/i915_mem.c
index 13176d136a99f..ba87ff17ff64c 100644
--- a/drivers/char/drm/i915_mem.c
+++ b/drivers/char/drm/i915_mem.c
@@ -1,7 +1,6 @@
/* i915_mem.c -- Simple agp/fb memory manager for i915 -*- linux-c -*-
*/
-/**************************************************************************
- *
+/*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
@@ -25,7 +24,7 @@
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
- **************************************************************************/
+ */
#include "drmP.h"
#include "drm.h"
diff --git a/drivers/char/drm/mga_dma.c b/drivers/char/drm/mga_dma.c
index 70dc7f64b7b91..c2a4bac14521f 100644
--- a/drivers/char/drm/mga_dma.c
+++ b/drivers/char/drm/mga_dma.c
@@ -44,7 +44,9 @@
#define MGA_DEFAULT_USEC_TIMEOUT 10000
#define MGA_FREELIST_DEBUG 0
-static int mga_do_cleanup_dma(drm_device_t * dev);
+#define MINIMAL_CLEANUP 0
+#define FULL_CLEANUP 1
+static int mga_do_cleanup_dma(drm_device_t *dev, int full_cleanup);
/* ================================================================
* Engine control
@@ -391,7 +393,7 @@ int mga_freelist_put(drm_device_t * dev, drm_buf_t * buf)
* DMA initialization, cleanup
*/
-int mga_driver_preinit(drm_device_t * dev, unsigned long flags)
+int mga_driver_load(drm_device_t * dev, unsigned long flags)
{
drm_mga_private_t *dev_priv;
@@ -405,6 +407,14 @@ int mga_driver_preinit(drm_device_t * dev, unsigned long flags)
dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT;
dev_priv->chipset = flags;
+ dev_priv->mmio_base = drm_get_resource_start(dev, 1);
+ dev_priv->mmio_size = drm_get_resource_len(dev, 1);
+
+ dev->counters += 3;
+ dev->types[6] = _DRM_STAT_IRQ;
+ dev->types[7] = _DRM_STAT_PRIMARY;
+ dev->types[8] = _DRM_STAT_SECONDARY;
+
return 0;
}
@@ -438,17 +448,19 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
drm_buf_desc_t req;
drm_agp_mode_t mode;
drm_agp_info_t info;
+ drm_agp_buffer_t agp_req;
+ drm_agp_binding_t bind_req;
/* Acquire AGP. */
err = drm_agp_acquire(dev);
if (err) {
- DRM_ERROR("Unable to acquire AGP\n");
+ DRM_ERROR("Unable to acquire AGP: %d\n", err);
return err;
}
err = drm_agp_info(dev, &info);
if (err) {
- DRM_ERROR("Unable to get AGP info\n");
+ DRM_ERROR("Unable to get AGP info: %d\n", err);
return err;
}
@@ -472,18 +484,24 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
}
/* Allocate and bind AGP memory. */
- dev_priv->agp_pages = agp_size / PAGE_SIZE;
- dev_priv->agp_mem = drm_alloc_agp(dev, dev_priv->agp_pages, 0);
- if (dev_priv->agp_mem == NULL) {
- dev_priv->agp_pages = 0;
+ agp_req.size = agp_size;
+ agp_req.type = 0;
+ err = drm_agp_alloc(dev, &agp_req);
+ if (err) {
+ dev_priv->agp_size = 0;
DRM_ERROR("Unable to allocate %uMB AGP memory\n",
dma_bs->agp_size);
- return DRM_ERR(ENOMEM);
+ return err;
}
+
+ dev_priv->agp_size = agp_size;
+ dev_priv->agp_handle = agp_req.handle;
- err = drm_bind_agp(dev_priv->agp_mem, 0);
+ bind_req.handle = agp_req.handle;
+ bind_req.offset = 0;
+ err = drm_agp_bind(dev, &bind_req);
if (err) {
- DRM_ERROR("Unable to bind AGP memory\n");
+ DRM_ERROR("Unable to bind AGP memory: %d\n", err);
return err;
}
@@ -497,7 +515,7 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
err = drm_addmap(dev, offset, warp_size,
_DRM_AGP, _DRM_READ_ONLY, &dev_priv->warp);
if (err) {
- DRM_ERROR("Unable to map WARP microcode\n");
+ DRM_ERROR("Unable to map WARP microcode: %d\n", err);
return err;
}
@@ -505,7 +523,7 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
err = drm_addmap(dev, offset, dma_bs->primary_size,
_DRM_AGP, _DRM_READ_ONLY, &dev_priv->primary);
if (err) {
- DRM_ERROR("Unable to map primary DMA region\n");
+ DRM_ERROR("Unable to map primary DMA region: %d\n", err);
return err;
}
@@ -513,7 +531,7 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
err = drm_addmap(dev, offset, secondary_size,
_DRM_AGP, 0, &dev->agp_buffer_map);
if (err) {
- DRM_ERROR("Unable to map secondary DMA region\n");
+ DRM_ERROR("Unable to map secondary DMA region: %d\n", err);
return err;
}
@@ -525,15 +543,29 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
err = drm_addbufs_agp(dev, &req);
if (err) {
- DRM_ERROR("Unable to add secondary DMA buffers\n");
+ DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err);
return err;
}
+ {
+ drm_map_list_t *_entry;
+ unsigned long agp_token = 0;
+
+ list_for_each_entry(_entry, &dev->maplist->head, head) {
+ if (_entry->map == dev->agp_buffer_map)
+ agp_token = _entry->user_token;
+ }
+ if (!agp_token)
+ return -EFAULT;
+
+ dev->agp_buffer_token = agp_token;
+ }
+
offset += secondary_size;
err = drm_addmap(dev, offset, agp_size - offset,
_DRM_AGP, 0, &dev_priv->agp_textures);
if (err) {
- DRM_ERROR("Unable to map AGP texture region\n");
+ DRM_ERROR("Unable to map AGP texture region %d\n", err);
return err;
}
@@ -603,7 +635,8 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev,
err = drm_addmap(dev, 0, warp_size, _DRM_CONSISTENT,
_DRM_READ_ONLY, &dev_priv->warp);
if (err != 0) {
- DRM_ERROR("Unable to create mapping for WARP microcode\n");
+ DRM_ERROR("Unable to create mapping for WARP microcode: %d\n",
+ err);
return err;
}
@@ -622,7 +655,7 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev,
}
if (err != 0) {
- DRM_ERROR("Unable to allocate primary DMA region\n");
+ DRM_ERROR("Unable to allocate primary DMA region: %d\n", err);
return DRM_ERR(ENOMEM);
}
@@ -646,7 +679,7 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev,
}
if (bin_count == 0) {
- DRM_ERROR("Unable to add secondary DMA buffers\n");
+ DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err);
return err;
}
@@ -682,7 +715,7 @@ static int mga_do_dma_bootstrap(drm_device_t * dev,
err = drm_addmap(dev, dev_priv->mmio_base, dev_priv->mmio_size,
_DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio);
if (err) {
- DRM_ERROR("Unable to map MMIO region\n");
+ DRM_ERROR("Unable to map MMIO region: %d\n", err);
return err;
}
@@ -690,7 +723,7 @@ static int mga_do_dma_bootstrap(drm_device_t * dev,
_DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL,
&dev_priv->status);
if (err) {
- DRM_ERROR("Unable to map status region\n");
+ DRM_ERROR("Unable to map status region: %d\n", err);
return err;
}
@@ -708,7 +741,7 @@ static int mga_do_dma_bootstrap(drm_device_t * dev,
*/
if (err) {
- mga_do_cleanup_dma(dev);
+ mga_do_cleanup_dma(dev, MINIMAL_CLEANUP);
}
/* Not only do we want to try and initialized PCI cards for PCI DMA,
@@ -731,35 +764,32 @@ int mga_dma_bootstrap(DRM_IOCTL_ARGS)
DRM_DEVICE;
drm_mga_dma_bootstrap_t bootstrap;
int err;
+ static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 };
+ const drm_mga_private_t *const dev_priv =
+ (drm_mga_private_t *) dev->dev_private;
DRM_COPY_FROM_USER_IOCTL(bootstrap,
(drm_mga_dma_bootstrap_t __user *) data,
sizeof(bootstrap));
err = mga_do_dma_bootstrap(dev, &bootstrap);
- if (!err) {
- static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 };
- const drm_mga_private_t *const dev_priv =
- (drm_mga_private_t *) dev->dev_private;
-
- if (dev_priv->agp_textures != NULL) {
- bootstrap.texture_handle =
- dev_priv->agp_textures->offset;
- bootstrap.texture_size = dev_priv->agp_textures->size;
- } else {
- bootstrap.texture_handle = 0;
- bootstrap.texture_size = 0;
- }
+ if (err) {
+ mga_do_cleanup_dma(dev, FULL_CLEANUP);
+ return err;
+ }
- bootstrap.agp_mode = modes[bootstrap.agp_mode & 0x07];
- if (DRM_COPY_TO_USER((void __user *)data, &bootstrap,
- sizeof(bootstrap))) {
- err = DRM_ERR(EFAULT);
- }
+ if (dev_priv->agp_textures != NULL) {
+ bootstrap.texture_handle = dev_priv->agp_textures->offset;
+ bootstrap.texture_size = dev_priv->agp_textures->size;
} else {
- mga_do_cleanup_dma(dev);
+ bootstrap.texture_handle = 0;
+ bootstrap.texture_size = 0;
}
+ bootstrap.agp_mode = modes[bootstrap.agp_mode & 0x07];
+ DRM_COPY_TO_USER_IOCTL((drm_mga_dma_bootstrap_t __user *)data,
+ bootstrap, sizeof(bootstrap));
+
return err;
}
@@ -853,13 +883,13 @@ static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init)
ret = mga_warp_install_microcode(dev_priv);
if (ret < 0) {
- DRM_ERROR("failed to install WARP ucode!\n");
+ DRM_ERROR("failed to install WARP ucode!: %d\n", ret);
return ret;
}
ret = mga_warp_init(dev_priv);
if (ret < 0) {
- DRM_ERROR("failed to init WARP engine!\n");
+ DRM_ERROR("failed to init WARP engine!: %d\n", ret);
return ret;
}
@@ -904,7 +934,7 @@ static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init)
return 0;
}
-static int mga_do_cleanup_dma(drm_device_t * dev)
+static int mga_do_cleanup_dma(drm_device_t *dev, int full_cleanup)
{
int err = 0;
DRM_DEBUG("\n");
@@ -932,31 +962,39 @@ static int mga_do_cleanup_dma(drm_device_t * dev)
if (dev_priv->used_new_dma_init) {
#if __OS_HAS_AGP
- if (dev_priv->agp_mem != NULL) {
- dev_priv->agp_textures = NULL;
- drm_unbind_agp(dev_priv->agp_mem);
+ if (dev_priv->agp_handle != 0) {
+ drm_agp_binding_t unbind_req;
+ drm_agp_buffer_t free_req;
+
+ unbind_req.handle = dev_priv->agp_handle;
+ drm_agp_unbind(dev, &unbind_req);
- drm_free_agp(dev_priv->agp_mem,
- dev_priv->agp_pages);
- dev_priv->agp_pages = 0;
- dev_priv->agp_mem = NULL;
+ free_req.handle = dev_priv->agp_handle;
+ drm_agp_free(dev, &free_req);
+
+ dev_priv->agp_textures = NULL;
+ dev_priv->agp_size = 0;
+ dev_priv->agp_handle = 0;
}
if ((dev->agp != NULL) && dev->agp->acquired) {
err = drm_agp_release(dev);
}
#endif
- dev_priv->used_new_dma_init = 0;
}
dev_priv->warp = NULL;
dev_priv->primary = NULL;
- dev_priv->mmio = NULL;
- dev_priv->status = NULL;
dev_priv->sarea = NULL;
dev_priv->sarea_priv = NULL;
dev->agp_buffer_map = NULL;
+ if (full_cleanup) {
+ dev_priv->mmio = NULL;
+ dev_priv->status = NULL;
+ dev_priv->used_new_dma_init = 0;
+ }
+
memset(&dev_priv->prim, 0, sizeof(dev_priv->prim));
dev_priv->warp_pipe = 0;
memset(dev_priv->warp_pipe_phys, 0,
@@ -967,7 +1005,7 @@ static int mga_do_cleanup_dma(drm_device_t * dev)
}
}
- return err;
+ return 0;
}
int mga_dma_init(DRM_IOCTL_ARGS)
@@ -985,11 +1023,11 @@ int mga_dma_init(DRM_IOCTL_ARGS)
case MGA_INIT_DMA:
err = mga_do_init_dma(dev, &init);
if (err) {
- (void)mga_do_cleanup_dma(dev);
+ (void)mga_do_cleanup_dma(dev, FULL_CLEANUP);
}
return err;
case MGA_CLEANUP_DMA:
- return mga_do_cleanup_dma(dev);
+ return mga_do_cleanup_dma(dev, FULL_CLEANUP);
}
return DRM_ERR(EINVAL);
@@ -1118,7 +1156,7 @@ int mga_dma_buffers(DRM_IOCTL_ARGS)
/**
* Called just before the module is unloaded.
*/
-int mga_driver_postcleanup(drm_device_t * dev)
+int mga_driver_unload(drm_device_t * dev)
{
drm_free(dev->dev_private, sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
dev->dev_private = NULL;
@@ -1129,9 +1167,9 @@ int mga_driver_postcleanup(drm_device_t * dev)
/**
* Called when the last opener of the device is closed.
*/
-void mga_driver_pretakedown(drm_device_t * dev)
+void mga_driver_lastclose(drm_device_t * dev)
{
- mga_do_cleanup_dma(dev);
+ mga_do_cleanup_dma(dev, FULL_CLEANUP);
}
int mga_driver_dma_quiescent(drm_device_t * dev)
diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c
index 1713451a5cc65..9f7ed0e0351b0 100644
--- a/drivers/char/drm/mga_drv.c
+++ b/drivers/char/drm/mga_drv.c
@@ -38,41 +38,6 @@
#include "drm_pciids.h"
static int mga_driver_device_is_agp(drm_device_t * dev);
-static int postinit(struct drm_device *dev, unsigned long flags)
-{
- drm_mga_private_t *const dev_priv =
- (drm_mga_private_t *) dev->dev_private;
-
- dev_priv->mmio_base = pci_resource_start(dev->pdev, 1);
- dev_priv->mmio_size = pci_resource_len(dev->pdev, 1);
-
- dev->counters += 3;
- dev->types[6] = _DRM_STAT_IRQ;
- dev->types[7] = _DRM_STAT_PRIMARY;
- dev->types[8] = _DRM_STAT_SECONDARY;
-
- DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
- DRIVER_NAME,
- DRIVER_MAJOR,
- DRIVER_MINOR,
- DRIVER_PATCHLEVEL,
- DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
- );
- return 0;
-}
-
-static int version(drm_version_t * version)
-{
- int len;
-
- version->version_major = DRIVER_MAJOR;
- version->version_minor = DRIVER_MINOR;
- version->version_patchlevel = DRIVER_PATCHLEVEL;
- DRM_COPY(version->name, DRIVER_NAME);
- DRM_COPY(version->date, DRIVER_DATE);
- DRM_COPY(version->desc, DRIVER_DESC);
- return 0;
-}
static struct pci_device_id pciidlist[] = {
mga_PCI_IDS
@@ -80,12 +45,12 @@ static struct pci_device_id pciidlist[] = {
static struct drm_driver driver = {
.driver_features =
- DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
+ DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA |
DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
DRIVER_IRQ_VBL,
- .preinit = mga_driver_preinit,
- .postcleanup = mga_driver_postcleanup,
- .pretakedown = mga_driver_pretakedown,
+ .load = mga_driver_load,
+ .unload = mga_driver_unload,
+ .lastclose = mga_driver_lastclose,
.dma_quiescent = mga_driver_dma_quiescent,
.device_is_agp = mga_driver_device_is_agp,
.vblank_wait = mga_driver_vblank_wait,
@@ -96,8 +61,6 @@ static struct drm_driver driver = {
.reclaim_buffers = drm_core_reclaim_buffers,
.get_map_ofs = drm_core_get_map_ofs,
.get_reg_ofs = drm_core_get_reg_ofs,
- .postinit = postinit,
- .version = version,
.ioctls = mga_ioctls,
.dma_ioctl = mga_dma_buffers,
.fops = {
@@ -113,9 +76,16 @@ static struct drm_driver driver = {
#endif
},
.pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
- }
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ },
+
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESC,
+ .date = DRIVER_DATE,
+ .major = DRIVER_MAJOR,
+ .minor = DRIVER_MINOR,
+ .patchlevel = DRIVER_PATCHLEVEL,
};
static int __init mga_init(void)
diff --git a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h
index 461728e6a58a4..6b0c531935061 100644
--- a/drivers/char/drm/mga_drv.h
+++ b/drivers/char/drm/mga_drv.h
@@ -38,11 +38,11 @@
#define DRIVER_NAME "mga"
#define DRIVER_DESC "Matrox G200/G400"
-#define DRIVER_DATE "20050607"
+#define DRIVER_DATE "20051102"
#define DRIVER_MAJOR 3
#define DRIVER_MINOR 2
-#define DRIVER_PATCHLEVEL 0
+#define DRIVER_PATCHLEVEL 1
typedef struct drm_mga_primary_buffer {
u8 *start;
@@ -144,22 +144,22 @@ typedef struct drm_mga_private {
drm_local_map_t *primary;
drm_local_map_t *agp_textures;
- DRM_AGP_MEM *agp_mem;
- unsigned int agp_pages;
+ unsigned long agp_handle;
+ unsigned int agp_size;
} drm_mga_private_t;
extern drm_ioctl_desc_t mga_ioctls[];
extern int mga_max_ioctl;
/* mga_dma.c */
-extern int mga_driver_preinit(drm_device_t * dev, unsigned long flags);
extern int mga_dma_bootstrap(DRM_IOCTL_ARGS);
extern int mga_dma_init(DRM_IOCTL_ARGS);
extern int mga_dma_flush(DRM_IOCTL_ARGS);
extern int mga_dma_reset(DRM_IOCTL_ARGS);
extern int mga_dma_buffers(DRM_IOCTL_ARGS);
-extern int mga_driver_postcleanup(drm_device_t * dev);
-extern void mga_driver_pretakedown(drm_device_t * dev);
+extern int mga_driver_load(drm_device_t *dev, unsigned long flags);
+extern int mga_driver_unload(drm_device_t * dev);
+extern void mga_driver_lastclose(drm_device_t * dev);
extern int mga_driver_dma_quiescent(drm_device_t * dev);
extern int mga_do_wait_for_idle(drm_mga_private_t * dev_priv);
diff --git a/drivers/char/drm/mga_state.c b/drivers/char/drm/mga_state.c
index 47f54b5ae956f..2837e669183a2 100644
--- a/drivers/char/drm/mga_state.c
+++ b/drivers/char/drm/mga_state.c
@@ -1127,19 +1127,19 @@ static int mga_wait_fence(DRM_IOCTL_ARGS)
}
drm_ioctl_desc_t mga_ioctls[] = {
- [DRM_IOCTL_NR(DRM_MGA_INIT)] = {mga_dma_init, 1, 1},
- [DRM_IOCTL_NR(DRM_MGA_FLUSH)] = {mga_dma_flush, 1, 0},
- [DRM_IOCTL_NR(DRM_MGA_RESET)] = {mga_dma_reset, 1, 0},
- [DRM_IOCTL_NR(DRM_MGA_SWAP)] = {mga_dma_swap, 1, 0},
- [DRM_IOCTL_NR(DRM_MGA_CLEAR)] = {mga_dma_clear, 1, 0},
- [DRM_IOCTL_NR(DRM_MGA_VERTEX)] = {mga_dma_vertex, 1, 0},
- [DRM_IOCTL_NR(DRM_MGA_INDICES)] = {mga_dma_indices, 1, 0},
- [DRM_IOCTL_NR(DRM_MGA_ILOAD)] = {mga_dma_iload, 1, 0},
- [DRM_IOCTL_NR(DRM_MGA_BLIT)] = {mga_dma_blit, 1, 0},
- [DRM_IOCTL_NR(DRM_MGA_GETPARAM)] = {mga_getparam, 1, 0},
- [DRM_IOCTL_NR(DRM_MGA_SET_FENCE)] = {mga_set_fence, 1, 0},
- [DRM_IOCTL_NR(DRM_MGA_WAIT_FENCE)] = {mga_wait_fence, 1, 0},
- [DRM_IOCTL_NR(DRM_MGA_DMA_BOOTSTRAP)] = {mga_dma_bootstrap, 1, 1},
+ [DRM_IOCTL_NR(DRM_MGA_INIT)] = {mga_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_MGA_FLUSH)] = {mga_dma_flush, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_MGA_RESET)] = {mga_dma_reset, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_MGA_SWAP)] = {mga_dma_swap, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_MGA_CLEAR)] = {mga_dma_clear, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_MGA_VERTEX)] = {mga_dma_vertex, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_MGA_INDICES)] = {mga_dma_indices, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_MGA_ILOAD)] = {mga_dma_iload, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_MGA_BLIT)] = {mga_dma_blit, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_MGA_GETPARAM)] = {mga_getparam, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_MGA_SET_FENCE)] = {mga_set_fence, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_MGA_WAIT_FENCE)] = {mga_wait_fence, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_MGA_DMA_BOOTSTRAP)] = {mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
};
int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls);
diff --git a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c
index 7452753d4d01d..db5a60450e689 100644
--- a/drivers/char/drm/r128_cce.c
+++ b/drivers/char/drm/r128_cce.c
@@ -1,6 +1,7 @@
-/* r128_cce.c -- ATI Rage 128 driver -*- linux-c -*-
+/* r128_cce.c -- ATI Rage 128 driver -*- linux-c -*-
* Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com
- *
+ */
+/*
* Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
@@ -559,7 +560,8 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init)
if (dev_priv->is_pci) {
#endif
dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN;
- dev_priv->gart_info.addr = dev_priv->gart_info.bus_addr = 0;
+ dev_priv->gart_info.addr = NULL;
+ dev_priv->gart_info.bus_addr = 0;
dev_priv->gart_info.is_pcie = 0;
if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
DRM_ERROR("failed to init PCI GART!\n");
@@ -601,15 +603,16 @@ int r128_do_cleanup_cce(drm_device_t * dev)
drm_core_ioremapfree(dev_priv->cce_ring, dev);
if (dev_priv->ring_rptr != NULL)
drm_core_ioremapfree(dev_priv->ring_rptr, dev);
- if (dev->agp_buffer_map != NULL)
+ if (dev->agp_buffer_map != NULL) {
drm_core_ioremapfree(dev->agp_buffer_map, dev);
+ dev->agp_buffer_map = NULL;
+ }
} else
#endif
{
if (dev_priv->gart_info.bus_addr)
if (!drm_ati_pcigart_cleanup(dev,
- &dev_priv->
- gart_info))
+ &dev_priv->gart_info))
DRM_ERROR
("failed to cleanup PCI GART!\n");
}
diff --git a/drivers/char/drm/r128_drm.h b/drivers/char/drm/r128_drm.h
index 5ddc03202411a..5d835b006f55e 100644
--- a/drivers/char/drm/r128_drm.h
+++ b/drivers/char/drm/r128_drm.h
@@ -1,7 +1,7 @@
/* r128_drm.h -- Public header for the r128 driver -*- linux-c -*-
* Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com
- *
- * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
+ */
+/* Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All rights reserved.
*
diff --git a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c
index 1661e73514025..e20450ae220e3 100644
--- a/drivers/char/drm/r128_drv.c
+++ b/drivers/char/drm/r128_drv.c
@@ -37,31 +37,6 @@
#include "drm_pciids.h"
-static int postinit(struct drm_device *dev, unsigned long flags)
-{
- DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
- DRIVER_NAME,
- DRIVER_MAJOR,
- DRIVER_MINOR,
- DRIVER_PATCHLEVEL,
- DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
- );
- return 0;
-}
-
-static int version(drm_version_t * version)
-{
- int len;
-
- version->version_major = DRIVER_MAJOR;
- version->version_minor = DRIVER_MINOR;
- version->version_patchlevel = DRIVER_PATCHLEVEL;
- DRM_COPY(version->name, DRIVER_NAME);
- DRM_COPY(version->date, DRIVER_DATE);
- DRM_COPY(version->desc, DRIVER_DESC);
- return 0;
-}
-
static struct pci_device_id pciidlist[] = {
r128_PCI_IDS
};
@@ -72,8 +47,8 @@ static struct drm_driver driver = {
DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
DRIVER_IRQ_VBL,
.dev_priv_size = sizeof(drm_r128_buf_priv_t),
- .prerelease = r128_driver_prerelease,
- .pretakedown = r128_driver_pretakedown,
+ .preclose = r128_driver_preclose,
+ .lastclose = r128_driver_lastclose,
.vblank_wait = r128_driver_vblank_wait,
.irq_preinstall = r128_driver_irq_preinstall,
.irq_postinstall = r128_driver_irq_postinstall,
@@ -82,8 +57,6 @@ static struct drm_driver driver = {
.reclaim_buffers = drm_core_reclaim_buffers,
.get_map_ofs = drm_core_get_map_ofs,
.get_reg_ofs = drm_core_get_reg_ofs,
- .postinit = postinit,
- .version = version,
.ioctls = r128_ioctls,
.dma_ioctl = r128_cce_buffers,
.fops = {
@@ -97,12 +70,19 @@ static struct drm_driver driver = {
#ifdef CONFIG_COMPAT
.compat_ioctl = r128_compat_ioctl,
#endif
- }
- ,
+ },
+
.pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
- }
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ },
+
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESC,
+ .date = DRIVER_DATE,
+ .major = DRIVER_MAJOR,
+ .minor = DRIVER_MINOR,
+ .patchlevel = DRIVER_PATCHLEVEL,
};
static int __init r128_init(void)
diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h
index 5c79e40eb88f9..94abffb2cca56 100644
--- a/drivers/char/drm/r128_drv.h
+++ b/drivers/char/drm/r128_drv.h
@@ -1,7 +1,7 @@
/* r128_drv.h -- Private header for r128 driver -*- linux-c -*-
* Created: Mon Dec 13 09:51:11 1999 by faith@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ */
+/* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All rights reserved.
*
@@ -154,8 +154,8 @@ extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS);
extern void r128_driver_irq_preinstall(drm_device_t * dev);
extern void r128_driver_irq_postinstall(drm_device_t * dev);
extern void r128_driver_irq_uninstall(drm_device_t * dev);
-extern void r128_driver_pretakedown(drm_device_t * dev);
-extern void r128_driver_prerelease(drm_device_t * dev, DRMFILE filp);
+extern void r128_driver_lastclose(drm_device_t * dev);
+extern void r128_driver_preclose(drm_device_t * dev, DRMFILE filp);
extern long r128_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg);
diff --git a/drivers/char/drm/r128_irq.c b/drivers/char/drm/r128_irq.c
index 27eb0e31bd3b3..87f8ca2b0685a 100644
--- a/drivers/char/drm/r128_irq.c
+++ b/drivers/char/drm/r128_irq.c
@@ -1,5 +1,5 @@
-/* r128_irq.c -- IRQ handling for radeon -*- linux-c -*-
- *
+/* r128_irq.c -- IRQ handling for radeon -*- linux-c -*- */
+/*
* Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
*
* The Weather Channel (TM) funded Tungsten Graphics to develop the
diff --git a/drivers/char/drm/r128_state.c b/drivers/char/drm/r128_state.c
index 14479cc08a570..caeecc2c36dab 100644
--- a/drivers/char/drm/r128_state.c
+++ b/drivers/char/drm/r128_state.c
@@ -1,7 +1,7 @@
/* r128_state.c -- State support for r128 -*- linux-c -*-
* Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com
- *
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ */
+/* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -1674,7 +1674,7 @@ static int r128_getparam(DRM_IOCTL_ARGS)
return 0;
}
-void r128_driver_prerelease(drm_device_t * dev, DRMFILE filp)
+void r128_driver_preclose(drm_device_t * dev, DRMFILE filp)
{
if (dev->dev_private) {
drm_r128_private_t *dev_priv = dev->dev_private;
@@ -1684,29 +1684,29 @@ void r128_driver_prerelease(drm_device_t * dev, DRMFILE filp)
}
}
-void r128_driver_pretakedown(drm_device_t * dev)
+void r128_driver_lastclose(drm_device_t * dev)
{
r128_do_cleanup_cce(dev);
}
drm_ioctl_desc_t r128_ioctls[] = {
- [DRM_IOCTL_NR(DRM_R128_INIT)] = {r128_cce_init, 1, 1},
- [DRM_IOCTL_NR(DRM_R128_CCE_START)] = {r128_cce_start, 1, 1},
- [DRM_IOCTL_NR(DRM_R128_CCE_STOP)] = {r128_cce_stop, 1, 1},
- [DRM_IOCTL_NR(DRM_R128_CCE_RESET)] = {r128_cce_reset, 1, 1},
- [DRM_IOCTL_NR(DRM_R128_CCE_IDLE)] = {r128_cce_idle, 1, 0},
- [DRM_IOCTL_NR(DRM_R128_RESET)] = {r128_engine_reset, 1, 0},
- [DRM_IOCTL_NR(DRM_R128_FULLSCREEN)] = {r128_fullscreen, 1, 0},
- [DRM_IOCTL_NR(DRM_R128_SWAP)] = {r128_cce_swap, 1, 0},
- [DRM_IOCTL_NR(DRM_R128_FLIP)] = {r128_cce_flip, 1, 0},
- [DRM_IOCTL_NR(DRM_R128_CLEAR)] = {r128_cce_clear, 1, 0},
- [DRM_IOCTL_NR(DRM_R128_VERTEX)] = {r128_cce_vertex, 1, 0},
- [DRM_IOCTL_NR(DRM_R128_INDICES)] = {r128_cce_indices, 1, 0},
- [DRM_IOCTL_NR(DRM_R128_BLIT)] = {r128_cce_blit, 1, 0},
- [DRM_IOCTL_NR(DRM_R128_DEPTH)] = {r128_cce_depth, 1, 0},
- [DRM_IOCTL_NR(DRM_R128_STIPPLE)] = {r128_cce_stipple, 1, 0},
- [DRM_IOCTL_NR(DRM_R128_INDIRECT)] = {r128_cce_indirect, 1, 1},
- [DRM_IOCTL_NR(DRM_R128_GETPARAM)] = {r128_getparam, 1, 0},
+ [DRM_IOCTL_NR(DRM_R128_INIT)] = {r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_R128_CCE_START)] = {r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_R128_CCE_STOP)] = {r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_R128_CCE_RESET)] = {r128_cce_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_R128_CCE_IDLE)] = {r128_cce_idle, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_R128_RESET)] = {r128_engine_reset, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_R128_FULLSCREEN)] = {r128_fullscreen, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_R128_SWAP)] = {r128_cce_swap, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_R128_FLIP)] = {r128_cce_flip, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_R128_CLEAR)] = {r128_cce_clear, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_R128_VERTEX)] = {r128_cce_vertex, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_R128_INDICES)] = {r128_cce_indices, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_R128_BLIT)] = {r128_cce_blit, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_R128_DEPTH)] = {r128_cce_depth, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_R128_STIPPLE)] = {r128_cce_stipple, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_R128_INDIRECT)] = {r128_cce_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_R128_GETPARAM)] = {r128_getparam, DRM_AUTH},
};
int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls);
diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c
index 3a1ac5f78b433..291dbf4c8186c 100644
--- a/drivers/char/drm/r300_cmdbuf.c
+++ b/drivers/char/drm/r300_cmdbuf.c
@@ -52,8 +52,8 @@ static const int r300_cliprect_cntl[4] = {
* Emit up to R300_SIMULTANEOUS_CLIPRECTS cliprects from the given command
* buffer, starting with index n.
*/
-static int r300_emit_cliprects(drm_radeon_private_t * dev_priv,
- drm_radeon_kcmd_buffer_t * cmdbuf, int n)
+static int r300_emit_cliprects(drm_radeon_private_t *dev_priv,
+ drm_radeon_kcmd_buffer_t *cmdbuf, int n)
{
drm_clip_rect_t box;
int nr;
@@ -216,6 +216,7 @@ void r300_init_reg_flags(void)
ADD_RANGE(R300_TX_UNK1_0, 16);
ADD_RANGE(R300_TX_SIZE_0, 16);
ADD_RANGE(R300_TX_FORMAT_0, 16);
+ ADD_RANGE(R300_TX_PITCH_0, 16);
/* Texture offset is dangerous and needs more checking */
ADD_RANGE_MARK(R300_TX_OFFSET_0, 16, MARK_CHECK_OFFSET);
ADD_RANGE(R300_TX_UNK4_0, 16);
@@ -242,7 +243,7 @@ static __inline__ int r300_check_range(unsigned reg, int count)
/* we expect offsets passed to the framebuffer to be either within video memory or
within AGP space */
-static __inline__ int r300_check_offset(drm_radeon_private_t * dev_priv,
+static __inline__ int r300_check_offset(drm_radeon_private_t *dev_priv,
u32 offset)
{
/* we realy want to check against end of video aperture
@@ -317,8 +318,8 @@ static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t *
*
* Note that checks are performed on contents and addresses of the registers
*/
-static __inline__ int r300_emit_packet0(drm_radeon_private_t * dev_priv,
- drm_radeon_kcmd_buffer_t * cmdbuf,
+static __inline__ int r300_emit_packet0(drm_radeon_private_t *dev_priv,
+ drm_radeon_kcmd_buffer_t *cmdbuf,
drm_r300_cmd_header_t header)
{
int reg;
@@ -363,8 +364,8 @@ static __inline__ int r300_emit_packet0(drm_radeon_private_t * dev_priv,
* the graphics card.
* Called by r300_do_cp_cmdbuf.
*/
-static __inline__ int r300_emit_vpu(drm_radeon_private_t * dev_priv,
- drm_radeon_kcmd_buffer_t * cmdbuf,
+static __inline__ int r300_emit_vpu(drm_radeon_private_t *dev_priv,
+ drm_radeon_kcmd_buffer_t *cmdbuf,
drm_r300_cmd_header_t header)
{
int sz;
@@ -400,8 +401,8 @@ static __inline__ int r300_emit_vpu(drm_radeon_private_t * dev_priv,
* Emit a clear packet from userspace.
* Called by r300_emit_packet3.
*/
-static __inline__ int r300_emit_clear(drm_radeon_private_t * dev_priv,
- drm_radeon_kcmd_buffer_t * cmdbuf)
+static __inline__ int r300_emit_clear(drm_radeon_private_t *dev_priv,
+ drm_radeon_kcmd_buffer_t *cmdbuf)
{
RING_LOCALS;
@@ -421,8 +422,8 @@ static __inline__ int r300_emit_clear(drm_radeon_private_t * dev_priv,
return 0;
}
-static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t * dev_priv,
- drm_radeon_kcmd_buffer_t * cmdbuf,
+static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv,
+ drm_radeon_kcmd_buffer_t *cmdbuf,
u32 header)
{
int count, i, k;
@@ -489,8 +490,8 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t * dev_priv,
return 0;
}
-static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t * dev_priv,
- drm_radeon_kcmd_buffer_t * cmdbuf)
+static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv,
+ drm_radeon_kcmd_buffer_t *cmdbuf)
{
u32 header;
int count;
@@ -554,8 +555,8 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t * dev_priv,
* Emit a rendering packet3 from userspace.
* Called by r300_do_cp_cmdbuf.
*/
-static __inline__ int r300_emit_packet3(drm_radeon_private_t * dev_priv,
- drm_radeon_kcmd_buffer_t * cmdbuf,
+static __inline__ int r300_emit_packet3(drm_radeon_private_t *dev_priv,
+ drm_radeon_kcmd_buffer_t *cmdbuf,
drm_r300_cmd_header_t header)
{
int n;
@@ -623,7 +624,7 @@ static __inline__ int r300_emit_packet3(drm_radeon_private_t * dev_priv,
/**
* Emit the sequence to pacify R300.
*/
-static __inline__ void r300_pacify(drm_radeon_private_t * dev_priv)
+static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv)
{
RING_LOCALS;
@@ -657,9 +658,10 @@ static void r300_discard_buffer(drm_device_t * dev, drm_buf_t * buf)
* commands on the DMA ring buffer.
* Called by the ioctl handler function radeon_cp_cmdbuf.
*/
-int r300_do_cp_cmdbuf(drm_device_t * dev,
+int r300_do_cp_cmdbuf(drm_device_t *dev,
DRMFILE filp,
- drm_file_t * filp_priv, drm_radeon_kcmd_buffer_t * cmdbuf)
+ drm_file_t *filp_priv,
+ drm_radeon_kcmd_buffer_t *cmdbuf)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_device_dma_t *dma = dev->dma;
diff --git a/drivers/char/drm/r300_reg.h b/drivers/char/drm/r300_reg.h
index e5b73c0023946..a0ed20e25221d 100644
--- a/drivers/char/drm/r300_reg.h
+++ b/drivers/char/drm/r300_reg.h
@@ -797,6 +797,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
# define R300_TX_FORMAT_YUV_MODE 0x00800000
+#define R300_TX_PITCH_0 0x4500
#define R300_TX_OFFSET_0 0x4540
/* BEGIN: Guess from R200 */
# define R300_TXO_ENDIAN_NO_SWAP (0 << 0)
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
index 342302d467435..915665c7fe7c6 100644
--- a/drivers/char/drm/radeon_cp.c
+++ b/drivers/char/drm/radeon_cp.c
@@ -1,5 +1,5 @@
-/* radeon_cp.c -- CP support for Radeon -*- linux-c -*-
- *
+/* radeon_cp.c -- CP support for Radeon -*- linux-c -*- */
+/*
* Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Fremont, California.
* All Rights Reserved.
@@ -824,7 +824,7 @@ static int RADEON_READ_PLL(drm_device_t * dev, int addr)
return RADEON_READ(RADEON_CLOCK_CNTL_DATA);
}
-static int RADEON_READ_PCIE(drm_radeon_private_t * dev_priv, int addr)
+static int RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr)
{
RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff);
return RADEON_READ(RADEON_PCIE_DATA);
@@ -1125,7 +1125,7 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev,
| (dev_priv->fb_location >> 16));
#if __OS_HAS_AGP
- if (!dev_priv->is_pci) {
+ if (dev_priv->flags & CHIP_IS_AGP) {
RADEON_WRITE(RADEON_MC_AGP_LOCATION,
(((dev_priv->gart_vm_start - 1 +
dev_priv->gart_size) & 0xffff0000) |
@@ -1152,7 +1152,7 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev,
dev_priv->ring.tail = cur_read_ptr;
#if __OS_HAS_AGP
- if (!dev_priv->is_pci) {
+ if (dev_priv->flags & CHIP_IS_AGP) {
/* set RADEON_AGP_BASE here instead of relying on X from user space */
RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base);
RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR,
@@ -1278,13 +1278,15 @@ static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
/* Enable or disable PCI GART on the chip */
static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
{
- u32 tmp = RADEON_READ(RADEON_AIC_CNTL);
+ u32 tmp;
if (dev_priv->flags & CHIP_IS_PCIE) {
radeon_set_pciegart(dev_priv, on);
return;
}
+ tmp = RADEON_READ(RADEON_AIC_CNTL);
+
if (on) {
RADEON_WRITE(RADEON_AIC_CNTL,
tmp | RADEON_PCIGART_TRANSLATE_EN);
@@ -1312,13 +1314,17 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
+
DRM_DEBUG("\n");
- dev_priv->is_pci = init->is_pci;
+ if (init->is_pci && (dev_priv->flags & CHIP_IS_AGP))
+ {
+ DRM_DEBUG("Forcing AGP card to PCI mode\n");
+ dev_priv->flags &= ~CHIP_IS_AGP;
+ }
- if (dev_priv->is_pci && !dev->sg) {
+ if ((!(dev_priv->flags & CHIP_IS_AGP)) && !dev->sg) {
DRM_ERROR("PCI GART memory not allocated!\n");
- dev->dev_private = (void *)dev_priv;
radeon_do_cleanup_cp(dev);
return DRM_ERR(EINVAL);
}
@@ -1327,12 +1333,11 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
if (dev_priv->usec_timeout < 1 ||
dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) {
DRM_DEBUG("TIMEOUT problem!\n");
- dev->dev_private = (void *)dev_priv;
radeon_do_cleanup_cp(dev);
return DRM_ERR(EINVAL);
}
- switch (init->func) {
+ switch(init->func) {
case RADEON_INIT_R200_CP:
dev_priv->microcode_version = UCODE_R200;
break;
@@ -1353,7 +1358,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) &&
(init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) {
DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode);
- dev->dev_private = (void *)dev_priv;
radeon_do_cleanup_cp(dev);
return DRM_ERR(EINVAL);
}
@@ -1416,8 +1420,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
DRM_GETSAREA();
- dev_priv->fb_offset = init->fb_offset;
- dev_priv->mmio_offset = init->mmio_offset;
dev_priv->ring_offset = init->ring_offset;
dev_priv->ring_rptr_offset = init->ring_rptr_offset;
dev_priv->buffers_offset = init->buffers_offset;
@@ -1425,29 +1427,19 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
if (!dev_priv->sarea) {
DRM_ERROR("could not find sarea!\n");
- dev->dev_private = (void *)dev_priv;
radeon_do_cleanup_cp(dev);
return DRM_ERR(EINVAL);
}
- dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset);
- if (!dev_priv->mmio) {
- DRM_ERROR("could not find mmio region!\n");
- dev->dev_private = (void *)dev_priv;
- radeon_do_cleanup_cp(dev);
- return DRM_ERR(EINVAL);
- }
dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset);
if (!dev_priv->cp_ring) {
DRM_ERROR("could not find cp ring region!\n");
- dev->dev_private = (void *)dev_priv;
radeon_do_cleanup_cp(dev);
return DRM_ERR(EINVAL);
}
dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset);
if (!dev_priv->ring_rptr) {
DRM_ERROR("could not find ring read pointer!\n");
- dev->dev_private = (void *)dev_priv;
radeon_do_cleanup_cp(dev);
return DRM_ERR(EINVAL);
}
@@ -1455,7 +1447,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
if (!dev->agp_buffer_map) {
DRM_ERROR("could not find dma buffer region!\n");
- dev->dev_private = (void *)dev_priv;
radeon_do_cleanup_cp(dev);
return DRM_ERR(EINVAL);
}
@@ -1465,7 +1456,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
drm_core_findmap(dev, init->gart_textures_offset);
if (!dev_priv->gart_textures) {
DRM_ERROR("could not find GART texture region!\n");
- dev->dev_private = (void *)dev_priv;
radeon_do_cleanup_cp(dev);
return DRM_ERR(EINVAL);
}
@@ -1476,7 +1466,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
init->sarea_priv_offset);
#if __OS_HAS_AGP
- if (!dev_priv->is_pci) {
+ if (dev_priv->flags & CHIP_IS_AGP) {
drm_core_ioremap(dev_priv->cp_ring, dev);
drm_core_ioremap(dev_priv->ring_rptr, dev);
drm_core_ioremap(dev->agp_buffer_map, dev);
@@ -1484,7 +1474,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
!dev_priv->ring_rptr->handle ||
!dev->agp_buffer_map->handle) {
DRM_ERROR("could not find ioremap agp regions!\n");
- dev->dev_private = (void *)dev_priv;
radeon_do_cleanup_cp(dev);
return DRM_ERR(EINVAL);
}
@@ -1525,7 +1514,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
+ RADEON_READ(RADEON_CONFIG_APER_SIZE);
#if __OS_HAS_AGP
- if (!dev_priv->is_pci)
+ if (dev_priv->flags & CHIP_IS_AGP)
dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
- dev->agp->base
+ dev_priv->gart_vm_start);
@@ -1551,7 +1540,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
#if __OS_HAS_AGP
- if (!dev_priv->is_pci) {
+ if (dev_priv->flags & CHIP_IS_AGP) {
/* Turn off PCI GART */
radeon_set_pcigart(dev_priv, 0);
} else
@@ -1561,25 +1550,28 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
if (dev_priv->pcigart_offset) {
dev_priv->gart_info.bus_addr =
dev_priv->pcigart_offset + dev_priv->fb_location;
+ dev_priv->gart_info.mapping.offset =
+ dev_priv->gart_info.bus_addr;
+ dev_priv->gart_info.mapping.size =
+ RADEON_PCIGART_TABLE_SIZE;
+
+ drm_core_ioremap(&dev_priv->gart_info.mapping, dev);
dev_priv->gart_info.addr =
- (unsigned long)drm_ioremap(dev_priv->gart_info.
- bus_addr,
- RADEON_PCIGART_TABLE_SIZE,
- dev);
+ dev_priv->gart_info.mapping.handle;
dev_priv->gart_info.is_pcie =
!!(dev_priv->flags & CHIP_IS_PCIE);
dev_priv->gart_info.gart_table_location =
DRM_ATI_GART_FB;
- DRM_DEBUG("Setting phys_pci_gart to %08lX %08lX\n",
+ DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n",
dev_priv->gart_info.addr,
dev_priv->pcigart_offset);
} else {
dev_priv->gart_info.gart_table_location =
DRM_ATI_GART_MAIN;
- dev_priv->gart_info.addr =
- dev_priv->gart_info.bus_addr = 0;
+ dev_priv->gart_info.addr = NULL;
+ dev_priv->gart_info.bus_addr = 0;
if (dev_priv->flags & CHIP_IS_PCIE) {
DRM_ERROR
("Cannot use PCI Express without GART in FB memory\n");
@@ -1590,7 +1582,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
DRM_ERROR("failed to init PCI GART!\n");
- dev->dev_private = (void *)dev_priv;
radeon_do_cleanup_cp(dev);
return DRM_ERR(ENOMEM);
}
@@ -1604,8 +1595,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
dev_priv->last_buf = 0;
- dev->dev_private = (void *)dev_priv;
-
radeon_do_engine_reset(dev);
return 0;
@@ -1624,11 +1613,15 @@ static int radeon_do_cleanup_cp(drm_device_t * dev)
drm_irq_uninstall(dev);
#if __OS_HAS_AGP
- if (!dev_priv->is_pci) {
- if (dev_priv->cp_ring != NULL)
+ if (dev_priv->flags & CHIP_IS_AGP) {
+ if (dev_priv->cp_ring != NULL) {
drm_core_ioremapfree(dev_priv->cp_ring, dev);
- if (dev_priv->ring_rptr != NULL)
+ dev_priv->cp_ring = NULL;
+ }
+ if (dev_priv->ring_rptr != NULL) {
drm_core_ioremapfree(dev_priv->ring_rptr, dev);
+ dev_priv->ring_rptr = NULL;
+ }
if (dev->agp_buffer_map != NULL) {
drm_core_ioremapfree(dev->agp_buffer_map, dev);
dev->agp_buffer_map = NULL;
@@ -1636,17 +1629,20 @@ static int radeon_do_cleanup_cp(drm_device_t * dev)
} else
#endif
{
- if (dev_priv->gart_info.bus_addr)
+
+ if (dev_priv->gart_info.bus_addr) {
+ /* Turn off PCI GART */
+ radeon_set_pcigart(dev_priv, 0);
if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info))
DRM_ERROR("failed to cleanup PCI GART!\n");
+ }
- if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) {
- drm_ioremapfree((void *)dev_priv->gart_info.addr,
- RADEON_PCIGART_TABLE_SIZE, dev);
+ if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB)
+ {
+ drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev);
dev_priv->gart_info.addr = 0;
}
}
-
/* only clear to the start of flags */
memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags));
@@ -1672,7 +1668,7 @@ static int radeon_do_resume_cp(drm_device_t * dev)
DRM_DEBUG("Starting radeon_do_resume_cp()\n");
#if __OS_HAS_AGP
- if (!dev_priv->is_pci) {
+ if (dev_priv->flags & CHIP_IS_AGP) {
/* Turn off PCI GART */
radeon_set_pcigart(dev_priv, 0);
} else
@@ -2103,7 +2099,7 @@ int radeon_cp_buffers(DRM_IOCTL_ARGS)
return ret;
}
-int radeon_driver_preinit(struct drm_device *dev, unsigned long flags)
+int radeon_driver_load(struct drm_device *dev, unsigned long flags)
{
drm_radeon_private_t *dev_priv;
int ret = 0;
@@ -2136,11 +2132,14 @@ int radeon_driver_preinit(struct drm_device *dev, unsigned long flags)
dev_priv->flags |= CHIP_IS_PCIE;
DRM_DEBUG("%s card detected\n",
- ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : "PCI"));
+ ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : (((dev_priv->flags & CHIP_IS_PCIE) ? "PCIE" : "PCI"))));
return ret;
}
-int radeon_presetup(struct drm_device *dev)
+/* Create mappings for registers and framebuffer so userland doesn't necessarily
+ * have to find them.
+ */
+int radeon_driver_firstopen(struct drm_device *dev)
{
int ret;
drm_local_map_t *map;
@@ -2161,12 +2160,11 @@ int radeon_presetup(struct drm_device *dev)
return 0;
}
-int radeon_driver_postcleanup(struct drm_device *dev)
+int radeon_driver_unload(struct drm_device *dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
DRM_DEBUG("\n");
-
drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
dev->dev_private = NULL;
diff --git a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h
index 1cd81a671a36c..9c177a6b2a4c4 100644
--- a/drivers/char/drm/radeon_drm.h
+++ b/drivers/char/drm/radeon_drm.h
@@ -624,6 +624,11 @@ typedef struct drm_radeon_indirect {
int discard;
} drm_radeon_indirect_t;
+/* enum for card type parameters */
+#define RADEON_CARD_PCI 0
+#define RADEON_CARD_AGP 1
+#define RADEON_CARD_PCIE 2
+
/* 1.3: An ioctl to get parameters that aren't available to the 3d
* client any other way.
*/
@@ -640,6 +645,7 @@ typedef struct drm_radeon_indirect {
#define RADEON_PARAM_SAREA_HANDLE 9
#define RADEON_PARAM_GART_TEX_HANDLE 10
#define RADEON_PARAM_SCRATCH_OFFSET 11
+#define RADEON_PARAM_CARD_TYPE 12
typedef struct drm_radeon_getparam {
int param;
diff --git a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c
index ee49670d81623..b04ed1b562b95 100644
--- a/drivers/char/drm/radeon_drv.c
+++ b/drivers/char/drm/radeon_drv.c
@@ -42,29 +42,15 @@ int radeon_no_wb;
MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers\n");
module_param_named(no_wb, radeon_no_wb, int, 0444);
-static int postinit(struct drm_device *dev, unsigned long flags)
+static int dri_library_name(struct drm_device *dev, char *buf)
{
- DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
- DRIVER_NAME,
- DRIVER_MAJOR,
- DRIVER_MINOR,
- DRIVER_PATCHLEVEL,
- DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
- );
- return 0;
-}
-
-static int version(drm_version_t * version)
-{
- int len;
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ int family = dev_priv->flags & CHIP_FAMILY_MASK;
- version->version_major = DRIVER_MAJOR;
- version->version_minor = DRIVER_MINOR;
- version->version_patchlevel = DRIVER_PATCHLEVEL;
- DRM_COPY(version->name, DRIVER_NAME);
- DRM_COPY(version->date, DRIVER_DATE);
- DRM_COPY(version->desc, DRIVER_DESC);
- return 0;
+ return snprintf(buf, PAGE_SIZE, "%s\n",
+ (family < CHIP_R200) ? "radeon" :
+ ((family < CHIP_R300) ? "r200" :
+ "r300"));
}
static struct pci_device_id pciidlist[] = {
@@ -77,23 +63,22 @@ static struct drm_driver driver = {
DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED |
DRIVER_IRQ_VBL,
.dev_priv_size = sizeof(drm_radeon_buf_priv_t),
- .preinit = radeon_driver_preinit,
- .presetup = radeon_presetup,
- .postcleanup = radeon_driver_postcleanup,
- .prerelease = radeon_driver_prerelease,
- .pretakedown = radeon_driver_pretakedown,
- .open_helper = radeon_driver_open_helper,
+ .load = radeon_driver_load,
+ .firstopen = radeon_driver_firstopen,
+ .open = radeon_driver_open,
+ .preclose = radeon_driver_preclose,
+ .postclose = radeon_driver_postclose,
+ .lastclose = radeon_driver_lastclose,
+ .unload = radeon_driver_unload,
.vblank_wait = radeon_driver_vblank_wait,
+ .dri_library_name = dri_library_name,
.irq_preinstall = radeon_driver_irq_preinstall,
.irq_postinstall = radeon_driver_irq_postinstall,
.irq_uninstall = radeon_driver_irq_uninstall,
.irq_handler = radeon_driver_irq_handler,
- .free_filp_priv = radeon_driver_free_filp_priv,
.reclaim_buffers = drm_core_reclaim_buffers,
.get_map_ofs = drm_core_get_map_ofs,
.get_reg_ofs = drm_core_get_reg_ofs,
- .postinit = postinit,
- .version = version,
.ioctls = radeon_ioctls,
.dma_ioctl = radeon_cp_buffers,
.fops = {
@@ -107,12 +92,19 @@ static struct drm_driver driver = {
#ifdef CONFIG_COMPAT
.compat_ioctl = radeon_compat_ioctl,
#endif
- }
- ,
+ },
+
.pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
- }
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ },
+
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESC,
+ .date = DRIVER_DATE,
+ .major = DRIVER_MAJOR,
+ .minor = DRIVER_MINOR,
+ .patchlevel = DRIVER_PATCHLEVEL,
};
static int __init radeon_init(void)
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
index d92ccee3e54c6..498b19b1d641a 100644
--- a/drivers/char/drm/radeon_drv.h
+++ b/drivers/char/drm/radeon_drv.h
@@ -38,7 +38,7 @@
#define DRIVER_NAME "radeon"
#define DRIVER_DESC "ATI Radeon"
-#define DRIVER_DATE "20050911"
+#define DRIVER_DATE "20051229"
/* Interface history:
*
@@ -73,7 +73,7 @@
* 1.11- Add packet R200_EMIT_RB3D_BLENDCOLOR to support GL_EXT_blend_color
* and GL_EXT_blend_[func|equation]_separate on r200
* 1.12- Add R300 CP microcode support - this just loads the CP on r300
- * (No 3D support yet - just microcode loading)
+ * (No 3D support yet - just microcode loading).
* 1.13- Add packet R200_EMIT_TCL_POINT_SPRITE_CNTL for ARB_point_parameters
* - Add hyperz support, add hyperz flags to clear ioctl.
* 1.14- Add support for color tiling
@@ -88,14 +88,13 @@
* R200_EMIT_PP_TXFILTER_0-5, 2 more regs) and R200_EMIT_ATF_TFACTOR
* (replaces R200_EMIT_TFACTOR_0 (8 consts instead of 6)
* 1.19- Add support for gart table in FB memory and PCIE r300
+ * 1.20- Add support for r300 texrect
+ * 1.21- Add support for card type getparam
*/
#define DRIVER_MAJOR 1
-#define DRIVER_MINOR 19
+#define DRIVER_MINOR 21
#define DRIVER_PATCHLEVEL 0
-#define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 )
-#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) )
-
/*
* Radeon chip families
*/
@@ -103,8 +102,8 @@ enum radeon_family {
CHIP_R100,
CHIP_RS100,
CHIP_RV100,
- CHIP_R200,
CHIP_RV200,
+ CHIP_R200,
CHIP_RS200,
CHIP_R250,
CHIP_RS250,
@@ -138,6 +137,9 @@ enum radeon_chip_flags {
CHIP_IS_PCIE = 0x00200000UL,
};
+#define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 )
+#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) )
+
typedef struct drm_radeon_freelist {
unsigned int age;
drm_buf_t *buf;
@@ -245,8 +247,6 @@ typedef struct drm_radeon_private {
drm_radeon_depth_clear_t depth_clear;
- unsigned long fb_offset;
- unsigned long mmio_offset;
unsigned long ring_offset;
unsigned long ring_rptr_offset;
unsigned long buffers_offset;
@@ -273,7 +273,6 @@ typedef struct drm_radeon_private {
/* starting from here on, data is preserved accross an open */
uint32_t flags; /* see radeon_chip_flags */
- int is_pci;
} drm_radeon_private_t;
typedef struct drm_radeon_buf_priv {
@@ -330,17 +329,14 @@ extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS);
extern void radeon_driver_irq_preinstall(drm_device_t * dev);
extern void radeon_driver_irq_postinstall(drm_device_t * dev);
extern void radeon_driver_irq_uninstall(drm_device_t * dev);
-extern void radeon_driver_prerelease(drm_device_t * dev, DRMFILE filp);
-extern void radeon_driver_pretakedown(drm_device_t * dev);
-extern int radeon_driver_open_helper(drm_device_t * dev,
- drm_file_t * filp_priv);
-extern void radeon_driver_free_filp_priv(drm_device_t * dev,
- drm_file_t * filp_priv);
-
-extern int radeon_preinit(struct drm_device *dev, unsigned long flags);
-extern int radeon_postinit(struct drm_device *dev, unsigned long flags);
-extern int radeon_postcleanup(struct drm_device *dev);
+extern int radeon_driver_load(struct drm_device *dev, unsigned long flags);
+extern int radeon_driver_unload(struct drm_device *dev);
+extern int radeon_driver_firstopen(struct drm_device *dev);
+extern void radeon_driver_preclose(drm_device_t * dev, DRMFILE filp);
+extern void radeon_driver_postclose(drm_device_t * dev, drm_file_t * filp);
+extern void radeon_driver_lastclose(drm_device_t * dev);
+extern int radeon_driver_open(drm_device_t * dev, drm_file_t * filp_priv);
extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg);
@@ -364,6 +360,8 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp,
*/
#define RADEON_AGP_COMMAND 0x0f60
+#define RADEON_AGP_COMMAND_PCI_CONFIG 0x0060 /* offset in PCI config */
+# define RADEON_AGP_ENABLE (1<<8)
#define RADEON_AUX_SCISSOR_CNTL 0x26f0
# define RADEON_EXCLUSIVE_SCISSOR_0 (1 << 24)
# define RADEON_EXCLUSIVE_SCISSOR_1 (1 << 25)
@@ -651,6 +649,8 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp,
#define RADEON_WAIT_UNTIL 0x1720
# define RADEON_WAIT_CRTC_PFLIP (1 << 0)
+# define RADEON_WAIT_2D_IDLE (1 << 14)
+# define RADEON_WAIT_3D_IDLE (1 << 15)
# define RADEON_WAIT_2D_IDLECLEAN (1 << 16)
# define RADEON_WAIT_3D_IDLECLEAN (1 << 17)
# define RADEON_WAIT_HOST_IDLECLEAN (1 << 18)
@@ -1105,7 +1105,6 @@ do { \
write = 0; \
_tab += _i; \
} \
- \
while (_size > 0) { \
*(ring + write) = *_tab++; \
write++; \
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
index 231ac1438c699..7bc27516d4255 100644
--- a/drivers/char/drm/radeon_state.c
+++ b/drivers/char/drm/radeon_state.c
@@ -1,5 +1,5 @@
-/* radeon_state.c -- State support for Radeon -*- linux-c -*-
- *
+/* radeon_state.c -- State support for Radeon -*- linux-c -*- */
+/*
* Copyright 2000 VA Linux Systems, Inc., Fremont, California.
* All Rights Reserved.
*
@@ -72,10 +72,7 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
case RADEON_EMIT_PP_MISC:
if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
- &data[(RADEON_RB3D_DEPTHOFFSET
- -
- RADEON_PP_MISC) /
- 4])) {
+ &data[(RADEON_RB3D_DEPTHOFFSET - RADEON_PP_MISC) / 4])) {
DRM_ERROR("Invalid depth buffer offset\n");
return DRM_ERR(EINVAL);
}
@@ -83,10 +80,7 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
case RADEON_EMIT_PP_CNTL:
if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
- &data[(RADEON_RB3D_COLOROFFSET
- -
- RADEON_PP_CNTL) /
- 4])) {
+ &data[(RADEON_RB3D_COLOROFFSET - RADEON_PP_CNTL) / 4])) {
DRM_ERROR("Invalid colour buffer offset\n");
return DRM_ERR(EINVAL);
}
@@ -109,10 +103,7 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
case RADEON_EMIT_PP_TXFILTER_1:
case RADEON_EMIT_PP_TXFILTER_2:
if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
- &data[(RADEON_PP_TXOFFSET_0
- -
- RADEON_PP_TXFILTER_0) /
- 4])) {
+ &data[(RADEON_PP_TXOFFSET_0 - RADEON_PP_TXFILTER_0) / 4])) {
DRM_ERROR("Invalid R100 texture offset\n");
return DRM_ERR(EINVAL);
}
@@ -126,8 +117,9 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
case R200_EMIT_PP_CUBIC_OFFSETS_5:{
int i;
for (i = 0; i < 5; i++) {
- if (radeon_check_and_fixup_offset
- (dev_priv, filp_priv, &data[i])) {
+ if (radeon_check_and_fixup_offset(dev_priv,
+ filp_priv,
+ &data[i])) {
DRM_ERROR
("Invalid R200 cubic texture offset\n");
return DRM_ERR(EINVAL);
@@ -239,8 +231,9 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *
dev_priv,
- drm_file_t * filp_priv,
- drm_radeon_kcmd_buffer_t *cmdbuf,
+ drm_file_t *filp_priv,
+ drm_radeon_kcmd_buffer_t *
+ cmdbuf,
unsigned int *cmdsz)
{
u32 *cmd = (u32 *) cmdbuf->buf;
@@ -555,7 +548,8 @@ static struct {
{R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4"},
{R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5"},
{R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL"},
- {R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"},
+ {R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1,
+ "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"},
{R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3"},
{R200_PP_CNTL_X, 1, "R200_PP_CNTL_X"},
{R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET"},
@@ -569,7 +563,7 @@ static struct {
{R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4,
"R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0"},
{R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0"}, /* 61 */
- {R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */
+ {R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */
{R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1"},
{R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1"},
{R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2"},
@@ -592,7 +586,7 @@ static struct {
{RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"},
{RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"},
{R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"},
- {R200_PP_AFS_0, 32, "R200_PP_AFS_0"}, /* 85 */
+ {R200_PP_AFS_0, 32, "R200_PP_AFS_0"}, /* 85 */
{R200_PP_AFS_1, 32, "R200_PP_AFS_1"},
{R200_PP_TFACTOR_0, 8, "R200_ATF_TFACTOR"},
{R200_PP_TXFILTER_0, 8, "R200_PP_TXCTLALL_0"},
@@ -985,8 +979,8 @@ static void radeon_cp_dispatch_clear(drm_device_t * dev,
* rendering a quad into just those buffers. Thus, we have to
* make sure the 3D engine is configured correctly.
*/
- if ((dev_priv->microcode_version == UCODE_R200) &&
- (flags & (RADEON_DEPTH | RADEON_STENCIL))) {
+ else if ((dev_priv->microcode_version == UCODE_R200) &&
+ (flags & (RADEON_DEPTH | RADEON_STENCIL))) {
int tempPP_CNTL;
int tempRE_CNTL;
@@ -1637,6 +1631,14 @@ static int radeon_cp_dispatch_texture(DRMFILE filp,
(u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset);
dwords = size / 4;
+#define RADEON_COPY_MT(_buf, _data, _width) \
+ do { \
+ if (DRM_COPY_FROM_USER(_buf, _data, (_width))) {\
+ DRM_ERROR("EFAULT on pad, %d bytes\n", (_width)); \
+ return DRM_ERR(EFAULT); \
+ } \
+ } while(0)
+
if (microtile) {
/* texture micro tiling in use, minimum texture width is thus 16 bytes.
however, we cannot use blitter directly for texture width < 64 bytes,
@@ -1648,46 +1650,19 @@ static int radeon_cp_dispatch_texture(DRMFILE filp,
from user space. */
if (tex->height == 1) {
if (tex_width >= 64 || tex_width <= 16) {
- if (DRM_COPY_FROM_USER(buffer, data,
- tex_width *
- sizeof(u32))) {
- DRM_ERROR
- ("EFAULT on pad, %d bytes\n",
- tex_width);
- return DRM_ERR(EFAULT);
- }
+ RADEON_COPY_MT(buffer, data,
+ (int)(tex_width * sizeof(u32)));
} else if (tex_width == 32) {
- if (DRM_COPY_FROM_USER
- (buffer, data, 16)) {
- DRM_ERROR
- ("EFAULT on pad, %d bytes\n",
- tex_width);
- return DRM_ERR(EFAULT);
- }
- if (DRM_COPY_FROM_USER
- (buffer + 8, data + 16, 16)) {
- DRM_ERROR
- ("EFAULT on pad, %d bytes\n",
- tex_width);
- return DRM_ERR(EFAULT);
- }
+ RADEON_COPY_MT(buffer, data, 16);
+ RADEON_COPY_MT(buffer + 8,
+ data + 16, 16);
}
} else if (tex_width >= 64 || tex_width == 16) {
- if (DRM_COPY_FROM_USER(buffer, data,
- dwords * sizeof(u32))) {
- DRM_ERROR("EFAULT on data, %d dwords\n",
- dwords);
- return DRM_ERR(EFAULT);
- }
+ RADEON_COPY_MT(buffer, data,
+ (int)(dwords * sizeof(u32)));
} else if (tex_width < 16) {
for (i = 0; i < tex->height; i++) {
- if (DRM_COPY_FROM_USER
- (buffer, data, tex_width)) {
- DRM_ERROR
- ("EFAULT on pad, %d bytes\n",
- tex_width);
- return DRM_ERR(EFAULT);
- }
+ RADEON_COPY_MT(buffer, data, tex_width);
buffer += 4;
data += tex_width;
}
@@ -1695,37 +1670,13 @@ static int radeon_cp_dispatch_texture(DRMFILE filp,
/* TODO: make sure this works when not fitting in one buffer
(i.e. 32bytes x 2048...) */
for (i = 0; i < tex->height; i += 2) {
- if (DRM_COPY_FROM_USER
- (buffer, data, 16)) {
- DRM_ERROR
- ("EFAULT on pad, %d bytes\n",
- tex_width);
- return DRM_ERR(EFAULT);
- }
+ RADEON_COPY_MT(buffer, data, 16);
data += 16;
- if (DRM_COPY_FROM_USER
- (buffer + 8, data, 16)) {
- DRM_ERROR
- ("EFAULT on pad, %d bytes\n",
- tex_width);
- return DRM_ERR(EFAULT);
- }
+ RADEON_COPY_MT(buffer + 8, data, 16);
data += 16;
- if (DRM_COPY_FROM_USER
- (buffer + 4, data, 16)) {
- DRM_ERROR
- ("EFAULT on pad, %d bytes\n",
- tex_width);
- return DRM_ERR(EFAULT);
- }
+ RADEON_COPY_MT(buffer + 4, data, 16);
data += 16;
- if (DRM_COPY_FROM_USER
- (buffer + 12, data, 16)) {
- DRM_ERROR
- ("EFAULT on pad, %d bytes\n",
- tex_width);
- return DRM_ERR(EFAULT);
- }
+ RADEON_COPY_MT(buffer + 12, data, 16);
data += 16;
buffer += 16;
}
@@ -1735,31 +1686,22 @@ static int radeon_cp_dispatch_texture(DRMFILE filp,
/* Texture image width is larger than the minimum, so we
* can upload it directly.
*/
- if (DRM_COPY_FROM_USER(buffer, data,
- dwords * sizeof(u32))) {
- DRM_ERROR("EFAULT on data, %d dwords\n",
- dwords);
- return DRM_ERR(EFAULT);
- }
+ RADEON_COPY_MT(buffer, data,
+ (int)(dwords * sizeof(u32)));
} else {
/* Texture image width is less than the minimum, so we
* need to pad out each image scanline to the minimum
* width.
*/
for (i = 0; i < tex->height; i++) {
- if (DRM_COPY_FROM_USER
- (buffer, data, tex_width)) {
- DRM_ERROR
- ("EFAULT on pad, %d bytes\n",
- tex_width);
- return DRM_ERR(EFAULT);
- }
+ RADEON_COPY_MT(buffer, data, tex_width);
buffer += 8;
data += tex_width;
}
}
}
+#undef RADEON_COPY_MT
buf->filp = filp;
buf->used = size;
offset = dev_priv->gart_buffers_offset + buf->offset;
@@ -1821,7 +1763,7 @@ static void radeon_cp_dispatch_stipple(drm_device_t * dev, u32 * stipple)
}
static void radeon_apply_surface_regs(int surf_index,
- drm_radeon_private_t * dev_priv)
+ drm_radeon_private_t *dev_priv)
{
if (!dev_priv->mmio)
return;
@@ -1847,8 +1789,8 @@ static void radeon_apply_surface_regs(int surf_index,
* freed, we suddenly need two surfaces to store A and C, which might
* not always be available.
*/
-static int alloc_surface(drm_radeon_surface_alloc_t * new,
- drm_radeon_private_t * dev_priv, DRMFILE filp)
+static int alloc_surface(drm_radeon_surface_alloc_t *new,
+ drm_radeon_private_t *dev_priv, DRMFILE filp)
{
struct radeon_virt_surface *s;
int i;
@@ -2158,6 +2100,11 @@ static int radeon_cp_vertex(DRM_IOCTL_ARGS)
LOCK_TEST_WITH_RETURN(dev, filp);
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ return DRM_ERR(EINVAL);
+ }
+
DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex_t __user *) data,
@@ -2596,9 +2543,9 @@ static int radeon_emit_packets(drm_radeon_private_t * dev_priv,
return 0;
}
-static __inline__ int radeon_emit_scalars(drm_radeon_private_t * dev_priv,
+static __inline__ int radeon_emit_scalars(drm_radeon_private_t *dev_priv,
drm_radeon_cmd_header_t header,
- drm_radeon_kcmd_buffer_t * cmdbuf)
+ drm_radeon_kcmd_buffer_t *cmdbuf)
{
int sz = header.scalars.count;
int start = header.scalars.offset;
@@ -2618,9 +2565,9 @@ static __inline__ int radeon_emit_scalars(drm_radeon_private_t * dev_priv,
/* God this is ugly
*/
-static __inline__ int radeon_emit_scalars2(drm_radeon_private_t * dev_priv,
+static __inline__ int radeon_emit_scalars2(drm_radeon_private_t *dev_priv,
drm_radeon_cmd_header_t header,
- drm_radeon_kcmd_buffer_t * cmdbuf)
+ drm_radeon_kcmd_buffer_t *cmdbuf)
{
int sz = header.scalars.count;
int start = ((unsigned int)header.scalars.offset) + 0x100;
@@ -2638,9 +2585,9 @@ static __inline__ int radeon_emit_scalars2(drm_radeon_private_t * dev_priv,
return 0;
}
-static __inline__ int radeon_emit_vectors(drm_radeon_private_t * dev_priv,
+static __inline__ int radeon_emit_vectors(drm_radeon_private_t *dev_priv,
drm_radeon_cmd_header_t header,
- drm_radeon_kcmd_buffer_t * cmdbuf)
+ drm_radeon_kcmd_buffer_t *cmdbuf)
{
int sz = header.vectors.count;
int start = header.vectors.offset;
@@ -2685,8 +2632,8 @@ static int radeon_emit_packet3(drm_device_t * dev,
return 0;
}
-static int radeon_emit_packet3_cliprect(drm_device_t * dev,
- drm_file_t * filp_priv,
+static int radeon_emit_packet3_cliprect(drm_device_t *dev,
+ drm_file_t *filp_priv,
drm_radeon_kcmd_buffer_t *cmdbuf,
int orig_nbox)
{
@@ -2818,7 +2765,8 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS)
kbuf = drm_alloc(cmdbuf.bufsz, DRM_MEM_DRIVER);
if (kbuf == NULL)
return DRM_ERR(ENOMEM);
- if (DRM_COPY_FROM_USER(kbuf, (void __user *)cmdbuf.buf, cmdbuf.bufsz)) {
+ if (DRM_COPY_FROM_USER(kbuf, (void __user *)cmdbuf.buf,
+ cmdbuf.bufsz)) {
drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER);
return DRM_ERR(EFAULT);
}
@@ -2981,7 +2929,7 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS)
value = dev_priv->gart_vm_start;
break;
case RADEON_PARAM_REGISTER_HANDLE:
- value = dev_priv->mmio_offset;
+ value = dev_priv->mmio->offset;
break;
case RADEON_PARAM_STATUS_HANDLE:
value = dev_priv->ring_rptr_offset;
@@ -3004,6 +2952,15 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS)
case RADEON_PARAM_GART_TEX_HANDLE:
value = dev_priv->gart_textures_offset;
break;
+
+ case RADEON_PARAM_CARD_TYPE:
+ if (dev_priv->flags & CHIP_IS_PCIE)
+ value = RADEON_CARD_PCIE;
+ else if (dev_priv->flags & CHIP_IS_AGP)
+ value = RADEON_CARD_AGP;
+ else
+ value = RADEON_CARD_PCI;
+ break;
default:
return DRM_ERR(EINVAL);
}
@@ -3066,10 +3023,11 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS)
/* When a client dies:
* - Check for and clean up flipped page state
* - Free any alloced GART memory.
+ * - Free any alloced radeon surfaces.
*
* DRM infrastructure takes care of reclaiming dma buffers.
*/
-void radeon_driver_prerelease(drm_device_t * dev, DRMFILE filp)
+void radeon_driver_preclose(drm_device_t * dev, DRMFILE filp)
{
if (dev->dev_private) {
drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -3082,16 +3040,17 @@ void radeon_driver_prerelease(drm_device_t * dev, DRMFILE filp)
}
}
-void radeon_driver_pretakedown(drm_device_t * dev)
+void radeon_driver_lastclose(drm_device_t * dev)
{
radeon_do_release(dev);
}
-int radeon_driver_open_helper(drm_device_t * dev, drm_file_t * filp_priv)
+int radeon_driver_open(drm_device_t * dev, drm_file_t * filp_priv)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
struct drm_radeon_driver_file_fields *radeon_priv;
+ DRM_DEBUG("\n");
radeon_priv =
(struct drm_radeon_driver_file_fields *)
drm_alloc(sizeof(*radeon_priv), DRM_MEM_FILES);
@@ -3100,6 +3059,7 @@ int radeon_driver_open_helper(drm_device_t * dev, drm_file_t * filp_priv)
return -ENOMEM;
filp_priv->driver_priv = radeon_priv;
+
if (dev_priv)
radeon_priv->radeon_fb_delta = dev_priv->fb_location;
else
@@ -3107,7 +3067,7 @@ int radeon_driver_open_helper(drm_device_t * dev, drm_file_t * filp_priv)
return 0;
}
-void radeon_driver_free_filp_priv(drm_device_t * dev, drm_file_t * filp_priv)
+void radeon_driver_postclose(drm_device_t * dev, drm_file_t * filp_priv)
{
struct drm_radeon_driver_file_fields *radeon_priv =
filp_priv->driver_priv;
@@ -3116,33 +3076,33 @@ void radeon_driver_free_filp_priv(drm_device_t * dev, drm_file_t * filp_priv)
}
drm_ioctl_desc_t radeon_ioctls[] = {
- [DRM_IOCTL_NR(DRM_RADEON_CP_INIT)] = {radeon_cp_init, 1, 1},
- [DRM_IOCTL_NR(DRM_RADEON_CP_START)] = {radeon_cp_start, 1, 1},
- [DRM_IOCTL_NR(DRM_RADEON_CP_STOP)] = {radeon_cp_stop, 1, 1},
- [DRM_IOCTL_NR(DRM_RADEON_CP_RESET)] = {radeon_cp_reset, 1, 1},
- [DRM_IOCTL_NR(DRM_RADEON_CP_IDLE)] = {radeon_cp_idle, 1, 0},
- [DRM_IOCTL_NR(DRM_RADEON_CP_RESUME)] = {radeon_cp_resume, 1, 0},
- [DRM_IOCTL_NR(DRM_RADEON_RESET)] = {radeon_engine_reset, 1, 0},
- [DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN)] = {radeon_fullscreen, 1, 0},
- [DRM_IOCTL_NR(DRM_RADEON_SWAP)] = {radeon_cp_swap, 1, 0},
- [DRM_IOCTL_NR(DRM_RADEON_CLEAR)] = {radeon_cp_clear, 1, 0},
- [DRM_IOCTL_NR(DRM_RADEON_VERTEX)] = {radeon_cp_vertex, 1, 0},
- [DRM_IOCTL_NR(DRM_RADEON_INDICES)] = {radeon_cp_indices, 1, 0},
- [DRM_IOCTL_NR(DRM_RADEON_TEXTURE)] = {radeon_cp_texture, 1, 0},
- [DRM_IOCTL_NR(DRM_RADEON_STIPPLE)] = {radeon_cp_stipple, 1, 0},
- [DRM_IOCTL_NR(DRM_RADEON_INDIRECT)] = {radeon_cp_indirect, 1, 1},
- [DRM_IOCTL_NR(DRM_RADEON_VERTEX2)] = {radeon_cp_vertex2, 1, 0},
- [DRM_IOCTL_NR(DRM_RADEON_CMDBUF)] = {radeon_cp_cmdbuf, 1, 0},
- [DRM_IOCTL_NR(DRM_RADEON_GETPARAM)] = {radeon_cp_getparam, 1, 0},
- [DRM_IOCTL_NR(DRM_RADEON_FLIP)] = {radeon_cp_flip, 1, 0},
- [DRM_IOCTL_NR(DRM_RADEON_ALLOC)] = {radeon_mem_alloc, 1, 0},
- [DRM_IOCTL_NR(DRM_RADEON_FREE)] = {radeon_mem_free, 1, 0},
- [DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP)] = {radeon_mem_init_heap, 1, 1},
- [DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT)] = {radeon_irq_emit, 1, 0},
- [DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT)] = {radeon_irq_wait, 1, 0},
- [DRM_IOCTL_NR(DRM_RADEON_SETPARAM)] = {radeon_cp_setparam, 1, 0},
- [DRM_IOCTL_NR(DRM_RADEON_SURF_ALLOC)] = {radeon_surface_alloc, 1, 0},
- [DRM_IOCTL_NR(DRM_RADEON_SURF_FREE)] = {radeon_surface_free, 1, 0}
+ [DRM_IOCTL_NR(DRM_RADEON_CP_INIT)] = {radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_RADEON_CP_START)] = {radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_RADEON_CP_STOP)] = {radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_RADEON_CP_RESET)] = {radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_RADEON_CP_IDLE)] = {radeon_cp_idle, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_RADEON_CP_RESUME)] = {radeon_cp_resume, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_RADEON_RESET)] = {radeon_engine_reset, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN)] = {radeon_fullscreen, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_RADEON_SWAP)] = {radeon_cp_swap, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_RADEON_CLEAR)] = {radeon_cp_clear, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_RADEON_VERTEX)] = {radeon_cp_vertex, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_RADEON_INDICES)] = {radeon_cp_indices, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_RADEON_TEXTURE)] = {radeon_cp_texture, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_RADEON_STIPPLE)] = {radeon_cp_stipple, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_RADEON_INDIRECT)] = {radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_RADEON_VERTEX2)] = {radeon_cp_vertex2, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_RADEON_CMDBUF)] = {radeon_cp_cmdbuf, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_RADEON_GETPARAM)] = {radeon_cp_getparam, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_RADEON_FLIP)] = {radeon_cp_flip, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_RADEON_ALLOC)] = {radeon_mem_alloc, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_RADEON_FREE)] = {radeon_mem_free, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP)] = {radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT)] = {radeon_irq_emit, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT)] = {radeon_irq_wait, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_RADEON_SETPARAM)] = {radeon_cp_setparam, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_RADEON_SURF_ALLOC)] = {radeon_surface_alloc, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_RADEON_SURF_FREE)] = {radeon_surface_free, DRM_AUTH}
};
int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls);
diff --git a/drivers/char/drm/savage_bci.c b/drivers/char/drm/savage_bci.c
index 6d10515795cc9..0d426deeefec1 100644
--- a/drivers/char/drm/savage_bci.c
+++ b/drivers/char/drm/savage_bci.c
@@ -533,16 +533,32 @@ static void savage_fake_dma_flush(drm_savage_private_t * dev_priv)
dev_priv->first_dma_page = dev_priv->current_dma_page = 0;
}
+int savage_driver_load(drm_device_t *dev, unsigned long chipset)
+{
+ drm_savage_private_t *dev_priv;
+
+ dev_priv = drm_alloc(sizeof(drm_savage_private_t), DRM_MEM_DRIVER);
+ if (dev_priv == NULL)
+ return DRM_ERR(ENOMEM);
+
+ memset(dev_priv, 0, sizeof(drm_savage_private_t));
+ dev->dev_private = (void *)dev_priv;
+
+ dev_priv->chipset = (enum savage_family)chipset;
+
+ return 0;
+}
+
+
/*
* Initalize mappings. On Savage4 and SavageIX the alignment
* and size of the aperture is not suitable for automatic MTRR setup
- * in drm_addmap. Therefore we do it manually before the maps are
- * initialized. We also need to take care of deleting the MTRRs in
- * postcleanup.
+ * in drm_addmap. Therefore we add them manually before the maps are
+ * initialized, and tear them down on last close.
*/
-int savage_preinit(drm_device_t * dev, unsigned long chipset)
+int savage_driver_firstopen(drm_device_t *dev)
{
- drm_savage_private_t *dev_priv;
+ drm_savage_private_t *dev_priv = dev->dev_private;
unsigned long mmio_base, fb_base, fb_size, aperture_base;
/* fb_rsrc and aper_rsrc aren't really used currently, but still exist
* in case we decide we need information on the BAR for BSD in the
@@ -551,14 +567,6 @@ int savage_preinit(drm_device_t * dev, unsigned long chipset)
unsigned int fb_rsrc, aper_rsrc;
int ret = 0;
- dev_priv = drm_alloc(sizeof(drm_savage_private_t), DRM_MEM_DRIVER);
- if (dev_priv == NULL)
- return DRM_ERR(ENOMEM);
-
- memset(dev_priv, 0, sizeof(drm_savage_private_t));
- dev->dev_private = (void *)dev_priv;
- dev_priv->chipset = (enum savage_family)chipset;
-
dev_priv->mtrr[0].handle = -1;
dev_priv->mtrr[1].handle = -1;
dev_priv->mtrr[2].handle = -1;
@@ -576,26 +584,24 @@ int savage_preinit(drm_device_t * dev, unsigned long chipset)
dev_priv->mtrr[0].base = fb_base;
dev_priv->mtrr[0].size = 0x01000000;
dev_priv->mtrr[0].handle =
- mtrr_add(dev_priv->mtrr[0].base,
- dev_priv->mtrr[0].size, MTRR_TYPE_WRCOMB,
- 1);
+ drm_mtrr_add(dev_priv->mtrr[0].base,
+ dev_priv->mtrr[0].size, DRM_MTRR_WC);
dev_priv->mtrr[1].base = fb_base + 0x02000000;
dev_priv->mtrr[1].size = 0x02000000;
dev_priv->mtrr[1].handle =
- mtrr_add(dev_priv->mtrr[1].base,
- dev_priv->mtrr[1].size, MTRR_TYPE_WRCOMB,
- 1);
+ drm_mtrr_add(dev_priv->mtrr[1].base,
+ dev_priv->mtrr[1].size, DRM_MTRR_WC);
dev_priv->mtrr[2].base = fb_base + 0x04000000;
dev_priv->mtrr[2].size = 0x04000000;
dev_priv->mtrr[2].handle =
- mtrr_add(dev_priv->mtrr[2].base,
- dev_priv->mtrr[2].size, MTRR_TYPE_WRCOMB,
- 1);
+ drm_mtrr_add(dev_priv->mtrr[2].base,
+ dev_priv->mtrr[2].size, DRM_MTRR_WC);
} else {
DRM_ERROR("strange pci_resource_len %08lx\n",
drm_get_resource_len(dev, 0));
}
- } else if (chipset != S3_SUPERSAVAGE && chipset != S3_SAVAGE2000) {
+ } else if (dev_priv->chipset != S3_SUPERSAVAGE &&
+ dev_priv->chipset != S3_SAVAGE2000) {
mmio_base = drm_get_resource_start(dev, 0);
fb_rsrc = 1;
fb_base = drm_get_resource_start(dev, 1);
@@ -609,9 +615,8 @@ int savage_preinit(drm_device_t * dev, unsigned long chipset)
dev_priv->mtrr[0].base = fb_base;
dev_priv->mtrr[0].size = 0x08000000;
dev_priv->mtrr[0].handle =
- mtrr_add(dev_priv->mtrr[0].base,
- dev_priv->mtrr[0].size, MTRR_TYPE_WRCOMB,
- 1);
+ drm_mtrr_add(dev_priv->mtrr[0].base,
+ dev_priv->mtrr[0].size, DRM_MTRR_WC);
} else {
DRM_ERROR("strange pci_resource_len %08lx\n",
drm_get_resource_len(dev, 1));
@@ -648,16 +653,21 @@ int savage_preinit(drm_device_t * dev, unsigned long chipset)
/*
* Delete MTRRs and free device-private data.
*/
-int savage_postcleanup(drm_device_t * dev)
+void savage_driver_lastclose(drm_device_t *dev)
{
drm_savage_private_t *dev_priv = dev->dev_private;
int i;
for (i = 0; i < 3; ++i)
if (dev_priv->mtrr[i].handle >= 0)
- mtrr_del(dev_priv->mtrr[i].handle,
+ drm_mtrr_del(dev_priv->mtrr[i].handle,
dev_priv->mtrr[i].base,
- dev_priv->mtrr[i].size);
+ dev_priv->mtrr[i].size, DRM_MTRR_WC);
+}
+
+int savage_driver_unload(drm_device_t *dev)
+{
+ drm_savage_private_t *dev_priv = dev->dev_private;
drm_free(dev_priv, sizeof(drm_savage_private_t), DRM_MEM_DRIVER);
@@ -994,8 +1004,7 @@ static int savage_bci_event_wait(DRM_IOCTL_ARGS)
* DMA buffer management
*/
-static int savage_bci_get_buffers(DRMFILE filp, drm_device_t * dev,
- drm_dma_t * d)
+static int savage_bci_get_buffers(DRMFILE filp, drm_device_t *dev, drm_dma_t *d)
{
drm_buf_t *buf;
int i;
@@ -1057,7 +1066,7 @@ int savage_bci_buffers(DRM_IOCTL_ARGS)
return ret;
}
-void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp)
+void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp)
{
drm_device_dma_t *dma = dev->dma;
drm_savage_private_t *dev_priv = dev->dev_private;
@@ -1090,10 +1099,10 @@ void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp)
}
drm_ioctl_desc_t savage_ioctls[] = {
- [DRM_IOCTL_NR(DRM_SAVAGE_BCI_INIT)] = {savage_bci_init, 1, 1},
- [DRM_IOCTL_NR(DRM_SAVAGE_BCI_CMDBUF)] = {savage_bci_cmdbuf, 1, 0},
- [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_EMIT)] = {savage_bci_event_emit, 1, 0},
- [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_WAIT)] = {savage_bci_event_wait, 1, 0},
+ [DRM_IOCTL_NR(DRM_SAVAGE_BCI_INIT)] = {savage_bci_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_SAVAGE_BCI_CMDBUF)] = {savage_bci_cmdbuf, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_EMIT)] = {savage_bci_event_emit, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_WAIT)] = {savage_bci_event_wait, DRM_AUTH},
};
int savage_max_ioctl = DRM_ARRAY_SIZE(savage_ioctls);
diff --git a/drivers/char/drm/savage_drv.c b/drivers/char/drm/savage_drv.c
index 22d799cde41cb..aa6c0d1a82f87 100644
--- a/drivers/char/drm/savage_drv.c
+++ b/drivers/char/drm/savage_drv.c
@@ -30,31 +30,6 @@
#include "drm_pciids.h"
-static int postinit(struct drm_device *dev, unsigned long flags)
-{
- DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
- DRIVER_NAME,
- DRIVER_MAJOR,
- DRIVER_MINOR,
- DRIVER_PATCHLEVEL,
- DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
- );
- return 0;
-}
-
-static int version(drm_version_t * version)
-{
- int len;
-
- version->version_major = DRIVER_MAJOR;
- version->version_minor = DRIVER_MINOR;
- version->version_patchlevel = DRIVER_PATCHLEVEL;
- DRM_COPY(version->name, DRIVER_NAME);
- DRM_COPY(version->date, DRIVER_DATE);
- DRM_COPY(version->desc, DRIVER_DESC);
- return 0;
-}
-
static struct pci_device_id pciidlist[] = {
savage_PCI_IDS
};
@@ -63,13 +38,13 @@ static struct drm_driver driver = {
.driver_features =
DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_PCI_DMA,
.dev_priv_size = sizeof(drm_savage_buf_priv_t),
- .preinit = savage_preinit,
- .postinit = postinit,
- .postcleanup = savage_postcleanup,
+ .load = savage_driver_load,
+ .firstopen = savage_driver_firstopen,
+ .lastclose = savage_driver_lastclose,
+ .unload = savage_driver_unload,
.reclaim_buffers = savage_reclaim_buffers,
.get_map_ofs = drm_core_get_map_ofs,
.get_reg_ofs = drm_core_get_reg_ofs,
- .version = version,
.ioctls = savage_ioctls,
.dma_ioctl = savage_bci_buffers,
.fops = {
@@ -80,12 +55,19 @@ static struct drm_driver driver = {
.mmap = drm_mmap,
.poll = drm_poll,
.fasync = drm_fasync,
- }
- ,
+ },
+
.pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
- }
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ },
+
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESC,
+ .date = DRIVER_DATE,
+ .major = DRIVER_MAJOR,
+ .minor = DRIVER_MINOR,
+ .patchlevel = DRIVER_PATCHLEVEL,
};
static int __init savage_init(void)
diff --git a/drivers/char/drm/savage_drv.h b/drivers/char/drm/savage_drv.h
index a4b0fa998a956..dd46cb85439c8 100644
--- a/drivers/char/drm/savage_drv.h
+++ b/drivers/char/drm/savage_drv.h
@@ -1,5 +1,5 @@
-/* savage_drv.h -- Private header for the savage driver
- *
+/* savage_drv.h -- Private header for the savage driver */
+/*
* Copyright 2004 Felix Kuehling
* All Rights Reserved.
*
@@ -192,7 +192,7 @@ typedef struct drm_savage_private {
/* Err, there is a macro wait_event in include/linux/wait.h.
* Avoid unwanted macro expansion. */
void (*emit_clip_rect) (struct drm_savage_private * dev_priv,
- drm_clip_rect_t * pbox);
+ const drm_clip_rect_t * pbox);
void (*dma_flush) (struct drm_savage_private * dev_priv);
} drm_savage_private_t;
@@ -208,16 +208,18 @@ extern void savage_dma_reset(drm_savage_private_t * dev_priv);
extern void savage_dma_wait(drm_savage_private_t * dev_priv, unsigned int page);
extern uint32_t *savage_dma_alloc(drm_savage_private_t * dev_priv,
unsigned int n);
-extern int savage_preinit(drm_device_t * dev, unsigned long chipset);
-extern int savage_postcleanup(drm_device_t * dev);
+extern int savage_driver_load(drm_device_t *dev, unsigned long chipset);
+extern int savage_driver_firstopen(drm_device_t *dev);
+extern void savage_driver_lastclose(drm_device_t *dev);
+extern int savage_driver_unload(drm_device_t *dev);
extern int savage_do_cleanup_bci(drm_device_t * dev);
extern void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp);
/* state functions */
extern void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv,
- drm_clip_rect_t * pbox);
+ const drm_clip_rect_t * pbox);
extern void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv,
- drm_clip_rect_t * pbox);
+ const drm_clip_rect_t * pbox);
#define SAVAGE_FB_SIZE_S3 0x01000000 /* 16MB */
#define SAVAGE_FB_SIZE_S4 0x02000000 /* 32MB */
@@ -500,15 +502,6 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv,
#define BCI_WRITE( val ) *bci_ptr++ = (uint32_t)(val)
-#define BCI_COPY_FROM_USER(src,n) do { \
- unsigned int i; \
- for (i = 0; i < n; ++i) { \
- uint32_t val; \
- DRM_GET_USER_UNCHECKED(val, &((uint32_t*)(src))[i]); \
- BCI_WRITE(val); \
- } \
-} while(0)
-
/*
* command DMA support
*/
@@ -534,8 +527,8 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv,
#define DMA_WRITE( val ) *dma_ptr++ = (uint32_t)(val)
-#define DMA_COPY_FROM_USER(src,n) do { \
- DRM_COPY_FROM_USER_UNCHECKED(dma_ptr, (src), (n)*4); \
+#define DMA_COPY(src, n) do { \
+ memcpy(dma_ptr, (src), (n)*4); \
dma_ptr += n; \
} while(0)
diff --git a/drivers/char/drm/savage_state.c b/drivers/char/drm/savage_state.c
index e87a5d59b99c4..ef2581d16146d 100644
--- a/drivers/char/drm/savage_state.c
+++ b/drivers/char/drm/savage_state.c
@@ -27,7 +27,7 @@
#include "savage_drv.h"
void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv,
- drm_clip_rect_t * pbox)
+ const drm_clip_rect_t * pbox)
{
uint32_t scstart = dev_priv->state.s3d.new_scstart;
uint32_t scend = dev_priv->state.s3d.new_scend;
@@ -53,7 +53,7 @@ void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv,
}
void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv,
- drm_clip_rect_t * pbox)
+ const drm_clip_rect_t * pbox)
{
uint32_t drawctrl0 = dev_priv->state.s4.new_drawctrl0;
uint32_t drawctrl1 = dev_priv->state.s4.new_drawctrl1;
@@ -115,18 +115,19 @@ static int savage_verify_texaddr(drm_savage_private_t * dev_priv, int unit,
#define SAVE_STATE(reg,where) \
if(start <= reg && start+count > reg) \
- DRM_GET_USER_UNCHECKED(dev_priv->state.where, &regs[reg-start])
+ dev_priv->state.where = regs[reg - start]
#define SAVE_STATE_MASK(reg,where,mask) do { \
if(start <= reg && start+count > reg) { \
uint32_t tmp; \
- DRM_GET_USER_UNCHECKED(tmp, &regs[reg-start]); \
+ tmp = regs[reg - start]; \
dev_priv->state.where = (tmp & (mask)) | \
(dev_priv->state.where & ~(mask)); \
} \
} while (0)
+
static int savage_verify_state_s3d(drm_savage_private_t * dev_priv,
unsigned int start, unsigned int count,
- const uint32_t __user * regs)
+ const uint32_t *regs)
{
if (start < SAVAGE_TEXPALADDR_S3D ||
start + count - 1 > SAVAGE_DESTTEXRWWATERMARK_S3D) {
@@ -148,8 +149,7 @@ static int savage_verify_state_s3d(drm_savage_private_t * dev_priv,
SAVE_STATE(SAVAGE_TEXADDR_S3D, s3d.texaddr);
if (dev_priv->state.s3d.texctrl & SAVAGE_TEXCTRL_TEXEN_MASK)
return savage_verify_texaddr(dev_priv, 0,
- dev_priv->state.s3d.
- texaddr);
+ dev_priv->state.s3d.texaddr);
}
return 0;
@@ -157,7 +157,7 @@ static int savage_verify_state_s3d(drm_savage_private_t * dev_priv,
static int savage_verify_state_s4(drm_savage_private_t * dev_priv,
unsigned int start, unsigned int count,
- const uint32_t __user * regs)
+ const uint32_t *regs)
{
int ret = 0;
@@ -174,19 +174,18 @@ static int savage_verify_state_s4(drm_savage_private_t * dev_priv,
~SAVAGE_SCISSOR_MASK_S4);
/* if any texture regs were changed ... */
- if (start <= SAVAGE_TEXDESCR_S4 && start + count > SAVAGE_TEXPALADDR_S4) {
+ if (start <= SAVAGE_TEXDESCR_S4 &&
+ start + count > SAVAGE_TEXPALADDR_S4) {
/* ... check texture state */
SAVE_STATE(SAVAGE_TEXDESCR_S4, s4.texdescr);
SAVE_STATE(SAVAGE_TEXADDR0_S4, s4.texaddr0);
SAVE_STATE(SAVAGE_TEXADDR1_S4, s4.texaddr1);
if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX0EN_MASK)
- ret |=
- savage_verify_texaddr(dev_priv, 0,
- dev_priv->state.s4.texaddr0);
+ ret |= savage_verify_texaddr(dev_priv, 0,
+ dev_priv->state.s4.texaddr0);
if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX1EN_MASK)
- ret |=
- savage_verify_texaddr(dev_priv, 1,
- dev_priv->state.s4.texaddr1);
+ ret |= savage_verify_texaddr(dev_priv, 1,
+ dev_priv->state.s4.texaddr1);
}
return ret;
@@ -197,7 +196,7 @@ static int savage_verify_state_s4(drm_savage_private_t * dev_priv,
static int savage_dispatch_state(drm_savage_private_t * dev_priv,
const drm_savage_cmd_header_t * cmd_header,
- const uint32_t __user * regs)
+ const uint32_t *regs)
{
unsigned int count = cmd_header->state.count;
unsigned int start = cmd_header->state.start;
@@ -209,9 +208,6 @@ static int savage_dispatch_state(drm_savage_private_t * dev_priv,
if (!count)
return 0;
- if (DRM_VERIFYAREA_READ(regs, count * 4))
- return DRM_ERR(EFAULT);
-
if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
ret = savage_verify_state_s3d(dev_priv, start, count, regs);
if (ret != 0)
@@ -236,8 +232,8 @@ static int savage_dispatch_state(drm_savage_private_t * dev_priv,
/* scissor regs are emitted in savage_dispatch_draw */
if (start < SAVAGE_DRAWCTRL0_S4) {
if (start + count > SAVAGE_DRAWCTRL1_S4 + 1)
- count2 =
- count - (SAVAGE_DRAWCTRL1_S4 + 1 - start);
+ count2 = count -
+ (SAVAGE_DRAWCTRL1_S4 + 1 - start);
if (start + count > SAVAGE_DRAWCTRL0_S4)
count = SAVAGE_DRAWCTRL0_S4 - start;
} else if (start <= SAVAGE_DRAWCTRL1_S4) {
@@ -263,7 +259,7 @@ static int savage_dispatch_state(drm_savage_private_t * dev_priv,
while (count > 0) {
unsigned int n = count < 255 ? count : 255;
DMA_SET_REGISTERS(start, n);
- DMA_COPY_FROM_USER(regs, n);
+ DMA_COPY(regs, n);
count -= n;
start += n;
regs += n;
@@ -421,8 +417,8 @@ static int savage_dispatch_dma_prim(drm_savage_private_t * dev_priv,
static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv,
const drm_savage_cmd_header_t * cmd_header,
- const uint32_t __user * vtxbuf,
- unsigned int vb_size, unsigned int vb_stride)
+ const uint32_t *vtxbuf, unsigned int vb_size,
+ unsigned int vb_stride)
{
unsigned char reorder = 0;
unsigned int prim = cmd_header->prim.prim;
@@ -507,8 +503,7 @@ static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv,
for (i = start; i < start + count; ++i) {
unsigned int j = i + reorder[i % 3];
- DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j],
- vtx_size);
+ DMA_COPY(&vtxbuf[vb_stride * j], vtx_size);
}
DMA_COMMIT();
@@ -517,13 +512,12 @@ static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv,
DMA_DRAW_PRIMITIVE(count, prim, skip);
if (vb_stride == vtx_size) {
- DMA_COPY_FROM_USER(&vtxbuf[vb_stride * start],
- vtx_size * count);
+ DMA_COPY(&vtxbuf[vb_stride * start],
+ vtx_size * count);
} else {
for (i = start; i < start + count; ++i) {
- DMA_COPY_FROM_USER(&vtxbuf
- [vb_stride * i],
- vtx_size);
+ DMA_COPY(&vtxbuf [vb_stride * i],
+ vtx_size);
}
}
@@ -541,7 +535,7 @@ static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv,
static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv,
const drm_savage_cmd_header_t * cmd_header,
- const uint16_t __user * usr_idx,
+ const uint16_t *idx,
const drm_buf_t * dmabuf)
{
unsigned char reorder = 0;
@@ -628,11 +622,8 @@ static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv,
while (n != 0) {
/* Can emit up to 255 indices (85 triangles) at once. */
unsigned int count = n > 255 ? 255 : n;
- /* Is it ok to allocate 510 bytes on the stack in an ioctl? */
- uint16_t idx[255];
- /* Copy and check indices */
- DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count * 2);
+ /* check indices */
for (i = 0; i < count; ++i) {
if (idx[i] > dmabuf->total / 32) {
DRM_ERROR("idx[%u]=%u out of range (0-%u)\n",
@@ -652,8 +643,8 @@ static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv,
for (i = 1; i + 1 < count; i += 2)
BCI_WRITE(idx[i + reorder[i % 3]] |
- (idx[i + 1 + reorder[(i + 1) % 3]] <<
- 16));
+ (idx[i + 1 +
+ reorder[(i + 1) % 3]] << 16));
if (i < count)
BCI_WRITE(idx[i + reorder[i % 3]]);
} else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
@@ -674,7 +665,7 @@ static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv,
BCI_WRITE(idx[i]);
}
- usr_idx += count;
+ idx += count;
n -= count;
prim |= BCI_CMD_DRAW_CONT;
@@ -685,8 +676,8 @@ static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv,
static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv,
const drm_savage_cmd_header_t * cmd_header,
- const uint16_t __user * usr_idx,
- const uint32_t __user * vtxbuf,
+ const uint16_t *idx,
+ const uint32_t *vtxbuf,
unsigned int vb_size, unsigned int vb_stride)
{
unsigned char reorder = 0;
@@ -751,11 +742,8 @@ static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv,
while (n != 0) {
/* Can emit up to 255 vertices (85 triangles) at once. */
unsigned int count = n > 255 ? 255 : n;
- /* Is it ok to allocate 510 bytes on the stack in an ioctl? */
- uint16_t idx[255];
-
- /* Copy and check indices */
- DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count * 2);
+
+ /* Check indices */
for (i = 0; i < count; ++i) {
if (idx[i] > vb_size / (vb_stride * 4)) {
DRM_ERROR("idx[%u]=%u out of range (0-%u)\n",
@@ -775,8 +763,7 @@ static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv,
for (i = 0; i < count; ++i) {
unsigned int j = idx[i + reorder[i % 3]];
- DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j],
- vtx_size);
+ DMA_COPY(&vtxbuf[vb_stride * j], vtx_size);
}
DMA_COMMIT();
@@ -786,14 +773,13 @@ static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv,
for (i = 0; i < count; ++i) {
unsigned int j = idx[i];
- DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j],
- vtx_size);
+ DMA_COPY(&vtxbuf[vb_stride * j], vtx_size);
}
DMA_COMMIT();
}
- usr_idx += count;
+ idx += count;
n -= count;
prim |= BCI_CMD_DRAW_CONT;
@@ -804,11 +790,11 @@ static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv,
static int savage_dispatch_clear(drm_savage_private_t * dev_priv,
const drm_savage_cmd_header_t * cmd_header,
- const drm_savage_cmd_header_t __user * data,
+ const drm_savage_cmd_header_t *data,
unsigned int nbox,
- const drm_clip_rect_t __user * usr_boxes)
+ const drm_clip_rect_t *boxes)
{
- unsigned int flags = cmd_header->clear0.flags, mask, value;
+ unsigned int flags = cmd_header->clear0.flags;
unsigned int clear_cmd;
unsigned int i, nbufs;
DMA_LOCALS;
@@ -816,9 +802,6 @@ static int savage_dispatch_clear(drm_savage_private_t * dev_priv,
if (nbox == 0)
return 0;
- DRM_GET_USER_UNCHECKED(mask, &data->clear1.mask);
- DRM_GET_USER_UNCHECKED(value, &data->clear1.value);
-
clear_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP |
BCI_CMD_SEND_COLOR | BCI_CMD_DEST_PBD_NEW;
BCI_CMD_SET_ROP(clear_cmd, 0xCC);
@@ -828,21 +811,19 @@ static int savage_dispatch_clear(drm_savage_private_t * dev_priv,
if (nbufs == 0)
return 0;
- if (mask != 0xffffffff) {
+ if (data->clear1.mask != 0xffffffff) {
/* set mask */
BEGIN_DMA(2);
DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1);
- DMA_WRITE(mask);
+ DMA_WRITE(data->clear1.mask);
DMA_COMMIT();
}
for (i = 0; i < nbox; ++i) {
- drm_clip_rect_t box;
unsigned int x, y, w, h;
unsigned int buf;
- DRM_COPY_FROM_USER_UNCHECKED(&box, &usr_boxes[i], sizeof(box));
- x = box.x1, y = box.y1;
- w = box.x2 - box.x1;
- h = box.y2 - box.y1;
+ x = boxes[i].x1, y = boxes[i].y1;
+ w = boxes[i].x2 - boxes[i].x1;
+ h = boxes[i].y2 - boxes[i].y1;
BEGIN_DMA(nbufs * 6);
for (buf = SAVAGE_FRONT; buf <= SAVAGE_DEPTH; buf <<= 1) {
if (!(flags & buf))
@@ -862,13 +843,13 @@ static int savage_dispatch_clear(drm_savage_private_t * dev_priv,
DMA_WRITE(dev_priv->depth_bd);
break;
}
- DMA_WRITE(value);
+ DMA_WRITE(data->clear1.value);
DMA_WRITE(BCI_X_Y(x, y));
DMA_WRITE(BCI_W_H(w, h));
}
DMA_COMMIT();
}
- if (mask != 0xffffffff) {
+ if (data->clear1.mask != 0xffffffff) {
/* reset mask */
BEGIN_DMA(2);
DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1);
@@ -880,8 +861,7 @@ static int savage_dispatch_clear(drm_savage_private_t * dev_priv,
}
static int savage_dispatch_swap(drm_savage_private_t * dev_priv,
- unsigned int nbox,
- const drm_clip_rect_t __user * usr_boxes)
+ unsigned int nbox, const drm_clip_rect_t *boxes)
{
unsigned int swap_cmd;
unsigned int i;
@@ -895,16 +875,14 @@ static int savage_dispatch_swap(drm_savage_private_t * dev_priv,
BCI_CMD_SET_ROP(swap_cmd, 0xCC);
for (i = 0; i < nbox; ++i) {
- drm_clip_rect_t box;
- DRM_COPY_FROM_USER_UNCHECKED(&box, &usr_boxes[i], sizeof(box));
-
BEGIN_DMA(6);
DMA_WRITE(swap_cmd);
DMA_WRITE(dev_priv->back_offset);
DMA_WRITE(dev_priv->back_bd);
- DMA_WRITE(BCI_X_Y(box.x1, box.y1));
- DMA_WRITE(BCI_X_Y(box.x1, box.y1));
- DMA_WRITE(BCI_W_H(box.x2 - box.x1, box.y2 - box.y1));
+ DMA_WRITE(BCI_X_Y(boxes[i].x1, boxes[i].y1));
+ DMA_WRITE(BCI_X_Y(boxes[i].x1, boxes[i].y1));
+ DMA_WRITE(BCI_W_H(boxes[i].x2 - boxes[i].x1,
+ boxes[i].y2 - boxes[i].y1));
DMA_COMMIT();
}
@@ -912,68 +890,52 @@ static int savage_dispatch_swap(drm_savage_private_t * dev_priv,
}
static int savage_dispatch_draw(drm_savage_private_t * dev_priv,
- const drm_savage_cmd_header_t __user * start,
- const drm_savage_cmd_header_t __user * end,
+ const drm_savage_cmd_header_t *start,
+ const drm_savage_cmd_header_t *end,
const drm_buf_t * dmabuf,
- const unsigned int __user * usr_vtxbuf,
+ const unsigned int *vtxbuf,
unsigned int vb_size, unsigned int vb_stride,
unsigned int nbox,
- const drm_clip_rect_t __user * usr_boxes)
+ const drm_clip_rect_t *boxes)
{
unsigned int i, j;
int ret;
for (i = 0; i < nbox; ++i) {
- drm_clip_rect_t box;
- const drm_savage_cmd_header_t __user *usr_cmdbuf;
- DRM_COPY_FROM_USER_UNCHECKED(&box, &usr_boxes[i], sizeof(box));
- dev_priv->emit_clip_rect(dev_priv, &box);
+ const drm_savage_cmd_header_t *cmdbuf;
+ dev_priv->emit_clip_rect(dev_priv, &boxes[i]);
- usr_cmdbuf = start;
- while (usr_cmdbuf < end) {
+ cmdbuf = start;
+ while (cmdbuf < end) {
drm_savage_cmd_header_t cmd_header;
- DRM_COPY_FROM_USER_UNCHECKED(&cmd_header, usr_cmdbuf,
- sizeof(cmd_header));
- usr_cmdbuf++;
+ cmd_header = *cmdbuf;
+ cmdbuf++;
switch (cmd_header.cmd.cmd) {
case SAVAGE_CMD_DMA_PRIM:
- ret =
- savage_dispatch_dma_prim(dev_priv,
- &cmd_header,
- dmabuf);
+ ret = savage_dispatch_dma_prim(
+ dev_priv, &cmd_header, dmabuf);
break;
case SAVAGE_CMD_VB_PRIM:
- ret =
- savage_dispatch_vb_prim(dev_priv,
- &cmd_header,
- (const uint32_t
- __user *)
- usr_vtxbuf, vb_size,
- vb_stride);
+ ret = savage_dispatch_vb_prim(
+ dev_priv, &cmd_header,
+ vtxbuf, vb_size, vb_stride);
break;
case SAVAGE_CMD_DMA_IDX:
j = (cmd_header.idx.count + 3) / 4;
/* j was check in savage_bci_cmdbuf */
- ret =
- savage_dispatch_dma_idx(dev_priv,
- &cmd_header,
- (const uint16_t
- __user *)
- usr_cmdbuf, dmabuf);
- usr_cmdbuf += j;
+ ret = savage_dispatch_dma_idx(dev_priv,
+ &cmd_header, (const uint16_t *)cmdbuf,
+ dmabuf);
+ cmdbuf += j;
break;
case SAVAGE_CMD_VB_IDX:
j = (cmd_header.idx.count + 3) / 4;
/* j was check in savage_bci_cmdbuf */
- ret =
- savage_dispatch_vb_idx(dev_priv,
- &cmd_header,
- (const uint16_t
- __user *)usr_cmdbuf,
- (const uint32_t
- __user *)usr_vtxbuf,
- vb_size, vb_stride);
- usr_cmdbuf += j;
+ ret = savage_dispatch_vb_idx(dev_priv,
+ &cmd_header, (const uint16_t *)cmdbuf,
+ (const uint32_t *)vtxbuf, vb_size,
+ vb_stride);
+ cmdbuf += j;
break;
default:
/* What's the best return code? EFAULT? */
@@ -998,10 +960,10 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
drm_device_dma_t *dma = dev->dma;
drm_buf_t *dmabuf;
drm_savage_cmdbuf_t cmdbuf;
- drm_savage_cmd_header_t __user *usr_cmdbuf;
- drm_savage_cmd_header_t __user *first_draw_cmd;
- unsigned int __user *usr_vtxbuf;
- drm_clip_rect_t __user *usr_boxes;
+ drm_savage_cmd_header_t *kcmd_addr = NULL;
+ drm_savage_cmd_header_t *first_draw_cmd;
+ unsigned int *kvb_addr = NULL;
+ drm_clip_rect_t *kbox_addr = NULL;
unsigned int i, j;
int ret = 0;
@@ -1024,15 +986,53 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
dmabuf = NULL;
}
- usr_cmdbuf = (drm_savage_cmd_header_t __user *) cmdbuf.cmd_addr;
- usr_vtxbuf = (unsigned int __user *)cmdbuf.vb_addr;
- usr_boxes = (drm_clip_rect_t __user *) cmdbuf.box_addr;
- if ((cmdbuf.size && DRM_VERIFYAREA_READ(usr_cmdbuf, cmdbuf.size * 8)) ||
- (cmdbuf.vb_size && DRM_VERIFYAREA_READ(usr_vtxbuf, cmdbuf.vb_size))
- || (cmdbuf.nbox
- && DRM_VERIFYAREA_READ(usr_boxes,
- cmdbuf.nbox * sizeof(drm_clip_rect_t))))
- return DRM_ERR(EFAULT);
+ /* Copy the user buffers into kernel temporary areas. This hasn't been
+ * a performance loss compared to VERIFYAREA_READ/
+ * COPY_FROM_USER_UNCHECKED when done in other drivers, and is correct
+ * for locking on FreeBSD.
+ */
+ if (cmdbuf.size) {
+ kcmd_addr = drm_alloc(cmdbuf.size * 8, DRM_MEM_DRIVER);
+ if (kcmd_addr == NULL)
+ return ENOMEM;
+
+ if (DRM_COPY_FROM_USER(kcmd_addr, cmdbuf.cmd_addr,
+ cmdbuf.size * 8))
+ {
+ drm_free(kcmd_addr, cmdbuf.size * 8, DRM_MEM_DRIVER);
+ return DRM_ERR(EFAULT);
+ }
+ cmdbuf.cmd_addr = kcmd_addr;
+ }
+ if (cmdbuf.vb_size) {
+ kvb_addr = drm_alloc(cmdbuf.vb_size, DRM_MEM_DRIVER);
+ if (kvb_addr == NULL) {
+ ret = DRM_ERR(ENOMEM);
+ goto done;
+ }
+
+ if (DRM_COPY_FROM_USER(kvb_addr, cmdbuf.vb_addr,
+ cmdbuf.vb_size)) {
+ ret = DRM_ERR(EFAULT);
+ goto done;
+ }
+ cmdbuf.vb_addr = kvb_addr;
+ }
+ if (cmdbuf.nbox) {
+ kbox_addr = drm_alloc(cmdbuf.nbox * sizeof(drm_clip_rect_t),
+ DRM_MEM_DRIVER);
+ if (kbox_addr == NULL) {
+ ret = DRM_ERR(ENOMEM);
+ goto done;
+ }
+
+ if (DRM_COPY_FROM_USER(kbox_addr, cmdbuf.box_addr,
+ cmdbuf.nbox * sizeof(drm_clip_rect_t))) {
+ ret = DRM_ERR(EFAULT);
+ goto done;
+ }
+ cmdbuf.box_addr = kbox_addr;
+ }
/* Make sure writes to DMA buffers are finished before sending
* DMA commands to the graphics hardware. */
@@ -1046,9 +1046,8 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
first_draw_cmd = NULL;
while (i < cmdbuf.size) {
drm_savage_cmd_header_t cmd_header;
- DRM_COPY_FROM_USER_UNCHECKED(&cmd_header, usr_cmdbuf,
- sizeof(cmd_header));
- usr_cmdbuf++;
+ cmd_header = *(drm_savage_cmd_header_t *)cmdbuf.cmd_addr;
+ cmdbuf.cmd_addr++;
i++;
/* Group drawing commands with same state to minimize
@@ -1068,21 +1067,18 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
case SAVAGE_CMD_DMA_PRIM:
case SAVAGE_CMD_VB_PRIM:
if (!first_draw_cmd)
- first_draw_cmd = usr_cmdbuf - 1;
- usr_cmdbuf += j;
+ first_draw_cmd = cmdbuf.cmd_addr - 1;
+ cmdbuf.cmd_addr += j;
i += j;
break;
default:
if (first_draw_cmd) {
- ret =
- savage_dispatch_draw(dev_priv,
- first_draw_cmd,
- usr_cmdbuf - 1, dmabuf,
- usr_vtxbuf,
- cmdbuf.vb_size,
- cmdbuf.vb_stride,
- cmdbuf.nbox,
- usr_boxes);
+ ret = savage_dispatch_draw(
+ dev_priv, first_draw_cmd,
+ cmdbuf.cmd_addr - 1,
+ dmabuf, cmdbuf.vb_addr, cmdbuf.vb_size,
+ cmdbuf.vb_stride,
+ cmdbuf.nbox, cmdbuf.box_addr);
if (ret != 0)
return ret;
first_draw_cmd = NULL;
@@ -1098,12 +1094,12 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
DRM_ERROR("command SAVAGE_CMD_STATE extends "
"beyond end of command buffer\n");
DMA_FLUSH();
- return DRM_ERR(EINVAL);
+ ret = DRM_ERR(EINVAL);
+ goto done;
}
ret = savage_dispatch_state(dev_priv, &cmd_header,
- (uint32_t __user *)
- usr_cmdbuf);
- usr_cmdbuf += j;
+ (const uint32_t *)cmdbuf.cmd_addr);
+ cmdbuf.cmd_addr += j;
i += j;
break;
case SAVAGE_CMD_CLEAR:
@@ -1111,39 +1107,40 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
DRM_ERROR("command SAVAGE_CMD_CLEAR extends "
"beyond end of command buffer\n");
DMA_FLUSH();
- return DRM_ERR(EINVAL);
+ ret = DRM_ERR(EINVAL);
+ goto done;
}
ret = savage_dispatch_clear(dev_priv, &cmd_header,
- usr_cmdbuf,
- cmdbuf.nbox, usr_boxes);
- usr_cmdbuf++;
+ cmdbuf.cmd_addr,
+ cmdbuf.nbox, cmdbuf.box_addr);
+ cmdbuf.cmd_addr++;
i++;
break;
case SAVAGE_CMD_SWAP:
- ret = savage_dispatch_swap(dev_priv,
- cmdbuf.nbox, usr_boxes);
+ ret = savage_dispatch_swap(dev_priv, cmdbuf.nbox,
+ cmdbuf.box_addr);
break;
default:
DRM_ERROR("invalid command 0x%x\n", cmd_header.cmd.cmd);
DMA_FLUSH();
- return DRM_ERR(EINVAL);
+ ret = DRM_ERR(EINVAL);
+ goto done;
}
if (ret != 0) {
DMA_FLUSH();
- return ret;
+ goto done;
}
}
if (first_draw_cmd) {
- ret =
- savage_dispatch_draw(dev_priv, first_draw_cmd, usr_cmdbuf,
- dmabuf, usr_vtxbuf, cmdbuf.vb_size,
- cmdbuf.vb_stride, cmdbuf.nbox,
- usr_boxes);
+ ret = savage_dispatch_draw (
+ dev_priv, first_draw_cmd, cmdbuf.cmd_addr, dmabuf,
+ cmdbuf.vb_addr, cmdbuf.vb_size, cmdbuf.vb_stride,
+ cmdbuf.nbox, cmdbuf.box_addr);
if (ret != 0) {
DMA_FLUSH();
- return ret;
+ goto done;
}
}
@@ -1157,5 +1154,12 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
savage_freelist_put(dev, dmabuf);
}
- return 0;
+done:
+ /* If we didn't need to allocate them, these'll be NULL */
+ drm_free(kcmd_addr, cmdbuf.size * 8, DRM_MEM_DRIVER);
+ drm_free(kvb_addr, cmdbuf.vb_size, DRM_MEM_DRIVER);
+ drm_free(kbox_addr, cmdbuf.nbox * sizeof(drm_clip_rect_t),
+ DRM_MEM_DRIVER);
+
+ return ret;
}
diff --git a/drivers/char/drm/sis_drm.h b/drivers/char/drm/sis_drm.h
index 8f273da76ddbd..30f7b38274668 100644
--- a/drivers/char/drm/sis_drm.h
+++ b/drivers/char/drm/sis_drm.h
@@ -1,3 +1,28 @@
+/* sis_drv.h -- Private header for sis driver -*- linux-c -*- */
+/*
+ * Copyright 2005 Eric Anholt
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
#ifndef __SIS_DRM_H__
#define __SIS_DRM_H__
diff --git a/drivers/char/drm/sis_drv.c b/drivers/char/drm/sis_drv.c
index 3cef10643a8f4..6f6d7d613ede7 100644
--- a/drivers/char/drm/sis_drv.c
+++ b/drivers/char/drm/sis_drv.c
@@ -32,31 +32,6 @@
#include "drm_pciids.h"
-static int postinit(struct drm_device *dev, unsigned long flags)
-{
- DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
- DRIVER_NAME,
- DRIVER_MAJOR,
- DRIVER_MINOR,
- DRIVER_PATCHLEVEL,
- DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
- );
- return 0;
-}
-
-static int version(drm_version_t * version)
-{
- int len;
-
- version->version_major = DRIVER_MAJOR;
- version->version_minor = DRIVER_MINOR;
- version->version_patchlevel = DRIVER_PATCHLEVEL;
- DRM_COPY(version->name, DRIVER_NAME);
- DRM_COPY(version->date, DRIVER_DATE);
- DRM_COPY(version->desc, DRIVER_DESC);
- return 0;
-}
-
static struct pci_device_id pciidlist[] = {
sisdrv_PCI_IDS
};
@@ -68,8 +43,6 @@ static struct drm_driver driver = {
.reclaim_buffers = drm_core_reclaim_buffers,
.get_map_ofs = drm_core_get_map_ofs,
.get_reg_ofs = drm_core_get_reg_ofs,
- .postinit = postinit,
- .version = version,
.ioctls = sis_ioctls,
.fops = {
.owner = THIS_MODULE,
@@ -79,11 +52,18 @@ static struct drm_driver driver = {
.mmap = drm_mmap,
.poll = drm_poll,
.fasync = drm_fasync,
- },
+ },
.pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
- }
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ },
+
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESC,
+ .date = DRIVER_DATE,
+ .major = DRIVER_MAJOR,
+ .minor = DRIVER_MINOR,
+ .patchlevel = DRIVER_PATCHLEVEL,
};
static int __init sis_init(void)
diff --git a/drivers/char/drm/sis_drv.h b/drivers/char/drm/sis_drv.h
index b1fddad83a936..e218e5269503b 100644
--- a/drivers/char/drm/sis_drv.h
+++ b/drivers/char/drm/sis_drv.h
@@ -1,5 +1,5 @@
-/* sis_drv.h -- Private header for sis driver -*- linux-c -*-
- *
+/* sis_drv.h -- Private header for sis driver -*- linux-c -*- */
+/*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All rights reserved.
diff --git a/drivers/char/drm/sis_ds.h b/drivers/char/drm/sis_ds.h
index da850b4f5440a..94f2b4728b638 100644
--- a/drivers/char/drm/sis_ds.h
+++ b/drivers/char/drm/sis_ds.h
@@ -1,6 +1,7 @@
-/* sis_ds.h -- Private header for Direct Rendering Manager -*- linux-c -*-
+/* sis_ds.h -- Private header for Direct Rendering Manager -*- linux-c -*-
* Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw
- *
+ */
+/*
* Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
* All rights reserved.
*
@@ -35,7 +36,7 @@
#define SET_SIZE 5000
-typedef unsigned int ITEM_TYPE;
+typedef unsigned long ITEM_TYPE;
typedef struct {
ITEM_TYPE val;
diff --git a/drivers/char/drm/sis_mm.c b/drivers/char/drm/sis_mm.c
index a8529728fa635..6774d2fe3452c 100644
--- a/drivers/char/drm/sis_mm.c
+++ b/drivers/char/drm/sis_mm.c
@@ -86,7 +86,7 @@ static int sis_fb_alloc(DRM_IOCTL_ARGS)
{
drm_sis_mem_t fb;
struct sis_memreq req;
- drm_sis_mem_t __user *argp = (void __user *)data;
+ drm_sis_mem_t __user *argp = (drm_sis_mem_t __user *)data;
int retval = 0;
DRM_COPY_FROM_USER_IOCTL(fb, argp, sizeof(fb));
@@ -110,7 +110,7 @@ static int sis_fb_alloc(DRM_IOCTL_ARGS)
DRM_COPY_TO_USER_IOCTL(argp, fb, sizeof(fb));
- DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb.size, req.offset);
+ DRM_DEBUG("alloc fb, size = %d, offset = %ld\n", fb.size, req.offset);
return retval;
}
@@ -127,9 +127,9 @@ static int sis_fb_free(DRM_IOCTL_ARGS)
if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free))
retval = DRM_ERR(EINVAL);
- sis_free((u32) fb.free);
+ sis_free(fb.free);
- DRM_DEBUG("free fb, offset = %lu\n", fb.free);
+ DRM_DEBUG("free fb, offset = 0x%lx\n", fb.free);
return retval;
}
@@ -176,7 +176,7 @@ static int sis_fb_alloc(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_sis_private_t *dev_priv = dev->dev_private;
- drm_sis_mem_t __user *argp = (void __user *)data;
+ drm_sis_mem_t __user *argp = (drm_sis_mem_t __user *)data;
drm_sis_mem_t fb;
PMemBlock block;
int retval = 0;
@@ -267,7 +267,7 @@ static int sis_ioctl_agp_alloc(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_sis_private_t *dev_priv = dev->dev_private;
- drm_sis_mem_t __user *argp = (void __user *)data;
+ drm_sis_mem_t __user *argp = (drm_sis_mem_t __user *)data;
drm_sis_mem_t agp;
PMemBlock block;
int retval = 0;
@@ -367,7 +367,7 @@ int sis_final_context(struct drm_device *dev, int context)
if (i < MAX_CONTEXT) {
set_t *set;
- unsigned int item;
+ ITEM_TYPE item;
int retval;
DRM_DEBUG("find socket %d, context = %d\n", i, context);
@@ -376,7 +376,7 @@ int sis_final_context(struct drm_device *dev, int context)
set = global_ppriv[i].sets[0];
retval = setFirst(set, &item);
while (retval) {
- DRM_DEBUG("free video memory 0x%x\n", item);
+ DRM_DEBUG("free video memory 0x%lx\n", item);
#if defined(__linux__) && defined(CONFIG_FB_SIS)
sis_free(item);
#else
@@ -390,7 +390,7 @@ int sis_final_context(struct drm_device *dev, int context)
set = global_ppriv[i].sets[1];
retval = setFirst(set, &item);
while (retval) {
- DRM_DEBUG("free agp memory 0x%x\n", item);
+ DRM_DEBUG("free agp memory 0x%lx\n", item);
mmFreeMem((PMemBlock) item);
retval = setNext(set, &item);
}
@@ -403,12 +403,12 @@ int sis_final_context(struct drm_device *dev, int context)
}
drm_ioctl_desc_t sis_ioctls[] = {
- [DRM_IOCTL_NR(DRM_SIS_FB_ALLOC)] = {sis_fb_alloc, 1, 0},
- [DRM_IOCTL_NR(DRM_SIS_FB_FREE)] = {sis_fb_free, 1, 0},
- [DRM_IOCTL_NR(DRM_SIS_AGP_INIT)] = {sis_ioctl_agp_init, 1, 1},
- [DRM_IOCTL_NR(DRM_SIS_AGP_ALLOC)] = {sis_ioctl_agp_alloc, 1, 0},
- [DRM_IOCTL_NR(DRM_SIS_AGP_FREE)] = {sis_ioctl_agp_free, 1, 0},
- [DRM_IOCTL_NR(DRM_SIS_FB_INIT)] = {sis_fb_init, 1, 1}
+ [DRM_IOCTL_NR(DRM_SIS_FB_ALLOC)] = {sis_fb_alloc, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_SIS_FB_FREE)] = {sis_fb_free, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_SIS_AGP_INIT)] = {sis_ioctl_agp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_SIS_AGP_ALLOC)] = {sis_ioctl_agp_alloc, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_SIS_AGP_FREE)] = {sis_ioctl_agp_free, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_SIS_FB_INIT)] = {sis_fb_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}
};
int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls);
diff --git a/drivers/char/drm/tdfx_drv.c b/drivers/char/drm/tdfx_drv.c
index c275cbb6e9ce2..baa4416032a82 100644
--- a/drivers/char/drm/tdfx_drv.c
+++ b/drivers/char/drm/tdfx_drv.c
@@ -36,31 +36,6 @@
#include "drm_pciids.h"
-static int postinit(struct drm_device *dev, unsigned long flags)
-{
- DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
- DRIVER_NAME,
- DRIVER_MAJOR,
- DRIVER_MINOR,
- DRIVER_PATCHLEVEL,
- DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
- );
- return 0;
-}
-
-static int version(drm_version_t * version)
-{
- int len;
-
- version->version_major = DRIVER_MAJOR;
- version->version_minor = DRIVER_MINOR;
- version->version_patchlevel = DRIVER_PATCHLEVEL;
- DRM_COPY(version->name, DRIVER_NAME);
- DRM_COPY(version->date, DRIVER_DATE);
- DRM_COPY(version->desc, DRIVER_DESC);
- return 0;
-}
-
static struct pci_device_id pciidlist[] = {
tdfx_PCI_IDS
};
@@ -70,8 +45,6 @@ static struct drm_driver driver = {
.reclaim_buffers = drm_core_reclaim_buffers,
.get_map_ofs = drm_core_get_map_ofs,
.get_reg_ofs = drm_core_get_reg_ofs,
- .postinit = postinit,
- .version = version,
.fops = {
.owner = THIS_MODULE,
.open = drm_open,
@@ -80,11 +53,18 @@ static struct drm_driver driver = {
.mmap = drm_mmap,
.poll = drm_poll,
.fasync = drm_fasync,
- },
+ },
.pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
- }
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ },
+
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESC,
+ .date = DRIVER_DATE,
+ .major = DRIVER_MAJOR,
+ .minor = DRIVER_MINOR,
+ .patchlevel = DRIVER_PATCHLEVEL,
};
static int __init tdfx_init(void)
diff --git a/drivers/char/drm/tdfx_drv.h b/drivers/char/drm/tdfx_drv.h
index a582a3db4c752..84204ec1b046b 100644
--- a/drivers/char/drm/tdfx_drv.h
+++ b/drivers/char/drm/tdfx_drv.h
@@ -1,6 +1,7 @@
/* tdfx.h -- 3dfx DRM template customization -*- linux-c -*-
* Created: Wed Feb 14 12:32:32 2001 by gareth@valinux.com
- *
+ */
+/*
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
@@ -30,10 +31,6 @@
#ifndef __TDFX_H__
#define __TDFX_H__
-/* This remains constant for all DRM template files.
- */
-#define DRM(x) tdfx_##x
-
/* General customization:
*/
diff --git a/drivers/char/drm/via_dma.c b/drivers/char/drm/via_dma.c
index d4b1766608b0e..593c0b8f650a9 100644
--- a/drivers/char/drm/via_dma.c
+++ b/drivers/char/drm/via_dma.c
@@ -213,7 +213,9 @@ static int via_initialize(drm_device_t * dev,
dev_priv->dma_wrap = init->size;
dev_priv->dma_offset = init->offset;
dev_priv->last_pause_ptr = NULL;
- dev_priv->hw_addr_ptr = dev_priv->mmio->handle + init->reg_pause_addr;
+ dev_priv->hw_addr_ptr =
+ (volatile uint32_t *)((char *)dev_priv->mmio->handle +
+ init->reg_pause_addr);
via_cmdbuf_start(dev_priv);
@@ -232,13 +234,13 @@ int via_dma_init(DRM_IOCTL_ARGS)
switch (init.func) {
case VIA_INIT_DMA:
- if (!capable(CAP_SYS_ADMIN))
+ if (!DRM_SUSER(DRM_CURPROC))
retcode = DRM_ERR(EPERM);
else
retcode = via_initialize(dev, dev_priv, &init);
break;
case VIA_CLEANUP_DMA:
- if (!capable(CAP_SYS_ADMIN))
+ if (!DRM_SUSER(DRM_CURPROC))
retcode = DRM_ERR(EPERM);
else
retcode = via_dma_cleanup(dev);
@@ -349,9 +351,6 @@ int via_cmdbuffer(DRM_IOCTL_ARGS)
return 0;
}
-extern int
-via_parse_command_stream(drm_device_t * dev, const uint32_t * buf,
- unsigned int size);
static int via_dispatch_pci_cmdbuffer(drm_device_t * dev,
drm_via_cmdbuffer_t * cmd)
{
@@ -450,9 +449,9 @@ static int via_hook_segment(drm_via_private_t * dev_priv,
if ((count <= 8) && (count >= 0)) {
uint32_t rgtr, ptr;
rgtr = *(dev_priv->hw_addr_ptr);
- ptr = ((char *)dev_priv->last_pause_ptr - dev_priv->dma_ptr) +
- dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4 -
- CMDBUF_ALIGNMENT_SIZE;
+ ptr = ((volatile char *)dev_priv->last_pause_ptr -
+ dev_priv->dma_ptr) + dev_priv->dma_offset +
+ (uint32_t) dev_priv->agpAddr + 4 - CMDBUF_ALIGNMENT_SIZE;
if (rgtr <= ptr) {
DRM_ERROR
("Command regulator\npaused at count %d, address %x, "
@@ -472,7 +471,7 @@ static int via_hook_segment(drm_via_private_t * dev_priv,
&& count--) ;
rgtr = *(dev_priv->hw_addr_ptr);
- ptr = ((char *)paused_at - dev_priv->dma_ptr) +
+ ptr = ((volatile char *)paused_at - dev_priv->dma_ptr) +
dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4;
ptr_low = (ptr > 3 * CMDBUF_ALIGNMENT_SIZE) ?
@@ -724,3 +723,22 @@ int via_cmdbuf_size(DRM_IOCTL_ARGS)
sizeof(d_siz));
return ret;
}
+
+drm_ioctl_desc_t via_ioctls[] = {
+ [DRM_IOCTL_NR(DRM_VIA_ALLOCMEM)] = {via_mem_alloc, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_VIA_FREEMEM)] = {via_mem_free, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_VIA_AGP_INIT)] = {via_agp_init, DRM_AUTH|DRM_MASTER},
+ [DRM_IOCTL_NR(DRM_VIA_FB_INIT)] = {via_fb_init, DRM_AUTH|DRM_MASTER},
+ [DRM_IOCTL_NR(DRM_VIA_MAP_INIT)] = {via_map_init, DRM_AUTH|DRM_MASTER},
+ [DRM_IOCTL_NR(DRM_VIA_DEC_FUTEX)] = {via_decoder_futex, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_VIA_DMA_INIT)] = {via_dma_init, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_VIA_CMDBUFFER)] = {via_cmdbuffer, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_VIA_FLUSH)] = {via_flush_ioctl, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_VIA_PCICMD)] = {via_pci_cmdbuffer, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_VIA_CMDBUF_SIZE)] = {via_cmdbuf_size, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_VIA_WAIT_IRQ)] = {via_wait_irq, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_VIA_DMA_BLIT)] = {via_dma_blit, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_VIA_BLIT_SYNC)] = {via_dma_blit_sync, DRM_AUTH}
+};
+
+int via_max_ioctl = DRM_ARRAY_SIZE(via_ioctls);
diff --git a/drivers/char/drm/via_dmablit.c b/drivers/char/drm/via_dmablit.c
new file mode 100644
index 0000000000000..9d5e027dae0e2
--- /dev/null
+++ b/drivers/char/drm/via_dmablit.c
@@ -0,0 +1,805 @@
+/* via_dmablit.c -- PCI DMA BitBlt support for the VIA Unichrome/Pro
+ *
+ * Copyright (C) 2005 Thomas Hellstrom, All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Thomas Hellstrom.
+ * Partially based on code obtained from Digeo Inc.
+ */
+
+
+/*
+ * Unmaps the DMA mappings.
+ * FIXME: Is this a NoOp on x86? Also
+ * FIXME: What happens if this one is called and a pending blit has previously done
+ * the same DMA mappings?
+ */
+
+#include "drmP.h"
+#include "via_drm.h"
+#include "via_drv.h"
+#include "via_dmablit.h"
+
+#include <linux/pagemap.h>
+
+#define VIA_PGDN(x) (((unsigned long)(x)) & PAGE_MASK)
+#define VIA_PGOFF(x) (((unsigned long)(x)) & ~PAGE_MASK)
+#define VIA_PFN(x) ((unsigned long)(x) >> PAGE_SHIFT)
+
+typedef struct _drm_via_descriptor {
+ uint32_t mem_addr;
+ uint32_t dev_addr;
+ uint32_t size;
+ uint32_t next;
+} drm_via_descriptor_t;
+
+
+/*
+ * Unmap a DMA mapping.
+ */
+
+
+
+static void
+via_unmap_blit_from_device(struct pci_dev *pdev, drm_via_sg_info_t *vsg)
+{
+ int num_desc = vsg->num_desc;
+ unsigned cur_descriptor_page = num_desc / vsg->descriptors_per_page;
+ unsigned descriptor_this_page = num_desc % vsg->descriptors_per_page;
+ drm_via_descriptor_t *desc_ptr = vsg->desc_pages[cur_descriptor_page] +
+ descriptor_this_page;
+ dma_addr_t next = vsg->chain_start;
+
+ while(num_desc--) {
+ if (descriptor_this_page-- == 0) {
+ cur_descriptor_page--;
+ descriptor_this_page = vsg->descriptors_per_page - 1;
+ desc_ptr = vsg->desc_pages[cur_descriptor_page] +
+ descriptor_this_page;
+ }
+ dma_unmap_single(&pdev->dev, next, sizeof(*desc_ptr), DMA_TO_DEVICE);
+ dma_unmap_page(&pdev->dev, desc_ptr->mem_addr, desc_ptr->size, vsg->direction);
+ next = (dma_addr_t) desc_ptr->next;
+ desc_ptr--;
+ }
+}
+
+/*
+ * If mode = 0, count how many descriptors are needed.
+ * If mode = 1, Map the DMA pages for the device, put together and map also the descriptors.
+ * Descriptors are run in reverse order by the hardware because we are not allowed to update the
+ * 'next' field without syncing calls when the descriptor is already mapped.
+ */
+
+static void
+via_map_blit_for_device(struct pci_dev *pdev,
+ const drm_via_dmablit_t *xfer,
+ drm_via_sg_info_t *vsg,
+ int mode)
+{
+ unsigned cur_descriptor_page = 0;
+ unsigned num_descriptors_this_page = 0;
+ unsigned char *mem_addr = xfer->mem_addr;
+ unsigned char *cur_mem;
+ unsigned char *first_addr = (unsigned char *)VIA_PGDN(mem_addr);
+ uint32_t fb_addr = xfer->fb_addr;
+ uint32_t cur_fb;
+ unsigned long line_len;
+ unsigned remaining_len;
+ int num_desc = 0;
+ int cur_line;
+ dma_addr_t next = 0 | VIA_DMA_DPR_EC;
+ drm_via_descriptor_t *desc_ptr = 0;
+
+ if (mode == 1)
+ desc_ptr = vsg->desc_pages[cur_descriptor_page];
+
+ for (cur_line = 0; cur_line < xfer->num_lines; ++cur_line) {
+
+ line_len = xfer->line_length;
+ cur_fb = fb_addr;
+ cur_mem = mem_addr;
+
+ while (line_len > 0) {
+
+ remaining_len = min(PAGE_SIZE-VIA_PGOFF(cur_mem), line_len);
+ line_len -= remaining_len;
+
+ if (mode == 1) {
+ desc_ptr->mem_addr =
+ dma_map_page(&pdev->dev,
+ vsg->pages[VIA_PFN(cur_mem) -
+ VIA_PFN(first_addr)],
+ VIA_PGOFF(cur_mem), remaining_len,
+ vsg->direction);
+ desc_ptr->dev_addr = cur_fb;
+
+ desc_ptr->size = remaining_len;
+ desc_ptr->next = (uint32_t) next;
+ next = dma_map_single(&pdev->dev, desc_ptr, sizeof(*desc_ptr),
+ DMA_TO_DEVICE);
+ desc_ptr++;
+ if (++num_descriptors_this_page >= vsg->descriptors_per_page) {
+ num_descriptors_this_page = 0;
+ desc_ptr = vsg->desc_pages[++cur_descriptor_page];
+ }
+ }
+
+ num_desc++;
+ cur_mem += remaining_len;
+ cur_fb += remaining_len;
+ }
+
+ mem_addr += xfer->mem_stride;
+ fb_addr += xfer->fb_stride;
+ }
+
+ if (mode == 1) {
+ vsg->chain_start = next;
+ vsg->state = dr_via_device_mapped;
+ }
+ vsg->num_desc = num_desc;
+}
+
+/*
+ * Function that frees up all resources for a blit. It is usable even if the
+ * blit info has only be partially built as long as the status enum is consistent
+ * with the actual status of the used resources.
+ */
+
+
+void
+via_free_sg_info(struct pci_dev *pdev, drm_via_sg_info_t *vsg)
+{
+ struct page *page;
+ int i;
+
+ switch(vsg->state) {
+ case dr_via_device_mapped:
+ via_unmap_blit_from_device(pdev, vsg);
+ case dr_via_desc_pages_alloc:
+ for (i=0; i<vsg->num_desc_pages; ++i) {
+ if (vsg->desc_pages[i] != NULL)
+ free_page((unsigned long)vsg->desc_pages[i]);
+ }
+ kfree(vsg->desc_pages);
+ case dr_via_pages_locked:
+ for (i=0; i<vsg->num_pages; ++i) {
+ if ( NULL != (page = vsg->pages[i])) {
+ if (! PageReserved(page) && (DMA_FROM_DEVICE == vsg->direction))
+ SetPageDirty(page);
+ page_cache_release(page);
+ }
+ }
+ case dr_via_pages_alloc:
+ vfree(vsg->pages);
+ default:
+ vsg->state = dr_via_sg_init;
+ }
+ if (vsg->bounce_buffer) {
+ vfree(vsg->bounce_buffer);
+ vsg->bounce_buffer = NULL;
+ }
+ vsg->free_on_sequence = 0;
+}
+
+/*
+ * Fire a blit engine.
+ */
+
+static void
+via_fire_dmablit(drm_device_t *dev, drm_via_sg_info_t *vsg, int engine)
+{
+ drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
+
+ VIA_WRITE(VIA_PCI_DMA_MAR0 + engine*0x10, 0);
+ VIA_WRITE(VIA_PCI_DMA_DAR0 + engine*0x10, 0);
+ VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_DD | VIA_DMA_CSR_TD |
+ VIA_DMA_CSR_DE);
+ VIA_WRITE(VIA_PCI_DMA_MR0 + engine*0x04, VIA_DMA_MR_CM | VIA_DMA_MR_TDIE);
+ VIA_WRITE(VIA_PCI_DMA_BCR0 + engine*0x10, 0);
+ VIA_WRITE(VIA_PCI_DMA_DPR0 + engine*0x10, vsg->chain_start);
+ VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_DE | VIA_DMA_CSR_TS);
+}
+
+/*
+ * Obtain a page pointer array and lock all pages into system memory. A segmentation violation will
+ * occur here if the calling user does not have access to the submitted address.
+ */
+
+static int
+via_lock_all_dma_pages(drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer)
+{
+ int ret;
+ unsigned long first_pfn = VIA_PFN(xfer->mem_addr);
+ vsg->num_pages = VIA_PFN(xfer->mem_addr + (xfer->num_lines * xfer->mem_stride -1)) -
+ first_pfn + 1;
+
+ if (NULL == (vsg->pages = vmalloc(sizeof(struct page *) * vsg->num_pages)))
+ return DRM_ERR(ENOMEM);
+ memset(vsg->pages, 0, sizeof(struct page *) * vsg->num_pages);
+ down_read(&current->mm->mmap_sem);
+ ret = get_user_pages(current, current->mm, (unsigned long) xfer->mem_addr,
+ vsg->num_pages, vsg->direction, 0, vsg->pages, NULL);
+
+ up_read(&current->mm->mmap_sem);
+ if (ret != vsg->num_pages) {
+ if (ret < 0)
+ return ret;
+ vsg->state = dr_via_pages_locked;
+ return DRM_ERR(EINVAL);
+ }
+ vsg->state = dr_via_pages_locked;
+ DRM_DEBUG("DMA pages locked\n");
+ return 0;
+}
+
+/*
+ * Allocate DMA capable memory for the blit descriptor chain, and an array that keeps track of the
+ * pages we allocate. We don't want to use kmalloc for the descriptor chain because it may be
+ * quite large for some blits, and pages don't need to be contingous.
+ */
+
+static int
+via_alloc_desc_pages(drm_via_sg_info_t *vsg)
+{
+ int i;
+
+ vsg->descriptors_per_page = PAGE_SIZE / sizeof( drm_via_descriptor_t);
+ vsg->num_desc_pages = (vsg->num_desc + vsg->descriptors_per_page - 1) /
+ vsg->descriptors_per_page;
+
+ if (NULL == (vsg->desc_pages = kmalloc(sizeof(void *) * vsg->num_desc_pages, GFP_KERNEL)))
+ return DRM_ERR(ENOMEM);
+
+ memset(vsg->desc_pages, 0, sizeof(void *) * vsg->num_desc_pages);
+ vsg->state = dr_via_desc_pages_alloc;
+ for (i=0; i<vsg->num_desc_pages; ++i) {
+ if (NULL == (vsg->desc_pages[i] =
+ (drm_via_descriptor_t *) __get_free_page(GFP_KERNEL)))
+ return DRM_ERR(ENOMEM);
+ }
+ DRM_DEBUG("Allocated %d pages for %d descriptors.\n", vsg->num_desc_pages,
+ vsg->num_desc);
+ return 0;
+}
+
+static void
+via_abort_dmablit(drm_device_t *dev, int engine)
+{
+ drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
+
+ VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_TA);
+}
+
+static void
+via_dmablit_engine_off(drm_device_t *dev, int engine)
+{
+ drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
+
+ VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_TD | VIA_DMA_CSR_DD);
+}
+
+
+
+/*
+ * The dmablit part of the IRQ handler. Trying to do only reasonably fast things here.
+ * The rest, like unmapping and freeing memory for done blits is done in a separate workqueue
+ * task. Basically the task of the interrupt handler is to submit a new blit to the engine, while
+ * the workqueue task takes care of processing associated with the old blit.
+ */
+
+void
+via_dmablit_handler(drm_device_t *dev, int engine, int from_irq)
+{
+ drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
+ drm_via_blitq_t *blitq = dev_priv->blit_queues + engine;
+ int cur;
+ int done_transfer;
+ unsigned long irqsave=0;
+ uint32_t status = 0;
+
+ DRM_DEBUG("DMA blit handler called. engine = %d, from_irq = %d, blitq = 0x%lx\n",
+ engine, from_irq, (unsigned long) blitq);
+
+ if (from_irq) {
+ spin_lock(&blitq->blit_lock);
+ } else {
+ spin_lock_irqsave(&blitq->blit_lock, irqsave);
+ }
+
+ done_transfer = blitq->is_active &&
+ (( status = VIA_READ(VIA_PCI_DMA_CSR0 + engine*0x04)) & VIA_DMA_CSR_TD);
+ done_transfer = done_transfer || ( blitq->aborting && !(status & VIA_DMA_CSR_DE));
+
+ cur = blitq->cur;
+ if (done_transfer) {
+
+ blitq->blits[cur]->aborted = blitq->aborting;
+ blitq->done_blit_handle++;
+ DRM_WAKEUP(blitq->blit_queue + cur);
+
+ cur++;
+ if (cur >= VIA_NUM_BLIT_SLOTS)
+ cur = 0;
+ blitq->cur = cur;
+
+ /*
+ * Clear transfer done flag.
+ */
+
+ VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_TD);
+
+ blitq->is_active = 0;
+ blitq->aborting = 0;
+ schedule_work(&blitq->wq);
+
+ } else if (blitq->is_active && time_after_eq(jiffies, blitq->end)) {
+
+ /*
+ * Abort transfer after one second.
+ */
+
+ via_abort_dmablit(dev, engine);
+ blitq->aborting = 1;
+ blitq->end = jiffies + DRM_HZ;
+ }
+
+ if (!blitq->is_active) {
+ if (blitq->num_outstanding) {
+ via_fire_dmablit(dev, blitq->blits[cur], engine);
+ blitq->is_active = 1;
+ blitq->cur = cur;
+ blitq->num_outstanding--;
+ blitq->end = jiffies + DRM_HZ;
+ if (!timer_pending(&blitq->poll_timer)) {
+ blitq->poll_timer.expires = jiffies+1;
+ add_timer(&blitq->poll_timer);
+ }
+ } else {
+ if (timer_pending(&blitq->poll_timer)) {
+ del_timer(&blitq->poll_timer);
+ }
+ via_dmablit_engine_off(dev, engine);
+ }
+ }
+
+ if (from_irq) {
+ spin_unlock(&blitq->blit_lock);
+ } else {
+ spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
+ }
+}
+
+
+
+/*
+ * Check whether this blit is still active, performing necessary locking.
+ */
+
+static int
+via_dmablit_active(drm_via_blitq_t *blitq, int engine, uint32_t handle, wait_queue_head_t **queue)
+{
+ unsigned long irqsave;
+ uint32_t slot;
+ int active;
+
+ spin_lock_irqsave(&blitq->blit_lock, irqsave);
+
+ /*
+ * Allow for handle wraparounds.
+ */
+
+ active = ((blitq->done_blit_handle - handle) > (1 << 23)) &&
+ ((blitq->cur_blit_handle - handle) <= (1 << 23));
+
+ if (queue && active) {
+ slot = handle - blitq->done_blit_handle + blitq->cur -1;
+ if (slot >= VIA_NUM_BLIT_SLOTS) {
+ slot -= VIA_NUM_BLIT_SLOTS;
+ }
+ *queue = blitq->blit_queue + slot;
+ }
+
+ spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
+
+ return active;
+}
+
+/*
+ * Sync. Wait for at least three seconds for the blit to be performed.
+ */
+
+static int
+via_dmablit_sync(drm_device_t *dev, uint32_t handle, int engine)
+{
+
+ drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
+ drm_via_blitq_t *blitq = dev_priv->blit_queues + engine;
+ wait_queue_head_t *queue;
+ int ret = 0;
+
+ if (via_dmablit_active(blitq, engine, handle, &queue)) {
+ DRM_WAIT_ON(ret, *queue, 3 * DRM_HZ,
+ !via_dmablit_active(blitq, engine, handle, NULL));
+ }
+ DRM_DEBUG("DMA blit sync handle 0x%x engine %d returned %d\n",
+ handle, engine, ret);
+
+ return ret;
+}
+
+
+/*
+ * A timer that regularly polls the blit engine in cases where we don't have interrupts:
+ * a) Broken hardware (typically those that don't have any video capture facility).
+ * b) Blit abort. The hardware doesn't send an interrupt when a blit is aborted.
+ * The timer and hardware IRQ's can and do work in parallel. If the hardware has
+ * irqs, it will shorten the latency somewhat.
+ */
+
+
+
+static void
+via_dmablit_timer(unsigned long data)
+{
+ drm_via_blitq_t *blitq = (drm_via_blitq_t *) data;
+ drm_device_t *dev = blitq->dev;
+ int engine = (int)
+ (blitq - ((drm_via_private_t *)dev->dev_private)->blit_queues);
+
+ DRM_DEBUG("Polling timer called for engine %d, jiffies %lu\n", engine,
+ (unsigned long) jiffies);
+
+ via_dmablit_handler(dev, engine, 0);
+
+ if (!timer_pending(&blitq->poll_timer)) {
+ blitq->poll_timer.expires = jiffies+1;
+ add_timer(&blitq->poll_timer);
+ }
+ via_dmablit_handler(dev, engine, 0);
+
+}
+
+
+
+
+/*
+ * Workqueue task that frees data and mappings associated with a blit.
+ * Also wakes up waiting processes. Each of these tasks handles one
+ * blit engine only and may not be called on each interrupt.
+ */
+
+
+static void
+via_dmablit_workqueue(void *data)
+{
+ drm_via_blitq_t *blitq = (drm_via_blitq_t *) data;
+ drm_device_t *dev = blitq->dev;
+ unsigned long irqsave;
+ drm_via_sg_info_t *cur_sg;
+ int cur_released;
+
+
+ DRM_DEBUG("Workqueue task called for blit engine %ld\n",(unsigned long)
+ (blitq - ((drm_via_private_t *)dev->dev_private)->blit_queues));
+
+ spin_lock_irqsave(&blitq->blit_lock, irqsave);
+
+ while(blitq->serviced != blitq->cur) {
+
+ cur_released = blitq->serviced++;
+
+ DRM_DEBUG("Releasing blit slot %d\n", cur_released);
+
+ if (blitq->serviced >= VIA_NUM_BLIT_SLOTS)
+ blitq->serviced = 0;
+
+ cur_sg = blitq->blits[cur_released];
+ blitq->num_free++;
+
+ spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
+
+ DRM_WAKEUP(&blitq->busy_queue);
+
+ via_free_sg_info(dev->pdev, cur_sg);
+ kfree(cur_sg);
+
+ spin_lock_irqsave(&blitq->blit_lock, irqsave);
+ }
+
+ spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
+}
+
+
+/*
+ * Init all blit engines. Currently we use two, but some hardware have 4.
+ */
+
+
+void
+via_init_dmablit(drm_device_t *dev)
+{
+ int i,j;
+ drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
+ drm_via_blitq_t *blitq;
+
+ pci_set_master(dev->pdev);
+
+ for (i=0; i< VIA_NUM_BLIT_ENGINES; ++i) {
+ blitq = dev_priv->blit_queues + i;
+ blitq->dev = dev;
+ blitq->cur_blit_handle = 0;
+ blitq->done_blit_handle = 0;
+ blitq->head = 0;
+ blitq->cur = 0;
+ blitq->serviced = 0;
+ blitq->num_free = VIA_NUM_BLIT_SLOTS;
+ blitq->num_outstanding = 0;
+ blitq->is_active = 0;
+ blitq->aborting = 0;
+ blitq->blit_lock = SPIN_LOCK_UNLOCKED;
+ for (j=0; j<VIA_NUM_BLIT_SLOTS; ++j) {
+ DRM_INIT_WAITQUEUE(blitq->blit_queue + j);
+ }
+ DRM_INIT_WAITQUEUE(&blitq->busy_queue);
+ INIT_WORK(&blitq->wq, via_dmablit_workqueue, blitq);
+ init_timer(&blitq->poll_timer);
+ blitq->poll_timer.function = &via_dmablit_timer;
+ blitq->poll_timer.data = (unsigned long) blitq;
+ }
+}
+
+/*
+ * Build all info and do all mappings required for a blit.
+ */
+
+
+static int
+via_build_sg_info(drm_device_t *dev, drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer)
+{
+ int draw = xfer->to_fb;
+ int ret = 0;
+
+ vsg->direction = (draw) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+ vsg->bounce_buffer = 0;
+
+ vsg->state = dr_via_sg_init;
+
+ if (xfer->num_lines <= 0 || xfer->line_length <= 0) {
+ DRM_ERROR("Zero size bitblt.\n");
+ return DRM_ERR(EINVAL);
+ }
+
+ /*
+ * Below check is a driver limitation, not a hardware one. We
+ * don't want to lock unused pages, and don't want to incoporate the
+ * extra logic of avoiding them. Make sure there are no.
+ * (Not a big limitation anyway.)
+ */
+
+ if (((xfer->mem_stride - xfer->line_length) >= PAGE_SIZE) ||
+ (xfer->mem_stride > 2048*4)) {
+ DRM_ERROR("Too large system memory stride. Stride: %d, "
+ "Length: %d\n", xfer->mem_stride, xfer->line_length);
+ return DRM_ERR(EINVAL);
+ }
+
+ if (xfer->num_lines > 2048) {
+ DRM_ERROR("Too many PCI DMA bitblt lines.\n");
+ return DRM_ERR(EINVAL);
+ }
+
+ /*
+ * we allow a negative fb stride to allow flipping of images in
+ * transfer.
+ */
+
+ if (xfer->mem_stride < xfer->line_length ||
+ abs(xfer->fb_stride) < xfer->line_length) {
+ DRM_ERROR("Invalid frame-buffer / memory stride.\n");
+ return DRM_ERR(EINVAL);
+ }
+
+ /*
+ * A hardware bug seems to be worked around if system memory addresses start on
+ * 16 byte boundaries. This seems a bit restrictive however. VIA is contacted
+ * about this. Meanwhile, impose the following restrictions:
+ */
+
+#ifdef VIA_BUGFREE
+ if ((((unsigned long)xfer->mem_addr & 3) != ((unsigned long)xfer->fb_addr & 3)) ||
+ ((xfer->mem_stride & 3) != (xfer->fb_stride & 3))) {
+ DRM_ERROR("Invalid DRM bitblt alignment.\n");
+ return DRM_ERR(EINVAL);
+ }
+#else
+ if ((((unsigned long)xfer->mem_addr & 15) ||
+ ((unsigned long)xfer->fb_addr & 3)) || (xfer->mem_stride & 15) ||
+ (xfer->fb_stride & 3)) {
+ DRM_ERROR("Invalid DRM bitblt alignment.\n");
+ return DRM_ERR(EINVAL);
+ }
+#endif
+
+ if (0 != (ret = via_lock_all_dma_pages(vsg, xfer))) {
+ DRM_ERROR("Could not lock DMA pages.\n");
+ via_free_sg_info(dev->pdev, vsg);
+ return ret;
+ }
+
+ via_map_blit_for_device(dev->pdev, xfer, vsg, 0);
+ if (0 != (ret = via_alloc_desc_pages(vsg))) {
+ DRM_ERROR("Could not allocate DMA descriptor pages.\n");
+ via_free_sg_info(dev->pdev, vsg);
+ return ret;
+ }
+ via_map_blit_for_device(dev->pdev, xfer, vsg, 1);
+
+ return 0;
+}
+
+
+/*
+ * Reserve one free slot in the blit queue. Will wait for one second for one
+ * to become available. Otherwise -EBUSY is returned.
+ */
+
+static int
+via_dmablit_grab_slot(drm_via_blitq_t *blitq, int engine)
+{
+ int ret=0;
+ unsigned long irqsave;
+
+ DRM_DEBUG("Num free is %d\n", blitq->num_free);
+ spin_lock_irqsave(&blitq->blit_lock, irqsave);
+ while(blitq->num_free == 0) {
+ spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
+
+ DRM_WAIT_ON(ret, blitq->busy_queue, DRM_HZ, blitq->num_free > 0);
+ if (ret) {
+ return (DRM_ERR(EINTR) == ret) ? DRM_ERR(EAGAIN) : ret;
+ }
+
+ spin_lock_irqsave(&blitq->blit_lock, irqsave);
+ }
+
+ blitq->num_free--;
+ spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
+
+ return 0;
+}
+
+/*
+ * Hand back a free slot if we changed our mind.
+ */
+
+static void
+via_dmablit_release_slot(drm_via_blitq_t *blitq)
+{
+ unsigned long irqsave;
+
+ spin_lock_irqsave(&blitq->blit_lock, irqsave);
+ blitq->num_free++;
+ spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
+ DRM_WAKEUP( &blitq->busy_queue );
+}
+
+/*
+ * Grab a free slot. Build blit info and queue a blit.
+ */
+
+
+static int
+via_dmablit(drm_device_t *dev, drm_via_dmablit_t *xfer)
+{
+ drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
+ drm_via_sg_info_t *vsg;
+ drm_via_blitq_t *blitq;
+ int ret;
+ int engine;
+ unsigned long irqsave;
+
+ if (dev_priv == NULL) {
+ DRM_ERROR("Called without initialization.\n");
+ return DRM_ERR(EINVAL);
+ }
+
+ engine = (xfer->to_fb) ? 0 : 1;
+ blitq = dev_priv->blit_queues + engine;
+ if (0 != (ret = via_dmablit_grab_slot(blitq, engine))) {
+ return ret;
+ }
+ if (NULL == (vsg = kmalloc(sizeof(*vsg), GFP_KERNEL))) {
+ via_dmablit_release_slot(blitq);
+ return DRM_ERR(ENOMEM);
+ }
+ if (0 != (ret = via_build_sg_info(dev, vsg, xfer))) {
+ via_dmablit_release_slot(blitq);
+ kfree(vsg);
+ return ret;
+ }
+ spin_lock_irqsave(&blitq->blit_lock, irqsave);
+
+ blitq->blits[blitq->head++] = vsg;
+ if (blitq->head >= VIA_NUM_BLIT_SLOTS)
+ blitq->head = 0;
+ blitq->num_outstanding++;
+ xfer->sync.sync_handle = ++blitq->cur_blit_handle;
+
+ spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
+ xfer->sync.engine = engine;
+
+ via_dmablit_handler(dev, engine, 0);
+
+ return 0;
+}
+
+/*
+ * Sync on a previously submitted blit. Note that the X server use signals extensively, and
+ * that there is a very big proability that this IOCTL will be interrupted by a signal. In that
+ * case it returns with -EAGAIN for the signal to be delivered.
+ * The caller should then reissue the IOCTL. This is similar to what is being done for drmGetLock().
+ */
+
+int
+via_dma_blit_sync( DRM_IOCTL_ARGS )
+{
+ drm_via_blitsync_t sync;
+ int err;
+ DRM_DEVICE;
+
+ DRM_COPY_FROM_USER_IOCTL(sync, (drm_via_blitsync_t *)data, sizeof(sync));
+
+ if (sync.engine >= VIA_NUM_BLIT_ENGINES)
+ return DRM_ERR(EINVAL);
+
+ err = via_dmablit_sync(dev, sync.sync_handle, sync.engine);
+
+ if (DRM_ERR(EINTR) == err)
+ err = DRM_ERR(EAGAIN);
+
+ return err;
+}
+
+
+/*
+ * Queue a blit and hand back a handle to be used for sync. This IOCTL may be interrupted by a signal
+ * while waiting for a free slot in the blit queue. In that case it returns with -EAGAIN and should
+ * be reissued. See the above IOCTL code.
+ */
+
+int
+via_dma_blit( DRM_IOCTL_ARGS )
+{
+ drm_via_dmablit_t xfer;
+ int err;
+ DRM_DEVICE;
+
+ DRM_COPY_FROM_USER_IOCTL(xfer, (drm_via_dmablit_t __user *)data, sizeof(xfer));
+
+ err = via_dmablit(dev, &xfer);
+
+ DRM_COPY_TO_USER_IOCTL((void __user *)data, xfer, sizeof(xfer));
+
+ return err;
+}
diff --git a/drivers/char/drm/via_dmablit.h b/drivers/char/drm/via_dmablit.h
new file mode 100644
index 0000000000000..f4036cd5d0e00
--- /dev/null
+++ b/drivers/char/drm/via_dmablit.h
@@ -0,0 +1,140 @@
+/* via_dmablit.h -- PCI DMA BitBlt support for the VIA Unichrome/Pro
+ *
+ * Copyright 2005 Thomas Hellstrom.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Thomas Hellstrom.
+ * Register info from Digeo Inc.
+ */
+
+#ifndef _VIA_DMABLIT_H
+#define _VIA_DMABLIT_H
+
+#include <linux/dma-mapping.h>
+
+#define VIA_NUM_BLIT_ENGINES 2
+#define VIA_NUM_BLIT_SLOTS 8
+
+struct _drm_via_descriptor;
+
+typedef struct _drm_via_sg_info {
+ struct page **pages;
+ unsigned long num_pages;
+ struct _drm_via_descriptor **desc_pages;
+ int num_desc_pages;
+ int num_desc;
+ enum dma_data_direction direction;
+ unsigned char *bounce_buffer;
+ dma_addr_t chain_start;
+ uint32_t free_on_sequence;
+ unsigned int descriptors_per_page;
+ int aborted;
+ enum {
+ dr_via_device_mapped,
+ dr_via_desc_pages_alloc,
+ dr_via_pages_locked,
+ dr_via_pages_alloc,
+ dr_via_sg_init
+ } state;
+} drm_via_sg_info_t;
+
+typedef struct _drm_via_blitq {
+ drm_device_t *dev;
+ uint32_t cur_blit_handle;
+ uint32_t done_blit_handle;
+ unsigned serviced;
+ unsigned head;
+ unsigned cur;
+ unsigned num_free;
+ unsigned num_outstanding;
+ unsigned long end;
+ int aborting;
+ int is_active;
+ drm_via_sg_info_t *blits[VIA_NUM_BLIT_SLOTS];
+ spinlock_t blit_lock;
+ wait_queue_head_t blit_queue[VIA_NUM_BLIT_SLOTS];
+ wait_queue_head_t busy_queue;
+ struct work_struct wq;
+ struct timer_list poll_timer;
+} drm_via_blitq_t;
+
+
+/*
+ * PCI DMA Registers
+ * Channels 2 & 3 don't seem to be implemented in hardware.
+ */
+
+#define VIA_PCI_DMA_MAR0 0xE40 /* Memory Address Register of Channel 0 */
+#define VIA_PCI_DMA_DAR0 0xE44 /* Device Address Register of Channel 0 */
+#define VIA_PCI_DMA_BCR0 0xE48 /* Byte Count Register of Channel 0 */
+#define VIA_PCI_DMA_DPR0 0xE4C /* Descriptor Pointer Register of Channel 0 */
+
+#define VIA_PCI_DMA_MAR1 0xE50 /* Memory Address Register of Channel 1 */
+#define VIA_PCI_DMA_DAR1 0xE54 /* Device Address Register of Channel 1 */
+#define VIA_PCI_DMA_BCR1 0xE58 /* Byte Count Register of Channel 1 */
+#define VIA_PCI_DMA_DPR1 0xE5C /* Descriptor Pointer Register of Channel 1 */
+
+#define VIA_PCI_DMA_MAR2 0xE60 /* Memory Address Register of Channel 2 */
+#define VIA_PCI_DMA_DAR2 0xE64 /* Device Address Register of Channel 2 */
+#define VIA_PCI_DMA_BCR2 0xE68 /* Byte Count Register of Channel 2 */
+#define VIA_PCI_DMA_DPR2 0xE6C /* Descriptor Pointer Register of Channel 2 */
+
+#define VIA_PCI_DMA_MAR3 0xE70 /* Memory Address Register of Channel 3 */
+#define VIA_PCI_DMA_DAR3 0xE74 /* Device Address Register of Channel 3 */
+#define VIA_PCI_DMA_BCR3 0xE78 /* Byte Count Register of Channel 3 */
+#define VIA_PCI_DMA_DPR3 0xE7C /* Descriptor Pointer Register of Channel 3 */
+
+#define VIA_PCI_DMA_MR0 0xE80 /* Mode Register of Channel 0 */
+#define VIA_PCI_DMA_MR1 0xE84 /* Mode Register of Channel 1 */
+#define VIA_PCI_DMA_MR2 0xE88 /* Mode Register of Channel 2 */
+#define VIA_PCI_DMA_MR3 0xE8C /* Mode Register of Channel 3 */
+
+#define VIA_PCI_DMA_CSR0 0xE90 /* Command/Status Register of Channel 0 */
+#define VIA_PCI_DMA_CSR1 0xE94 /* Command/Status Register of Channel 1 */
+#define VIA_PCI_DMA_CSR2 0xE98 /* Command/Status Register of Channel 2 */
+#define VIA_PCI_DMA_CSR3 0xE9C /* Command/Status Register of Channel 3 */
+
+#define VIA_PCI_DMA_PTR 0xEA0 /* Priority Type Register */
+
+/* Define for DMA engine */
+/* DPR */
+#define VIA_DMA_DPR_EC (1<<1) /* end of chain */
+#define VIA_DMA_DPR_DDIE (1<<2) /* descriptor done interrupt enable */
+#define VIA_DMA_DPR_DT (1<<3) /* direction of transfer (RO) */
+
+/* MR */
+#define VIA_DMA_MR_CM (1<<0) /* chaining mode */
+#define VIA_DMA_MR_TDIE (1<<1) /* transfer done interrupt enable */
+#define VIA_DMA_MR_HENDMACMD (1<<7) /* ? */
+
+/* CSR */
+#define VIA_DMA_CSR_DE (1<<0) /* DMA enable */
+#define VIA_DMA_CSR_TS (1<<1) /* transfer start */
+#define VIA_DMA_CSR_TA (1<<2) /* transfer abort */
+#define VIA_DMA_CSR_TD (1<<3) /* transfer done */
+#define VIA_DMA_CSR_DD (1<<4) /* descriptor done */
+#define VIA_DMA_DPR_EC (1<<1) /* end of chain */
+
+
+
+#endif
diff --git a/drivers/char/drm/via_drm.h b/drivers/char/drm/via_drm.h
index ebde9206115eb..47f0b5b263795 100644
--- a/drivers/char/drm/via_drm.h
+++ b/drivers/char/drm/via_drm.h
@@ -75,6 +75,8 @@
#define DRM_VIA_CMDBUF_SIZE 0x0b
#define NOT_USED
#define DRM_VIA_WAIT_IRQ 0x0d
+#define DRM_VIA_DMA_BLIT 0x0e
+#define DRM_VIA_BLIT_SYNC 0x0f
#define DRM_IOCTL_VIA_ALLOCMEM DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_ALLOCMEM, drm_via_mem_t)
#define DRM_IOCTL_VIA_FREEMEM DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_FREEMEM, drm_via_mem_t)
@@ -89,6 +91,8 @@
#define DRM_IOCTL_VIA_CMDBUF_SIZE DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_CMDBUF_SIZE, \
drm_via_cmdbuf_size_t)
#define DRM_IOCTL_VIA_WAIT_IRQ DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_WAIT_IRQ, drm_via_irqwait_t)
+#define DRM_IOCTL_VIA_DMA_BLIT DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_DMA_BLIT, drm_via_dmablit_t)
+#define DRM_IOCTL_VIA_BLIT_SYNC DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_BLIT_SYNC, drm_via_blitsync_t)
/* Indices into buf.Setup where various bits of state are mirrored per
* context and per buffer. These can be fired at the card as a unit,
@@ -103,8 +107,12 @@
#define VIA_BACK 0x2
#define VIA_DEPTH 0x4
#define VIA_STENCIL 0x8
-#define VIDEO 0
-#define AGP 1
+#define VIA_MEM_VIDEO 0 /* matches drm constant */
+#define VIA_MEM_AGP 1 /* matches drm constant */
+#define VIA_MEM_SYSTEM 2
+#define VIA_MEM_MIXED 3
+#define VIA_MEM_UNKNOWN 4
+
typedef struct {
uint32_t offset;
uint32_t size;
@@ -192,6 +200,9 @@ typedef struct _drm_via_sarea {
unsigned int XvMCSubPicOn[VIA_NR_XVMC_PORTS];
unsigned int XvMCCtxNoGrabbed; /* Last context to hold decoder */
+ /* Used by the 3d driver only at this point, for pageflipping:
+ */
+ unsigned int pfCurrentOffset;
} drm_via_sarea_t;
typedef struct _drm_via_cmdbuf_size {
@@ -212,6 +223,16 @@ typedef enum {
#define VIA_IRQ_FLAGS_MASK 0xF0000000
+enum drm_via_irqs {
+ drm_via_irq_hqv0 = 0,
+ drm_via_irq_hqv1,
+ drm_via_irq_dma0_dd,
+ drm_via_irq_dma0_td,
+ drm_via_irq_dma1_dd,
+ drm_via_irq_dma1_td,
+ drm_via_irq_num
+};
+
struct drm_via_wait_irq_request {
unsigned irq;
via_irq_seq_type_t type;
@@ -224,20 +245,25 @@ typedef union drm_via_irqwait {
struct drm_wait_vblank_reply reply;
} drm_via_irqwait_t;
-#ifdef __KERNEL__
-
-int via_fb_init(DRM_IOCTL_ARGS);
-int via_mem_alloc(DRM_IOCTL_ARGS);
-int via_mem_free(DRM_IOCTL_ARGS);
-int via_agp_init(DRM_IOCTL_ARGS);
-int via_map_init(DRM_IOCTL_ARGS);
-int via_decoder_futex(DRM_IOCTL_ARGS);
-int via_dma_init(DRM_IOCTL_ARGS);
-int via_cmdbuffer(DRM_IOCTL_ARGS);
-int via_flush_ioctl(DRM_IOCTL_ARGS);
-int via_pci_cmdbuffer(DRM_IOCTL_ARGS);
-int via_cmdbuf_size(DRM_IOCTL_ARGS);
-int via_wait_irq(DRM_IOCTL_ARGS);
+typedef struct drm_via_blitsync {
+ uint32_t sync_handle;
+ unsigned engine;
+} drm_via_blitsync_t;
+
+typedef struct drm_via_dmablit {
+ uint32_t num_lines;
+ uint32_t line_length;
+
+ uint32_t fb_addr;
+ uint32_t fb_stride;
+
+ unsigned char *mem_addr;
+ uint32_t mem_stride;
+
+ int bounce_buffer;
+ int to_fb;
+
+ drm_via_blitsync_t sync;
+} drm_via_dmablit_t;
-#endif
#endif /* _VIA_DRM_H_ */
diff --git a/drivers/char/drm/via_drv.c b/drivers/char/drm/via_drv.c
index 016665e0c69f6..3f012255d3153 100644
--- a/drivers/char/drm/via_drv.c
+++ b/drivers/char/drm/via_drv.c
@@ -29,54 +29,21 @@
#include "drm_pciids.h"
-static int postinit(struct drm_device *dev, unsigned long flags)
+static int dri_library_name(struct drm_device *dev, char *buf)
{
- DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
- DRIVER_NAME,
- DRIVER_MAJOR,
- DRIVER_MINOR,
- DRIVER_PATCHLEVEL,
- DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
- );
- return 0;
-}
-
-static int version(drm_version_t * version)
-{
- int len;
-
- version->version_major = DRIVER_MAJOR;
- version->version_minor = DRIVER_MINOR;
- version->version_patchlevel = DRIVER_PATCHLEVEL;
- DRM_COPY(version->name, DRIVER_NAME);
- DRM_COPY(version->date, DRIVER_DATE);
- DRM_COPY(version->desc, DRIVER_DESC);
- return 0;
+ return snprintf(buf, PAGE_SIZE, "unichrome");
}
static struct pci_device_id pciidlist[] = {
viadrv_PCI_IDS
};
-static drm_ioctl_desc_t ioctls[] = {
- [DRM_IOCTL_NR(DRM_VIA_ALLOCMEM)] = {via_mem_alloc, 1, 0},
- [DRM_IOCTL_NR(DRM_VIA_FREEMEM)] = {via_mem_free, 1, 0},
- [DRM_IOCTL_NR(DRM_VIA_AGP_INIT)] = {via_agp_init, 1, 0},
- [DRM_IOCTL_NR(DRM_VIA_FB_INIT)] = {via_fb_init, 1, 0},
- [DRM_IOCTL_NR(DRM_VIA_MAP_INIT)] = {via_map_init, 1, 0},
- [DRM_IOCTL_NR(DRM_VIA_DEC_FUTEX)] = {via_decoder_futex, 1, 0},
- [DRM_IOCTL_NR(DRM_VIA_DMA_INIT)] = {via_dma_init, 1, 0},
- [DRM_IOCTL_NR(DRM_VIA_CMDBUFFER)] = {via_cmdbuffer, 1, 0},
- [DRM_IOCTL_NR(DRM_VIA_FLUSH)] = {via_flush_ioctl, 1, 0},
- [DRM_IOCTL_NR(DRM_VIA_PCICMD)] = {via_pci_cmdbuffer, 1, 0},
- [DRM_IOCTL_NR(DRM_VIA_CMDBUF_SIZE)] = {via_cmdbuf_size, 1, 0},
- [DRM_IOCTL_NR(DRM_VIA_WAIT_IRQ)] = {via_wait_irq, 1, 0}
-};
-
static struct drm_driver driver = {
.driver_features =
DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ |
DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
+ .load = via_driver_load,
+ .unload = via_driver_unload,
.context_ctor = via_init_context,
.context_dtor = via_final_context,
.vblank_wait = via_driver_vblank_wait,
@@ -85,13 +52,11 @@ static struct drm_driver driver = {
.irq_uninstall = via_driver_irq_uninstall,
.irq_handler = via_driver_irq_handler,
.dma_quiescent = via_driver_dma_quiescent,
+ .dri_library_name = dri_library_name,
.reclaim_buffers = drm_core_reclaim_buffers,
.get_map_ofs = drm_core_get_map_ofs,
.get_reg_ofs = drm_core_get_reg_ofs,
- .postinit = postinit,
- .version = version,
- .ioctls = ioctls,
- .num_ioctls = DRM_ARRAY_SIZE(ioctls),
+ .ioctls = via_ioctls,
.fops = {
.owner = THIS_MODULE,
.open = drm_open,
@@ -100,15 +65,23 @@ static struct drm_driver driver = {
.mmap = drm_mmap,
.poll = drm_poll,
.fasync = drm_fasync,
- },
+ },
.pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
- }
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ },
+
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESC,
+ .date = DRIVER_DATE,
+ .major = DRIVER_MAJOR,
+ .minor = DRIVER_MINOR,
+ .patchlevel = DRIVER_PATCHLEVEL,
};
static int __init via_init(void)
{
+ driver.num_ioctls = via_max_ioctl;
via_init_command_verifier();
return drm_init(&driver);
}
diff --git a/drivers/char/drm/via_drv.h b/drivers/char/drm/via_drv.h
index 7d5daf43797ee..aad4f99f54057 100644
--- a/drivers/char/drm/via_drv.h
+++ b/drivers/char/drm/via_drv.h
@@ -24,24 +24,26 @@
#ifndef _VIA_DRV_H_
#define _VIA_DRV_H_
-#define DRIVER_AUTHOR "VIA"
+#define DRIVER_AUTHOR "Various"
#define DRIVER_NAME "via"
#define DRIVER_DESC "VIA Unichrome / Pro"
-#define DRIVER_DATE "20050523"
+#define DRIVER_DATE "20051116"
#define DRIVER_MAJOR 2
-#define DRIVER_MINOR 6
-#define DRIVER_PATCHLEVEL 3
+#define DRIVER_MINOR 7
+#define DRIVER_PATCHLEVEL 4
#include "via_verifier.h"
+#include "via_dmablit.h"
+
#define VIA_PCI_BUF_SIZE 60000
#define VIA_FIRE_BUF_SIZE 1024
-#define VIA_NUM_IRQS 2
+#define VIA_NUM_IRQS 4
typedef struct drm_via_ring_buffer {
- drm_map_t map;
+ drm_local_map_t map;
char *virtual_start;
} drm_via_ring_buffer_t;
@@ -56,9 +58,9 @@ typedef struct drm_via_irq {
typedef struct drm_via_private {
drm_via_sarea_t *sarea_priv;
- drm_map_t *sarea;
- drm_map_t *fb;
- drm_map_t *mmio;
+ drm_local_map_t *sarea;
+ drm_local_map_t *fb;
+ drm_local_map_t *mmio;
unsigned long agpAddr;
wait_queue_head_t decoder_queue[VIA_NR_XVMC_LOCKS];
char *dma_ptr;
@@ -82,8 +84,15 @@ typedef struct drm_via_private {
maskarray_t *irq_masks;
uint32_t irq_enable_mask;
uint32_t irq_pending_mask;
+ int *irq_map;
+ drm_via_blitq_t blit_queues[VIA_NUM_BLIT_ENGINES];
} drm_via_private_t;
+enum via_family {
+ VIA_OTHER = 0,
+ VIA_PRO_GROUP_A,
+};
+
/* VIA MMIO register access */
#define VIA_BASE ((dev_priv->mmio))
@@ -92,12 +101,31 @@ typedef struct drm_via_private {
#define VIA_READ8(reg) DRM_READ8(VIA_BASE, reg)
#define VIA_WRITE8(reg,val) DRM_WRITE8(VIA_BASE, reg, val)
+extern drm_ioctl_desc_t via_ioctls[];
+extern int via_max_ioctl;
+
+extern int via_fb_init(DRM_IOCTL_ARGS);
+extern int via_mem_alloc(DRM_IOCTL_ARGS);
+extern int via_mem_free(DRM_IOCTL_ARGS);
+extern int via_agp_init(DRM_IOCTL_ARGS);
+extern int via_map_init(DRM_IOCTL_ARGS);
+extern int via_decoder_futex(DRM_IOCTL_ARGS);
+extern int via_dma_init(DRM_IOCTL_ARGS);
+extern int via_cmdbuffer(DRM_IOCTL_ARGS);
+extern int via_flush_ioctl(DRM_IOCTL_ARGS);
+extern int via_pci_cmdbuffer(DRM_IOCTL_ARGS);
+extern int via_cmdbuf_size(DRM_IOCTL_ARGS);
+extern int via_wait_irq(DRM_IOCTL_ARGS);
+extern int via_dma_blit_sync( DRM_IOCTL_ARGS );
+extern int via_dma_blit( DRM_IOCTL_ARGS );
+
+extern int via_driver_load(drm_device_t *dev, unsigned long chipset);
+extern int via_driver_unload(drm_device_t *dev);
+
extern int via_init_context(drm_device_t * dev, int context);
extern int via_final_context(drm_device_t * dev, int context);
extern int via_do_cleanup_map(drm_device_t * dev);
-extern int via_map_init(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
extern int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence);
extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS);
@@ -111,8 +139,10 @@ extern int via_driver_dma_quiescent(drm_device_t * dev);
extern void via_init_futex(drm_via_private_t * dev_priv);
extern void via_cleanup_futex(drm_via_private_t * dev_priv);
extern void via_release_futex(drm_via_private_t * dev_priv, int context);
+extern int via_driver_irq_wait(drm_device_t * dev, unsigned int irq,
+ int force_sequence, unsigned int *sequence);
-extern int via_parse_command_stream(drm_device_t * dev, const uint32_t * buf,
- unsigned int size);
+extern void via_dmablit_handler(drm_device_t *dev, int engine, int from_irq);
+extern void via_init_dmablit(drm_device_t *dev);
#endif
diff --git a/drivers/char/drm/via_ds.c b/drivers/char/drm/via_ds.c
index 5c71e089246c7..9429736b3b96f 100644
--- a/drivers/char/drm/via_ds.c
+++ b/drivers/char/drm/via_ds.c
@@ -22,14 +22,7 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/pci.h>
-#include <asm/io.h>
+#include "drmP.h"
#include "via_ds.h"
extern unsigned int VIA_DEBUG;
diff --git a/drivers/char/drm/via_irq.c b/drivers/char/drm/via_irq.c
index d023add1929b1..56d7e3daea126 100644
--- a/drivers/char/drm/via_irq.c
+++ b/drivers/char/drm/via_irq.c
@@ -50,6 +50,15 @@
#define VIA_IRQ_HQV1_ENABLE (1 << 25)
#define VIA_IRQ_HQV0_PENDING (1 << 9)
#define VIA_IRQ_HQV1_PENDING (1 << 10)
+#define VIA_IRQ_DMA0_DD_ENABLE (1 << 20)
+#define VIA_IRQ_DMA0_TD_ENABLE (1 << 21)
+#define VIA_IRQ_DMA1_DD_ENABLE (1 << 22)
+#define VIA_IRQ_DMA1_TD_ENABLE (1 << 23)
+#define VIA_IRQ_DMA0_DD_PENDING (1 << 4)
+#define VIA_IRQ_DMA0_TD_PENDING (1 << 5)
+#define VIA_IRQ_DMA1_DD_PENDING (1 << 6)
+#define VIA_IRQ_DMA1_TD_PENDING (1 << 7)
+
/*
* Device-specific IRQs go here. This type might need to be extended with
@@ -61,13 +70,24 @@ static maskarray_t via_pro_group_a_irqs[] = {
{VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010,
0x00000000},
{VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010,
- 0x00000000}
+ 0x00000000},
+ {VIA_IRQ_DMA0_TD_ENABLE, VIA_IRQ_DMA0_TD_PENDING, VIA_PCI_DMA_CSR0,
+ VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008},
+ {VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1,
+ VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008},
};
static int via_num_pro_group_a =
sizeof(via_pro_group_a_irqs) / sizeof(maskarray_t);
+static int via_irqmap_pro_group_a[] = {0, 1, -1, 2, -1, 3};
-static maskarray_t via_unichrome_irqs[] = { };
+static maskarray_t via_unichrome_irqs[] = {
+ {VIA_IRQ_DMA0_TD_ENABLE, VIA_IRQ_DMA0_TD_PENDING, VIA_PCI_DMA_CSR0,
+ VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008},
+ {VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1,
+ VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008}
+};
static int via_num_unichrome = sizeof(via_unichrome_irqs) / sizeof(maskarray_t);
+static int via_irqmap_unichrome[] = {-1, -1, -1, 0, -1, 1};
static unsigned time_diff(struct timeval *now, struct timeval *then)
{
@@ -113,6 +133,11 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
atomic_inc(&cur_irq->irq_received);
DRM_WAKEUP(&cur_irq->irq_queue);
handled = 1;
+ if (dev_priv->irq_map[drm_via_irq_dma0_td] == i) {
+ via_dmablit_handler(dev, 0, 1);
+ } else if (dev_priv->irq_map[drm_via_irq_dma1_td] == i) {
+ via_dmablit_handler(dev, 1, 1);
+ }
}
cur_irq++;
}
@@ -165,7 +190,7 @@ int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence)
return ret;
}
-static int
+int
via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence,
unsigned int *sequence)
{
@@ -174,6 +199,7 @@ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence,
drm_via_irq_t *cur_irq = dev_priv->via_irqs;
int ret = 0;
maskarray_t *masks = dev_priv->irq_masks;
+ int real_irq;
DRM_DEBUG("%s\n", __FUNCTION__);
@@ -182,15 +208,23 @@ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence,
return DRM_ERR(EINVAL);
}
- if (irq >= dev_priv->num_irqs) {
+ if (irq >= drm_via_irq_num) {
DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__,
irq);
return DRM_ERR(EINVAL);
}
- cur_irq += irq;
+ real_irq = dev_priv->irq_map[irq];
+
+ if (real_irq < 0) {
+ DRM_ERROR("%s Video IRQ %d not available on this hardware.\n",
+ __FUNCTION__, irq);
+ return DRM_ERR(EINVAL);
+ }
+
+ cur_irq += real_irq;
- if (masks[irq][2] && !force_sequence) {
+ if (masks[real_irq][2] && !force_sequence) {
DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ,
((VIA_READ(masks[irq][2]) & masks[irq][3]) ==
masks[irq][4]));
@@ -226,6 +260,8 @@ void via_driver_irq_preinstall(drm_device_t * dev)
via_pro_group_a_irqs : via_unichrome_irqs;
dev_priv->num_irqs = (dev_priv->pro_group_a) ?
via_num_pro_group_a : via_num_unichrome;
+ dev_priv->irq_map = (dev_priv->pro_group_a) ?
+ via_irqmap_pro_group_a : via_irqmap_unichrome;
for (i = 0; i < dev_priv->num_irqs; ++i) {
atomic_set(&cur_irq->irq_received, 0);
@@ -241,7 +277,7 @@ void via_driver_irq_preinstall(drm_device_t * dev)
dev_priv->last_vblank_valid = 0;
- // Clear VSync interrupt regs
+ /* Clear VSync interrupt regs */
status = VIA_READ(VIA_REG_INTERRUPT);
VIA_WRITE(VIA_REG_INTERRUPT, status &
~(dev_priv->irq_enable_mask));
@@ -291,8 +327,7 @@ void via_driver_irq_uninstall(drm_device_t * dev)
int via_wait_irq(DRM_IOCTL_ARGS)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
+ DRM_DEVICE;
drm_via_irqwait_t __user *argp = (void __user *)data;
drm_via_irqwait_t irqwait;
struct timeval now;
diff --git a/drivers/char/drm/via_map.c b/drivers/char/drm/via_map.c
index 6bd6ac52ad1b2..c6a08e96285bf 100644
--- a/drivers/char/drm/via_map.c
+++ b/drivers/char/drm/via_map.c
@@ -27,16 +27,10 @@
static int via_do_init_map(drm_device_t * dev, drm_via_init_t * init)
{
- drm_via_private_t *dev_priv;
+ drm_via_private_t *dev_priv = dev->dev_private;
DRM_DEBUG("%s\n", __FUNCTION__);
- dev_priv = drm_alloc(sizeof(drm_via_private_t), DRM_MEM_DRIVER);
- if (dev_priv == NULL)
- return -ENOMEM;
-
- memset(dev_priv, 0, sizeof(drm_via_private_t));
-
DRM_GETSAREA();
if (!dev_priv->sarea) {
DRM_ERROR("could not find sarea!\n");
@@ -67,7 +61,8 @@ static int via_do_init_map(drm_device_t * dev, drm_via_init_t * init)
dev_priv->agpAddr = init->agpAddr;
via_init_futex(dev_priv);
- dev_priv->pro_group_a = (dev->pdev->device == 0x3118);
+
+ via_init_dmablit(dev);
dev->dev_private = (void *)dev_priv;
return 0;
@@ -75,15 +70,7 @@ static int via_do_init_map(drm_device_t * dev, drm_via_init_t * init)
int via_do_cleanup_map(drm_device_t * dev)
{
- if (dev->dev_private) {
-
- drm_via_private_t *dev_priv = dev->dev_private;
-
- via_dma_cleanup(dev);
-
- drm_free(dev_priv, sizeof(drm_via_private_t), DRM_MEM_DRIVER);
- dev->dev_private = NULL;
- }
+ via_dma_cleanup(dev);
return 0;
}
@@ -107,3 +94,29 @@ int via_map_init(DRM_IOCTL_ARGS)
return -EINVAL;
}
+
+int via_driver_load(drm_device_t *dev, unsigned long chipset)
+{
+ drm_via_private_t *dev_priv;
+
+ dev_priv = drm_calloc(1, sizeof(drm_via_private_t), DRM_MEM_DRIVER);
+ if (dev_priv == NULL)
+ return DRM_ERR(ENOMEM);
+
+ dev->dev_private = (void *)dev_priv;
+
+ if (chipset == VIA_PRO_GROUP_A)
+ dev_priv->pro_group_a = 1;
+
+ return 0;
+}
+
+int via_driver_unload(drm_device_t *dev)
+{
+ drm_via_private_t *dev_priv = dev->dev_private;
+
+ drm_free(dev_priv, sizeof(drm_via_private_t), DRM_MEM_DRIVER);
+
+ return 0;
+}
+
diff --git a/drivers/char/drm/via_mm.c b/drivers/char/drm/via_mm.c
index 3baddacdff26a..33e0cb12e4c30 100644
--- a/drivers/char/drm/via_mm.c
+++ b/drivers/char/drm/via_mm.c
@@ -42,7 +42,7 @@ static int via_agp_free(drm_via_mem_t * mem);
static int via_fb_alloc(drm_via_mem_t * mem);
static int via_fb_free(drm_via_mem_t * mem);
-static int add_alloc_set(int context, int type, unsigned int val)
+static int add_alloc_set(int context, int type, unsigned long val)
{
int i, retval = 0;
@@ -56,7 +56,7 @@ static int add_alloc_set(int context, int type, unsigned int val)
return retval;
}
-static int del_alloc_set(int context, int type, unsigned int val)
+static int del_alloc_set(int context, int type, unsigned long val)
{
int i, retval = 0;
@@ -199,13 +199,13 @@ int via_mem_alloc(DRM_IOCTL_ARGS)
sizeof(mem));
switch (mem.type) {
- case VIDEO:
+ case VIA_MEM_VIDEO:
if (via_fb_alloc(&mem) < 0)
return -EFAULT;
DRM_COPY_TO_USER_IOCTL((drm_via_mem_t __user *) data, mem,
sizeof(mem));
return 0;
- case AGP:
+ case VIA_MEM_AGP:
if (via_agp_alloc(&mem) < 0)
return -EFAULT;
DRM_COPY_TO_USER_IOCTL((drm_via_mem_t __user *) data, mem,
@@ -232,7 +232,7 @@ static int via_fb_alloc(drm_via_mem_t * mem)
if (block) {
fb.offset = block->ofs;
fb.free = (unsigned long)block;
- if (!add_alloc_set(fb.context, VIDEO, fb.free)) {
+ if (!add_alloc_set(fb.context, VIA_MEM_VIDEO, fb.free)) {
DRM_DEBUG("adding to allocation set fails\n");
via_mmFreeMem((PMemBlock) fb.free);
retval = -1;
@@ -269,7 +269,7 @@ static int via_agp_alloc(drm_via_mem_t * mem)
if (block) {
agp.offset = block->ofs;
agp.free = (unsigned long)block;
- if (!add_alloc_set(agp.context, AGP, agp.free)) {
+ if (!add_alloc_set(agp.context, VIA_MEM_AGP, agp.free)) {
DRM_DEBUG("adding to allocation set fails\n");
via_mmFreeMem((PMemBlock) agp.free);
retval = -1;
@@ -297,11 +297,11 @@ int via_mem_free(DRM_IOCTL_ARGS)
switch (mem.type) {
- case VIDEO:
+ case VIA_MEM_VIDEO:
if (via_fb_free(&mem) == 0)
return 0;
break;
- case AGP:
+ case VIA_MEM_AGP:
if (via_agp_free(&mem) == 0)
return 0;
break;
@@ -329,7 +329,7 @@ static int via_fb_free(drm_via_mem_t * mem)
via_mmFreeMem((PMemBlock) fb.free);
- if (!del_alloc_set(fb.context, VIDEO, fb.free)) {
+ if (!del_alloc_set(fb.context, VIA_MEM_VIDEO, fb.free)) {
retval = -1;
}
@@ -352,7 +352,7 @@ static int via_agp_free(drm_via_mem_t * mem)
via_mmFreeMem((PMemBlock) agp.free);
- if (!del_alloc_set(agp.context, AGP, agp.free)) {
+ if (!del_alloc_set(agp.context, VIA_MEM_AGP, agp.free)) {
retval = -1;
}
diff --git a/drivers/char/drm/via_verifier.c b/drivers/char/drm/via_verifier.c
index 4ac495f297f7d..70c897c887664 100644
--- a/drivers/char/drm/via_verifier.c
+++ b/drivers/char/drm/via_verifier.c
@@ -237,7 +237,7 @@ static hazard_t table3[256];
static __inline__ int
eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words)
{
- if ((*buf - buf_end) >= num_words) {
+ if ((buf_end - *buf) >= num_words) {
*buf += num_words;
return 0;
}
@@ -249,14 +249,14 @@ eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words)
* Partially stolen from drm_memory.h
*/
-static __inline__ drm_map_t *via_drm_lookup_agp_map(drm_via_state_t * seq,
+static __inline__ drm_local_map_t *via_drm_lookup_agp_map(drm_via_state_t *seq,
unsigned long offset,
unsigned long size,
drm_device_t * dev)
{
struct list_head *list;
drm_map_list_t *r_list;
- drm_map_t *map = seq->map_cache;
+ drm_local_map_t *map = seq->map_cache;
if (map && map->offset <= offset
&& (offset + size) <= (map->offset + map->size)) {
diff --git a/drivers/char/drm/via_verifier.h b/drivers/char/drm/via_verifier.h
index eb4eda3443451..256590fcc22ac 100644
--- a/drivers/char/drm/via_verifier.h
+++ b/drivers/char/drm/via_verifier.h
@@ -47,7 +47,7 @@ typedef struct {
int agp_texture;
int multitex;
drm_device_t *dev;
- drm_map_t *map_cache;
+ drm_local_map_t *map_cache;
uint32_t vertex_count;
int agp;
const uint32_t *buf_start;
@@ -55,5 +55,7 @@ typedef struct {
extern int via_verify_command_stream(const uint32_t * buf, unsigned int size,
drm_device_t * dev, int agp);
+extern int via_parse_command_stream(drm_device_t *dev, const uint32_t *buf,
+ unsigned int size);
#endif
diff --git a/drivers/char/drm/via_video.c b/drivers/char/drm/via_video.c
index 7fab9fbdf424f..300ac61b09edb 100644
--- a/drivers/char/drm/via_video.c
+++ b/drivers/char/drm/via_video.c
@@ -50,8 +50,11 @@ void via_release_futex(drm_via_private_t * dev_priv, int context)
unsigned int i;
volatile int *lock;
+ if (!dev_priv->sarea_priv)
+ return;
+
for (i = 0; i < VIA_NR_XVMC_LOCKS; ++i) {
- lock = (int *)XVMCLOCKPTR(dev_priv->sarea_priv, i);
+ lock = (volatile int *)XVMCLOCKPTR(dev_priv->sarea_priv, i);
if ((_DRM_LOCKING_CONTEXT(*lock) == context)) {
if (_DRM_LOCK_IS_HELD(*lock)
&& (*lock & _DRM_LOCK_CONT)) {
@@ -79,7 +82,7 @@ int via_decoder_futex(DRM_IOCTL_ARGS)
if (fx.lock > VIA_NR_XVMC_LOCKS)
return -EFAULT;
- lock = (int *)XVMCLOCKPTR(sAPriv, fx.lock);
+ lock = (volatile int *)XVMCLOCKPTR(sAPriv, fx.lock);
switch (fx.func) {
case VIA_FUTEX_WAIT:
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 704c3c07f0ab8..29c41f4418c06 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -534,7 +534,7 @@ static ssize_t write_kmem(struct file * file, const char __user * buf,
return virtr + wrote;
}
-#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI))
+#if defined(CONFIG_ISA) || !defined(__mc68000__)
static ssize_t read_port(struct file * file, char __user * buf,
size_t count, loff_t *ppos)
{
@@ -795,7 +795,7 @@ static struct file_operations null_fops = {
.write = write_null,
};
-#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI))
+#if defined(CONFIG_ISA) || !defined(__mc68000__)
static struct file_operations port_fops = {
.llseek = memory_lseek,
.read = read_port,
@@ -865,7 +865,7 @@ static int memory_open(struct inode * inode, struct file * filp)
case 3:
filp->f_op = &null_fops;
break;
-#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI))
+#if defined(CONFIG_ISA) || !defined(__mc68000__)
case 4:
filp->f_op = &port_fops;
break;
@@ -912,7 +912,7 @@ static const struct {
{1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
{2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
{3, "null", S_IRUGO | S_IWUGO, &null_fops},
-#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI))
+#if defined(CONFIG_ISA) || !defined(__mc68000__)
{4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
#endif
{5, "zero", S_IRUGO | S_IWUGO, &zero_fops},
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c
index faee5e7acaf7a..4e5360388748e 100644
--- a/drivers/char/viocons.c
+++ b/drivers/char/viocons.c
@@ -476,19 +476,19 @@ static struct port_info *get_port_data(struct tty_struct *tty)
*/
static void initDataEvent(struct viocharlpevent *viochar, HvLpIndex lp)
{
+ struct HvLpEvent *hev = &viochar->event;
+
memset(viochar, 0, sizeof(struct viocharlpevent));
- viochar->event.xFlags.xValid = 1;
- viochar->event.xFlags.xFunction = HvLpEvent_Function_Int;
- viochar->event.xFlags.xAckInd = HvLpEvent_AckInd_NoAck;
- viochar->event.xFlags.xAckType = HvLpEvent_AckType_DeferredAck;
- viochar->event.xType = HvLpEvent_Type_VirtualIo;
- viochar->event.xSubtype = viomajorsubtype_chario | viochardata;
- viochar->event.xSourceLp = HvLpConfig_getLpIndex();
- viochar->event.xTargetLp = lp;
- viochar->event.xSizeMinus1 = sizeof(struct viocharlpevent);
- viochar->event.xSourceInstanceId = viopath_sourceinst(lp);
- viochar->event.xTargetInstanceId = viopath_targetinst(lp);
+ hev->flags = HV_LP_EVENT_VALID | HV_LP_EVENT_DEFERRED_ACK |
+ HV_LP_EVENT_INT;
+ hev->xType = HvLpEvent_Type_VirtualIo;
+ hev->xSubtype = viomajorsubtype_chario | viochardata;
+ hev->xSourceLp = HvLpConfig_getLpIndex();
+ hev->xTargetLp = lp;
+ hev->xSizeMinus1 = sizeof(struct viocharlpevent);
+ hev->xSourceInstanceId = viopath_sourceinst(lp);
+ hev->xTargetInstanceId = viopath_targetinst(lp);
}
/*
@@ -752,7 +752,7 @@ static void vioHandleOpenEvent(struct HvLpEvent *event)
struct port_info *pi;
int reject = 0;
- if (event->xFlags.xFunction == HvLpEvent_Function_Ack) {
+ if (hvlpevent_is_ack(event)) {
if (port >= VTTY_PORTS)
return;
@@ -788,7 +788,7 @@ static void vioHandleOpenEvent(struct HvLpEvent *event)
}
/* This had better require an ack, otherwise complain */
- if (event->xFlags.xAckInd != HvLpEvent_AckInd_DoAck) {
+ if (!hvlpevent_need_ack(event)) {
printk(VIOCONS_KERN_WARN "viocharopen without ack bit!\n");
return;
}
@@ -856,7 +856,7 @@ static void vioHandleCloseEvent(struct HvLpEvent *event)
struct viocharlpevent *cevent = (struct viocharlpevent *)event;
u8 port = cevent->virtual_device;
- if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
+ if (hvlpevent_is_int(event)) {
if (port >= VTTY_PORTS) {
printk(VIOCONS_KERN_WARN
"close message from invalid virtual device.\n");
@@ -1056,8 +1056,7 @@ static void vioHandleCharEvent(struct HvLpEvent *event)
vioHandleConfig(event);
break;
default:
- if ((event->xFlags.xFunction == HvLpEvent_Function_Int) &&
- (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck)) {
+ if (hvlpevent_is_int(event) && hvlpevent_need_ack(event)) {
event->xRc = HvLpEvent_Rc_InvalidSubtype;
HvCallEvent_ackLpEvent(event);
}
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 70f7ab829d36f..86e2234faf80e 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -899,6 +899,12 @@ static int i2c_pxa_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num
struct pxa_i2c *i2c = adap->algo_data;
int ret, i;
+ /* If the I2C controller is disabled we need to reset it (probably due
+ to a suspend/resume destroying state). We do this here as we can then
+ avoid worrying about resuming the controller before its users. */
+ if (!(ICR & ICR_IUE))
+ i2c_pxa_reset(i2c);
+
for (i = adap->retries; i >= 0; i--) {
ret = i2c_pxa_do_xfer(i2c, msgs, num);
if (ret != I2C_RETRY)
@@ -939,7 +945,9 @@ static struct pxa_i2c i2c_pxa = {
static int i2c_pxa_probe(struct platform_device *dev)
{
struct pxa_i2c *i2c = &i2c_pxa;
+#ifdef CONFIG_I2C_PXA_SLAVE
struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
+#endif
int ret;
#ifdef CONFIG_PXA27x
@@ -1024,5 +1032,7 @@ static void i2c_adap_pxa_exit(void)
return platform_driver_unregister(&i2c_pxa_driver);
}
+MODULE_LICENSE("GPL");
+
module_init(i2c_adap_pxa_init);
module_exit(i2c_adap_pxa_exit);
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index bcbaeb50bb933..8d50df4526a4e 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -55,22 +55,9 @@
#include <asm/io.h>
#include <asm/bitops.h>
-void ide_softirq_done(struct request *rq)
-{
- request_queue_t *q = rq->q;
-
- add_disk_randomness(rq->rq_disk);
- end_that_request_chunk(rq, 1, rq->data_len);
-
- spin_lock_irq(q->queue_lock);
- end_that_request_last(rq, 1);
- spin_unlock_irq(q->queue_lock);
-}
-
int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate,
int nr_sectors)
{
- unsigned int nbytes;
int ret = 1;
BUG_ON(!(rq->flags & REQ_STARTED));
@@ -94,27 +81,12 @@ int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate,
HWGROUP(drive)->hwif->ide_dma_on(drive);
}
- /*
- * For partial completions (or non fs/pc requests), use the regular
- * direct completion path. Same thing for requests that failed, to
- * preserve the ->errors value we use the normal completion path
- * for those
- */
- nbytes = nr_sectors << 9;
- if (!rq->errors && rq_all_done(rq, nbytes)) {
- rq->data_len = nbytes;
+ if (!end_that_request_first(rq, uptodate, nr_sectors)) {
+ add_disk_randomness(rq->rq_disk);
blkdev_dequeue_request(rq);
HWGROUP(drive)->rq = NULL;
- blk_complete_request(rq);
+ end_that_request_last(rq, uptodate);
ret = 0;
- } else {
- if (!end_that_request_first(rq, uptodate, nr_sectors)) {
- add_disk_randomness(rq->rq_disk);
- blkdev_dequeue_request(rq);
- HWGROUP(drive)->rq = NULL;
- end_that_request_last(rq, uptodate);
- ret = 0;
- }
}
return ret;
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 7cb2d86601dbd..e7425546b4b17 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1011,8 +1011,6 @@ static int ide_init_queue(ide_drive_t *drive)
blk_queue_max_hw_segments(q, max_sg_entries);
blk_queue_max_phys_segments(q, max_sg_entries);
- blk_queue_softirq_done(q, ide_softirq_done);
-
/* assign drive queue */
drive->queue = q;
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index b42e0fbab59b6..aff83f966803b 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -24,13 +24,14 @@
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/device.h>
+#include <linux/mutex.h>
#include <asm/dma.h>
#include <asm/hardware.h>
#include "ucb1x00.h"
-static DECLARE_MUTEX(ucb1x00_sem);
+static DEFINE_MUTEX(ucb1x00_mutex);
static LIST_HEAD(ucb1x00_drivers);
static LIST_HEAD(ucb1x00_devices);
@@ -521,12 +522,12 @@ static int ucb1x00_probe(struct mcp *mcp)
goto err_irq;
INIT_LIST_HEAD(&ucb->devs);
- down(&ucb1x00_sem);
+ mutex_lock(&ucb1x00_mutex);
list_add(&ucb->node, &ucb1x00_devices);
list_for_each_entry(drv, &ucb1x00_drivers, node) {
ucb1x00_add_dev(ucb, drv);
}
- up(&ucb1x00_sem);
+ mutex_unlock(&ucb1x00_mutex);
goto out;
err_irq:
@@ -544,13 +545,13 @@ static void ucb1x00_remove(struct mcp *mcp)
struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
struct list_head *l, *n;
- down(&ucb1x00_sem);
+ mutex_lock(&ucb1x00_mutex);
list_del(&ucb->node);
list_for_each_safe(l, n, &ucb->devs) {
struct ucb1x00_dev *dev = list_entry(l, struct ucb1x00_dev, dev_node);
ucb1x00_remove_dev(dev);
}
- up(&ucb1x00_sem);
+ mutex_unlock(&ucb1x00_mutex);
free_irq(ucb->irq, ucb);
class_device_unregister(&ucb->cdev);
@@ -561,12 +562,12 @@ int ucb1x00_register_driver(struct ucb1x00_driver *drv)
struct ucb1x00 *ucb;
INIT_LIST_HEAD(&drv->devs);
- down(&ucb1x00_sem);
+ mutex_lock(&ucb1x00_mutex);
list_add(&drv->node, &ucb1x00_drivers);
list_for_each_entry(ucb, &ucb1x00_devices, node) {
ucb1x00_add_dev(ucb, drv);
}
- up(&ucb1x00_sem);
+ mutex_unlock(&ucb1x00_mutex);
return 0;
}
@@ -574,13 +575,13 @@ void ucb1x00_unregister_driver(struct ucb1x00_driver *drv)
{
struct list_head *n, *l;
- down(&ucb1x00_sem);
+ mutex_lock(&ucb1x00_mutex);
list_del(&drv->node);
list_for_each_safe(l, n, &drv->devs) {
struct ucb1x00_dev *dev = list_entry(l, struct ucb1x00_dev, drv_node);
ucb1x00_remove_dev(dev);
}
- up(&ucb1x00_sem);
+ mutex_unlock(&ucb1x00_mutex);
}
static int ucb1x00_suspend(struct mcp *mcp, pm_message_t state)
@@ -588,12 +589,12 @@ static int ucb1x00_suspend(struct mcp *mcp, pm_message_t state)
struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
struct ucb1x00_dev *dev;
- down(&ucb1x00_sem);
+ mutex_lock(&ucb1x00_mutex);
list_for_each_entry(dev, &ucb->devs, dev_node) {
if (dev->drv->suspend)
dev->drv->suspend(dev, state);
}
- up(&ucb1x00_sem);
+ mutex_unlock(&ucb1x00_mutex);
return 0;
}
@@ -602,12 +603,12 @@ static int ucb1x00_resume(struct mcp *mcp)
struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
struct ucb1x00_dev *dev;
- down(&ucb1x00_sem);
+ mutex_lock(&ucb1x00_mutex);
list_for_each_entry(dev, &ucb->devs, dev_node) {
if (dev->drv->resume)
dev->drv->resume(dev);
}
- up(&ucb1x00_sem);
+ mutex_unlock(&ucb1x00_mutex);
return 0;
}
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c
index f2c42b13945d9..9b7c37e0e5742 100644
--- a/drivers/mmc/mmc_block.c
+++ b/drivers/mmc/mmc_block.c
@@ -28,6 +28,7 @@
#include <linux/kdev_t.h>
#include <linux/blkdev.h>
#include <linux/devfs_fs_kernel.h>
+#include <linux/mutex.h>
#include <linux/mmc/card.h>
#include <linux/mmc/protocol.h>
@@ -57,33 +58,33 @@ struct mmc_blk_data {
unsigned int read_only;
};
-static DECLARE_MUTEX(open_lock);
+static DEFINE_MUTEX(open_lock);
static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
{
struct mmc_blk_data *md;
- down(&open_lock);
+ mutex_lock(&open_lock);
md = disk->private_data;
if (md && md->usage == 0)
md = NULL;
if (md)
md->usage++;
- up(&open_lock);
+ mutex_unlock(&open_lock);
return md;
}
static void mmc_blk_put(struct mmc_blk_data *md)
{
- down(&open_lock);
+ mutex_lock(&open_lock);
md->usage--;
if (md->usage == 0) {
put_disk(md->disk);
mmc_cleanup_queue(&md->queue);
kfree(md);
}
- up(&open_lock);
+ mutex_unlock(&open_lock);
}
static int mmc_blk_open(struct inode *inode, struct file *filp)
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index 77eadf84cb2cb..f0f04be989d62 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -590,9 +590,9 @@ static void veth_handle_event(struct HvLpEvent *event, struct pt_regs *regs)
{
struct veth_lpevent *veth_event = (struct veth_lpevent *)event;
- if (event->xFlags.xFunction == HvLpEvent_Function_Ack)
+ if (hvlpevent_is_ack(event))
veth_handle_ack(veth_event);
- else if (event->xFlags.xFunction == HvLpEvent_Function_Int)
+ else
veth_handle_int(veth_event);
}
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c
index 5d957dfe23d94..fda06941e7306 100644
--- a/drivers/pcmcia/pxa2xx_mainstone.c
+++ b/drivers/pcmcia/pxa2xx_mainstone.c
@@ -171,27 +171,22 @@ static int __init mst_pcmcia_init(void)
{
int ret;
- mst_pcmcia_device = kzalloc(sizeof(*mst_pcmcia_device), GFP_KERNEL);
+ mst_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
if (!mst_pcmcia_device)
return -ENOMEM;
- mst_pcmcia_device->name = "pxa2xx-pcmcia";
+
mst_pcmcia_device->dev.platform_data = &mst_pcmcia_ops;
- ret = platform_device_register(mst_pcmcia_device);
+ ret = platform_device_add(mst_pcmcia_device);
+
if (ret)
- kfree(mst_pcmcia_device);
+ platform_device_put(mst_pcmcia_device);
return ret;
}
static void __exit mst_pcmcia_exit(void)
{
- /*
- * This call is supposed to free our mst_pcmcia_device.
- * Unfortunately platform_device don't have a free method, and
- * we can't assume it's free of any reference at this point so we
- * can't free it either.
- */
platform_device_unregister(mst_pcmcia_device);
}
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index 12a7244a5ec86..fd3647368955f 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -263,30 +263,25 @@ static int __init sharpsl_pcmcia_init(void)
{
int ret;
- sharpsl_pcmcia_ops.nr=platform_scoop_config->num_devs;
- sharpsl_pcmcia_device = kzalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL);
+ sharpsl_pcmcia_ops.nr = platform_scoop_config->num_devs;
+ sharpsl_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
+
if (!sharpsl_pcmcia_device)
return -ENOMEM;
- sharpsl_pcmcia_device->name = "pxa2xx-pcmcia";
sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops;
- sharpsl_pcmcia_device->dev.parent=platform_scoop_config->devs[0].dev;
+ sharpsl_pcmcia_device->dev.parent = platform_scoop_config->devs[0].dev;
+
+ ret = platform_device_add(sharpsl_pcmcia_device);
- ret = platform_device_register(sharpsl_pcmcia_device);
if (ret)
- kfree(sharpsl_pcmcia_device);
+ platform_device_put(sharpsl_pcmcia_device);
return ret;
}
static void __exit sharpsl_pcmcia_exit(void)
{
- /*
- * This call is supposed to free our sharpsl_pcmcia_device.
- * Unfortunately platform_device don't have a free method, and
- * we can't assume it's free of any reference at this point so we
- * can't free it either.
- */
platform_device_unregister(sharpsl_pcmcia_device);
}
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 54e5cc0dd5f8c..fb610c3634a4b 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -41,6 +41,7 @@
#include <linux/serial.h>
#include <linux/serial_8250.h>
#include <linux/nmi.h>
+#include <linux/mutex.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -2467,7 +2468,7 @@ static struct platform_device *serial8250_isa_devs;
* 16x50 serial ports to be configured at run-time, to support PCMCIA
* modems and PCI multiport cards.
*/
-static DECLARE_MUTEX(serial_sem);
+static DEFINE_MUTEX(serial_mutex);
static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *port)
{
@@ -2522,7 +2523,7 @@ int serial8250_register_port(struct uart_port *port)
if (port->uartclk == 0)
return -EINVAL;
- down(&serial_sem);
+ mutex_lock(&serial_mutex);
uart = serial8250_find_match_or_unused(port);
if (uart) {
@@ -2544,7 +2545,7 @@ int serial8250_register_port(struct uart_port *port)
if (ret == 0)
ret = uart->port.line;
}
- up(&serial_sem);
+ mutex_unlock(&serial_mutex);
return ret;
}
@@ -2561,7 +2562,7 @@ void serial8250_unregister_port(int line)
{
struct uart_8250_port *uart = &serial8250_ports[line];
- down(&serial_sem);
+ mutex_lock(&serial_mutex);
uart_remove_one_port(&serial8250_reg, &uart->port);
if (serial8250_isa_devs) {
uart->port.flags &= ~UPF_BOOT_AUTOCONF;
@@ -2571,7 +2572,7 @@ void serial8250_unregister_port(int line)
} else {
uart->port.dev = NULL;
}
- up(&serial_sem);
+ mutex_unlock(&serial_mutex);
}
EXPORT_SYMBOL(serial8250_unregister_port);
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 698cb76819d95..843717275d497 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -280,6 +280,40 @@ config SERIAL_AMBA_PL011_CONSOLE
your boot loader (lilo or loadlin) about how to pass options to the
kernel at boot time.)
+config SERIAL_AT91
+ bool "AT91RM9200 serial port support"
+ depends on ARM && ARCH_AT91RM9200
+ select SERIAL_CORE
+ help
+ This enables the driver for the on-chip UARTs of the AT91RM9200
+ processor.
+
+config SERIAL_AT91_CONSOLE
+ bool "Support for console on AT91RM9200 serial port"
+ depends on SERIAL_AT91=y
+ select SERIAL_CORE_CONSOLE
+ help
+ Say Y here if you wish to use a UART on the AT91RM9200 as the system
+ console (the system console is the device which receives all kernel
+ messages and warnings and which allows logins in single user mode).
+
+config SERIAL_AT91_TTYAT
+ bool "Install as device ttyAT0-4 instead of ttyS0-4"
+ depends on SERIAL_AT91=y
+ help
+ Say Y here if you wish to have the five internal AT91RM9200 UARTs
+ appear as /dev/ttyAT0-4 (major 240, minor 0-4) instead of the
+ normal /dev/ttyS0-4 (major 4, minor 64-68). This is necessary if
+ you also want other UARTs, such as external 8250/16C550 compatible
+ UARTs.
+ The ttySn nodes are legally reserved for the 8250 serial driver
+ but are often misused by other serial drivers.
+
+ To use this, you should create suitable ttyATn device nodes in
+ /dev/, and pass "console=ttyATn" to the kernel.
+
+ Say Y if you have an external 8250/16C550 UART. If unsure, say N.
+
config SERIAL_CLPS711X
tristate "CLPS711X serial port support"
depends on ARM && ARCH_CLPS711X
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 137148bba4faa..24a583e482bbf 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -56,3 +56,4 @@ obj-$(CONFIG_SERIAL_JSM) += jsm/
obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o
obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o
obj-$(CONFIG_SERIAL_SGI_IOC4) += ioc4_serial.o
+obj-$(CONFIG_SERIAL_AT91) += at91_serial.o
diff --git a/drivers/serial/at91_serial.c b/drivers/serial/at91_serial.c
new file mode 100644
index 0000000000000..0e206063d6858
--- /dev/null
+++ b/drivers/serial/at91_serial.c
@@ -0,0 +1,894 @@
+/*
+ * linux/drivers/char/at91_serial.c
+ *
+ * Driver for Atmel AT91RM9200 Serial ports
+ *
+ * Copyright (C) 2003 Rick Bronson
+ *
+ * Based on drivers/char/serial_sa1100.c, by Deep Blue Solutions Ltd.
+ * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/tty.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/tty_flip.h>
+
+#include <asm/io.h>
+
+#include <asm/arch/at91rm9200_usart.h>
+#include <asm/mach/serial_at91rm9200.h>
+#include <asm/arch/board.h>
+#include <asm/arch/pio.h>
+
+
+#if defined(CONFIG_SERIAL_AT91_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/serial_core.h>
+
+#ifdef CONFIG_SERIAL_AT91_TTYAT
+
+/* Use device name ttyAT, major 204 and minor 154-169. This is necessary if we
+ * should coexist with the 8250 driver, such as if we have an external 16C550
+ * UART. */
+#define SERIAL_AT91_MAJOR 204
+#define MINOR_START 154
+#define AT91_DEVICENAME "ttyAT"
+
+#else
+
+/* Use device name ttyS, major 4, minor 64-68. This is the usual serial port
+ * name, but it is legally reserved for the 8250 driver. */
+#define SERIAL_AT91_MAJOR TTY_MAJOR
+#define MINOR_START 64
+#define AT91_DEVICENAME "ttyS"
+
+#endif
+
+#define AT91_VA_BASE_DBGU ((unsigned long) AT91_VA_BASE_SYS + AT91_DBGU)
+#define AT91_ISR_PASS_LIMIT 256
+
+#define UART_PUT_CR(port,v) writel(v, (port)->membase + AT91_US_CR)
+#define UART_GET_MR(port) readl((port)->membase + AT91_US_MR)
+#define UART_PUT_MR(port,v) writel(v, (port)->membase + AT91_US_MR)
+#define UART_PUT_IER(port,v) writel(v, (port)->membase + AT91_US_IER)
+#define UART_PUT_IDR(port,v) writel(v, (port)->membase + AT91_US_IDR)
+#define UART_GET_IMR(port) readl((port)->membase + AT91_US_IMR)
+#define UART_GET_CSR(port) readl((port)->membase + AT91_US_CSR)
+#define UART_GET_CHAR(port) readl((port)->membase + AT91_US_RHR)
+#define UART_PUT_CHAR(port,v) writel(v, (port)->membase + AT91_US_THR)
+#define UART_GET_BRGR(port) readl((port)->membase + AT91_US_BRGR)
+#define UART_PUT_BRGR(port,v) writel(v, (port)->membase + AT91_US_BRGR)
+#define UART_PUT_RTOR(port,v) writel(v, (port)->membase + AT91_US_RTOR)
+
+// #define UART_GET_CR(port) readl((port)->membase + AT91_US_CR) // is write-only
+
+ /* PDC registers */
+#define UART_PUT_PTCR(port,v) writel(v, (port)->membase + AT91_PDC_PTCR)
+#define UART_PUT_RPR(port,v) writel(v, (port)->membase + AT91_PDC_RPR)
+#define UART_PUT_RCR(port,v) writel(v, (port)->membase + AT91_PDC_RCR)
+#define UART_GET_RCR(port) readl((port)->membase + AT91_PDC_RCR)
+#define UART_PUT_RNPR(port,v) writel(v, (port)->membase + AT91_PDC_RNPR)
+#define UART_PUT_RNCR(port,v) writel(v, (port)->membase + AT91_PDC_RNCR)
+
+
+static int (*at91_open)(struct uart_port *);
+static void (*at91_close)(struct uart_port *);
+
+#ifdef SUPPORT_SYSRQ
+static struct console at91_console;
+#endif
+
+/*
+ * Return TIOCSER_TEMT when transmitter FIFO and Shift register is empty.
+ */
+static u_int at91_tx_empty(struct uart_port *port)
+{
+ return (UART_GET_CSR(port) & AT91_US_TXEMPTY) ? TIOCSER_TEMT : 0;
+}
+
+/*
+ * Set state of the modem control output lines
+ */
+static void at91_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+ unsigned int control = 0;
+
+ /*
+ * Errata #39: RTS0 is not internally connected to PA21. We need to drive
+ * the pin manually.
+ */
+ if (port->mapbase == AT91_VA_BASE_US0) {
+ if (mctrl & TIOCM_RTS)
+ at91_sys_write(AT91_PIOA + PIO_CODR, AT91_PA21_RTS0);
+ else
+ at91_sys_write(AT91_PIOA + PIO_SODR, AT91_PA21_RTS0);
+ }
+
+ if (mctrl & TIOCM_RTS)
+ control |= AT91_US_RTSEN;
+ else
+ control |= AT91_US_RTSDIS;
+
+ if (mctrl & TIOCM_DTR)
+ control |= AT91_US_DTREN;
+ else
+ control |= AT91_US_DTRDIS;
+
+ UART_PUT_CR(port,control);
+}
+
+/*
+ * Get state of the modem control input lines
+ */
+static u_int at91_get_mctrl(struct uart_port *port)
+{
+ unsigned int status, ret = 0;
+
+ status = UART_GET_CSR(port);
+
+ /*
+ * The control signals are active low.
+ */
+ if (!(status & AT91_US_DCD))
+ ret |= TIOCM_CD;
+ if (!(status & AT91_US_CTS))
+ ret |= TIOCM_CTS;
+ if (!(status & AT91_US_DSR))
+ ret |= TIOCM_DSR;
+ if (!(status & AT91_US_RI))
+ ret |= TIOCM_RI;
+
+ return ret;
+}
+
+/*
+ * Stop transmitting.
+ */
+static void at91_stop_tx(struct uart_port *port)
+{
+ UART_PUT_IDR(port, AT91_US_TXRDY);
+ port->read_status_mask &= ~AT91_US_TXRDY;
+}
+
+/*
+ * Start transmitting.
+ */
+static void at91_start_tx(struct uart_port *port)
+{
+ port->read_status_mask |= AT91_US_TXRDY;
+ UART_PUT_IER(port, AT91_US_TXRDY);
+}
+
+/*
+ * Stop receiving - port is in process of being closed.
+ */
+static void at91_stop_rx(struct uart_port *port)
+{
+ UART_PUT_IDR(port, AT91_US_RXRDY);
+}
+
+/*
+ * Enable modem status interrupts
+ */
+static void at91_enable_ms(struct uart_port *port)
+{
+ port->read_status_mask |= (AT91_US_RIIC | AT91_US_DSRIC | AT91_US_DCDIC | AT91_US_CTSIC);
+ UART_PUT_IER(port, AT91_US_RIIC | AT91_US_DSRIC | AT91_US_DCDIC | AT91_US_CTSIC);
+}
+
+/*
+ * Control the transmission of a break signal
+ */
+static void at91_break_ctl(struct uart_port *port, int break_state)
+{
+ if (break_state != 0)
+ UART_PUT_CR(port, AT91_US_STTBRK); /* start break */
+ else
+ UART_PUT_CR(port, AT91_US_STPBRK); /* stop break */
+}
+
+/*
+ * Characters received (called from interrupt handler)
+ */
+static void at91_rx_chars(struct uart_port *port, struct pt_regs *regs)
+{
+ struct tty_struct *tty = port->info->tty;
+ unsigned int status, ch, flg;
+
+ status = UART_GET_CSR(port) & port->read_status_mask;
+ while (status & (AT91_US_RXRDY)) {
+ ch = UART_GET_CHAR(port);
+
+ if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+ goto ignore_char;
+ port->icount.rx++;
+
+ flg = TTY_NORMAL;
+
+ /*
+ * note that the error handling code is
+ * out of the main execution path
+ */
+ if (unlikely(status & (AT91_US_PARE | AT91_US_FRAME | AT91_US_OVRE))) {
+ UART_PUT_CR(port, AT91_US_RSTSTA); /* clear error */
+ if (status & (AT91_US_PARE))
+ port->icount.parity++;
+ if (status & (AT91_US_FRAME))
+ port->icount.frame++;
+ if (status & (AT91_US_OVRE))
+ port->icount.overrun++;
+
+ if (status & AT91_US_PARE)
+ flg = TTY_PARITY;
+ else if (status & AT91_US_FRAME)
+ flg = TTY_FRAME;
+ if (status & AT91_US_OVRE) {
+ /*
+ * overrun does *not* affect the character
+ * we read from the FIFO
+ */
+ tty_insert_flip_char(tty, ch, flg);
+ ch = 0;
+ flg = TTY_OVERRUN;
+ }
+#ifdef SUPPORT_SYSRQ
+ port->sysrq = 0;
+#endif
+ }
+
+ if (uart_handle_sysrq_char(port, ch, regs))
+ goto ignore_char;
+
+ tty_insert_flip_char(tty, ch, flg);
+
+ ignore_char:
+ status = UART_GET_CSR(port) & port->read_status_mask;
+ }
+
+ tty_flip_buffer_push(tty);
+}
+
+/*
+ * Transmit characters (called from interrupt handler)
+ */
+static void at91_tx_chars(struct uart_port *port)
+{
+ struct circ_buf *xmit = &port->info->xmit;
+
+ if (port->x_char) {
+ UART_PUT_CHAR(port, port->x_char);
+ port->icount.tx++;
+ port->x_char = 0;
+ return;
+ }
+ if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+ at91_stop_tx(port);
+ return;
+ }
+
+ while (UART_GET_CSR(port) & AT91_US_TXRDY) {
+ UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+ port->icount.tx++;
+ if (uart_circ_empty(xmit))
+ break;
+ }
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(port);
+
+ if (uart_circ_empty(xmit))
+ at91_stop_tx(port);
+}
+
+/*
+ * Interrupt handler
+ */
+static irqreturn_t at91_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct uart_port *port = dev_id;
+ unsigned int status, pending, pass_counter = 0;
+
+ status = UART_GET_CSR(port);
+ pending = status & port->read_status_mask;
+ if (pending) {
+ do {
+ if (pending & AT91_US_RXRDY)
+ at91_rx_chars(port, regs);
+
+ /* Clear the relevent break bits */
+ if (pending & AT91_US_RXBRK) {
+ UART_PUT_CR(port, AT91_US_RSTSTA);
+ port->icount.brk++;
+ uart_handle_break(port);
+ }
+
+ // TODO: All reads to CSR will clear these interrupts!
+ if (pending & AT91_US_RIIC) port->icount.rng++;
+ if (pending & AT91_US_DSRIC) port->icount.dsr++;
+ if (pending & AT91_US_DCDIC)
+ uart_handle_dcd_change(port, !(status & AT91_US_DCD));
+ if (pending & AT91_US_CTSIC)
+ uart_handle_cts_change(port, !(status & AT91_US_CTS));
+ if (pending & (AT91_US_RIIC | AT91_US_DSRIC | AT91_US_DCDIC | AT91_US_CTSIC))
+ wake_up_interruptible(&port->info->delta_msr_wait);
+
+ if (pending & AT91_US_TXRDY)
+ at91_tx_chars(port);
+ if (pass_counter++ > AT91_ISR_PASS_LIMIT)
+ break;
+
+ status = UART_GET_CSR(port);
+ pending = status & port->read_status_mask;
+ } while (pending);
+ }
+ return IRQ_HANDLED;
+}
+
+/*
+ * Perform initialization and enable port for reception
+ */
+static int at91_startup(struct uart_port *port)
+{
+ int retval;
+
+ /*
+ * Ensure that no interrupts are enabled otherwise when
+ * request_irq() is called we could get stuck trying to
+ * handle an unexpected interrupt
+ */
+ UART_PUT_IDR(port, -1);
+
+ /*
+ * Allocate the IRQ
+ */
+ retval = request_irq(port->irq, at91_interrupt, SA_SHIRQ, "at91_serial", port);
+ if (retval) {
+ printk("at91_serial: at91_startup - Can't get irq\n");
+ return retval;
+ }
+
+ /*
+ * If there is a specific "open" function (to register
+ * control line interrupts)
+ */
+ if (at91_open) {
+ retval = at91_open(port);
+ if (retval) {
+ free_irq(port->irq, port);
+ return retval;
+ }
+ }
+
+ port->read_status_mask = AT91_US_RXRDY | AT91_US_TXRDY | AT91_US_OVRE
+ | AT91_US_FRAME | AT91_US_PARE | AT91_US_RXBRK;
+ /*
+ * Finally, enable the serial port
+ */
+ UART_PUT_CR(port, AT91_US_RSTSTA | AT91_US_RSTRX);
+ UART_PUT_CR(port, AT91_US_TXEN | AT91_US_RXEN); /* enable xmit & rcvr */
+ UART_PUT_IER(port, AT91_US_RXRDY); /* do receive only */
+ return 0;
+}
+
+/*
+ * Disable the port
+ */
+static void at91_shutdown(struct uart_port *port)
+{
+ /*
+ * Disable all interrupts, port and break condition.
+ */
+ UART_PUT_CR(port, AT91_US_RSTSTA);
+ UART_PUT_IDR(port, -1);
+
+ /*
+ * Free the interrupt
+ */
+ free_irq(port->irq, port);
+
+ /*
+ * If there is a specific "close" function (to unregister
+ * control line interrupts)
+ */
+ if (at91_close)
+ at91_close(port);
+}
+
+/*
+ * Power / Clock management.
+ */
+static void at91_serial_pm(struct uart_port *port, unsigned int state, unsigned int oldstate)
+{
+ switch (state) {
+ case 0:
+ /*
+ * Enable the peripheral clock for this serial port.
+ * This is called on uart_open() or a resume event.
+ */
+ at91_sys_write(AT91_PMC_PCER, 1 << port->irq);
+ break;
+ case 3:
+ /*
+ * Disable the peripheral clock for this serial port.
+ * This is called on uart_close() or a suspend event.
+ */
+ if (port->irq != AT91_ID_SYS) /* is this a shared clock? */
+ at91_sys_write(AT91_PMC_PCDR, 1 << port->irq);
+ break;
+ default:
+ printk(KERN_ERR "at91_serial: unknown pm %d\n", state);
+ }
+}
+
+/*
+ * Change the port parameters
+ */
+static void at91_set_termios(struct uart_port *port, struct termios * termios, struct termios * old)
+{
+ unsigned long flags;
+ unsigned int mode, imr, quot, baud;
+
+ baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
+ quot = uart_get_divisor(port, baud);
+
+ /* Get current mode register */
+ mode = UART_GET_MR(port) & ~(AT91_US_CHRL | AT91_US_NBSTOP | AT91_US_PAR);
+
+ /* byte size */
+ switch (termios->c_cflag & CSIZE) {
+ case CS5:
+ mode |= AT91_US_CHRL_5;
+ break;
+ case CS6:
+ mode |= AT91_US_CHRL_6;
+ break;
+ case CS7:
+ mode |= AT91_US_CHRL_7;
+ break;
+ default:
+ mode |= AT91_US_CHRL_8;
+ break;
+ }
+
+ /* stop bits */
+ if (termios->c_cflag & CSTOPB)
+ mode |= AT91_US_NBSTOP_2;
+
+ /* parity */
+ if (termios->c_cflag & PARENB) {
+ if (termios->c_cflag & CMSPAR) { /* Mark or Space parity */
+ if (termios->c_cflag & PARODD)
+ mode |= AT91_US_PAR_MARK;
+ else
+ mode |= AT91_US_PAR_SPACE;
+ }
+ else if (termios->c_cflag & PARODD)
+ mode |= AT91_US_PAR_ODD;
+ else
+ mode |= AT91_US_PAR_EVEN;
+ }
+ else
+ mode |= AT91_US_PAR_NONE;
+
+ spin_lock_irqsave(&port->lock, flags);
+
+ port->read_status_mask |= AT91_US_OVRE;
+ if (termios->c_iflag & INPCK)
+ port->read_status_mask |= AT91_US_FRAME | AT91_US_PARE;
+ if (termios->c_iflag & (BRKINT | PARMRK))
+ port->read_status_mask |= AT91_US_RXBRK;
+
+ /*
+ * Characters to ignore
+ */
+ port->ignore_status_mask = 0;
+ if (termios->c_iflag & IGNPAR)
+ port->ignore_status_mask |= (AT91_US_FRAME | AT91_US_PARE);
+ if (termios->c_iflag & IGNBRK) {
+ port->ignore_status_mask |= AT91_US_RXBRK;
+ /*
+ * If we're ignoring parity and break indicators,
+ * ignore overruns too (for real raw support).
+ */
+ if (termios->c_iflag & IGNPAR)
+ port->ignore_status_mask |= AT91_US_OVRE;
+ }
+
+ // TODO: Ignore all characters if CREAD is set.
+
+ /* update the per-port timeout */
+ uart_update_timeout(port, termios->c_cflag, baud);
+
+ /* disable interrupts and drain transmitter */
+ imr = UART_GET_IMR(port); /* get interrupt mask */
+ UART_PUT_IDR(port, -1); /* disable all interrupts */
+ while (!(UART_GET_CSR(port) & AT91_US_TXEMPTY)) { barrier(); }
+
+ /* disable receiver and transmitter */
+ UART_PUT_CR(port, AT91_US_TXDIS | AT91_US_RXDIS);
+
+ /* set the parity, stop bits and data size */
+ UART_PUT_MR(port, mode);
+
+ /* set the baud rate */
+ UART_PUT_BRGR(port, quot);
+ UART_PUT_CR(port, AT91_US_RSTSTA | AT91_US_RSTRX);
+ UART_PUT_CR(port, AT91_US_TXEN | AT91_US_RXEN);
+
+ /* restore interrupts */
+ UART_PUT_IER(port, imr);
+
+ /* CTS flow-control and modem-status interrupts */
+ if (UART_ENABLE_MS(port, termios->c_cflag))
+ port->ops->enable_ms(port);
+
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/*
+ * Return string describing the specified port
+ */
+static const char *at91_type(struct uart_port *port)
+{
+ return (port->type == PORT_AT91RM9200) ? "AT91_SERIAL" : NULL;
+}
+
+/*
+ * Release the memory region(s) being used by 'port'.
+ */
+static void at91_release_port(struct uart_port *port)
+{
+ release_mem_region(port->mapbase,
+ (port->mapbase == AT91_VA_BASE_DBGU) ? 512 : SZ_16K);
+}
+
+/*
+ * Request the memory region(s) being used by 'port'.
+ */
+static int at91_request_port(struct uart_port *port)
+{
+ return request_mem_region(port->mapbase,
+ (port->mapbase == AT91_VA_BASE_DBGU) ? 512 : SZ_16K,
+ "at91_serial") != NULL ? 0 : -EBUSY;
+
+}
+
+/*
+ * Configure/autoconfigure the port.
+ */
+static void at91_config_port(struct uart_port *port, int flags)
+{
+ if (flags & UART_CONFIG_TYPE) {
+ port->type = PORT_AT91RM9200;
+ at91_request_port(port);
+ }
+}
+
+/*
+ * Verify the new serial_struct (for TIOCSSERIAL).
+ */
+static int at91_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+ int ret = 0;
+ if (ser->type != PORT_UNKNOWN && ser->type != PORT_AT91RM9200)
+ ret = -EINVAL;
+ if (port->irq != ser->irq)
+ ret = -EINVAL;
+ if (ser->io_type != SERIAL_IO_MEM)
+ ret = -EINVAL;
+ if (port->uartclk / 16 != ser->baud_base)
+ ret = -EINVAL;
+ if ((void *)port->mapbase != ser->iomem_base)
+ ret = -EINVAL;
+ if (port->iobase != ser->port)
+ ret = -EINVAL;
+ if (ser->hub6 != 0)
+ ret = -EINVAL;
+ return ret;
+}
+
+static struct uart_ops at91_pops = {
+ .tx_empty = at91_tx_empty,
+ .set_mctrl = at91_set_mctrl,
+ .get_mctrl = at91_get_mctrl,
+ .stop_tx = at91_stop_tx,
+ .start_tx = at91_start_tx,
+ .stop_rx = at91_stop_rx,
+ .enable_ms = at91_enable_ms,
+ .break_ctl = at91_break_ctl,
+ .startup = at91_startup,
+ .shutdown = at91_shutdown,
+ .set_termios = at91_set_termios,
+ .type = at91_type,
+ .release_port = at91_release_port,
+ .request_port = at91_request_port,
+ .config_port = at91_config_port,
+ .verify_port = at91_verify_port,
+ .pm = at91_serial_pm,
+};
+
+static struct uart_port at91_ports[AT91_NR_UART];
+
+void __init at91_init_ports(void)
+{
+ static int first = 1;
+ int i;
+
+ if (!first)
+ return;
+ first = 0;
+
+ for (i = 0; i < AT91_NR_UART; i++) {
+ at91_ports[i].iotype = UPIO_MEM;
+ at91_ports[i].flags = UPF_BOOT_AUTOCONF;
+ at91_ports[i].uartclk = at91_master_clock;
+ at91_ports[i].ops = &at91_pops;
+ at91_ports[i].fifosize = 1;
+ at91_ports[i].line = i;
+ }
+}
+
+void __init at91_register_uart_fns(struct at91rm9200_port_fns *fns)
+{
+ if (fns->enable_ms)
+ at91_pops.enable_ms = fns->enable_ms;
+ if (fns->get_mctrl)
+ at91_pops.get_mctrl = fns->get_mctrl;
+ if (fns->set_mctrl)
+ at91_pops.set_mctrl = fns->set_mctrl;
+ at91_open = fns->open;
+ at91_close = fns->close;
+ at91_pops.pm = fns->pm;
+ at91_pops.set_wake = fns->set_wake;
+}
+
+/*
+ * Setup ports.
+ */
+void __init at91_register_uart(int idx, int port)
+{
+ if ((idx < 0) || (idx >= AT91_NR_UART)) {
+ printk(KERN_ERR "%s: bad index number %d\n", __FUNCTION__, idx);
+ return;
+ }
+
+ switch (port) {
+ case 0:
+ at91_ports[idx].membase = (void __iomem *) AT91_VA_BASE_US0;
+ at91_ports[idx].mapbase = AT91_VA_BASE_US0;
+ at91_ports[idx].irq = AT91_ID_US0;
+ AT91_CfgPIO_USART0();
+ break;
+ case 1:
+ at91_ports[idx].membase = (void __iomem *) AT91_VA_BASE_US1;
+ at91_ports[idx].mapbase = AT91_VA_BASE_US1;
+ at91_ports[idx].irq = AT91_ID_US1;
+ AT91_CfgPIO_USART1();
+ break;
+ case 2:
+ at91_ports[idx].membase = (void __iomem *) AT91_VA_BASE_US2;
+ at91_ports[idx].mapbase = AT91_VA_BASE_US2;
+ at91_ports[idx].irq = AT91_ID_US2;
+ AT91_CfgPIO_USART2();
+ break;
+ case 3:
+ at91_ports[idx].membase = (void __iomem *) AT91_VA_BASE_US3;
+ at91_ports[idx].mapbase = AT91_VA_BASE_US3;
+ at91_ports[idx].irq = AT91_ID_US3;
+ AT91_CfgPIO_USART3();
+ break;
+ case 4:
+ at91_ports[idx].membase = (void __iomem *) AT91_VA_BASE_DBGU;
+ at91_ports[idx].mapbase = AT91_VA_BASE_DBGU;
+ at91_ports[idx].irq = AT91_ID_SYS;
+ AT91_CfgPIO_DBGU();
+ break;
+ default:
+ printk(KERN_ERR "%s : bad port number %d\n", __FUNCTION__, port);
+ }
+}
+
+#ifdef CONFIG_SERIAL_AT91_CONSOLE
+
+/*
+ * Interrupts are disabled on entering
+ */
+static void at91_console_write(struct console *co, const char *s, u_int count)
+{
+ struct uart_port *port = at91_ports + co->index;
+ unsigned int status, i, imr;
+
+ /*
+ * First, save IMR and then disable interrupts
+ */
+ imr = UART_GET_IMR(port); /* get interrupt mask */
+ UART_PUT_IDR(port, AT91_US_RXRDY | AT91_US_TXRDY);
+
+ /*
+ * Now, do each character
+ */
+ for (i = 0; i < count; i++) {
+ do {
+ status = UART_GET_CSR(port);
+ } while (!(status & AT91_US_TXRDY));
+ UART_PUT_CHAR(port, s[i]);
+ if (s[i] == '\n') {
+ do {
+ status = UART_GET_CSR(port);
+ } while (!(status & AT91_US_TXRDY));
+ UART_PUT_CHAR(port, '\r');
+ }
+ }
+
+ /*
+ * Finally, wait for transmitter to become empty
+ * and restore IMR
+ */
+ do {
+ status = UART_GET_CSR(port);
+ } while (!(status & AT91_US_TXRDY));
+ UART_PUT_IER(port, imr); /* set interrupts back the way they were */
+}
+
+/*
+ * If the port was already initialised (eg, by a boot loader), try to determine
+ * the current setup.
+ */
+static void __init at91_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
+{
+ unsigned int mr, quot;
+
+// TODO: CR is a write-only register
+// unsigned int cr;
+//
+// cr = UART_GET_CR(port) & (AT91_US_RXEN | AT91_US_TXEN);
+// if (cr == (AT91_US_RXEN | AT91_US_TXEN)) {
+// /* ok, the port was enabled */
+// }
+
+ mr = UART_GET_MR(port) & AT91_US_CHRL;
+ if (mr == AT91_US_CHRL_8)
+ *bits = 8;
+ else
+ *bits = 7;
+
+ mr = UART_GET_MR(port) & AT91_US_PAR;
+ if (mr == AT91_US_PAR_EVEN)
+ *parity = 'e';
+ else if (mr == AT91_US_PAR_ODD)
+ *parity = 'o';
+
+ quot = UART_GET_BRGR(port);
+ *baud = port->uartclk / (16 * (quot));
+}
+
+static int __init at91_console_setup(struct console *co, char *options)
+{
+ struct uart_port *port;
+ int baud = 115200;
+ int bits = 8;
+ int parity = 'n';
+ int flow = 'n';
+
+ /*
+ * Check whether an invalid uart number has been specified, and
+ * if so, search for the first available port that does have
+ * console support.
+ */
+ port = uart_get_console(at91_ports, AT91_NR_UART, co);
+
+ /*
+ * Enable the serial console, in-case bootloader did not do it.
+ */
+ at91_sys_write(AT91_PMC_PCER, 1 << port->irq); /* enable clock */
+ UART_PUT_IDR(port, -1); /* disable interrupts */
+ UART_PUT_CR(port, AT91_US_RSTSTA | AT91_US_RSTRX);
+ UART_PUT_CR(port, AT91_US_TXEN | AT91_US_RXEN);
+
+ if (options)
+ uart_parse_options(options, &baud, &parity, &bits, &flow);
+ else
+ at91_console_get_options(port, &baud, &parity, &bits);
+
+ return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct uart_driver at91_uart;
+
+static struct console at91_console = {
+ .name = AT91_DEVICENAME,
+ .write = at91_console_write,
+ .device = uart_console_device,
+ .setup = at91_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+ .data = &at91_uart,
+};
+
+#define AT91_CONSOLE_DEVICE &at91_console
+
+static int __init at91_console_init(void)
+{
+ at91_init_ports();
+
+ at91_console.index = at91_console_port;
+ register_console(&at91_console);
+ return 0;
+}
+console_initcall(at91_console_init);
+
+#else
+#define AT91_CONSOLE_DEVICE NULL
+#endif
+
+static struct uart_driver at91_uart = {
+ .owner = THIS_MODULE,
+ .driver_name = AT91_DEVICENAME,
+ .dev_name = AT91_DEVICENAME,
+ .devfs_name = AT91_DEVICENAME,
+ .major = SERIAL_AT91_MAJOR,
+ .minor = MINOR_START,
+ .nr = AT91_NR_UART,
+ .cons = AT91_CONSOLE_DEVICE,
+};
+
+static int __init at91_serial_init(void)
+{
+ int ret, i;
+
+ at91_init_ports();
+
+ ret = uart_register_driver(&at91_uart);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < AT91_NR_UART; i++) {
+ if (at91_serial_map[i] >= 0)
+ uart_add_one_port(&at91_uart, &at91_ports[i]);
+ }
+
+ return 0;
+}
+
+static void __exit at91_serial_exit(void)
+{
+ int i;
+
+ for (i = 0; i < AT91_NR_UART; i++) {
+ if (at91_serial_map[i] >= 0)
+ uart_remove_one_port(&at91_uart, &at91_ports[i]);
+ }
+
+ uart_unregister_driver(&at91_uart);
+}
+
+module_init(at91_serial_init);
+module_exit(at91_serial_exit);
+
+MODULE_AUTHOR("Rick Bronson");
+MODULE_DESCRIPTION("AT91 generic serial port driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index 08c42c0001884..be12623d85447 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -442,6 +442,7 @@ static char *serial_version = "$Revision: 1.25 $";
#include <linux/init.h>
#include <asm/uaccess.h>
#include <linux/kernel.h>
+#include <linux/mutex.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -1315,11 +1316,7 @@ static const struct control_pins e100_modem_pins[NR_PORTS] =
* memory if large numbers of serial ports are open.
*/
static unsigned char *tmp_buf;
-#ifdef DECLARE_MUTEX
-static DECLARE_MUTEX(tmp_buf_sem);
-#else
-static struct semaphore tmp_buf_sem = MUTEX;
-#endif
+static DEFINE_MUTEX(tmp_buf_mutex);
/* Calculate the chartime depending on baudrate, numbor of bits etc. */
static void update_char_time(struct e100_serial * info)
@@ -3661,7 +3658,7 @@ rs_raw_write(struct tty_struct * tty, int from_user,
* design.
*/
if (from_user) {
- down(&tmp_buf_sem);
+ mutex_lock(&tmp_buf_mutex);
while (1) {
int c1;
c = CIRC_SPACE_TO_END(info->xmit.head,
@@ -3692,7 +3689,7 @@ rs_raw_write(struct tty_struct * tty, int from_user,
count -= c;
ret += c;
}
- up(&tmp_buf_sem);
+ mutex_unlock(&tmp_buf_mutex);
} else {
cli();
while (count) {
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index f330d6c0e0dfa..5f52883e64d2a 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -60,6 +60,7 @@
#include <linux/pmu.h>
#include <linux/bitops.h>
#include <linux/sysrq.h>
+#include <linux/mutex.h>
#include <asm/sections.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -96,7 +97,7 @@ MODULE_LICENSE("GPL");
*/
static struct uart_pmac_port pmz_ports[MAX_ZS_PORTS];
static int pmz_ports_count;
-static DECLARE_MUTEX(pmz_irq_sem);
+static DEFINE_MUTEX(pmz_irq_mutex);
static struct uart_driver pmz_uart_reg = {
.owner = THIS_MODULE,
@@ -922,7 +923,7 @@ static int pmz_startup(struct uart_port *port)
if (uap->node == NULL)
return -ENODEV;
- down(&pmz_irq_sem);
+ mutex_lock(&pmz_irq_mutex);
uap->flags |= PMACZILOG_FLAG_IS_OPEN;
@@ -940,11 +941,11 @@ static int pmz_startup(struct uart_port *port)
dev_err(&uap->dev->ofdev.dev,
"Unable to register zs interrupt handler.\n");
pmz_set_scc_power(uap, 0);
- up(&pmz_irq_sem);
+ mutex_unlock(&pmz_irq_mutex);
return -ENXIO;
}
- up(&pmz_irq_sem);
+ mutex_unlock(&pmz_irq_mutex);
/* Right now, we deal with delay by blocking here, I'll be
* smarter later on
@@ -981,7 +982,7 @@ static void pmz_shutdown(struct uart_port *port)
if (uap->node == NULL)
return;
- down(&pmz_irq_sem);
+ mutex_lock(&pmz_irq_mutex);
/* Release interrupt handler */
free_irq(uap->port.irq, uap);
@@ -1002,7 +1003,7 @@ static void pmz_shutdown(struct uart_port *port)
if (ZS_IS_CONS(uap) || ZS_IS_ASLEEP(uap)) {
spin_unlock_irqrestore(&port->lock, flags);
- up(&pmz_irq_sem);
+ mutex_unlock(&pmz_irq_mutex);
return;
}
@@ -1019,7 +1020,7 @@ static void pmz_shutdown(struct uart_port *port)
spin_unlock_irqrestore(&port->lock, flags);
- up(&pmz_irq_sem);
+ mutex_unlock(&pmz_irq_mutex);
pmz_debug("pmz: shutdown() done.\n");
}
@@ -1591,7 +1592,7 @@ static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state)
state = pmz_uart_reg.state + uap->port.line;
- down(&pmz_irq_sem);
+ mutex_lock(&pmz_irq_mutex);
down(&state->sem);
spin_lock_irqsave(&uap->port.lock, flags);
@@ -1624,7 +1625,7 @@ static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state)
pmz_set_scc_power(uap, 0);
up(&state->sem);
- up(&pmz_irq_sem);
+ mutex_unlock(&pmz_irq_mutex);
pmz_debug("suspend, switching complete\n");
@@ -1651,7 +1652,7 @@ static int pmz_resume(struct macio_dev *mdev)
state = pmz_uart_reg.state + uap->port.line;
- down(&pmz_irq_sem);
+ mutex_lock(&pmz_irq_mutex);
down(&state->sem);
spin_lock_irqsave(&uap->port.lock, flags);
@@ -1685,7 +1686,7 @@ static int pmz_resume(struct macio_dev *mdev)
bail:
up(&state->sem);
- up(&pmz_irq_sem);
+ mutex_unlock(&pmz_irq_mutex);
/* Right now, we deal with delay by blocking here, I'll be
* smarter later on
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 9589509fc5bd7..2ca620900bcc2 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -33,6 +33,7 @@
#include <linux/device.h>
#include <linux/serial.h> /* for serial_state and serial_icounter_struct */
#include <linux/delay.h>
+#include <linux/mutex.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
@@ -47,7 +48,7 @@
/*
* This is used to lock changes in serial line configuration.
*/
-static DECLARE_MUTEX(port_sem);
+static DEFINE_MUTEX(port_mutex);
#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
@@ -1472,7 +1473,7 @@ static struct uart_state *uart_get(struct uart_driver *drv, int line)
{
struct uart_state *state;
- down(&port_sem);
+ mutex_lock(&port_mutex);
state = drv->state + line;
if (down_interruptible(&state->sem)) {
state = ERR_PTR(-ERESTARTSYS);
@@ -1509,7 +1510,7 @@ static struct uart_state *uart_get(struct uart_driver *drv, int line)
}
out:
- up(&port_sem);
+ mutex_unlock(&port_mutex);
return state;
}
@@ -2219,7 +2220,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
state = drv->state + port->line;
- down(&port_sem);
+ mutex_lock(&port_mutex);
if (state->port) {
ret = -EINVAL;
goto out;
@@ -2255,7 +2256,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
register_console(port->cons);
out:
- up(&port_sem);
+ mutex_unlock(&port_mutex);
return ret;
}
@@ -2279,7 +2280,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
printk(KERN_ALERT "Removing wrong port: %p != %p\n",
state->port, port);
- down(&port_sem);
+ mutex_lock(&port_mutex);
/*
* Remove the devices from devfs
@@ -2288,7 +2289,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
uart_unconfigure_port(drv, state);
state->port = NULL;
- up(&port_sem);
+ mutex_unlock(&port_mutex);
return 0;
}
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index fdd1f1915a427..ee98a867bc6da 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -52,6 +52,7 @@
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
+#include <linux/mutex.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -1018,7 +1019,7 @@ static void serial_txx9_resume_port(int line)
uart_resume_port(&serial_txx9_reg, &serial_txx9_ports[line].port);
}
-static DECLARE_MUTEX(serial_txx9_sem);
+static DEFINE_MUTEX(serial_txx9_mutex);
/**
* serial_txx9_register_port - register a serial port
@@ -1037,7 +1038,7 @@ static int __devinit serial_txx9_register_port(struct uart_port *port)
struct uart_txx9_port *uart;
int ret = -ENOSPC;
- down(&serial_txx9_sem);
+ mutex_lock(&serial_txx9_mutex);
for (i = 0; i < UART_NR; i++) {
uart = &serial_txx9_ports[i];
if (uart->port.type == PORT_UNKNOWN)
@@ -1058,7 +1059,7 @@ static int __devinit serial_txx9_register_port(struct uart_port *port)
if (ret == 0)
ret = uart->port.line;
}
- up(&serial_txx9_sem);
+ mutex_unlock(&serial_txx9_mutex);
return ret;
}
@@ -1073,7 +1074,7 @@ static void __devexit serial_txx9_unregister_port(int line)
{
struct uart_txx9_port *uart = &serial_txx9_ports[line];
- down(&serial_txx9_sem);
+ mutex_lock(&serial_txx9_mutex);
uart_remove_one_port(&serial_txx9_reg, &uart->port);
uart->port.flags = 0;
uart->port.type = PORT_UNKNOWN;
@@ -1082,7 +1083,7 @@ static void __devexit serial_txx9_unregister_port(int line)
uart->port.membase = 0;
uart->port.dev = NULL;
uart_add_one_port(&serial_txx9_reg, &uart->port);
- up(&serial_txx9_sem);
+ mutex_unlock(&serial_txx9_mutex);
}
/*
diff --git a/include/asm-arm/arch-at91rm9200/at91rm9200_pdc.h b/include/asm-arm/arch-at91rm9200/at91rm9200_pdc.h
new file mode 100644
index 0000000000000..ce1150d4438d4
--- /dev/null
+++ b/include/asm-arm/arch-at91rm9200/at91rm9200_pdc.h
@@ -0,0 +1,36 @@
+/*
+ * include/asm-arm/arch-at91rm9200/at91rm9200_pdc.h
+ *
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * Peripheral Data Controller (PDC) registers.
+ * Based on AT91RM9200 datasheet revision E.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef AT91RM9200_PDC_H
+#define AT91RM9200_PDC_H
+
+#define AT91_PDC_RPR 0x100 /* Receive Pointer Register */
+#define AT91_PDC_RCR 0x104 /* Receive Counter Register */
+#define AT91_PDC_TPR 0x108 /* Transmit Pointer Register */
+#define AT91_PDC_TCR 0x10c /* Transmit Counter Register */
+#define AT91_PDC_RNPR 0x110 /* Receive Next Pointer Register */
+#define AT91_PDC_RNCR 0x114 /* Receive Next Counter Register */
+#define AT91_PDC_TNPR 0x118 /* Transmit Next Pointer Register */
+#define AT91_PDC_TNCR 0x11c /* Transmit Next Counter Register */
+
+#define AT91_PDC_PTCR 0x120 /* Transfer Control Register */
+#define AT91_PDC_RXTEN (1 << 0) /* Receiver Transfer Enable */
+#define AT91_PDC_RXTDIS (1 << 1) /* Receiver Transfer Disable */
+#define AT91_PDC_TXTEN (1 << 8) /* Transmitter Transfer Enable */
+#define AT91_PDC_TXTDIS (1 << 9) /* Transmitter Transfer Disable */
+
+#define AT91_PDC_PTSR 0x124 /* Transfer Status Register */
+
+#endif
diff --git a/include/asm-arm/arch-at91rm9200/at91rm9200_usart.h b/include/asm-arm/arch-at91rm9200/at91rm9200_usart.h
new file mode 100644
index 0000000000000..79f851e31b9c5
--- /dev/null
+++ b/include/asm-arm/arch-at91rm9200/at91rm9200_usart.h
@@ -0,0 +1,123 @@
+/*
+ * include/asm-arm/arch-at91rm9200/at91rm9200_usart.h
+ *
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * USART registers.
+ * Based on AT91RM9200 datasheet revision E.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef AT91RM9200_USART_H
+#define AT91RM9200_USART_H
+
+#define AT91_US_CR 0x00 /* Control Register */
+#define AT91_US_RSTRX (1 << 2) /* Reset Receiver */
+#define AT91_US_RSTTX (1 << 3) /* Reset Transmitter */
+#define AT91_US_RXEN (1 << 4) /* Receiver Enable */
+#define AT91_US_RXDIS (1 << 5) /* Receiver Disable */
+#define AT91_US_TXEN (1 << 6) /* Transmitter Enable */
+#define AT91_US_TXDIS (1 << 7) /* Transmitter Disable */
+#define AT91_US_RSTSTA (1 << 8) /* Reset Status Bits */
+#define AT91_US_STTBRK (1 << 9) /* Start Break */
+#define AT91_US_STPBRK (1 << 10) /* Stop Break */
+#define AT91_US_STTTO (1 << 11) /* Start Time-out */
+#define AT91_US_SENDA (1 << 12) /* Send Address */
+#define AT91_US_RSTIT (1 << 13) /* Reset Iterations */
+#define AT91_US_RSTNACK (1 << 14) /* Reset Non Acknowledge */
+#define AT91_US_RETTO (1 << 15) /* Rearm Time-out */
+#define AT91_US_DTREN (1 << 16) /* Data Terminal Ready Enable */
+#define AT91_US_DTRDIS (1 << 17) /* Data Terminal Ready Disable */
+#define AT91_US_RTSEN (1 << 18) /* Request To Send Enable */
+#define AT91_US_RTSDIS (1 << 19) /* Request To Send Disable */
+
+#define AT91_US_MR 0x04 /* Mode Register */
+#define AT91_US_USMODE (0xf << 0) /* Mode of the USART */
+#define AT91_US_USMODE_NORMAL 0
+#define AT91_US_USMODE_RS485 1
+#define AT91_US_USMODE_HWHS 2
+#define AT91_US_USMODE_MODEM 3
+#define AT91_US_USMODE_ISO7816_T0 4
+#define AT91_US_USMODE_ISO7816_T1 6
+#define AT91_US_USMODE_IRDA 8
+#define AT91_US_USCLKS (3 << 4) /* Clock Selection */
+#define AT91_US_CHRL (3 << 6) /* Character Length */
+#define AT91_US_CHRL_5 (0 << 6)
+#define AT91_US_CHRL_6 (1 << 6)
+#define AT91_US_CHRL_7 (2 << 6)
+#define AT91_US_CHRL_8 (3 << 6)
+#define AT91_US_SYNC (1 << 8) /* Synchronous Mode Select */
+#define AT91_US_PAR (7 << 9) /* Parity Type */
+#define AT91_US_PAR_EVEN (0 << 9)
+#define AT91_US_PAR_ODD (1 << 9)
+#define AT91_US_PAR_SPACE (2 << 9)
+#define AT91_US_PAR_MARK (3 << 9)
+#define AT91_US_PAR_NONE (4 << 9)
+#define AT91_US_PAR_MULTI_DROP (6 << 9)
+#define AT91_US_NBSTOP (3 << 12) /* Number of Stop Bits */
+#define AT91_US_NBSTOP_1 (0 << 12)
+#define AT91_US_NBSTOP_1_5 (1 << 12)
+#define AT91_US_NBSTOP_2 (2 << 12)
+#define AT91_US_CHMODE (3 << 14) /* Channel Mode */
+#define AT91_US_CHMODE_NORMAL (0 << 14)
+#define AT91_US_CHMODE_ECHO (1 << 14)
+#define AT91_US_CHMODE_LOC_LOOP (2 << 14)
+#define AT91_US_CHMODE_REM_LOOP (3 << 14)
+#define AT91_US_MSBF (1 << 16) /* Bit Order */
+#define AT91_US_MODE9 (1 << 17) /* 9-bit Character Length */
+#define AT91_US_CLKO (1 << 18) /* Clock Output Select */
+#define AT91_US_OVER (1 << 19) /* Oversampling Mode */
+#define AT91_US_INACK (1 << 20) /* Inhibit Non Acknowledge */
+#define AT91_US_DSNACK (1 << 21) /* Disable Successive NACK */
+#define AT91_US_MAX_ITER (7 << 24) /* Max Iterations */
+#define AT91_US_FILTER (1 << 28) /* Infrared Receive Line Filter */
+
+#define AT91_US_IER 0x08 /* Interrupt Enable Register */
+#define AT91_US_RXRDY (1 << 0) /* Receiver Ready */
+#define AT91_US_TXRDY (1 << 1) /* Transmitter Ready */
+#define AT91_US_RXBRK (1 << 2) /* Break Received / End of Break */
+#define AT91_US_ENDRX (1 << 3) /* End of Receiver Transfer */
+#define AT91_US_ENDTX (1 << 4) /* End of Transmitter Transfer */
+#define AT91_US_OVRE (1 << 5) /* Overrun Error */
+#define AT91_US_FRAME (1 << 6) /* Framing Error */
+#define AT91_US_PARE (1 << 7) /* Parity Error */
+#define AT91_US_TIMEOUT (1 << 8) /* Receiver Time-out */
+#define AT91_US_TXEMPTY (1 << 9) /* Transmitter Empty */
+#define AT91_US_ITERATION (1 << 10) /* Max number of Repetitions Reached */
+#define AT91_US_TXBUFE (1 << 11) /* Transmission Buffer Empty */
+#define AT91_US_RXBUFF (1 << 12) /* Reception Buffer Full */
+#define AT91_US_NACK (1 << 13) /* Non Acknowledge */
+#define AT91_US_RIIC (1 << 16) /* Ring Indicator Input Change */
+#define AT91_US_DSRIC (1 << 17) /* Data Set Ready Input Change */
+#define AT91_US_DCDIC (1 << 18) /* Data Carrier Detect Input Change */
+#define AT91_US_CTSIC (1 << 19) /* Clear to Send Input Change */
+#define AT91_US_RI (1 << 20) /* RI */
+#define AT91_US_DSR (1 << 21) /* DSR */
+#define AT91_US_DCD (1 << 22) /* DCD */
+#define AT91_US_CTS (1 << 23) /* CTS */
+
+#define AT91_US_IDR 0x0c /* Interrupt Disable Register */
+#define AT91_US_IMR 0x10 /* Interrupt Mask Register */
+#define AT91_US_CSR 0x14 /* Channel Status Register */
+#define AT91_US_RHR 0x18 /* Receiver Holding Register */
+#define AT91_US_THR 0x1c /* Transmitter Holding Register */
+
+#define AT91_US_BRGR 0x20 /* Baud Rate Generator Register */
+#define AT91_US_CD (0xffff << 0) /* Clock Divider */
+
+#define AT91_US_RTOR 0x24 /* Receiver Time-out Register */
+#define AT91_US_TO (0xffff << 0) /* Time-out Value */
+
+#define AT91_US_TTGR 0x28 /* Transmitter Timeguard Register */
+#define AT91_US_TG (0xff << 0) /* Timeguard Value */
+
+#define AT91_US_FIDI 0x40 /* FI DI Ratio Register */
+#define AT91_US_NER 0x44 /* Number of Errors Register */
+#define AT91_US_IF 0x4c /* IrDA Filter Register */
+
+#endif
diff --git a/include/asm-arm/byteorder.h b/include/asm-arm/byteorder.h
index 741f5bc5d016e..17eaf8bdf0925 100644
--- a/include/asm-arm/byteorder.h
+++ b/include/asm-arm/byteorder.h
@@ -22,7 +22,16 @@ static inline __attribute_const__ __u32 ___arch__swab32(__u32 x)
{
__u32 t;
- t = x ^ ((x << 16) | (x >> 16)); /* eor r1,r0,r0,ror #16 */
+ if (__builtin_constant_p(x)) {
+ t = x ^ ((x << 16) | (x >> 16)); /* eor r1,r0,r0,ror #16 */
+ } else {
+ /*
+ * The compiler needs a bit of a hint here to always do the
+ * right thing and not screw it up to different degrees
+ * depending on the gcc version.
+ */
+ asm ("eor\t%0, %1, %1, ror #16" : "=r" (t) : "r" (x));
+ }
x = (x << 24) | (x >> 8); /* mov r0,r0,ror #8 */
t &= ~0x00FF0000; /* bic r1,r1,#0x00FF0000 */
x ^= (t >> 8); /* eor r0,r0,r1,lsr #8 */
diff --git a/include/asm-arm/mach/serial_at91rm9200.h b/include/asm-arm/mach/serial_at91rm9200.h
new file mode 100644
index 0000000000000..98f4b0cb883ca
--- /dev/null
+++ b/include/asm-arm/mach/serial_at91rm9200.h
@@ -0,0 +1,36 @@
+/*
+ * linux/include/asm-arm/mach/serial_at91rm9200.h
+ *
+ * Based on serial_sa1100.h by Nicolas Pitre
+ *
+ * Copyright (C) 2002 ATMEL Rousset
+ *
+ * Low level machine dependent UART functions.
+ */
+#include <linux/config.h>
+
+struct uart_port;
+
+/*
+ * This is a temporary structure for registering these
+ * functions; it is intended to be discarded after boot.
+ */
+struct at91rm9200_port_fns {
+ void (*set_mctrl)(struct uart_port *, u_int);
+ u_int (*get_mctrl)(struct uart_port *);
+ void (*enable_ms)(struct uart_port *);
+ void (*pm)(struct uart_port *, u_int, u_int);
+ int (*set_wake)(struct uart_port *, u_int);
+ int (*open)(struct uart_port *);
+ void (*close)(struct uart_port *);
+};
+
+#if defined(CONFIG_SERIAL_AT91)
+void at91_register_uart_fns(struct at91rm9200_port_fns *fns);
+void at91_register_uart(int idx, int port);
+#else
+#define at91_register_uart_fns(fns) do { } while (0)
+#define at91_register_uart(idx,port) do { } while (0)
+#endif
+
+
diff --git a/include/asm-arm/memory.h b/include/asm-arm/memory.h
index 3d7f08bd9030f..b4e1146ab682c 100644
--- a/include/asm-arm/memory.h
+++ b/include/asm-arm/memory.h
@@ -25,6 +25,7 @@
#include <linux/config.h>
#include <linux/compiler.h>
#include <asm/arch/memory.h>
+#include <asm/sizes.h>
#ifndef TASK_SIZE
/*
@@ -48,6 +49,14 @@
#endif
/*
+ * Size of DMA-consistent memory region. Must be multiple of 2M,
+ * between 2MB and 14MB inclusive.
+ */
+#ifndef CONSISTENT_DMA_SIZE
+#define CONSISTENT_DMA_SIZE SZ_2M
+#endif
+
+/*
* Physical vs virtual RAM address space conversion. These are
* private definitions which should NOT be used outside memory.h
* files. Use virt_to_phys/phys_to_virt/__pa/__va instead.
diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h
index 8a8393e507747..d5677cbec200f 100644
--- a/include/asm-powerpc/iommu.h
+++ b/include/asm-powerpc/iommu.h
@@ -64,25 +64,6 @@ extern void iommu_free_table(struct device_node *dn);
#endif /* CONFIG_PPC_MULTIPLATFORM */
-#ifdef CONFIG_PPC_PSERIES
-
-/* Creates table for an individual device node */
-extern void iommu_devnode_init_pSeries(struct device_node *dn);
-
-#endif /* CONFIG_PPC_PSERIES */
-
-#ifdef CONFIG_PPC_ISERIES
-
-/* Creates table for an individual device node */
-extern void iommu_devnode_init_iSeries(struct device_node *dn);
-/* Get table parameters from HV */
-extern void iommu_table_getparms_iSeries(unsigned long busno,
- unsigned char slotno,
- unsigned char virtbus,
- struct iommu_table* tbl);
-
-#endif /* CONFIG_PPC_ISERIES */
-
/* Initializes an iommu_table based in values set in the passed-in
* structure
*/
diff --git a/include/asm-powerpc/iseries/hv_call.h b/include/asm-powerpc/iseries/hv_call.h
index e9f831c9a5e50..162d653ad51fc 100644
--- a/include/asm-powerpc/iseries/hv_call.h
+++ b/include/asm-powerpc/iseries/hv_call.h
@@ -1,5 +1,4 @@
/*
- * HvCall.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -15,8 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-/*
+ *
* This file contains the "hypervisor call" interface which is used to
* drive the hypervisor from the OS.
*/
diff --git a/include/asm-powerpc/iseries/hv_call_event.h b/include/asm-powerpc/iseries/hv_call_event.h
index 46763a30590ac..4cec4762076df 100644
--- a/include/asm-powerpc/iseries/hv_call_event.h
+++ b/include/asm-powerpc/iseries/hv_call_event.h
@@ -1,5 +1,4 @@
/*
- * HvCallEvent.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -15,8 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-/*
+ *
* This file contains the "hypervisor call" interface which is used to
* drive the hypervisor from the OS.
*/
@@ -33,32 +31,9 @@ typedef u8 HvLpEvent_Type;
typedef u8 HvLpEvent_AckInd;
typedef u8 HvLpEvent_AckType;
-struct HvCallEvent_PackedParms {
- u8 xAckType:1;
- u8 xAckInd:1;
- u8 xRsvd:1;
- u8 xTargetLp:5;
- u8 xType;
- u16 xSubtype;
- HvLpInstanceId xSourceInstId;
- HvLpInstanceId xTargetInstId;
-};
-
typedef u8 HvLpDma_Direction;
typedef u8 HvLpDma_AddressType;
-struct HvCallEvent_PackedDmaParms {
- u8 xDirection:1;
- u8 xLocalAddrType:1;
- u8 xRemoteAddrType:1;
- u8 xRsvd1:5;
- HvLpIndex xRemoteLp;
- u8 xType;
- u8 xRsvd2;
- HvLpInstanceId xLocalInstId;
- HvLpInstanceId xRemoteInstId;
-};
-
typedef u64 HvLpEvent_Rc;
typedef u64 HvLpDma_Rc;
@@ -92,11 +67,8 @@ static inline void HvCallEvent_setInterLpQueueIndex(u8 queueIndex)
static inline void HvCallEvent_setLpEventStack(u8 queueIndex,
char *eventStackAddr, u32 eventStackSize)
{
- u64 abs_addr;
-
- abs_addr = virt_to_abs(eventStackAddr);
- HvCall3(HvCallEventSetLpEventStack, queueIndex, abs_addr,
- eventStackSize);
+ HvCall3(HvCallEventSetLpEventStack, queueIndex,
+ virt_to_abs(eventStackAddr), eventStackSize);
}
static inline void HvCallEvent_setLpEventQueueInterruptProc(u8 queueIndex,
@@ -108,14 +80,7 @@ static inline void HvCallEvent_setLpEventQueueInterruptProc(u8 queueIndex,
static inline HvLpEvent_Rc HvCallEvent_signalLpEvent(struct HvLpEvent *event)
{
- u64 abs_addr;
-
-#ifdef DEBUG_SENDEVENT
- printk("HvCallEvent_signalLpEvent: *event = %016lx\n ",
- (unsigned long)event);
-#endif
- abs_addr = virt_to_abs(event);
- return HvCall1(HvCallEventSignalLpEvent, abs_addr);
+ return HvCall1(HvCallEventSignalLpEvent, virt_to_abs(event));
}
static inline HvLpEvent_Rc HvCallEvent_signalLpEventFast(HvLpIndex targetLp,
@@ -127,17 +92,21 @@ static inline HvLpEvent_Rc HvCallEvent_signalLpEventFast(HvLpIndex targetLp,
{
/* Pack the misc bits into a single Dword to pass to PLIC */
union {
- struct HvCallEvent_PackedParms parms;
+ struct {
+ u8 ack_and_target;
+ u8 type;
+ u16 subtype;
+ HvLpInstanceId src_inst;
+ HvLpInstanceId target_inst;
+ } parms;
u64 dword;
} packed;
- packed.parms.xAckType = ackType;
- packed.parms.xAckInd = ackInd;
- packed.parms.xRsvd = 0;
- packed.parms.xTargetLp = targetLp;
- packed.parms.xType = type;
- packed.parms.xSubtype = subtype;
- packed.parms.xSourceInstId = sourceInstanceId;
- packed.parms.xTargetInstId = targetInstanceId;
+
+ packed.parms.ack_and_target = (ackType << 7) | (ackInd << 6) | targetLp;
+ packed.parms.type = type;
+ packed.parms.subtype = subtype;
+ packed.parms.src_inst = sourceInstanceId;
+ packed.parms.target_inst = targetInstanceId;
return HvCall7(HvCallEventSignalLpEventParms, packed.dword,
correlationToken, eventData1, eventData2,
@@ -146,18 +115,12 @@ static inline HvLpEvent_Rc HvCallEvent_signalLpEventFast(HvLpIndex targetLp,
static inline HvLpEvent_Rc HvCallEvent_ackLpEvent(struct HvLpEvent *event)
{
- u64 abs_addr;
-
- abs_addr = virt_to_abs(event);
- return HvCall1(HvCallEventAckLpEvent, abs_addr);
+ return HvCall1(HvCallEventAckLpEvent, virt_to_abs(event));
}
static inline HvLpEvent_Rc HvCallEvent_cancelLpEvent(struct HvLpEvent *event)
{
- u64 abs_addr;
-
- abs_addr = virt_to_abs(event);
- return HvCall1(HvCallEventCancelLpEvent, abs_addr);
+ return HvCall1(HvCallEventCancelLpEvent, virt_to_abs(event));
}
static inline HvLpInstanceId HvCallEvent_getSourceLpInstanceId(
@@ -195,59 +158,34 @@ static inline HvLpDma_Rc HvCallEvent_dmaBufList(HvLpEvent_Type type,
{
/* Pack the misc bits into a single Dword to pass to PLIC */
union {
- struct HvCallEvent_PackedDmaParms parms;
+ struct {
+ u8 flags;
+ HvLpIndex remote;
+ u8 type;
+ u8 reserved;
+ HvLpInstanceId local_inst;
+ HvLpInstanceId remote_inst;
+ } parms;
u64 dword;
} packed;
- packed.parms.xDirection = direction;
- packed.parms.xLocalAddrType = localAddressType;
- packed.parms.xRemoteAddrType = remoteAddressType;
- packed.parms.xRsvd1 = 0;
- packed.parms.xRemoteLp = remoteLp;
- packed.parms.xType = type;
- packed.parms.xRsvd2 = 0;
- packed.parms.xLocalInstId = localInstanceId;
- packed.parms.xRemoteInstId = remoteInstanceId;
+ packed.parms.flags = (direction << 7) |
+ (localAddressType << 6) | (remoteAddressType << 5);
+ packed.parms.remote = remoteLp;
+ packed.parms.type = type;
+ packed.parms.reserved = 0;
+ packed.parms.local_inst = localInstanceId;
+ packed.parms.remote_inst = remoteInstanceId;
return HvCall4(HvCallEventDmaBufList, packed.dword, localBufList,
remoteBufList, transferLength);
}
-static inline HvLpDma_Rc HvCallEvent_dmaSingle(HvLpEvent_Type type,
- HvLpIndex remoteLp, HvLpDma_Direction direction,
- HvLpInstanceId localInstanceId,
- HvLpInstanceId remoteInstanceId,
- HvLpDma_AddressType localAddressType,
- HvLpDma_AddressType remoteAddressType,
- u64 localAddrOrTce, u64 remoteAddrOrTce, u32 transferLength)
-{
- /* Pack the misc bits into a single Dword to pass to PLIC */
- union {
- struct HvCallEvent_PackedDmaParms parms;
- u64 dword;
- } packed;
-
- packed.parms.xDirection = direction;
- packed.parms.xLocalAddrType = localAddressType;
- packed.parms.xRemoteAddrType = remoteAddressType;
- packed.parms.xRsvd1 = 0;
- packed.parms.xRemoteLp = remoteLp;
- packed.parms.xType = type;
- packed.parms.xRsvd2 = 0;
- packed.parms.xLocalInstId = localInstanceId;
- packed.parms.xRemoteInstId = remoteInstanceId;
-
- return (HvLpDma_Rc)HvCall4(HvCallEventDmaSingle, packed.dword,
- localAddrOrTce, remoteAddrOrTce, transferLength);
-}
-
static inline HvLpDma_Rc HvCallEvent_dmaToSp(void *local, u32 remote,
u32 length, HvLpDma_Direction dir)
{
- u64 abs_addr;
-
- abs_addr = virt_to_abs(local);
- return HvCall4(HvCallEventDmaToSp, abs_addr, remote, length, dir);
+ return HvCall4(HvCallEventDmaToSp, virt_to_abs(local), remote,
+ length, dir);
}
#endif /* _ASM_POWERPC_ISERIES_HV_CALL_EVENT_H */
diff --git a/include/asm-powerpc/iseries/hv_call_sc.h b/include/asm-powerpc/iseries/hv_call_sc.h
index dec7e9d9ab788..f5d2109592504 100644
--- a/include/asm-powerpc/iseries/hv_call_sc.h
+++ b/include/asm-powerpc/iseries/hv_call_sc.h
@@ -1,5 +1,4 @@
/*
- * HvCallSc.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/asm-powerpc/iseries/hv_lp_config.h b/include/asm-powerpc/iseries/hv_lp_config.h
index bc00f036bca03..df8b20739719f 100644
--- a/include/asm-powerpc/iseries/hv_lp_config.h
+++ b/include/asm-powerpc/iseries/hv_lp_config.h
@@ -1,5 +1,4 @@
/*
- * HvLpConfig.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/asm-powerpc/iseries/hv_lp_event.h b/include/asm-powerpc/iseries/hv_lp_event.h
index 499ab1ad01854..4065a4de4935f 100644
--- a/include/asm-powerpc/iseries/hv_lp_event.h
+++ b/include/asm-powerpc/iseries/hv_lp_event.h
@@ -1,5 +1,4 @@
/*
- * HvLpEvent.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -32,17 +31,8 @@
* partitions through PLIC.
*/
-struct HvEventFlags {
- u8 xValid:1; /* Indicates a valid request x00-x00 */
- u8 xRsvd1:4; /* Reserved ... */
- u8 xAckType:1; /* Immediate or deferred ... */
- u8 xAckInd:1; /* Indicates if ACK required ... */
- u8 xFunction:1; /* Interrupt or Acknowledge ... */
-};
-
-
struct HvLpEvent {
- struct HvEventFlags xFlags; /* Event flags x00-x00 */
+ u8 flags; /* Event flags x00-x00 */
u8 xType; /* Type of message x01-x01 */
u16 xSubtype; /* Subtype for event x02-x03 */
u8 xSourceLp; /* Source LP x04-x04 */
@@ -126,6 +116,11 @@ extern int HvLpEvent_closePath(HvLpEvent_Type eventType, HvLpIndex lpIndex);
#define HvLpEvent_AckType_ImmediateAck 0
#define HvLpEvent_AckType_DeferredAck 1
+#define HV_LP_EVENT_INT 0x01
+#define HV_LP_EVENT_DO_ACK 0x02
+#define HV_LP_EVENT_DEFERRED_ACK 0x04
+#define HV_LP_EVENT_VALID 0x80
+
#define HvLpDma_Direction_LocalToRemote 0
#define HvLpDma_Direction_RemoteToLocal 1
@@ -139,4 +134,29 @@ extern int HvLpEvent_closePath(HvLpEvent_Type eventType, HvLpIndex lpIndex);
#define HvLpDma_Rc_InvalidAddress 4
#define HvLpDma_Rc_InvalidLength 5
+static inline int hvlpevent_is_valid(struct HvLpEvent *h)
+{
+ return h->flags & HV_LP_EVENT_VALID;
+}
+
+static inline void hvlpevent_invalidate(struct HvLpEvent *h)
+{
+ h->flags &= ~ HV_LP_EVENT_VALID;
+}
+
+static inline int hvlpevent_is_int(struct HvLpEvent *h)
+{
+ return h->flags & HV_LP_EVENT_INT;
+}
+
+static inline int hvlpevent_is_ack(struct HvLpEvent *h)
+{
+ return !hvlpevent_is_int(h);
+}
+
+static inline int hvlpevent_need_ack(struct HvLpEvent *h)
+{
+ return h->flags & HV_LP_EVENT_DO_ACK;
+}
+
#endif /* _ASM_POWERPC_ISERIES_HV_LP_EVENT_H */
diff --git a/include/asm-powerpc/iseries/hv_types.h b/include/asm-powerpc/iseries/hv_types.h
index c38f7e3d01dce..c3e6d2a1d1c3d 100644
--- a/include/asm-powerpc/iseries/hv_types.h
+++ b/include/asm-powerpc/iseries/hv_types.h
@@ -1,5 +1,4 @@
/*
- * HvTypes.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/asm-powerpc/iseries/iseries_io.h b/include/asm-powerpc/iseries/iseries_io.h
index 56b2113ff0f57..496aa852b6170 100644
--- a/include/asm-powerpc/iseries/iseries_io.h
+++ b/include/asm-powerpc/iseries/iseries_io.h
@@ -6,7 +6,7 @@
#ifdef CONFIG_PPC_ISERIES
#include <linux/types.h>
/*
- * File iSeries_io.h created by Allan Trautman on Thu Dec 28 2000.
+ * Created by Allan Trautman on Thu Dec 28 2000.
*
* Remaps the io.h for the iSeries Io
* Copyright (C) 2000 Allan H Trautman, IBM Corporation
@@ -32,6 +32,7 @@
* End Change Activity
*/
+#ifdef CONFIG_PCI
extern u8 iSeries_Read_Byte(const volatile void __iomem * IoAddress);
extern u16 iSeries_Read_Word(const volatile void __iomem * IoAddress);
extern u32 iSeries_Read_Long(const volatile void __iomem * IoAddress);
@@ -44,6 +45,17 @@ extern void iSeries_memcpy_toio(volatile void __iomem *dest, void *source,
size_t n);
extern void iSeries_memcpy_fromio(void *dest,
const volatile void __iomem *source, size_t n);
+#else
+static inline u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
+{
+ return 0xff;
+}
+
+static inline void iSeries_Write_Byte(u8 IoData,
+ volatile void __iomem *IoAddress)
+{
+}
+#endif /* CONFIG_PCI */
#endif /* CONFIG_PPC_ISERIES */
#endif /* _ASM_POWERPC_ISERIES_ISERIES_IO_H */
diff --git a/include/asm-powerpc/iseries/it_exp_vpd_panel.h b/include/asm-powerpc/iseries/it_exp_vpd_panel.h
index 66a17a230c529..304a609ae21a9 100644
--- a/include/asm-powerpc/iseries/it_exp_vpd_panel.h
+++ b/include/asm-powerpc/iseries/it_exp_vpd_panel.h
@@ -1,5 +1,4 @@
/*
- * ItExtVpdPanel.h
* Copyright (C) 2002 Dave Boutcher IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/asm-powerpc/iseries/it_lp_naca.h b/include/asm-powerpc/iseries/it_lp_naca.h
index c3ef1de45d82e..4fdcf052927ff 100644
--- a/include/asm-powerpc/iseries/it_lp_naca.h
+++ b/include/asm-powerpc/iseries/it_lp_naca.h
@@ -1,5 +1,4 @@
/*
- * ItLpNaca.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -37,17 +36,13 @@ struct ItLpNaca {
u8 xLpIndex; // LP Index x0B-x0B
u16 xMaxLpQueues; // Number of allocated queues x0C-x0D
u16 xLpQueueOffset; // Offset to start of LP queues x0E-x0F
- u8 xPirEnvironMode:8; // Piranha or hardware x10-x10
- u8 xPirConsoleMode:8; // Piranha console indicator x11-x11
- u8 xPirDasdMode:8; // Piranha dasd indicator x12-x12
+ u8 xPirEnvironMode; // Piranha or hardware x10-x10
+ u8 xPirConsoleMode; // Piranha console indicator x11-x11
+ u8 xPirDasdMode; // Piranha dasd indicator x12-x12
u8 xRsvd1_0[5]; // Reserved for Piranha related x13-x17
- u8 xLparInstalled:1; // Is LPAR installed on system x18-x1F
- u8 xSysPartitioned:1; // Is the system partitioned ...
- u8 xHwSyncedTBs:1; // Hardware synced TBs ...
- u8 xIntProcUtilHmt:1; // Utilize HMT for interrupts ...
- u8 xRsvd1_1:4; // Reserved ...
- u8 xSpVpdFormat:8; // VPD areas are in CSP format ...
- u8 xIntProcRatio:8; // Ratio of int procs to procs ...
+ u8 flags; // flags, see below x18-x1F
+ u8 xSpVpdFormat; // VPD areas are in CSP format ...
+ u8 xIntProcRatio; // Ratio of int procs to procs ...
u8 xRsvd1_2[5]; // Reserved ...
u16 xRsvd1_3; // Reserved x20-x21
u16 xPlicVrmIndex; // VRM index of PLIC x22-x23
@@ -77,4 +72,9 @@ struct ItLpNaca {
extern struct ItLpNaca itLpNaca;
+#define ITLPNACA_LPAR 0x80 /* Is LPAR installed on the system */
+#define ITLPNACA_PARTITIONED 0x40 /* Is the system partitioned */
+#define ITLPNACA_HWSYNCEDTBS 0x20 /* Hardware synced TBs */
+#define ITLPNACA_HMTINT 0x10 /* Utilize MHT for interrupts */
+
#endif /* _ASM_POWERPC_ISERIES_IT_LP_NACA_H */
diff --git a/include/asm-powerpc/iseries/it_lp_queue.h b/include/asm-powerpc/iseries/it_lp_queue.h
index a60d03afbf95b..b7c6fc12cce22 100644
--- a/include/asm-powerpc/iseries/it_lp_queue.h
+++ b/include/asm-powerpc/iseries/it_lp_queue.h
@@ -1,5 +1,4 @@
/*
- * ItLpQueue.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/asm-powerpc/iseries/it_lp_reg_save.h b/include/asm-powerpc/iseries/it_lp_reg_save.h
index 81824e1bb7675..5403b756f654d 100644
--- a/include/asm-powerpc/iseries/it_lp_reg_save.h
+++ b/include/asm-powerpc/iseries/it_lp_reg_save.h
@@ -1,5 +1,4 @@
/*
- * ItLpRegSave.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -83,4 +82,4 @@ struct ItLpRegSave {
extern struct ItLpRegSave iseries_reg_save[];
-#endif /* _ITLPREGSAVE_H */
+#endif /* _ASM_POWERPC_ISERIES_IT_LP_REG_SAVE_H */
diff --git a/include/asm-powerpc/iseries/lpar_map.h b/include/asm-powerpc/iseries/lpar_map.h
index 84fc321615bff..2ec384d66abb9 100644
--- a/include/asm-powerpc/iseries/lpar_map.h
+++ b/include/asm-powerpc/iseries/lpar_map.h
@@ -1,5 +1,4 @@
/*
- * LparMap.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/asm-powerpc/iseries/mf.h b/include/asm-powerpc/iseries/mf.h
index e7bd57a03fb17..857e5202fc784 100644
--- a/include/asm-powerpc/iseries/mf.h
+++ b/include/asm-powerpc/iseries/mf.h
@@ -1,5 +1,4 @@
/*
- * mf.h
* Copyright (C) 2001 Troy D. Armstrong IBM Corporation
* Copyright (C) 2004 Stephen Rothwell IBM Corporation
*
diff --git a/include/asm-powerpc/iseries/vio.h b/include/asm-powerpc/iseries/vio.h
index 7e3a469420ddb..72a97d37aac35 100644
--- a/include/asm-powerpc/iseries/vio.h
+++ b/include/asm-powerpc/iseries/vio.h
@@ -1,5 +1,4 @@
/* -*- linux-c -*-
- * drivers/char/vio.h
*
* iSeries Virtual I/O Message Path header
*
diff --git a/include/asm-powerpc/pci-bridge.h b/include/asm-powerpc/pci-bridge.h
index b0d816fe2e27e..38de92d41a148 100644
--- a/include/asm-powerpc/pci-bridge.h
+++ b/include/asm-powerpc/pci-bridge.h
@@ -142,8 +142,6 @@ void pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus);
extern int pcibios_remove_root_bus(struct pci_controller *phb);
-extern void phbs_remap_io(void);
-
static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus)
{
struct device_node *busdn = bus->sysdata;
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index 1be629b4fb97b..9b822afa7d0e1 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -133,6 +133,14 @@ extern int fix_alignment(struct pt_regs *);
extern void cvt_fd(float *from, double *to, struct thread_struct *thread);
extern void cvt_df(double *from, float *to, struct thread_struct *thread);
+#ifndef CONFIG_SMP
+extern void discard_lazy_cpu_state(void);
+#else
+static inline void discard_lazy_cpu_state(void)
+{
+}
+#endif
+
#ifdef CONFIG_ALTIVEC
extern void flush_altivec_to_thread(struct task_struct *);
#else
diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h
index 212dca66fcac2..fb49c0c49ea10 100644
--- a/include/asm-ppc/system.h
+++ b/include/asm-ppc/system.h
@@ -4,7 +4,6 @@
#ifndef __PPC_SYSTEM_H
#define __PPC_SYSTEM_H
-#include <linux/config.h>
#include <linux/kernel.h>
#include <asm/atomic.h>
@@ -39,7 +38,7 @@
#ifdef CONFIG_SMP
#define smp_mb() mb()
#define smp_rmb() rmb()
-#define smp_wmb() wmb()
+#define smp_wmb() __asm__ __volatile__ ("eieio" : : : "memory")
#define smp_read_barrier_depends() read_barrier_depends()
#else
#define smp_mb() barrier()
@@ -74,6 +73,7 @@ extern void chrp_nvram_init(void);
extern void read_rtc_time(void);
extern void pmac_find_display(void);
extern void giveup_fpu(struct task_struct *);
+extern void disable_kernel_fp(void);
extern void enable_kernel_fp(void);
extern void flush_fp_to_thread(struct task_struct *);
extern void enable_kernel_altivec(void);
@@ -86,6 +86,14 @@ extern int fix_alignment(struct pt_regs *);
extern void cvt_fd(float *from, double *to, struct thread_struct *thread);
extern void cvt_df(double *from, float *to, struct thread_struct *thread);
+#ifndef CONFIG_SMP
+extern void discard_lazy_cpu_state(void);
+#else
+static inline void discard_lazy_cpu_state(void)
+{
+}
+#endif
+
#ifdef CONFIG_ALTIVEC
extern void flush_altivec_to_thread(struct task_struct *);
#else
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index cf5cfdf8d6130..089bfb1fa01a7 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -49,8 +49,6 @@ struct hrtimer_base;
* struct hrtimer - the basic hrtimer structure
*
* @node: red black tree node for time ordered insertion
- * @list: list head for easier access to the time ordered list,
- * without walking the red black tree.
* @expires: the absolute expiry time in the hrtimers internal
* representation. The time is related to the clock on
* which the timer is based.
@@ -63,7 +61,6 @@ struct hrtimer_base;
*/
struct hrtimer {
struct rb_node node;
- struct list_head list;
ktime_t expires;
enum hrtimer_state state;
int (*function)(void *);
@@ -78,7 +75,7 @@ struct hrtimer {
* to a base on another cpu.
* @lock: lock protecting the base and associated timers
* @active: red black tree root node for the active timers
- * @pending: list of pending timers for simple time ordered access
+ * @first: pointer to the timer node which expires first
* @resolution: the resolution of the clock, in nanoseconds
* @get_time: function to retrieve the current time of the clock
* @curr_timer: the timer which is executing a callback right now
@@ -87,8 +84,8 @@ struct hrtimer_base {
clockid_t index;
spinlock_t lock;
struct rb_root active;
- struct list_head pending;
- unsigned long resolution;
+ struct rb_node *first;
+ ktime_t resolution;
ktime_t (*get_time)(void);
struct hrtimer *curr_timer;
};
@@ -125,8 +122,7 @@ static inline int hrtimer_active(const struct hrtimer *timer)
}
/* Forward a hrtimer so it expires after now: */
-extern unsigned long hrtimer_forward(struct hrtimer *timer,
- const ktime_t interval);
+extern unsigned long hrtimer_forward(struct hrtimer *timer, ktime_t interval);
/* Precise sleep: */
extern long hrtimer_nanosleep(struct timespec *rqtp,
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 9a8c05dbe4f38..f2e1b5b228982 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1002,7 +1002,6 @@ extern int noautodma;
extern int ide_end_request (ide_drive_t *drive, int uptodate, int nrsecs);
extern int __ide_end_request (ide_drive_t *drive, struct request *rq, int uptodate, int nrsecs);
-extern void ide_softirq_done(struct request *rq);
/*
* This is used on exit from the driver to designate the next irq handler
diff --git a/include/linux/ktime.h b/include/linux/ktime.h
index 222a047cc145e..1bd6552cc3413 100644
--- a/include/linux/ktime.h
+++ b/include/linux/ktime.h
@@ -272,8 +272,8 @@ static inline u64 ktime_to_ns(const ktime_t kt)
* idea of the (in)accuracy of timers. Timer values are rounded up to
* this resolution values.
*/
-#define KTIME_REALTIME_RES (NSEC_PER_SEC/HZ)
-#define KTIME_MONOTONIC_RES (NSEC_PER_SEC/HZ)
+#define KTIME_REALTIME_RES (ktime_t){ .tv64 = TICK_NSEC }
+#define KTIME_MONOTONIC_RES (ktime_t){ .tv64 = TICK_NSEC }
/* Get the monotonic time in timespec format: */
extern void ktime_get_ts(struct timespec *ts);
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index e3710d7e260aa..a8187c3c8a7b0 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -67,6 +67,9 @@
/* Parisc type numbers. */
#define PORT_MUX 48
+/* Atmel AT91RM9200 SoC */
+#define PORT_AT91RM9200 49
+
/* Macintosh Zilog type numbers */
#define PORT_MAC_ZILOG 50 /* m68k : not yet implemented */
#define PORT_PMAC_ZILOG 51
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index f073a2461faa0..04ccab099e84e 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -275,7 +275,7 @@ void unlock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags)
* The number of overruns is added to the overrun field.
*/
unsigned long
-hrtimer_forward(struct hrtimer *timer, const ktime_t interval)
+hrtimer_forward(struct hrtimer *timer, ktime_t interval)
{
unsigned long orun = 1;
ktime_t delta, now;
@@ -287,6 +287,9 @@ hrtimer_forward(struct hrtimer *timer, const ktime_t interval)
if (delta.tv64 < 0)
return 0;
+ if (interval.tv64 < timer->base->resolution.tv64)
+ interval.tv64 = timer->base->resolution.tv64;
+
if (unlikely(delta.tv64 >= interval.tv64)) {
nsec_t incr = ktime_to_ns(interval);
@@ -314,7 +317,6 @@ hrtimer_forward(struct hrtimer *timer, const ktime_t interval)
static void enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_base *base)
{
struct rb_node **link = &base->active.rb_node;
- struct list_head *prev = &base->pending;
struct rb_node *parent = NULL;
struct hrtimer *entry;
@@ -330,22 +332,23 @@ static void enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_base *base)
*/
if (timer->expires.tv64 < entry->expires.tv64)
link = &(*link)->rb_left;
- else {
+ else
link = &(*link)->rb_right;
- prev = &entry->list;
- }
}
/*
- * Insert the timer to the rbtree and to the sorted list:
+ * Insert the timer to the rbtree and check whether it
+ * replaces the first pending timer
*/
rb_link_node(&timer->node, parent, link);
rb_insert_color(&timer->node, &base->active);
- list_add(&timer->list, prev);
timer->state = HRTIMER_PENDING;
-}
+ if (!base->first || timer->expires.tv64 <
+ rb_entry(base->first, struct hrtimer, node)->expires.tv64)
+ base->first = &timer->node;
+}
/*
* __remove_hrtimer - internal function to remove a timer
@@ -355,9 +358,11 @@ static void enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_base *base)
static void __remove_hrtimer(struct hrtimer *timer, struct hrtimer_base *base)
{
/*
- * Remove the timer from the sorted list and from the rbtree:
+ * Remove the timer from the rbtree and replace the
+ * first entry pointer if necessary.
*/
- list_del(&timer->list);
+ if (base->first == &timer->node)
+ base->first = rb_next(&timer->node);
rb_erase(&timer->node, &base->active);
}
@@ -516,9 +521,8 @@ int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp)
{
struct hrtimer_base *bases;
- tp->tv_sec = 0;
bases = per_cpu(hrtimer_bases, raw_smp_processor_id());
- tp->tv_nsec = bases[which_clock].resolution;
+ *tp = ktime_to_timespec(bases[which_clock].resolution);
return 0;
}
@@ -529,16 +533,17 @@ int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp)
static inline void run_hrtimer_queue(struct hrtimer_base *base)
{
ktime_t now = base->get_time();
+ struct rb_node *node;
spin_lock_irq(&base->lock);
- while (!list_empty(&base->pending)) {
+ while ((node = base->first)) {
struct hrtimer *timer;
int (*fn)(void *);
int restart;
void *data;
- timer = list_entry(base->pending.next, struct hrtimer, list);
+ timer = rb_entry(node, struct hrtimer, node);
if (now.tv64 <= timer->expires.tv64)
break;
@@ -732,7 +737,6 @@ static void __devinit init_hrtimers_cpu(int cpu)
for (i = 0; i < MAX_HRTIMER_BASES; i++) {
spin_lock_init(&base->lock);
- INIT_LIST_HEAD(&base->pending);
base++;
}
}