aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/DocBook/Makefile2
-rw-r--r--Documentation/DocBook/kernel-api.tmpl1
-rw-r--r--Documentation/acpi-hotkey.txt2
-rw-r--r--Documentation/fujitsu/frv/kernel-ABI.txt192
-rw-r--r--Documentation/kernel-parameters.txt34
-rw-r--r--Documentation/networking/packet_mmap.txt2
-rw-r--r--Documentation/networking/tuntap.txt2
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt69
-rw-r--r--arch/arm/configs/at91rm9200dk_defconfig2
-rw-r--r--arch/arm/configs/at91rm9200ek_defconfig2
-rw-r--r--arch/arm/kernel/armksyms.c13
-rw-r--r--arch/arm/kernel/setup.c3
-rw-r--r--arch/arm/mach-at91rm9200/Makefile9
-rw-r--r--arch/arm/mach-at91rm9200/board-csb337.c3
-rw-r--r--arch/arm/mach-at91rm9200/board-csb637.c3
-rw-r--r--arch/arm/mach-at91rm9200/board-dk.c10
-rw-r--r--arch/arm/mach-at91rm9200/board-ek.c10
-rw-r--r--arch/arm/mach-at91rm9200/devices.c154
-rw-r--r--arch/arm/mach-at91rm9200/leds.c100
-rw-r--r--arch/arm/mach-ep93xx/core.c10
-rw-r--r--arch/arm/mach-ep93xx/ts72xx.c39
-rw-r--r--arch/arm/mach-imx/dma.c511
-rw-r--r--arch/arm/mach-imx/generic.c13
-rw-r--r--arch/arm/mach-imx/mx1ads.c18
-rw-r--r--arch/arm/mach-ixp23xx/espresso.c9
-rw-r--r--arch/arm/mach-ixp23xx/pci.c18
-rw-r--r--arch/arm/mach-omap1/Kconfig20
-rw-r--r--arch/arm/mach-omap1/Makefile11
-rw-r--r--arch/arm/mach-omap1/board-ams-delta.c116
-rw-r--r--arch/arm/mach-omap1/board-generic.c2
-rw-r--r--arch/arm/mach-omap1/board-h2.c200
-rw-r--r--arch/arm/mach-omap1/board-h3.c277
-rw-r--r--arch/arm/mach-omap1/board-innovator.c56
-rw-r--r--arch/arm/mach-omap1/board-netstar.c160
-rw-r--r--arch/arm/mach-omap1/board-nokia770.c268
-rw-r--r--arch/arm/mach-omap1/board-osk.c95
-rw-r--r--arch/arm/mach-omap1/board-palmte.c12
-rw-r--r--arch/arm/mach-omap1/board-perseus2.c123
-rw-r--r--arch/arm/mach-omap1/board-voiceblue.c8
-rw-r--r--arch/arm/mach-omap1/clock.c9
-rw-r--r--arch/arm/mach-omap1/clock.h91
-rw-r--r--arch/arm/mach-omap1/devices.c40
-rw-r--r--arch/arm/mach-omap1/io.c4
-rw-r--r--arch/arm/mach-omap1/irq.c18
-rw-r--r--arch/arm/mach-omap1/mux.c30
-rw-r--r--arch/arm/mach-omap1/pm.c770
-rw-r--r--arch/arm/mach-omap1/serial.c6
-rw-r--r--arch/arm/mach-omap1/sleep.S (renamed from arch/arm/plat-omap/sleep.S)111
-rw-r--r--arch/arm/mach-omap1/time.c197
-rw-r--r--arch/arm/mach-omap2/Kconfig3
-rw-r--r--arch/arm/mach-omap2/Makefile6
-rw-r--r--arch/arm/mach-omap2/board-apollon.c285
-rw-r--r--arch/arm/mach-omap2/board-h4.c174
-rw-r--r--arch/arm/mach-omap2/clock.c79
-rw-r--r--arch/arm/mach-omap2/clock.h37
-rw-r--r--arch/arm/mach-omap2/devices.c42
-rw-r--r--arch/arm/mach-omap2/io.c21
-rw-r--r--arch/arm/mach-omap2/memory.c102
-rw-r--r--arch/arm/mach-omap2/memory.h34
-rw-r--r--arch/arm/mach-omap2/mux.c45
-rw-r--r--arch/arm/mach-omap2/pm.c149
-rw-r--r--arch/arm/mach-omap2/prcm-regs.h (renamed from arch/arm/mach-omap2/prcm.h)188
-rw-r--r--arch/arm/mach-omap2/prcm.c40
-rw-r--r--arch/arm/mach-omap2/sleep.S144
-rw-r--r--arch/arm/mach-omap2/sram-fn.S4
-rw-r--r--arch/arm/mach-pxa/poodle.c4
-rw-r--r--arch/arm/mach-s3c2410/Kconfig7
-rw-r--r--arch/arm/mach-s3c2410/Makefile2
-rw-r--r--arch/arm/mach-s3c2410/clock.c2
-rw-r--r--arch/arm/mach-s3c2410/common-smdk.c134
-rw-r--r--arch/arm/mach-s3c2410/common-smdk.h15
-rw-r--r--arch/arm/mach-s3c2410/mach-anubis.c4
-rw-r--r--arch/arm/mach-s3c2410/mach-rx3715.c35
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2410.c13
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2440.c17
-rw-r--r--arch/arm/mach-sa1100/collie.c72
-rw-r--r--arch/arm/mm/consistent.c17
-rw-r--r--arch/arm/mm/mm-armv.c11
-rw-r--r--arch/arm/mm/proc-xsc3.S2
-rw-r--r--arch/arm/plat-omap/Kconfig4
-rw-r--r--arch/arm/plat-omap/Makefile6
-rw-r--r--arch/arm/plat-omap/clock.c67
-rw-r--r--arch/arm/plat-omap/devices.c143
-rw-r--r--arch/arm/plat-omap/dma.c6
-rw-r--r--arch/arm/plat-omap/dmtimer.c26
-rw-r--r--arch/arm/plat-omap/fb.c80
-rw-r--r--arch/arm/plat-omap/gpio.c86
-rw-r--r--arch/arm/plat-omap/mcbsp.c345
-rw-r--r--arch/arm/plat-omap/ocpi.c3
-rw-r--r--arch/arm/plat-omap/pm.c1
-rw-r--r--arch/arm/plat-omap/sram.c143
-rw-r--r--arch/arm/plat-omap/timer32k.c325
-rw-r--r--arch/i386/kernel/crash.c2
-rw-r--r--block/ll_rw_blk.c2
-rw-r--r--drivers/char/watchdog/Kconfig7
-rw-r--r--drivers/char/watchdog/Makefile1
-rw-r--r--drivers/char/watchdog/at91_wdt.c228
-rw-r--r--drivers/char/watchdog/pcwd.c137
-rw-r--r--drivers/char/watchdog/pcwd_usb.c3
-rw-r--r--drivers/hwmon/hdaps.c37
-rw-r--r--drivers/ieee1394/sbp2.c32
-rw-r--r--drivers/md/dm-target.c3
-rw-r--r--drivers/md/raid1.c6
-rw-r--r--drivers/md/raid10.c6
-rw-r--r--drivers/md/raid5.c34
-rw-r--r--drivers/md/raid6main.c29
-rw-r--r--drivers/mmc/Kconfig18
-rw-r--r--drivers/mmc/Makefile2
-rw-r--r--drivers/mmc/at91_mci.c988
-rw-r--r--drivers/mmc/imxmmc.c1096
-rw-r--r--drivers/mmc/imxmmc.h67
-rw-r--r--drivers/mtd/chips/Kconfig21
-rw-r--r--drivers/net/8139cp.c12
-rw-r--r--drivers/net/arcnet/arcnet.c3
-rw-r--r--drivers/net/b44.c3
-rw-r--r--drivers/net/chelsio/sge.c3
-rw-r--r--drivers/net/e1000/e1000_main.c3
-rw-r--r--drivers/net/eql.c3
-rw-r--r--drivers/net/irda/sa1100_ir.c3
-rw-r--r--drivers/net/ne2k-pci.c4
-rw-r--r--drivers/net/ns83820.c3
-rw-r--r--drivers/net/starfire.c3
-rw-r--r--drivers/net/tg3.c15
-rw-r--r--drivers/net/tokenring/abyss.c3
-rw-r--r--drivers/net/tokenring/madgemc.c3
-rw-r--r--drivers/net/wireless/ipw2200.c9
-rw-r--r--drivers/net/yellowfin.c3
-rw-r--r--drivers/s390/block/dasd_erp.c8
-rw-r--r--drivers/s390/char/sclp_rw.c2
-rw-r--r--drivers/s390/char/tape_block.c13
-rw-r--r--drivers/s390/net/lcs.c13
-rw-r--r--drivers/scsi/aic7xxx/Kconfig.aic7xxx2
-rw-r--r--drivers/serial/jsm/jsm.h2
-rw-r--r--drivers/serial/jsm/jsm_driver.c2
-rw-r--r--drivers/serial/jsm/jsm_neo.c2
-rw-r--r--fs/direct-io.c3
-rw-r--r--fs/dquot.c6
-rw-r--r--fs/exec.c2
-rw-r--r--fs/fcntl.c3
-rw-r--r--fs/freevxfs/vxfs_olt.c9
-rw-r--r--fs/hfsplus/bnode.c6
-rw-r--r--fs/hfsplus/btree.c3
-rw-r--r--fs/inode.c15
-rw-r--r--fs/jffs2/background.c3
-rw-r--r--fs/smbfs/file.c6
-rw-r--r--fs/sysfs/dir.c2
-rw-r--r--fs/sysfs/file.c2
-rw-r--r--fs/sysfs/inode.c3
-rw-r--r--fs/sysv/dir.c6
-rw-r--r--fs/udf/inode.c6
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c113
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h1
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c120
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.h11
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c11
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h12
-rw-r--r--fs/xfs/quota/xfs_qm.c17
-rw-r--r--fs/xfs/quota/xfs_trans_dquot.c68
-rw-r--r--fs/xfs/xfs_bmap.c11
-rw-r--r--fs/xfs/xfs_bmap.h9
-rw-r--r--fs/xfs/xfs_clnt.h1
-rw-r--r--fs/xfs/xfs_error.h3
-rw-r--r--fs/xfs/xfs_mount.c71
-rw-r--r--fs/xfs/xfs_mount.h5
-rw-r--r--fs/xfs/xfs_quota.h5
-rw-r--r--fs/xfs/xfs_vfsops.c10
-rw-r--r--fs/xfs/xfs_vnodeops.c4
-rw-r--r--include/asm-arm/arch-at91rm9200/at91rm9200_mci.h104
-rw-r--r--include/asm-arm/arch-at91rm9200/board.h24
-rw-r--r--include/asm-arm/arch-ep93xx/ts72xx.h11
-rw-r--r--include/asm-arm/arch-imx/dma.h17
-rw-r--r--include/asm-arm/arch-imx/imx-dma.h90
-rw-r--r--include/asm-arm/arch-imx/mmc.h12
-rw-r--r--include/asm-arm/arch-ixp23xx/memory.h17
-rw-r--r--include/asm-arm/arch-ixp23xx/platform.h1
-rw-r--r--include/asm-arm/arch-omap/aic23.h4
-rw-r--r--include/asm-arm/arch-omap/board-ams-delta.h65
-rw-r--r--include/asm-arm/arch-omap/board-apollon.h45
-rw-r--r--include/asm-arm/arch-omap/board-h2.h4
-rw-r--r--include/asm-arm/arch-omap/board-h3.h4
-rw-r--r--include/asm-arm/arch-omap/board-h4.h8
-rw-r--r--include/asm-arm/arch-omap/board-netstar.h19
-rw-r--r--include/asm-arm/arch-omap/board-nokia.h54
-rw-r--r--include/asm-arm/arch-omap/board-perseus2.h4
-rw-r--r--include/asm-arm/arch-omap/board.h30
-rw-r--r--include/asm-arm/arch-omap/clock.h13
-rw-r--r--include/asm-arm/arch-omap/dma.h1
-rw-r--r--include/asm-arm/arch-omap/dmtimer.h1
-rw-r--r--include/asm-arm/arch-omap/dsp.h6
-rw-r--r--include/asm-arm/arch-omap/dsp_common.h13
-rw-r--r--include/asm-arm/arch-omap/gpioexpander.h24
-rw-r--r--include/asm-arm/arch-omap/hardware.h8
-rw-r--r--include/asm-arm/arch-omap/irda.h36
-rw-r--r--include/asm-arm/arch-omap/irqs.h5
-rw-r--r--include/asm-arm/arch-omap/keypad.h36
-rw-r--r--include/asm-arm/arch-omap/lcd_lph8923.h14
-rw-r--r--include/asm-arm/arch-omap/mcbsp.h65
-rw-r--r--include/asm-arm/arch-omap/mcspi.h16
-rw-r--r--include/asm-arm/arch-omap/menelaus.h2
-rw-r--r--include/asm-arm/arch-omap/mux.h54
-rw-r--r--include/asm-arm/arch-omap/omap-alsa.h124
-rw-r--r--include/asm-arm/arch-omap/omapfb.h98
-rw-r--r--include/asm-arm/arch-omap/param.h8
-rw-r--r--include/asm-arm/arch-omap/pm.h81
-rw-r--r--include/asm-arm/arch-omap/prcm.h404
-rw-r--r--include/asm-arm/arch-omap/sram.h2
-rw-r--r--include/asm-arm/arch-omap/system.h17
-rw-r--r--include/asm-arm/arch-s3c2410/entry-macro.S167
-rw-r--r--include/asm-arm/dma-mapping.h22
-rw-r--r--include/asm-arm/memory.h8
-rw-r--r--include/asm-arm/pgtable-hwdef.h1
-rw-r--r--include/asm-arm/pgtable.h1
-rw-r--r--include/linux/fs.h2
-rw-r--r--include/linux/hrtimer.h2
-rw-r--r--include/sound/core.h2
-rw-r--r--include/sound/pcm.h15
-rw-r--r--include/sound/pcm_oss.h3
-rw-r--r--ipc/shm.c15
-rw-r--r--ipc/util.c6
-rw-r--r--kernel/power/Kconfig2
-rw-r--r--kernel/printk.c6
-rw-r--r--kernel/ptrace.c3
-rw-r--r--kernel/signal.c6
-rw-r--r--kernel/time.c8
-rw-r--r--kernel/timer.c3
-rw-r--r--mm/highmem.c15
-rw-r--r--mm/mmap.c9
-rw-r--r--mm/page-writeback.c2
-rw-r--r--mm/slab.c18
-rw-r--r--mm/swap_state.c3
-rw-r--r--mm/vmalloc.c3
-rw-r--r--sound/core/Kconfig5
-rw-r--r--sound/core/control.c6
-rw-r--r--sound/core/control_compat.c6
-rw-r--r--sound/core/init.c9
-rw-r--r--sound/core/oss/pcm_oss.c288
-rw-r--r--sound/core/pcm.c14
-rw-r--r--sound/core/pcm_lib.c49
-rw-r--r--sound/core/pcm_native.c157
-rw-r--r--sound/isa/Kconfig23
-rw-r--r--sound/isa/Makefile2
-rw-r--r--sound/isa/adlib.c161
-rw-r--r--sound/isa/cmi8330.c4
-rw-r--r--sound/isa/opti9xx/Makefile2
-rw-r--r--sound/isa/opti9xx/miro.c1455
-rw-r--r--sound/isa/opti9xx/miro.h73
-rw-r--r--sound/pci/Kconfig30
-rw-r--r--sound/pci/Makefile3
-rw-r--r--sound/pci/als300.c866
-rw-r--r--sound/pci/cs4281.c28
-rw-r--r--sound/pci/hda/hda_codec.c2
-rw-r--r--sound/pci/hda/hda_intel.c2
-rw-r--r--sound/pci/hda/patch_analog.c9
-rw-r--r--sound/pci/hda/patch_realtek.c298
-rw-r--r--sound/pci/hda/patch_sigmatel.c53
-rw-r--r--sound/pci/ice1712/aureon.c163
-rw-r--r--sound/pci/ice1712/ice1712.c2
-rw-r--r--sound/pci/ice1712/ice1712.h1
-rw-r--r--sound/pci/maestro3.c57
-rw-r--r--sound/pci/pcxhr/pcxhr_core.c9
-rw-r--r--sound/pci/riptide/Makefile3
-rw-r--r--sound/pci/riptide/riptide.c2223
-rw-r--r--sound/pci/via82xx.c1
-rw-r--r--sound/usb/usbmixer.c37
264 files changed, 15463 insertions, 2602 deletions
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index 7d87dd73cbe4..5a2882d275ba 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -2,7 +2,7 @@
2# This makefile is used to generate the kernel documentation, 2# This makefile is used to generate the kernel documentation,
3# primarily based on in-line comments in various source files. 3# primarily based on in-line comments in various source files.
4# See Documentation/kernel-doc-nano-HOWTO.txt for instruction in how 4# See Documentation/kernel-doc-nano-HOWTO.txt for instruction in how
5# to ducument the SRC - and how to read it. 5# to document the SRC - and how to read it.
6# To add a new book the only step required is to add the book to the 6# To add a new book the only step required is to add the book to the
7# list of DOCBOOKS. 7# list of DOCBOOKS.
8 8
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index 8c9c6704e85b..ca02e04a906c 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -322,7 +322,6 @@ X!Earch/i386/kernel/mca.c
322 <chapter id="sysfs"> 322 <chapter id="sysfs">
323 <title>The Filesystem for Exporting Kernel Objects</title> 323 <title>The Filesystem for Exporting Kernel Objects</title>
324!Efs/sysfs/file.c 324!Efs/sysfs/file.c
325!Efs/sysfs/dir.c
326!Efs/sysfs/symlink.c 325!Efs/sysfs/symlink.c
327!Efs/sysfs/bin.c 326!Efs/sysfs/bin.c
328 </chapter> 327 </chapter>
diff --git a/Documentation/acpi-hotkey.txt b/Documentation/acpi-hotkey.txt
index 744f1aec6553..38040fa37649 100644
--- a/Documentation/acpi-hotkey.txt
+++ b/Documentation/acpi-hotkey.txt
@@ -30,7 +30,7 @@ specific hotkey(event))
30echo "event_num:event_type:event_argument" > 30echo "event_num:event_type:event_argument" >
31 /proc/acpi/hotkey/action. 31 /proc/acpi/hotkey/action.
32The result of the execution of this aml method is 32The result of the execution of this aml method is
33attached to /proc/acpi/hotkey/poll_method, which is dnyamically 33attached to /proc/acpi/hotkey/poll_method, which is dynamically
34created. Please use command "cat /proc/acpi/hotkey/polling_method" 34created. Please use command "cat /proc/acpi/hotkey/polling_method"
35to retrieve it. 35to retrieve it.
36 36
diff --git a/Documentation/fujitsu/frv/kernel-ABI.txt b/Documentation/fujitsu/frv/kernel-ABI.txt
index 0ed9b0a779bc..8b0a5fc8bfd9 100644
--- a/Documentation/fujitsu/frv/kernel-ABI.txt
+++ b/Documentation/fujitsu/frv/kernel-ABI.txt
@@ -1,17 +1,19 @@
1 ================================= 1 =================================
2 INTERNAL KERNEL ABI FOR FR-V ARCH 2 INTERNAL KERNEL ABI FOR FR-V ARCH
3 ================================= 3 =================================
4 4
5The internal FRV kernel ABI is not quite the same as the userspace ABI. A number of the registers 5The internal FRV kernel ABI is not quite the same as the userspace ABI. A
6are used for special purposed, and the ABI is not consistent between modules vs core, and MMU vs 6number of the registers are used for special purposed, and the ABI is not
7no-MMU. 7consistent between modules vs core, and MMU vs no-MMU.
8 8
9This partly stems from the fact that FRV CPUs do not have a separate supervisor stack pointer, and 9This partly stems from the fact that FRV CPUs do not have a separate
10most of them do not have any scratch registers, thus requiring at least one general purpose 10supervisor stack pointer, and most of them do not have any scratch
11register to be clobbered in such an event. Also, within the kernel core, it is possible to simply 11registers, thus requiring at least one general purpose register to be
12jump or call directly between functions using a relative offset. This cannot be extended to modules 12clobbered in such an event. Also, within the kernel core, it is possible to
13for the displacement is likely to be too far. Thus in modules the address of a function to call 13simply jump or call directly between functions using a relative offset.
14must be calculated in a register and then used, requiring two extra instructions. 14This cannot be extended to modules for the displacement is likely to be too
15far. Thus in modules the address of a function to call must be calculated
16in a register and then used, requiring two extra instructions.
15 17
16This document has the following sections: 18This document has the following sections:
17 19
@@ -39,7 +41,8 @@ When a system call is made, the following registers are effective:
39CPU OPERATING MODES 41CPU OPERATING MODES
40=================== 42===================
41 43
42The FR-V CPU has three basic operating modes. In order of increasing capability: 44The FR-V CPU has three basic operating modes. In order of increasing
45capability:
43 46
44 (1) User mode. 47 (1) User mode.
45 48
@@ -47,42 +50,46 @@ The FR-V CPU has three basic operating modes. In order of increasing capability:
47 50
48 (2) Kernel mode. 51 (2) Kernel mode.
49 52
50 Normal kernel mode. There are many additional control registers available that may be 53 Normal kernel mode. There are many additional control registers
51 accessed in this mode, in addition to all the stuff available to user mode. This has two 54 available that may be accessed in this mode, in addition to all the
52 submodes: 55 stuff available to user mode. This has two submodes:
53 56
54 (a) Exceptions enabled (PSR.T == 1). 57 (a) Exceptions enabled (PSR.T == 1).
55 58
56 Exceptions will invoke the appropriate normal kernel mode handler. On entry to the 59 Exceptions will invoke the appropriate normal kernel mode
57 handler, the PSR.T bit will be cleared. 60 handler. On entry to the handler, the PSR.T bit will be cleared.
58 61
59 (b) Exceptions disabled (PSR.T == 0). 62 (b) Exceptions disabled (PSR.T == 0).
60 63
61 No exceptions or interrupts may happen. Any mandatory exceptions will cause the CPU to 64 No exceptions or interrupts may happen. Any mandatory exceptions
62 halt unless the CPU is told to jump into debug mode instead. 65 will cause the CPU to halt unless the CPU is told to jump into
66 debug mode instead.
63 67
64 (3) Debug mode. 68 (3) Debug mode.
65 69
66 No exceptions may happen in this mode. Memory protection and management exceptions will be 70 No exceptions may happen in this mode. Memory protection and
67 flagged for later consideration, but the exception handler won't be invoked. Debugging traps 71 management exceptions will be flagged for later consideration, but
68 such as hardware breakpoints and watchpoints will be ignored. This mode is entered only by 72 the exception handler won't be invoked. Debugging traps such as
69 debugging events obtained from the other two modes. 73 hardware breakpoints and watchpoints will be ignored. This mode is
74 entered only by debugging events obtained from the other two modes.
70 75
71 All kernel mode registers may be accessed, plus a few extra debugging specific registers. 76 All kernel mode registers may be accessed, plus a few extra debugging
77 specific registers.
72 78
73 79
74================================= 80=================================
75INTERNAL KERNEL-MODE REGISTER ABI 81INTERNAL KERNEL-MODE REGISTER ABI
76================================= 82=================================
77 83
78There are a number of permanent register assignments that are set up by entry.S in the exception 84There are a number of permanent register assignments that are set up by
79prologue. Note that there is a complete set of exception prologues for each of user->kernel 85entry.S in the exception prologue. Note that there is a complete set of
80transition and kernel->kernel transition. There are also user->debug and kernel->debug mode 86exception prologues for each of user->kernel transition and kernel->kernel
81transition prologues. 87transition. There are also user->debug and kernel->debug mode transition
88prologues.
82 89
83 90
84 REGISTER FLAVOUR USE 91 REGISTER FLAVOUR USE
85 =============== ======= ==================================================== 92 =============== ======= ==============================================
86 GR1 Supervisor stack pointer 93 GR1 Supervisor stack pointer
87 GR15 Current thread info pointer 94 GR15 Current thread info pointer
88 GR16 GP-Rel base register for small data 95 GR16 GP-Rel base register for small data
@@ -92,10 +99,12 @@ transition prologues.
92 GR31 NOMMU Destroyed by debug mode entry 99 GR31 NOMMU Destroyed by debug mode entry
93 GR31 MMU Destroyed by TLB miss kernel mode entry 100 GR31 MMU Destroyed by TLB miss kernel mode entry
94 CCR.ICC2 Virtual interrupt disablement tracking 101 CCR.ICC2 Virtual interrupt disablement tracking
95 CCCR.CC3 Cleared by exception prologue (atomic op emulation) 102 CCCR.CC3 Cleared by exception prologue
103 (atomic op emulation)
96 SCR0 MMU See mmu-layout.txt. 104 SCR0 MMU See mmu-layout.txt.
97 SCR1 MMU See mmu-layout.txt. 105 SCR1 MMU See mmu-layout.txt.
98 SCR2 MMU Save for EAR0 (destroyed by icache insns in debug mode) 106 SCR2 MMU Save for EAR0 (destroyed by icache insns
107 in debug mode)
99 SCR3 MMU Save for GR31 during debug exceptions 108 SCR3 MMU Save for GR31 during debug exceptions
100 DAMR/IAMR NOMMU Fixed memory protection layout. 109 DAMR/IAMR NOMMU Fixed memory protection layout.
101 DAMR/IAMR MMU See mmu-layout.txt. 110 DAMR/IAMR MMU See mmu-layout.txt.
@@ -104,18 +113,21 @@ transition prologues.
104Certain registers are also used or modified across function calls: 113Certain registers are also used or modified across function calls:
105 114
106 REGISTER CALL RETURN 115 REGISTER CALL RETURN
107 =============== =============================== =============================== 116 =============== =============================== ======================
108 GR0 Fixed Zero - 117 GR0 Fixed Zero -
109 GR2 Function call frame pointer 118 GR2 Function call frame pointer
110 GR3 Special Preserved 119 GR3 Special Preserved
111 GR3-GR7 - Clobbered 120 GR3-GR7 - Clobbered
112 GR8 Function call arg #1 Return value (or clobbered) 121 GR8 Function call arg #1 Return value
113 GR9 Function call arg #2 Return value MSW (or clobbered) 122 (or clobbered)
123 GR9 Function call arg #2 Return value MSW
124 (or clobbered)
114 GR10-GR13 Function call arg #3-#6 Clobbered 125 GR10-GR13 Function call arg #3-#6 Clobbered
115 GR14 - Clobbered 126 GR14 - Clobbered
116 GR15-GR16 Special Preserved 127 GR15-GR16 Special Preserved
117 GR17-GR27 - Preserved 128 GR17-GR27 - Preserved
118 GR28-GR31 Special Only accessed explicitly 129 GR28-GR31 Special Only accessed
130 explicitly
119 LR Return address after CALL Clobbered 131 LR Return address after CALL Clobbered
120 CCR/CCCR - Mostly Clobbered 132 CCR/CCCR - Mostly Clobbered
121 133
@@ -124,46 +136,53 @@ Certain registers are also used or modified across function calls:
124INTERNAL DEBUG-MODE REGISTER ABI 136INTERNAL DEBUG-MODE REGISTER ABI
125================================ 137================================
126 138
127This is the same as the kernel-mode register ABI for functions calls. The difference is that in 139This is the same as the kernel-mode register ABI for functions calls. The
128debug-mode there's a different stack and a different exception frame. Almost all the global 140difference is that in debug-mode there's a different stack and a different
129registers from kernel-mode (including the stack pointer) may be changed. 141exception frame. Almost all the global registers from kernel-mode
142(including the stack pointer) may be changed.
130 143
131 REGISTER FLAVOUR USE 144 REGISTER FLAVOUR USE
132 =============== ======= ==================================================== 145 =============== ======= ==============================================
133 GR1 Debug stack pointer 146 GR1 Debug stack pointer
134 GR16 GP-Rel base register for small data 147 GR16 GP-Rel base register for small data
135 GR31 Current debug exception frame pointer (__debug_frame) 148 GR31 Current debug exception frame pointer
149 (__debug_frame)
136 SCR3 MMU Saved value of GR31 150 SCR3 MMU Saved value of GR31
137 151
138 152
139Note that debug mode is able to interfere with the kernel's emulated atomic ops, so it must be 153Note that debug mode is able to interfere with the kernel's emulated atomic
140exceedingly careful not to do any that would interact with the main kernel in this regard. Hence 154ops, so it must be exceedingly careful not to do any that would interact
141the debug mode code (gdbstub) is almost completely self-contained. The only external code used is 155with the main kernel in this regard. Hence the debug mode code (gdbstub) is
142the sprintf family of functions. 156almost completely self-contained. The only external code used is the
157sprintf family of functions.
143 158
144Futhermore, break.S is so complicated because single-step mode does not switch off on entry to an 159Futhermore, break.S is so complicated because single-step mode does not
145exception. That means unless manually disabled, single-stepping will blithely go on stepping into 160switch off on entry to an exception. That means unless manually disabled,
146things like interrupts. See gdbstub.txt for more information. 161single-stepping will blithely go on stepping into things like interrupts.
162See gdbstub.txt for more information.
147 163
148 164
149========================== 165==========================
150VIRTUAL INTERRUPT HANDLING 166VIRTUAL INTERRUPT HANDLING
151========================== 167==========================
152 168
153Because accesses to the PSR is so slow, and to disable interrupts we have to access it twice (once 169Because accesses to the PSR is so slow, and to disable interrupts we have
154to read and once to write), we don't actually disable interrupts at all if we don't have to. What 170to access it twice (once to read and once to write), we don't actually
155we do instead is use the ICC2 condition code flags to note virtual disablement, such that if we 171disable interrupts at all if we don't have to. What we do instead is use
156then do take an interrupt, we note the flag, really disable interrupts, set another flag and resume 172the ICC2 condition code flags to note virtual disablement, such that if we
157execution at the point the interrupt happened. Setting condition flags as a side effect of an 173then do take an interrupt, we note the flag, really disable interrupts, set
158arithmetic or logical instruction is really fast. This use of the ICC2 only occurs within the 174another flag and resume execution at the point the interrupt happened.
175Setting condition flags as a side effect of an arithmetic or logical
176instruction is really fast. This use of the ICC2 only occurs within the
159kernel - it does not affect userspace. 177kernel - it does not affect userspace.
160 178
161The flags we use are: 179The flags we use are:
162 180
163 (*) CCR.ICC2.Z [Zero flag] 181 (*) CCR.ICC2.Z [Zero flag]
164 182
165 Set to virtually disable interrupts, clear when interrupts are virtually enabled. Can be 183 Set to virtually disable interrupts, clear when interrupts are
166 modified by logical instructions without affecting the Carry flag. 184 virtually enabled. Can be modified by logical instructions without
185 affecting the Carry flag.
167 186
168 (*) CCR.ICC2.C [Carry flag] 187 (*) CCR.ICC2.C [Carry flag]
169 188
@@ -176,8 +195,9 @@ What happens is this:
176 195
177 ICC2.Z is 0, ICC2.C is 1. 196 ICC2.Z is 0, ICC2.C is 1.
178 197
179 (2) An interrupt occurs. The exception prologue examines ICC2.Z and determines that nothing needs 198 (2) An interrupt occurs. The exception prologue examines ICC2.Z and
180 doing. This is done simply with an unlikely BEQ instruction. 199 determines that nothing needs doing. This is done simply with an
200 unlikely BEQ instruction.
181 201
182 (3) The interrupts are disabled (local_irq_disable) 202 (3) The interrupts are disabled (local_irq_disable)
183 203
@@ -187,48 +207,56 @@ What happens is this:
187 207
188 ICC2.Z would be set to 0. 208 ICC2.Z would be set to 0.
189 209
190 A TIHI #2 instruction (trap #2 if condition HI - Z==0 && C==0) would be used to trap if 210 A TIHI #2 instruction (trap #2 if condition HI - Z==0 && C==0) would
191 interrupts were now virtually enabled, but physically disabled - which they're not, so the 211 be used to trap if interrupts were now virtually enabled, but
192 trap isn't taken. The kernel would then be back to state (1). 212 physically disabled - which they're not, so the trap isn't taken. The
213 kernel would then be back to state (1).
193 214
194 (5) An interrupt occurs. The exception prologue examines ICC2.Z and determines that the interrupt 215 (5) An interrupt occurs. The exception prologue examines ICC2.Z and
195 shouldn't actually have happened. It jumps aside, and there disabled interrupts by setting 216 determines that the interrupt shouldn't actually have happened. It
196 PSR.PIL to 14 and then it clears ICC2.C. 217 jumps aside, and there disabled interrupts by setting PSR.PIL to 14
218 and then it clears ICC2.C.
197 219
198 (6) If interrupts were then saved and disabled again (local_irq_save): 220 (6) If interrupts were then saved and disabled again (local_irq_save):
199 221
200 ICC2.Z would be shifted into the save variable and masked off (giving a 1). 222 ICC2.Z would be shifted into the save variable and masked off
223 (giving a 1).
201 224
202 ICC2.Z would then be set to 1 (thus unchanged), and ICC2.C would be unaffected (ie: 0). 225 ICC2.Z would then be set to 1 (thus unchanged), and ICC2.C would be
226 unaffected (ie: 0).
203 227
204 (7) If interrupts were then restored from state (6) (local_irq_restore): 228 (7) If interrupts were then restored from state (6) (local_irq_restore):
205 229
206 ICC2.Z would be set to indicate the result of XOR'ing the saved value (ie: 1) with 1, which 230 ICC2.Z would be set to indicate the result of XOR'ing the saved
207 gives a result of 0 - thus leaving ICC2.Z set. 231 value (ie: 1) with 1, which gives a result of 0 - thus leaving
232 ICC2.Z set.
208 233
209 ICC2.C would remain unaffected (ie: 0). 234 ICC2.C would remain unaffected (ie: 0).
210 235
211 A TIHI #2 instruction would be used to again assay the current state, but this would do 236 A TIHI #2 instruction would be used to again assay the current state,
212 nothing as Z==1. 237 but this would do nothing as Z==1.
213 238
214 (8) If interrupts were then enabled (local_irq_enable): 239 (8) If interrupts were then enabled (local_irq_enable):
215 240
216 ICC2.Z would be cleared. ICC2.C would be left unaffected. Both flags would now be 0. 241 ICC2.Z would be cleared. ICC2.C would be left unaffected. Both
242 flags would now be 0.
217 243
218 A TIHI #2 instruction again issued to assay the current state would then trap as both Z==0 244 A TIHI #2 instruction again issued to assay the current state would
219 [interrupts virtually enabled] and C==0 [interrupts really disabled] would then be true. 245 then trap as both Z==0 [interrupts virtually enabled] and C==0
246 [interrupts really disabled] would then be true.
220 247
221 (9) The trap #2 handler would simply enable hardware interrupts (set PSR.PIL to 0), set ICC2.C to 248 (9) The trap #2 handler would simply enable hardware interrupts
222 1 and return. 249 (set PSR.PIL to 0), set ICC2.C to 1 and return.
223 250
224(10) Immediately upon returning, the pending interrupt would be taken. 251(10) Immediately upon returning, the pending interrupt would be taken.
225 252
226(11) The interrupt handler would take the path of actually processing the interrupt (ICC2.Z is 253(11) The interrupt handler would take the path of actually processing the
227 clear, BEQ fails as per step (2)). 254 interrupt (ICC2.Z is clear, BEQ fails as per step (2)).
228 255
229(12) The interrupt handler would then set ICC2.C to 1 since hardware interrupts are definitely 256(12) The interrupt handler would then set ICC2.C to 1 since hardware
230 enabled - or else the kernel wouldn't be here. 257 interrupts are definitely enabled - or else the kernel wouldn't be here.
231 258
232(13) On return from the interrupt handler, things would be back to state (1). 259(13) On return from the interrupt handler, things would be back to state (1).
233 260
234This trap (#2) is only available in kernel mode. In user mode it will result in SIGILL. 261This trap (#2) is only available in kernel mode. In user mode it will
262result in SIGILL.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index f8cb55c30b0f..b3a6187e5305 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1,4 +1,4 @@
1February 2003 Kernel Parameters v2.5.59 1 Kernel Parameters
2 ~~~~~~~~~~~~~~~~~ 2 ~~~~~~~~~~~~~~~~~
3 3
4The following is a consolidated list of the kernel parameters as implemented 4The following is a consolidated list of the kernel parameters as implemented
@@ -17,9 +17,17 @@ are specified on the kernel command line with the module name plus
17 17
18 usbcore.blinkenlights=1 18 usbcore.blinkenlights=1
19 19
20The text in square brackets at the beginning of the description states the 20This document may not be entirely up to date and comprehensive. The command
21restrictions on the kernel for the said kernel parameter to be valid. The 21"modinfo -p ${modulename}" shows a current list of all parameters of a loadable
22restrictions referred to are that the relevant option is valid if: 22module. Loadable modules, after being loaded into the running kernel, also
23reveal their parameters in /sys/module/${modulename}/parameters/. Some of these
24parameters may be changed at runtime by the command
25"echo -n ${value} > /sys/module/${modulename}/parameters/${parm}".
26
27The parameters listed below are only valid if certain kernel build options were
28enabled and if respective hardware is present. The text in square brackets at
29the beginning of each description states the restrictions within which a
30parameter is applicable:
23 31
24 ACPI ACPI support is enabled. 32 ACPI ACPI support is enabled.
25 ALSA ALSA sound support is enabled. 33 ALSA ALSA sound support is enabled.
@@ -1046,10 +1054,10 @@ running once the system is up.
1046 noltlbs [PPC] Do not use large page/tlb entries for kernel 1054 noltlbs [PPC] Do not use large page/tlb entries for kernel
1047 lowmem mapping on PPC40x. 1055 lowmem mapping on PPC40x.
1048 1056
1049 nomce [IA-32] Machine Check Exception
1050
1051 nomca [IA-64] Disable machine check abort handling 1057 nomca [IA-64] Disable machine check abort handling
1052 1058
1059 nomce [IA-32] Machine Check Exception
1060
1053 noresidual [PPC] Don't use residual data on PReP machines. 1061 noresidual [PPC] Don't use residual data on PReP machines.
1054 1062
1055 noresume [SWSUSP] Disables resume and restores original swap 1063 noresume [SWSUSP] Disables resume and restores original swap
@@ -1682,20 +1690,6 @@ running once the system is up.
1682 1690
1683 1691
1684______________________________________________________________________ 1692______________________________________________________________________
1685Changelog:
1686
16872000-06-?? Mr. Unknown
1688 The last known update (for 2.4.0) - the changelog was not kept before.
1689
16902002-11-24 Petr Baudis <pasky@ucw.cz>
1691 Randy Dunlap <randy.dunlap@verizon.net>
1692 Update for 2.5.49, description for most of the options introduced,
1693 references to other documentation (C files, READMEs, ..), added S390,
1694 PPC, SPARC, MTD, ALSA and OSS category. Minor corrections and
1695 reformatting.
1696
16972005-10-19 Randy Dunlap <rdunlap@xenotime.net>
1698 Lots of typos, whitespace, some reformatting.
1699 1693
1700TODO: 1694TODO:
1701 1695
diff --git a/Documentation/networking/packet_mmap.txt b/Documentation/networking/packet_mmap.txt
index 4fc8e9874320..aaf99d5f0dad 100644
--- a/Documentation/networking/packet_mmap.txt
+++ b/Documentation/networking/packet_mmap.txt
@@ -254,7 +254,7 @@ and, the number of frames be
254 254
255 <block number> * <block size> / <frame size> 255 <block number> * <block size> / <frame size>
256 256
257Suposse the following parameters, which apply for 2.6 kernel and an 257Suppose the following parameters, which apply for 2.6 kernel and an
258i386 architecture: 258i386 architecture:
259 259
260 <size-max> = 131072 bytes 260 <size-max> = 131072 bytes
diff --git a/Documentation/networking/tuntap.txt b/Documentation/networking/tuntap.txt
index ec3d109d787a..76750fb9151a 100644
--- a/Documentation/networking/tuntap.txt
+++ b/Documentation/networking/tuntap.txt
@@ -138,7 +138,7 @@ This means that you have to read/write IP packets when you are using tun and
138ethernet frames when using tap. 138ethernet frames when using tap.
139 139
1405. What is the difference between BPF and TUN/TAP driver? 1405. What is the difference between BPF and TUN/TAP driver?
141BFP is an advanced packet filter. It can be attached to existing 141BPF is an advanced packet filter. It can be attached to existing
142network interface. It does not provide a virtual network interface. 142network interface. It does not provide a virtual network interface.
143A TUN/TAP driver does provide a virtual network interface and it is possible 143A TUN/TAP driver does provide a virtual network interface and it is possible
144to attach BPF to this interface. 144to attach BPF to this interface.
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 1def6049784c..0ee2c7dfc482 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -120,6 +120,34 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
120 enable - enable card 120 enable - enable card
121 - Default: enabled, for PCI and ISA PnP cards 121 - Default: enabled, for PCI and ISA PnP cards
122 122
123 Module snd-adlib
124 ----------------
125
126 Module for AdLib FM cards.
127
128 port - port # for OPL chip
129
130 This module supports multiple cards. It does not support autoprobe, so
131 the port must be specified. For actual AdLib FM cards it will be 0x388.
132 Note that this card does not have PCM support and no mixer; only FM
133 synthesis.
134
135 Make sure you have "sbiload" from the alsa-tools package available and,
136 after loading the module, find out the assigned ALSA sequencer port
137 number through "sbiload -l". Example output:
138
139 Port Client name Port name
140 64:0 OPL2 FM synth OPL2 FM Port
141
142 Load the std.sb and drums.sb patches also supplied by sbiload:
143
144 sbiload -p 64:0 std.sb drums.sb
145
146 If you use this driver to drive an OPL3, you can use std.o3 and drums.o3
147 instead. To have the card produce sound, use aplaymidi from alsa-utils:
148
149 aplaymidi -p 64:0 foo.mid
150
123 Module snd-ad1816a 151 Module snd-ad1816a
124 ------------------ 152 ------------------
125 153
@@ -190,6 +218,15 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
190 218
191 The power-management is supported. 219 The power-management is supported.
192 220
221 Module snd-als300
222 -----------------
223
224 Module for Avance Logic ALS300 and ALS300+
225
226 This module supports multiple cards.
227
228 The power-management is supported.
229
193 Module snd-als4000 230 Module snd-als4000
194 ------------------ 231 ------------------
195 232
@@ -701,6 +738,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
701 uniwill 3-jack 738 uniwill 3-jack
702 F1734 2-jack 739 F1734 2-jack
703 lg LG laptop (m1 express dual) 740 lg LG laptop (m1 express dual)
741 lg-lw LG LW20 laptop
704 test for testing/debugging purpose, almost all controls can be 742 test for testing/debugging purpose, almost all controls can be
705 adjusted. Appearing only when compiled with 743 adjusted. Appearing only when compiled with
706 $CONFIG_SND_DEBUG=y 744 $CONFIG_SND_DEBUG=y
@@ -1013,6 +1051,23 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
1013 1051
1014 The power-management is supported. 1052 The power-management is supported.
1015 1053
1054 Module snd-miro
1055 ---------------
1056
1057 Module for Miro soundcards: miroSOUND PCM 1 pro,
1058 miroSOUND PCM 12,
1059 miroSOUND PCM 20 Radio.
1060
1061 port - Port # (0x530,0x604,0xe80,0xf40)
1062 irq - IRQ # (5,7,9,10,11)
1063 dma1 - 1st dma # (0,1,3)
1064 dma2 - 2nd dma # (0,1)
1065 mpu_port - MPU-401 port # (0x300,0x310,0x320,0x330)
1066 mpu_irq - MPU-401 irq # (5,7,9,10)
1067 fm_port - FM Port # (0x388)
1068 wss - enable WSS mode
1069 ide - enable onboard ide support
1070
1016 Module snd-mixart 1071 Module snd-mixart
1017 ----------------- 1072 -----------------
1018 1073
@@ -1202,6 +1257,20 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
1202 1257
1203 The power-management is supported. 1258 The power-management is supported.
1204 1259
1260 Module snd-riptide
1261 ------------------
1262
1263 Module for Conexant Riptide chip
1264
1265 joystick_port - Joystick port # (default: 0x200)
1266 mpu_port - MPU401 port # (default: 0x330)
1267 opl3_port - OPL3 port # (default: 0x388)
1268
1269 This module supports multiple cards.
1270 The driver requires the firmware loader support on kernel.
1271 You need to install the firmware file "riptide.hex" to the standard
1272 firmware path (e.g. /lib/firmware).
1273
1205 Module snd-rme32 1274 Module snd-rme32
1206 ---------------- 1275 ----------------
1207 1276
diff --git a/arch/arm/configs/at91rm9200dk_defconfig b/arch/arm/configs/at91rm9200dk_defconfig
index 1fe73d198888..9e1c1cceb735 100644
--- a/arch/arm/configs/at91rm9200dk_defconfig
+++ b/arch/arm/configs/at91rm9200dk_defconfig
@@ -379,7 +379,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
379# CONFIG_MTD_DOC2001 is not set 379# CONFIG_MTD_DOC2001 is not set
380# CONFIG_MTD_DOC2001PLUS is not set 380# CONFIG_MTD_DOC2001PLUS is not set
381CONFIG_MTD_AT91_DATAFLASH=y 381CONFIG_MTD_AT91_DATAFLASH=y
382CONFIG_MTD_AT91_DATAFLASH_CARD=y 382# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
383 383
384# 384#
385# NAND Flash Device Drivers 385# NAND Flash Device Drivers
diff --git a/arch/arm/configs/at91rm9200ek_defconfig b/arch/arm/configs/at91rm9200ek_defconfig
index b7d934cdb1b7..6e0805a971d7 100644
--- a/arch/arm/configs/at91rm9200ek_defconfig
+++ b/arch/arm/configs/at91rm9200ek_defconfig
@@ -370,7 +370,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
370# CONFIG_MTD_DOC2001 is not set 370# CONFIG_MTD_DOC2001 is not set
371# CONFIG_MTD_DOC2001PLUS is not set 371# CONFIG_MTD_DOC2001PLUS is not set
372CONFIG_MTD_AT91_DATAFLASH=y 372CONFIG_MTD_AT91_DATAFLASH=y
373CONFIG_MTD_AT91_DATAFLASH_CARD=y 373# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
374 374
375# 375#
376# NAND Flash Device Drivers 376# NAND Flash Device Drivers
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 1574941ebfe1..ee083b3f0522 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -100,23 +100,12 @@ EXPORT_SYMBOL(__raw_writesl);
100#endif 100#endif
101 101
102 /* string / mem functions */ 102 /* string / mem functions */
103EXPORT_SYMBOL(strcpy);
104EXPORT_SYMBOL(strncpy);
105EXPORT_SYMBOL(strcat);
106EXPORT_SYMBOL(strncat);
107EXPORT_SYMBOL(strcmp);
108EXPORT_SYMBOL(strncmp);
109EXPORT_SYMBOL(strchr); 103EXPORT_SYMBOL(strchr);
110EXPORT_SYMBOL(strlen);
111EXPORT_SYMBOL(strnlen);
112EXPORT_SYMBOL(strpbrk); 104EXPORT_SYMBOL(strpbrk);
113EXPORT_SYMBOL(strrchr); 105EXPORT_SYMBOL(strrchr);
114EXPORT_SYMBOL(strstr);
115EXPORT_SYMBOL(memset); 106EXPORT_SYMBOL(memset);
116EXPORT_SYMBOL(memcpy); 107EXPORT_SYMBOL(memcpy);
117EXPORT_SYMBOL(memmove); 108EXPORT_SYMBOL(memmove);
118EXPORT_SYMBOL(memcmp);
119EXPORT_SYMBOL(memscan);
120EXPORT_SYMBOL(memchr); 109EXPORT_SYMBOL(memchr);
121EXPORT_SYMBOL(__memzero); 110EXPORT_SYMBOL(__memzero);
122 111
@@ -190,8 +179,6 @@ EXPORT_SYMBOL(_find_next_bit_be);
190 179
191 /* syscalls */ 180 /* syscalls */
192EXPORT_SYMBOL(sys_write); 181EXPORT_SYMBOL(sys_write);
193EXPORT_SYMBOL(sys_read);
194EXPORT_SYMBOL(sys_lseek); 182EXPORT_SYMBOL(sys_lseek);
195EXPORT_SYMBOL(sys_open);
196EXPORT_SYMBOL(sys_exit); 183EXPORT_SYMBOL(sys_exit);
197EXPORT_SYMBOL(sys_wait4); 184EXPORT_SYMBOL(sys_wait4);
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index b7cd280bfd63..437528403959 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -252,6 +252,9 @@ static void __init dump_cpu_info(int cpu)
252 dump_cache("cache", cpu, CACHE_ISIZE(info)); 252 dump_cache("cache", cpu, CACHE_ISIZE(info));
253 } 253 }
254 } 254 }
255
256 if (arch_is_coherent())
257 printk("Cache coherency enabled\n");
255} 258}
256 259
257int cpu_architecture(void) 260int cpu_architecture(void)
diff --git a/arch/arm/mach-at91rm9200/Makefile b/arch/arm/mach-at91rm9200/Makefile
index 75e6ee318ded..ef88c4128edc 100644
--- a/arch/arm/mach-at91rm9200/Makefile
+++ b/arch/arm/mach-at91rm9200/Makefile
@@ -16,11 +16,12 @@ obj-$(CONFIG_MACH_CSB637) += board-csb637.o
16#obj-$(CONFIG_MACH_KB9200) += board-kb9202.o 16#obj-$(CONFIG_MACH_KB9200) += board-kb9202.o
17 17
18# LEDs support 18# LEDs support
19#led-$(CONFIG_ARCH_AT91RM9200DK) += leds.o 19led-$(CONFIG_ARCH_AT91RM9200DK) += leds.o
20#led-$(CONFIG_MACH_AT91RM9200EK) += leds.o 20led-$(CONFIG_MACH_AT91RM9200EK) += leds.o
21#led-$(CONFIG_MACH_CSB337) += leds.o 21led-$(CONFIG_MACH_CSB337) += leds.o
22#led-$(CONFIG_MACH_CSB637) += leds.o 22led-$(CONFIG_MACH_CSB637) += leds.o
23#led-$(CONFIG_MACH_KB9200) += leds.o 23#led-$(CONFIG_MACH_KB9200) += leds.o
24#led-$(CONFIG_MACH_KAFA) += leds.o
24obj-$(CONFIG_LEDS) += $(led-y) 25obj-$(CONFIG_LEDS) += $(led-y)
25 26
26# VGA support 27# VGA support
diff --git a/arch/arm/mach-at91rm9200/board-csb337.c b/arch/arm/mach-at91rm9200/board-csb337.c
index 54022e58d50d..f45104ceea8f 100644
--- a/arch/arm/mach-at91rm9200/board-csb337.c
+++ b/arch/arm/mach-at91rm9200/board-csb337.c
@@ -67,6 +67,9 @@ static void __init csb337_map_io(void)
67 /* Initialize clocks: 3.6864 MHz crystal */ 67 /* Initialize clocks: 3.6864 MHz crystal */
68 at91_clock_init(3686400); 68 at91_clock_init(3686400);
69 69
70 /* Setup the LEDs */
71 at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
72
70#ifdef CONFIG_SERIAL_AT91 73#ifdef CONFIG_SERIAL_AT91
71 at91_console_port = CSB337_SERIAL_CONSOLE; 74 at91_console_port = CSB337_SERIAL_CONSOLE;
72 memcpy(at91_serial_map, serial, sizeof(serial)); 75 memcpy(at91_serial_map, serial, sizeof(serial));
diff --git a/arch/arm/mach-at91rm9200/board-csb637.c b/arch/arm/mach-at91rm9200/board-csb637.c
index 8195f9d919ea..f2c2d6e79bc6 100644
--- a/arch/arm/mach-at91rm9200/board-csb637.c
+++ b/arch/arm/mach-at91rm9200/board-csb637.c
@@ -67,6 +67,9 @@ static void __init csb637_map_io(void)
67 /* Initialize clocks: 3.6864 MHz crystal */ 67 /* Initialize clocks: 3.6864 MHz crystal */
68 at91_clock_init(3686400); 68 at91_clock_init(3686400);
69 69
70 /* Setup the LEDs */
71 at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
72
70#ifdef CONFIG_SERIAL_AT91 73#ifdef CONFIG_SERIAL_AT91
71 at91_console_port = CSB637_SERIAL_CONSOLE; 74 at91_console_port = CSB637_SERIAL_CONSOLE;
72 memcpy(at91_serial_map, serial, sizeof(serial)); 75 memcpy(at91_serial_map, serial, sizeof(serial));
diff --git a/arch/arm/mach-at91rm9200/board-dk.c b/arch/arm/mach-at91rm9200/board-dk.c
index 8a783368366e..2d7200ed66ed 100644
--- a/arch/arm/mach-at91rm9200/board-dk.c
+++ b/arch/arm/mach-at91rm9200/board-dk.c
@@ -70,6 +70,9 @@ static void __init dk_map_io(void)
70 /* Initialize clocks: 18.432 MHz crystal */ 70 /* Initialize clocks: 18.432 MHz crystal */
71 at91_clock_init(18432000); 71 at91_clock_init(18432000);
72 72
73 /* Setup the LEDs */
74 at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
75
73#ifdef CONFIG_SERIAL_AT91 76#ifdef CONFIG_SERIAL_AT91
74 at91_console_port = DK_SERIAL_CONSOLE; 77 at91_console_port = DK_SERIAL_CONSOLE;
75 memcpy(at91_serial_map, serial, sizeof(serial)); 78 memcpy(at91_serial_map, serial, sizeof(serial));
@@ -118,9 +121,14 @@ static void __init dk_board_init(void)
118 at91_add_device_udc(&dk_udc_data); 121 at91_add_device_udc(&dk_udc_data);
119 /* Compact Flash */ 122 /* Compact Flash */
120 at91_add_device_cf(&dk_cf_data); 123 at91_add_device_cf(&dk_cf_data);
124#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
125 /* DataFlash card */
126 at91_set_gpio_output(AT91_PIN_PB7, 0);
127#else
121 /* MMC */ 128 /* MMC */
122 at91_set_gpio_output(AT91_PIN_PB7, 1); /* this MMC card slot can optionally use SPI signaling (CS3). default: MMC */ 129 at91_set_gpio_output(AT91_PIN_PB7, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */
123 at91_add_device_mmc(&dk_mmc_data); 130 at91_add_device_mmc(&dk_mmc_data);
131#endif
124 /* VGA */ 132 /* VGA */
125// dk_add_device_video(); 133// dk_add_device_video();
126} 134}
diff --git a/arch/arm/mach-at91rm9200/board-ek.c b/arch/arm/mach-at91rm9200/board-ek.c
index fd0752eba897..80d90f5135a1 100644
--- a/arch/arm/mach-at91rm9200/board-ek.c
+++ b/arch/arm/mach-at91rm9200/board-ek.c
@@ -70,6 +70,9 @@ static void __init ek_map_io(void)
70 /* Initialize clocks: 18.432 MHz crystal */ 70 /* Initialize clocks: 18.432 MHz crystal */
71 at91_clock_init(18432000); 71 at91_clock_init(18432000);
72 72
73 /* Setup the LEDs */
74 at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2);
75
73#ifdef CONFIG_SERIAL_AT91 76#ifdef CONFIG_SERIAL_AT91
74 at91_console_port = EK_SERIAL_CONSOLE; 77 at91_console_port = EK_SERIAL_CONSOLE;
75 memcpy(at91_serial_map, serial, sizeof(serial)); 78 memcpy(at91_serial_map, serial, sizeof(serial));
@@ -111,9 +114,14 @@ static void __init ek_board_init(void)
111 at91_add_device_usbh(&ek_usbh_data); 114 at91_add_device_usbh(&ek_usbh_data);
112 /* USB Device */ 115 /* USB Device */
113 at91_add_device_udc(&ek_udc_data); 116 at91_add_device_udc(&ek_udc_data);
117#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
118 /* DataFlash card */
119 at91_set_gpio_output(AT91_PIN_PB22, 0);
120#else
114 /* MMC */ 121 /* MMC */
115 at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). default: MMC */ 122 at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */
116 at91_add_device_mmc(&ek_mmc_data); 123 at91_add_device_mmc(&ek_mmc_data);
124#endif
117 /* VGA */ 125 /* VGA */
118// ek_add_device_video(); 126// ek_add_device_video();
119} 127}
diff --git a/arch/arm/mach-at91rm9200/devices.c b/arch/arm/mach-at91rm9200/devices.c
index 57eedd5beaf6..1781b8f342c4 100644
--- a/arch/arm/mach-at91rm9200/devices.c
+++ b/arch/arm/mach-at91rm9200/devices.c
@@ -28,10 +28,10 @@
28static u64 ohci_dmamask = 0xffffffffUL; 28static u64 ohci_dmamask = 0xffffffffUL;
29static struct at91_usbh_data usbh_data; 29static struct at91_usbh_data usbh_data;
30 30
31static struct resource at91rm9200_usbh_resource[] = { 31static struct resource at91_usbh_resource[] = {
32 [0] = { 32 [0] = {
33 .start = AT91_UHP_BASE, 33 .start = AT91_UHP_BASE,
34 .end = AT91_UHP_BASE + SZ_1M -1, 34 .end = AT91_UHP_BASE + SZ_1M - 1,
35 .flags = IORESOURCE_MEM, 35 .flags = IORESOURCE_MEM,
36 }, 36 },
37 [1] = { 37 [1] = {
@@ -49,8 +49,8 @@ static struct platform_device at91rm9200_usbh_device = {
49 .coherent_dma_mask = 0xffffffff, 49 .coherent_dma_mask = 0xffffffff,
50 .platform_data = &usbh_data, 50 .platform_data = &usbh_data,
51 }, 51 },
52 .resource = at91rm9200_usbh_resource, 52 .resource = at91_usbh_resource,
53 .num_resources = ARRAY_SIZE(at91rm9200_usbh_resource), 53 .num_resources = ARRAY_SIZE(at91_usbh_resource),
54}; 54};
55 55
56void __init at91_add_device_usbh(struct at91_usbh_data *data) 56void __init at91_add_device_usbh(struct at91_usbh_data *data)
@@ -121,6 +121,19 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {}
121static u64 eth_dmamask = 0xffffffffUL; 121static u64 eth_dmamask = 0xffffffffUL;
122static struct at91_eth_data eth_data; 122static struct at91_eth_data eth_data;
123 123
124static struct resource at91_eth_resources[] = {
125 [0] = {
126 .start = AT91_BASE_EMAC,
127 .end = AT91_BASE_EMAC + SZ_16K - 1,
128 .flags = IORESOURCE_MEM,
129 },
130 [1] = {
131 .start = AT91_ID_EMAC,
132 .end = AT91_ID_EMAC,
133 .flags = IORESOURCE_IRQ,
134 },
135};
136
124static struct platform_device at91rm9200_eth_device = { 137static struct platform_device at91rm9200_eth_device = {
125 .name = "at91_ether", 138 .name = "at91_ether",
126 .id = -1, 139 .id = -1,
@@ -129,7 +142,8 @@ static struct platform_device at91rm9200_eth_device = {
129 .coherent_dma_mask = 0xffffffff, 142 .coherent_dma_mask = 0xffffffff,
130 .platform_data = &eth_data, 143 .platform_data = &eth_data,
131 }, 144 },
132 .num_resources = 0, 145 .resource = at91_eth_resources,
146 .num_resources = ARRAY_SIZE(at91_eth_resources),
133}; 147};
134 148
135void __init at91_add_device_eth(struct at91_eth_data *data) 149void __init at91_add_device_eth(struct at91_eth_data *data)
@@ -224,15 +238,20 @@ static u64 mmc_dmamask = 0xffffffffUL;
224static struct at91_mmc_data mmc_data; 238static struct at91_mmc_data mmc_data;
225 239
226static struct resource at91_mmc_resources[] = { 240static struct resource at91_mmc_resources[] = {
227 { 241 [0] = {
228 .start = AT91_BASE_MCI, 242 .start = AT91_BASE_MCI,
229 .end = AT91_BASE_MCI + SZ_16K - 1, 243 .end = AT91_BASE_MCI + SZ_16K - 1,
230 .flags = IORESOURCE_MEM, 244 .flags = IORESOURCE_MEM,
231 } 245 },
246 [1] = {
247 .start = AT91_ID_MCI,
248 .end = AT91_ID_MCI,
249 .flags = IORESOURCE_IRQ,
250 },
232}; 251};
233 252
234static struct platform_device at91rm9200_mmc_device = { 253static struct platform_device at91rm9200_mmc_device = {
235 .name = "at91rm9200_mci", 254 .name = "at91_mci",
236 .id = -1, 255 .id = -1,
237 .dev = { 256 .dev = {
238 .dma_mask = &mmc_dmamask, 257 .dma_mask = &mmc_dmamask,
@@ -290,4 +309,123 @@ void __init at91_add_device_mmc(struct at91_mmc_data *data)
290void __init at91_add_device_mmc(struct at91_mmc_data *data) {} 309void __init at91_add_device_mmc(struct at91_mmc_data *data) {}
291#endif 310#endif
292 311
312/* --------------------------------------------------------------------
313 * NAND / SmartMedia
314 * -------------------------------------------------------------------- */
315
316#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE)
317static struct at91_nand_data nand_data;
318
319static struct resource at91_nand_resources[] = {
320 {
321 .start = AT91_SMARTMEDIA_BASE,
322 .end = AT91_SMARTMEDIA_BASE + SZ_8M - 1,
323 .flags = IORESOURCE_MEM,
324 }
325};
326
327static struct platform_device at91_nand_device = {
328 .name = "at91_nand",
329 .id = -1,
330 .dev = {
331 .platform_data = &nand_data,
332 },
333 .resource = at91_nand_resources,
334 .num_resources = ARRAY_SIZE(at91_nand_resources),
335};
336
337void __init at91_add_device_nand(struct at91_nand_data *data)
338{
339 if (!data)
340 return;
341
342 /* enable pin */
343 if (data->enable_pin)
344 at91_set_gpio_output(data->enable_pin, 1);
345
346 /* ready/busy pin */
347 if (data->rdy_pin)
348 at91_set_gpio_input(data->rdy_pin, 1);
349
350 /* card detect pin */
351 if (data->det_pin)
352 at91_set_gpio_input(data->det_pin, 1);
353
354 at91_set_A_periph(AT91_PIN_PC1, 0); /* SMOE */
355 at91_set_A_periph(AT91_PIN_PC3, 0); /* SMWE */
356
357 nand_data = *data;
358 platform_device_register(&at91_nand_device);
359}
360#else
361void __init at91_add_device_nand(struct at91_nand_data *data) {}
362#endif
363
364
365/* --------------------------------------------------------------------
366 * TWI (i2c)
367 * -------------------------------------------------------------------- */
368
369#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
370static struct platform_device at91rm9200_twi_device = {
371 .name = "at91_i2c",
372 .id = -1,
373 .num_resources = 0,
374};
375
376void __init at91_add_device_i2c(void)
377{
378 /* pins used for TWI interface */
379 at91_set_A_periph(AT91_PIN_PA25, 0); /* TWD */
380 at91_set_multi_drive(AT91_PIN_PA25, 1);
381
382 at91_set_A_periph(AT91_PIN_PA26, 0); /* TWCK */
383 at91_set_multi_drive(AT91_PIN_PA26, 1);
384
385 platform_device_register(&at91rm9200_twi_device);
386}
387#else
388void __init at91_add_device_i2c(void) {}
389#endif
390
391
392/* --------------------------------------------------------------------
393 * RTC
394 * -------------------------------------------------------------------- */
395
396#if defined(CONFIG_AT91_RTC) || defined(CONFIG_AT91_RTC_MODULE)
397static struct platform_device at91rm9200_rtc_device = {
398 .name = "at91_rtc",
399 .id = -1,
400 .num_resources = 0,
401};
402
403void __init at91_add_device_rtc(void)
404{
405 platform_device_register(&at91rm9200_rtc_device);
406}
407#else
408void __init at91_add_device_rtc(void) {}
409#endif
410
411
412/* --------------------------------------------------------------------
413 * LEDs
414 * -------------------------------------------------------------------- */
415
416#if defined(CONFIG_LEDS)
417u8 at91_leds_cpu;
418u8 at91_leds_timer;
419
420void __init at91_init_leds(u8 cpu_led, u8 timer_led)
421{
422 at91_leds_cpu = cpu_led;
423 at91_leds_timer = timer_led;
424}
425
426#else
427void __init at91_init_leds(u8 cpu_led, u8 timer_led) {}
428#endif
429
430
293/* -------------------------------------------------------------------- */ 431/* -------------------------------------------------------------------- */
diff --git a/arch/arm/mach-at91rm9200/leds.c b/arch/arm/mach-at91rm9200/leds.c
new file mode 100644
index 000000000000..28150e8905ba
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/leds.c
@@ -0,0 +1,100 @@
1/*
2 * LED driver for Atmel AT91-based boards.
3 *
4 * Copyright (C) SAN People (Pty) Ltd
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10*/
11
12#include <linux/config.h>
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/init.h>
16
17#include <asm/mach-types.h>
18#include <asm/leds.h>
19#include <asm/arch/board.h>
20#include <asm/arch/gpio.h>
21
22
23static inline void at91_led_on(unsigned int led)
24{
25 at91_set_gpio_value(led, 0);
26}
27
28static inline void at91_led_off(unsigned int led)
29{
30 at91_set_gpio_value(led, 1);
31}
32
33static inline void at91_led_toggle(unsigned int led)
34{
35 unsigned long is_off = at91_get_gpio_value(led);
36 if (is_off)
37 at91_led_on(led);
38 else
39 at91_led_off(led);
40}
41
42
43/*
44 * Handle LED events.
45 */
46static void at91_leds_event(led_event_t evt)
47{
48 unsigned long flags;
49
50 local_irq_save(flags);
51
52 switch(evt) {
53 case led_start: /* System startup */
54 at91_led_on(at91_leds_cpu);
55 break;
56
57 case led_stop: /* System stop / suspend */
58 at91_led_off(at91_leds_cpu);
59 break;
60
61#ifdef CONFIG_LEDS_TIMER
62 case led_timer: /* Every 50 timer ticks */
63 at91_led_toggle(at91_leds_timer);
64 break;
65#endif
66
67#ifdef CONFIG_LEDS_CPU
68 case led_idle_start: /* Entering idle state */
69 at91_led_off(at91_leds_cpu);
70 break;
71
72 case led_idle_end: /* Exit idle state */
73 at91_led_on(at91_leds_cpu);
74 break;
75#endif
76
77 default:
78 break;
79 }
80
81 local_irq_restore(flags);
82}
83
84
85static int __init leds_init(void)
86{
87 if (!at91_leds_timer || !at91_leds_cpu)
88 return -ENODEV;
89
90 /* Enable PIO to access the LEDs */
91 at91_set_gpio_output(at91_leds_timer, 1);
92 at91_set_gpio_output(at91_leds_cpu, 1);
93
94 leds_event = at91_leds_event;
95
96 leds_event(led_start);
97 return 0;
98}
99
100__initcall(leds_init);
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 2d892e4daa07..dcd417625389 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -424,6 +424,14 @@ static struct amba_device uart3_device = {
424 .periphid = 0x00041010, 424 .periphid = 0x00041010,
425}; 425};
426 426
427
428static struct platform_device ep93xx_rtc_device = {
429 .name = "ep93xx-rtc",
430 .id = -1,
431 .num_resources = 0,
432};
433
434
427void __init ep93xx_init_devices(void) 435void __init ep93xx_init_devices(void)
428{ 436{
429 unsigned int v; 437 unsigned int v;
@@ -439,4 +447,6 @@ void __init ep93xx_init_devices(void)
439 amba_device_register(&uart1_device, &iomem_resource); 447 amba_device_register(&uart1_device, &iomem_resource);
440 amba_device_register(&uart2_device, &iomem_resource); 448 amba_device_register(&uart2_device, &iomem_resource);
441 amba_device_register(&uart3_device, &iomem_resource); 449 amba_device_register(&uart3_device, &iomem_resource);
450
451 platform_device_register(&ep93xx_rtc_device);
442} 452}
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index 777e75daa8a5..9be01b0c3f48 100644
--- a/arch/arm/mach-ep93xx/ts72xx.c
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -17,6 +17,8 @@
17#include <linux/sched.h> 17#include <linux/sched.h>
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/mtd/physmap.h> 19#include <linux/mtd/physmap.h>
20#include <linux/platform_device.h>
21#include <linux/m48t86.h>
20#include <asm/io.h> 22#include <asm/io.h>
21#include <asm/hardware.h> 23#include <asm/hardware.h>
22#include <asm/mach-types.h> 24#include <asm/mach-types.h>
@@ -39,6 +41,16 @@ static struct map_desc ts72xx_io_desc[] __initdata = {
39 .pfn = __phys_to_pfn(TS72XX_OPTIONS2_PHYS_BASE), 41 .pfn = __phys_to_pfn(TS72XX_OPTIONS2_PHYS_BASE),
40 .length = TS72XX_OPTIONS2_SIZE, 42 .length = TS72XX_OPTIONS2_SIZE,
41 .type = MT_DEVICE, 43 .type = MT_DEVICE,
44 }, {
45 .virtual = TS72XX_RTC_INDEX_VIRT_BASE,
46 .pfn = __phys_to_pfn(TS72XX_RTC_INDEX_PHYS_BASE),
47 .length = TS72XX_RTC_INDEX_SIZE,
48 .type = MT_DEVICE,
49 }, {
50 .virtual = TS72XX_RTC_DATA_VIRT_BASE,
51 .pfn = __phys_to_pfn(TS72XX_RTC_DATA_PHYS_BASE),
52 .length = TS72XX_RTC_DATA_SIZE,
53 .type = MT_DEVICE,
42 } 54 }
43}; 55};
44 56
@@ -99,11 +111,38 @@ static void __init ts72xx_map_io(void)
99 } 111 }
100} 112}
101 113
114static unsigned char ts72xx_rtc_readb(unsigned long addr)
115{
116 __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE);
117 return __raw_readb(TS72XX_RTC_DATA_VIRT_BASE);
118}
119
120static void ts72xx_rtc_writeb(unsigned char value, unsigned long addr)
121{
122 __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE);
123 __raw_writeb(value, TS72XX_RTC_DATA_VIRT_BASE);
124}
125
126static struct m48t86_ops ts72xx_rtc_ops = {
127 .readb = ts72xx_rtc_readb,
128 .writeb = ts72xx_rtc_writeb,
129};
130
131static struct platform_device ts72xx_rtc_device = {
132 .name = "rtc-m48t86",
133 .id = -1,
134 .dev = {
135 .platform_data = &ts72xx_rtc_ops,
136 },
137 .num_resources = 0,
138};
139
102static void __init ts72xx_init_machine(void) 140static void __init ts72xx_init_machine(void)
103{ 141{
104 ep93xx_init_devices(); 142 ep93xx_init_devices();
105 if (board_is_ts7200()) 143 if (board_is_ts7200())
106 physmap_configure(TS72XX_NOR_PHYS_BASE, 0x01000000, 1, NULL); 144 physmap_configure(TS72XX_NOR_PHYS_BASE, 0x01000000, 1, NULL);
145 platform_device_register(&ts72xx_rtc_device);
107} 146}
108 147
109MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC") 148MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC")
diff --git a/arch/arm/mach-imx/dma.c b/arch/arm/mach-imx/dma.c
index 71a59e196166..4ca51dcf13ac 100644
--- a/arch/arm/mach-imx/dma.c
+++ b/arch/arm/mach-imx/dma.c
@@ -7,11 +7,18 @@
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 * 9 *
10 * 03/03/2004 Sascha Hauer <sascha@saschahauer.de> 10 * 2004-03-03 Sascha Hauer <sascha@saschahauer.de>
11 * initial version heavily inspired by 11 * initial version heavily inspired by
12 * linux/arch/arm/mach-pxa/dma.c 12 * linux/arch/arm/mach-pxa/dma.c
13 *
14 * 2005-04-17 Pavel Pisa <pisa@cmp.felk.cvut.cz>
15 * Changed to support scatter gather DMA
16 * by taking Russell's code from RiscPC
17 *
13 */ 18 */
14 19
20#undef DEBUG
21
15#include <linux/module.h> 22#include <linux/module.h>
16#include <linux/init.h> 23#include <linux/init.h>
17#include <linux/kernel.h> 24#include <linux/kernel.h>
@@ -22,69 +29,368 @@
22#include <asm/irq.h> 29#include <asm/irq.h>
23#include <asm/hardware.h> 30#include <asm/hardware.h>
24#include <asm/dma.h> 31#include <asm/dma.h>
32#include <asm/arch/imx-dma.h>
33
34struct imx_dma_channel imx_dma_channels[IMX_DMA_CHANNELS];
35
36/*
37 * imx_dma_sg_next - prepare next chunk for scatter-gather DMA emulation
38 * @dma_ch: i.MX DMA channel number
39 * @lastcount: number of bytes transferred during last transfer
40 *
41 * Functions prepares DMA controller for next sg data chunk transfer.
42 * The @lastcount argument informs function about number of bytes transferred
43 * during last block. Zero value can be used for @lastcount to setup DMA
44 * for the first chunk.
45 */
46static inline int imx_dma_sg_next(imx_dmach_t dma_ch, unsigned int lastcount)
47{
48 struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
49 unsigned int nextcount;
50 unsigned int nextaddr;
51
52 if (!imxdma->name) {
53 printk(KERN_CRIT "%s: called for not allocated channel %d\n",
54 __FUNCTION__, dma_ch);
55 return 0;
56 }
57
58 imxdma->resbytes -= lastcount;
59
60 if (!imxdma->sg) {
61 pr_debug("imxdma%d: no sg data\n", dma_ch);
62 return 0;
63 }
64
65 imxdma->sgbc += lastcount;
66 if ((imxdma->sgbc >= imxdma->sg->length) || !imxdma->resbytes) {
67 if ((imxdma->sgcount <= 1) || !imxdma->resbytes) {
68 pr_debug("imxdma%d: sg transfer limit reached\n",
69 dma_ch);
70 imxdma->sgcount=0;
71 imxdma->sg = NULL;
72 return 0;
73 } else {
74 imxdma->sgcount--;
75 imxdma->sg++;
76 imxdma->sgbc = 0;
77 }
78 }
79 nextcount = imxdma->sg->length - imxdma->sgbc;
80 nextaddr = imxdma->sg->dma_address + imxdma->sgbc;
25 81
26static struct dma_channel { 82 if(imxdma->resbytes < nextcount)
27 char *name; 83 nextcount = imxdma->resbytes;
28 void (*irq_handler) (int, void *, struct pt_regs *);
29 void (*err_handler) (int, void *, struct pt_regs *);
30 void *data;
31} dma_channels[11];
32 84
33/* set err_handler to NULL to have the standard info-only error handler */ 85 if ((imxdma->dma_mode & DMA_MODE_MASK) == DMA_MODE_READ)
86 DAR(dma_ch) = nextaddr;
87 else
88 SAR(dma_ch) = nextaddr;
89
90 CNTR(dma_ch) = nextcount;
91 pr_debug("imxdma%d: next sg chunk dst 0x%08x, src 0x%08x, size 0x%08x\n",
92 dma_ch, DAR(dma_ch), SAR(dma_ch), CNTR(dma_ch));
93
94 return nextcount;
95}
96
97/*
98 * imx_dma_setup_sg_base - scatter-gather DMA emulation
99 * @dma_ch: i.MX DMA channel number
100 * @sg: pointer to the scatter-gather list/vector
101 * @sgcount: scatter-gather list hungs count
102 *
103 * Functions sets up i.MX DMA state for emulated scatter-gather transfer
104 * and sets up channel registers to be ready for the first chunk
105 */
106static int
107imx_dma_setup_sg_base(imx_dmach_t dma_ch,
108 struct scatterlist *sg, unsigned int sgcount)
109{
110 struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
111
112 imxdma->sg = sg;
113 imxdma->sgcount = sgcount;
114 imxdma->sgbc = 0;
115 return imx_dma_sg_next(dma_ch, 0);
116}
117
118/**
119 * imx_dma_setup_single - setup i.MX DMA channel for linear memory to/from device transfer
120 * @dma_ch: i.MX DMA channel number
121 * @dma_address: the DMA/physical memory address of the linear data block
122 * to transfer
123 * @dma_length: length of the data block in bytes
124 * @dev_addr: physical device port address
125 * @dmamode: DMA transfer mode, %DMA_MODE_READ from the device to the memory
126 * or %DMA_MODE_WRITE from memory to the device
127 *
128 * The function setups DMA channel source and destination addresses for transfer
129 * specified by provided parameters. The scatter-gather emulation is disabled,
130 * because linear data block
131 * form the physical address range is transfered.
132 * Return value: if incorrect parameters are provided -%EINVAL.
133 * Zero indicates success.
134 */
34int 135int
35imx_request_dma(char *name, imx_dma_prio prio, 136imx_dma_setup_single(imx_dmach_t dma_ch, dma_addr_t dma_address,
36 void (*irq_handler) (int, void *, struct pt_regs *), 137 unsigned int dma_length, unsigned int dev_addr,
37 void (*err_handler) (int, void *, struct pt_regs *), void *data) 138 dmamode_t dmamode)
38{ 139{
39 unsigned long flags; 140 struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
40 int i, found = 0;
41 141
42 /* basic sanity checks */ 142 imxdma->sg = NULL;
43 if (!name || !irq_handler) 143 imxdma->sgcount = 0;
144 imxdma->dma_mode = dmamode;
145 imxdma->resbytes = dma_length;
146
147 if (!dma_address) {
148 printk(KERN_ERR "imxdma%d: imx_dma_setup_single null address\n",
149 dma_ch);
44 return -EINVAL; 150 return -EINVAL;
151 }
45 152
46 local_irq_save(flags); 153 if (!dma_length) {
154 printk(KERN_ERR "imxdma%d: imx_dma_setup_single zero length\n",
155 dma_ch);
156 return -EINVAL;
157 }
47 158
48 /* try grabbing a DMA channel with the requested priority */ 159 if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) {
49 for (i = prio; i < prio + (prio == DMA_PRIO_LOW) ? 8 : 4; i++) { 160 pr_debug("imxdma%d: mx_dma_setup_single2dev dma_addressg=0x%08x dma_length=%d dev_addr=0x%08x for read\n",
50 if (!dma_channels[i].name) { 161 dma_ch, (unsigned int)dma_address, dma_length,
51 found = 1; 162 dev_addr);
52 break; 163 SAR(dma_ch) = dev_addr;
53 } 164 DAR(dma_ch) = (unsigned int)dma_address;
165 } else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) {
166 pr_debug("imxdma%d: mx_dma_setup_single2dev dma_addressg=0x%08x dma_length=%d dev_addr=0x%08x for write\n",
167 dma_ch, (unsigned int)dma_address, dma_length,
168 dev_addr);
169 SAR(dma_ch) = (unsigned int)dma_address;
170 DAR(dma_ch) = dev_addr;
171 } else {
172 printk(KERN_ERR "imxdma%d: imx_dma_setup_single bad dmamode\n",
173 dma_ch);
174 return -EINVAL;
54 } 175 }
55 176
56 if (!found) { 177 CNTR(dma_ch) = dma_length;
57 /* requested prio group is full, try hier priorities */ 178
58 for (i = prio - 1; i >= 0; i--) { 179 return 0;
59 if (!dma_channels[i].name) { 180}
60 found = 1; 181
61 break; 182/**
62 } 183 * imx_dma_setup_sg - setup i.MX DMA channel SG list to/from device transfer
63 } 184 * @dma_ch: i.MX DMA channel number
185 * @sg: pointer to the scatter-gather list/vector
186 * @sgcount: scatter-gather list hungs count
187 * @dma_length: total length of the transfer request in bytes
188 * @dev_addr: physical device port address
189 * @dmamode: DMA transfer mode, %DMA_MODE_READ from the device to the memory
190 * or %DMA_MODE_WRITE from memory to the device
191 *
192 * The function setups DMA channel state and registers to be ready for transfer
193 * specified by provided parameters. The scatter-gather emulation is set up
194 * according to the parameters.
195 *
196 * The full preparation of the transfer requires setup of more register
197 * by the caller before imx_dma_enable() can be called.
198 *
199 * %BLR(dma_ch) holds transfer burst length in bytes, 0 means 64 bytes
200 *
201 * %RSSR(dma_ch) has to be set to the DMA request line source %DMA_REQ_xxx
202 *
203 * %CCR(dma_ch) has to specify transfer parameters, the next settings is typical
204 * for linear or simple scatter-gather transfers if %DMA_MODE_READ is specified
205 *
206 * %CCR_DMOD_LINEAR | %CCR_DSIZ_32 | %CCR_SMOD_FIFO | %CCR_SSIZ_x
207 *
208 * The typical setup for %DMA_MODE_WRITE is specified by next options combination
209 *
210 * %CCR_SMOD_LINEAR | %CCR_SSIZ_32 | %CCR_DMOD_FIFO | %CCR_DSIZ_x
211 *
212 * Be carefull there and do not mistakenly mix source and target device
213 * port sizes constants, they are really different:
214 * %CCR_SSIZ_8, %CCR_SSIZ_16, %CCR_SSIZ_32,
215 * %CCR_DSIZ_8, %CCR_DSIZ_16, %CCR_DSIZ_32
216 *
217 * Return value: if incorrect parameters are provided -%EINVAL.
218 * Zero indicates success.
219 */
220int
221imx_dma_setup_sg(imx_dmach_t dma_ch,
222 struct scatterlist *sg, unsigned int sgcount, unsigned int dma_length,
223 unsigned int dev_addr, dmamode_t dmamode)
224{
225 int res;
226 struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
227
228 imxdma->sg = NULL;
229 imxdma->sgcount = 0;
230 imxdma->dma_mode = dmamode;
231 imxdma->resbytes = dma_length;
232
233 if (!sg || !sgcount) {
234 printk(KERN_ERR "imxdma%d: imx_dma_setup_sg epty sg list\n",
235 dma_ch);
236 return -EINVAL;
237 }
238
239 if (!sg->length) {
240 printk(KERN_ERR "imxdma%d: imx_dma_setup_sg zero length\n",
241 dma_ch);
242 return -EINVAL;
64 } 243 }
65 244
66 if (found) { 245 if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) {
67 DIMR &= ~(1 << i); 246 pr_debug("imxdma%d: mx_dma_setup_sg2dev sg=%p sgcount=%d total length=%d dev_addr=0x%08x for read\n",
68 dma_channels[i].name = name; 247 dma_ch, sg, sgcount, dma_length, dev_addr);
69 dma_channels[i].irq_handler = irq_handler; 248 SAR(dma_ch) = dev_addr;
70 dma_channels[i].err_handler = err_handler; 249 } else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) {
71 dma_channels[i].data = data; 250 pr_debug("imxdma%d: mx_dma_setup_sg2dev sg=%p sgcount=%d total length=%d dev_addr=0x%08x for write\n",
251 dma_ch, sg, sgcount, dma_length, dev_addr);
252 DAR(dma_ch) = dev_addr;
72 } else { 253 } else {
73 printk(KERN_WARNING "No more available DMA channels for %s\n", 254 printk(KERN_ERR "imxdma%d: imx_dma_setup_sg bad dmamode\n",
74 name); 255 dma_ch);
75 i = -ENODEV; 256 return -EINVAL;
257 }
258
259 res = imx_dma_setup_sg_base(dma_ch, sg, sgcount);
260 if (res <= 0) {
261 printk(KERN_ERR "imxdma%d: no sg chunk ready\n", dma_ch);
262 return -EINVAL;
263 }
264
265 return 0;
266}
267
268/**
269 * imx_dma_setup_handlers - setup i.MX DMA channel end and error notification handlers
270 * @dma_ch: i.MX DMA channel number
271 * @irq_handler: the pointer to the function called if the transfer
272 * ends successfully
273 * @err_handler: the pointer to the function called if the premature
274 * end caused by error occurs
275 * @data: user specified value to be passed to the handlers
276 */
277int
278imx_dma_setup_handlers(imx_dmach_t dma_ch,
279 void (*irq_handler) (int, void *, struct pt_regs *),
280 void (*err_handler) (int, void *, struct pt_regs *),
281 void *data)
282{
283 struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
284 unsigned long flags;
285
286 if (!imxdma->name) {
287 printk(KERN_CRIT "%s: called for not allocated channel %d\n",
288 __FUNCTION__, dma_ch);
289 return -ENODEV;
290 }
291
292 local_irq_save(flags);
293 DISR = (1 << dma_ch);
294 imxdma->irq_handler = irq_handler;
295 imxdma->err_handler = err_handler;
296 imxdma->data = data;
297 local_irq_restore(flags);
298 return 0;
299}
300
301/**
302 * imx_dma_enable - function to start i.MX DMA channel operation
303 * @dma_ch: i.MX DMA channel number
304 *
305 * The channel has to be allocated by driver through imx_dma_request()
306 * or imx_dma_request_by_prio() function.
307 * The transfer parameters has to be set to the channel registers through
308 * call of the imx_dma_setup_single() or imx_dma_setup_sg() function
309 * and registers %BLR(dma_ch), %RSSR(dma_ch) and %CCR(dma_ch) has to
310 * be set prior this function call by the channel user.
311 */
312void imx_dma_enable(imx_dmach_t dma_ch)
313{
314 struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
315 unsigned long flags;
316
317 pr_debug("imxdma%d: imx_dma_enable\n", dma_ch);
318
319 if (!imxdma->name) {
320 printk(KERN_CRIT "%s: called for not allocated channel %d\n",
321 __FUNCTION__, dma_ch);
322 return;
323 }
324
325 local_irq_save(flags);
326 DISR = (1 << dma_ch);
327 DIMR &= ~(1 << dma_ch);
328 CCR(dma_ch) |= CCR_CEN;
329 local_irq_restore(flags);
330}
331
332/**
333 * imx_dma_disable - stop, finish i.MX DMA channel operatin
334 * @dma_ch: i.MX DMA channel number
335 */
336void imx_dma_disable(imx_dmach_t dma_ch)
337{
338 unsigned long flags;
339
340 pr_debug("imxdma%d: imx_dma_disable\n", dma_ch);
341
342 local_irq_save(flags);
343 DIMR |= (1 << dma_ch);
344 CCR(dma_ch) &= ~CCR_CEN;
345 DISR = (1 << dma_ch);
346 local_irq_restore(flags);
347}
348
349/**
350 * imx_dma_request - request/allocate specified channel number
351 * @dma_ch: i.MX DMA channel number
352 * @name: the driver/caller own non-%NULL identification
353 */
354int imx_dma_request(imx_dmach_t dma_ch, const char *name)
355{
356 struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
357 unsigned long flags;
358
359 /* basic sanity checks */
360 if (!name)
361 return -EINVAL;
362
363 if (dma_ch >= IMX_DMA_CHANNELS) {
364 printk(KERN_CRIT "%s: called for non-existed channel %d\n",
365 __FUNCTION__, dma_ch);
366 return -EINVAL;
76 } 367 }
77 368
369 local_irq_save(flags);
370 if (imxdma->name) {
371 local_irq_restore(flags);
372 return -ENODEV;
373 }
374
375 imxdma->name = name;
376 imxdma->irq_handler = NULL;
377 imxdma->err_handler = NULL;
378 imxdma->data = NULL;
379 imxdma->sg = NULL;
78 local_irq_restore(flags); 380 local_irq_restore(flags);
79 return i; 381 return 0;
80} 382}
81 383
82void 384/**
83imx_free_dma(int dma_ch) 385 * imx_dma_free - release previously acquired channel
386 * @dma_ch: i.MX DMA channel number
387 */
388void imx_dma_free(imx_dmach_t dma_ch)
84{ 389{
85 unsigned long flags; 390 unsigned long flags;
391 struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
86 392
87 if (!dma_channels[dma_ch].name) { 393 if (!imxdma->name) {
88 printk(KERN_CRIT 394 printk(KERN_CRIT
89 "%s: trying to free channel %d which is already freed\n", 395 "%s: trying to free channel %d which is already freed\n",
90 __FUNCTION__, dma_ch); 396 __FUNCTION__, dma_ch);
@@ -92,27 +398,84 @@ imx_free_dma(int dma_ch)
92 } 398 }
93 399
94 local_irq_save(flags); 400 local_irq_save(flags);
95 DIMR &= ~(1 << dma_ch); 401 /* Disable interrupts */
96 dma_channels[dma_ch].name = NULL; 402 DIMR |= (1 << dma_ch);
403 CCR(dma_ch) &= ~CCR_CEN;
404 imxdma->name = NULL;
97 local_irq_restore(flags); 405 local_irq_restore(flags);
98} 406}
99 407
100static irqreturn_t 408/**
101dma_err_handler(int irq, void *dev_id, struct pt_regs *regs) 409 * imx_dma_request_by_prio - find and request some of free channels best suiting requested priority
410 * @dma_ch: i.MX DMA channel number
411 * @name: the driver/caller own non-%NULL identification
412 * @prio: one of the hardware distinguished priority level:
413 * %DMA_PRIO_HIGH, %DMA_PRIO_MEDIUM, %DMA_PRIO_LOW
414 *
415 * This function tries to find free channel in the specified priority group
416 * if the priority cannot be achieved it tries to look for free channel
417 * in the higher and then even lower priority groups.
418 *
419 * Return value: If there is no free channel to allocate, -%ENODEV is returned.
420 * Zero value indicates successful channel allocation.
421 */
422int
423imx_dma_request_by_prio(imx_dmach_t * pdma_ch, const char *name,
424 imx_dma_prio prio)
425{
426 int i;
427 int best;
428
429 switch (prio) {
430 case (DMA_PRIO_HIGH):
431 best = 8;
432 break;
433 case (DMA_PRIO_MEDIUM):
434 best = 4;
435 break;
436 case (DMA_PRIO_LOW):
437 default:
438 best = 0;
439 break;
440 }
441
442 for (i = best; i < IMX_DMA_CHANNELS; i++) {
443 if (!imx_dma_request(i, name)) {
444 *pdma_ch = i;
445 return 0;
446 }
447 }
448
449 for (i = best - 1; i >= 0; i--) {
450 if (!imx_dma_request(i, name)) {
451 *pdma_ch = i;
452 return 0;
453 }
454 }
455
456 printk(KERN_ERR "%s: no free DMA channel found\n", __FUNCTION__);
457
458 return -ENODEV;
459}
460
461static irqreturn_t dma_err_handler(int irq, void *dev_id, struct pt_regs *regs)
102{ 462{
103 int i, disr = DISR; 463 int i, disr = DISR;
104 struct dma_channel *channel; 464 struct imx_dma_channel *channel;
105 unsigned int err_mask = DBTOSR | DRTOSR | DSESR | DBOSR; 465 unsigned int err_mask = DBTOSR | DRTOSR | DSESR | DBOSR;
106 466
107 DISR = disr; 467 DISR = disr;
108 for (i = 0; i < 11; i++) { 468 for (i = 0; i < IMX_DMA_CHANNELS; i++) {
109 channel = &dma_channels[i]; 469 channel = &imx_dma_channels[i];
110 470
111 if ( (err_mask & 1<<i) && channel->name && channel->err_handler) { 471 if ((err_mask & 1 << i) && channel->name
472 && channel->err_handler) {
112 channel->err_handler(i, channel->data, regs); 473 channel->err_handler(i, channel->data, regs);
113 continue; 474 continue;
114 } 475 }
115 476
477 imx_dma_channels[i].sg = NULL;
478
116 if (DBTOSR & (1 << i)) { 479 if (DBTOSR & (1 << i)) {
117 printk(KERN_WARNING 480 printk(KERN_WARNING
118 "Burst timeout on channel %d (%s)\n", 481 "Burst timeout on channel %d (%s)\n",
@@ -141,17 +504,27 @@ dma_err_handler(int irq, void *dev_id, struct pt_regs *regs)
141 return IRQ_HANDLED; 504 return IRQ_HANDLED;
142} 505}
143 506
144static irqreturn_t 507static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
145dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
146{ 508{
147 int i, disr = DISR; 509 int i, disr = DISR;
148 510
511 pr_debug("imxdma: dma_irq_handler called, disr=0x%08x\n",
512 disr);
513
149 DISR = disr; 514 DISR = disr;
150 for (i = 0; i < 11; i++) { 515 for (i = 0; i < IMX_DMA_CHANNELS; i++) {
151 if (disr & (1 << i)) { 516 if (disr & (1 << i)) {
152 struct dma_channel *channel = &dma_channels[i]; 517 struct imx_dma_channel *channel = &imx_dma_channels[i];
153 if (channel->name && channel->irq_handler) { 518 if (channel->name) {
154 channel->irq_handler(i, channel->data, regs); 519 if (imx_dma_sg_next(i, CNTR(i))) {
520 CCR(i) &= ~CCR_CEN;
521 mb();
522 CCR(i) |= CCR_CEN;
523 } else {
524 if (channel->irq_handler)
525 channel->irq_handler(i,
526 channel->data, regs);
527 }
155 } else { 528 } else {
156 /* 529 /*
157 * IRQ for an unregistered DMA channel: 530 * IRQ for an unregistered DMA channel:
@@ -165,10 +538,10 @@ dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
165 return IRQ_HANDLED; 538 return IRQ_HANDLED;
166} 539}
167 540
168static int __init 541static int __init imx_dma_init(void)
169imx_dma_init(void)
170{ 542{
171 int ret; 543 int ret;
544 int i;
172 545
173 /* reset DMA module */ 546 /* reset DMA module */
174 DCR = DCR_DRST; 547 DCR = DCR_DRST;
@@ -189,15 +562,27 @@ imx_dma_init(void)
189 DCR = DCR_DEN; 562 DCR = DCR_DEN;
190 563
191 /* clear all interrupts */ 564 /* clear all interrupts */
192 DISR = 0x3ff; 565 DISR = (1 << IMX_DMA_CHANNELS) - 1;
193 566
194 /* enable interrupts */ 567 /* enable interrupts */
195 DIMR = 0; 568 DIMR = (1 << IMX_DMA_CHANNELS) - 1;
569
570 for (i = 0; i < IMX_DMA_CHANNELS; i++) {
571 imx_dma_channels[i].sg = NULL;
572 imx_dma_channels[i].dma_num = i;
573 }
196 574
197 return ret; 575 return ret;
198} 576}
199 577
200arch_initcall(imx_dma_init); 578arch_initcall(imx_dma_init);
201 579
202EXPORT_SYMBOL(imx_request_dma); 580EXPORT_SYMBOL(imx_dma_setup_single);
203EXPORT_SYMBOL(imx_free_dma); 581EXPORT_SYMBOL(imx_dma_setup_sg);
582EXPORT_SYMBOL(imx_dma_setup_handlers);
583EXPORT_SYMBOL(imx_dma_enable);
584EXPORT_SYMBOL(imx_dma_disable);
585EXPORT_SYMBOL(imx_dma_request);
586EXPORT_SYMBOL(imx_dma_free);
587EXPORT_SYMBOL(imx_dma_request_by_prio);
588EXPORT_SYMBOL(imx_dma_channels);
diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c
index 37613ad68366..9d8331be2b58 100644
--- a/arch/arm/mach-imx/generic.c
+++ b/arch/arm/mach-imx/generic.c
@@ -33,6 +33,7 @@
33#include <asm/arch/imx-regs.h> 33#include <asm/arch/imx-regs.h>
34 34
35#include <asm/mach/map.h> 35#include <asm/mach/map.h>
36#include <asm/arch/mmc.h>
36 37
37void imx_gpio_mode(int gpio_mode) 38void imx_gpio_mode(int gpio_mode)
38{ 39{
@@ -175,13 +176,25 @@ static struct resource imx_mmc_resources[] = {
175 }, 176 },
176}; 177};
177 178
179static u64 imxmmmc_dmamask = 0xffffffffUL;
180
178static struct platform_device imx_mmc_device = { 181static struct platform_device imx_mmc_device = {
179 .name = "imx-mmc", 182 .name = "imx-mmc",
180 .id = 0, 183 .id = 0,
184 .dev = {
185 .dma_mask = &imxmmmc_dmamask,
186 .coherent_dma_mask = 0xffffffff,
187 },
181 .num_resources = ARRAY_SIZE(imx_mmc_resources), 188 .num_resources = ARRAY_SIZE(imx_mmc_resources),
182 .resource = imx_mmc_resources, 189 .resource = imx_mmc_resources,
183}; 190};
184 191
192void __init imx_set_mmc_info(struct imxmmc_platform_data *info)
193{
194 imx_mmc_device.dev.platform_data = info;
195}
196EXPORT_SYMBOL(imx_set_mmc_info);
197
185static struct resource imx_uart1_resources[] = { 198static struct resource imx_uart1_resources[] = {
186 [0] = { 199 [0] = {
187 .start = 0x00206000, 200 .start = 0x00206000,
diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c
index 8ab1b040288c..e34d0df90aed 100644
--- a/arch/arm/mach-imx/mx1ads.c
+++ b/arch/arm/mach-imx/mx1ads.c
@@ -25,6 +25,7 @@
25#include <asm/mach-types.h> 25#include <asm/mach-types.h>
26 26
27#include <asm/mach/arch.h> 27#include <asm/mach/arch.h>
28#include <asm/arch/mmc.h>
28#include <linux/interrupt.h> 29#include <linux/interrupt.h>
29#include "generic.h" 30#include "generic.h"
30 31
@@ -51,12 +52,29 @@ static struct platform_device *devices[] __initdata = {
51 &cs89x0_device, 52 &cs89x0_device,
52}; 53};
53 54
55#ifdef CONFIG_MMC_IMX
56static int mx1ads_mmc_card_present(void)
57{
58 /* MMC/SD Card Detect is PB 20 on MX1ADS V1.0.7 */
59 return (SSR(1) & (1 << 20) ? 0 : 1);
60}
61
62static struct imxmmc_platform_data mx1ads_mmc_info = {
63 .card_present = mx1ads_mmc_card_present,
64};
65#endif
66
54static void __init 67static void __init
55mx1ads_init(void) 68mx1ads_init(void)
56{ 69{
57#ifdef CONFIG_LEDS 70#ifdef CONFIG_LEDS
58 imx_gpio_mode(GPIO_PORTA | GPIO_OUT | 2); 71 imx_gpio_mode(GPIO_PORTA | GPIO_OUT | 2);
59#endif 72#endif
73#ifdef CONFIG_MMC_IMX
74 /* SD/MMC card detect */
75 imx_gpio_mode(GPIO_PORTB | GPIO_GIUS | GPIO_IN | 20);
76 imx_set_mmc_info(&mx1ads_mmc_info);
77#endif
60 platform_add_devices(devices, ARRAY_SIZE(devices)); 78 platform_add_devices(devices, ARRAY_SIZE(devices));
61} 79}
62 80
diff --git a/arch/arm/mach-ixp23xx/espresso.c b/arch/arm/mach-ixp23xx/espresso.c
index 2327c9790416..bf688c128630 100644
--- a/arch/arm/mach-ixp23xx/espresso.c
+++ b/arch/arm/mach-ixp23xx/espresso.c
@@ -44,6 +44,15 @@
44#include <asm/mach/irq.h> 44#include <asm/mach/irq.h>
45#include <asm/mach/pci.h> 45#include <asm/mach/pci.h>
46 46
47static int __init espresso_pci_init(void)
48{
49 if (machine_is_espresso())
50 ixp23xx_pci_slave_init();
51
52 return 0;
53};
54subsys_initcall(espresso_pci_init);
55
47static void __init espresso_init(void) 56static void __init espresso_init(void)
48{ 57{
49 physmap_configure(0x90000000, 0x02000000, 2, NULL); 58 physmap_configure(0x90000000, 0x02000000, 2, NULL);
diff --git a/arch/arm/mach-ixp23xx/pci.c b/arch/arm/mach-ixp23xx/pci.c
index 5330ad78c1bb..ac72f94c5b4d 100644
--- a/arch/arm/mach-ixp23xx/pci.c
+++ b/arch/arm/mach-ixp23xx/pci.c
@@ -201,7 +201,7 @@ int clear_master_aborts(void)
201 return 0; 201 return 0;
202} 202}
203 203
204void __init ixp23xx_pci_preinit(void) 204static void __init ixp23xx_pci_common_init(void)
205{ 205{
206#ifdef __ARMEB__ 206#ifdef __ARMEB__
207 *IXP23XX_PCI_CONTROL |= 0x20000; /* set I/O swapping */ 207 *IXP23XX_PCI_CONTROL |= 0x20000; /* set I/O swapping */
@@ -219,7 +219,18 @@ void __init ixp23xx_pci_preinit(void)
219 *IXP23XX_PCI_CPP_ADDR_BITS &= ~(1 << 1); 219 *IXP23XX_PCI_CPP_ADDR_BITS &= ~(1 << 1);
220 } else { 220 } else {
221 *IXP23XX_PCI_CPP_ADDR_BITS |= (1 << 1); 221 *IXP23XX_PCI_CPP_ADDR_BITS |= (1 << 1);
222
223 /*
224 * Enable coherency on A2 silicon.
225 */
226 if (arch_is_coherent())
227 *IXP23XX_CPP2XSI_CURR_XFER_REG3 &= ~IXP23XX_CPP2XSI_COH_OFF;
222 } 228 }
229}
230
231void __init ixp23xx_pci_preinit(void)
232{
233 ixp23xx_pci_common_init();
223 234
224 hook_fault_code(16+6, ixp23xx_pci_abort_handler, SIGBUS, 235 hook_fault_code(16+6, ixp23xx_pci_abort_handler, SIGBUS,
225 "PCI config cycle to non-existent device"); 236 "PCI config cycle to non-existent device");
@@ -273,3 +284,8 @@ int ixp23xx_pci_setup(int nr, struct pci_sys_data *sys)
273 284
274 return 1; 285 return 1;
275} 286}
287
288void ixp23xx_pci_slave_init(void)
289{
290 ixp23xx_pci_common_init();
291}
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index 86a0f0d14345..f8d716ccc1df 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -69,12 +69,6 @@ config MACH_VOICEBLUE
69 Support for Voiceblue GSM/VoIP gateway. Say Y here if you have 69 Support for Voiceblue GSM/VoIP gateway. Say Y here if you have
70 such a board. 70 such a board.
71 71
72config MACH_NETSTAR
73 bool "NetStar"
74 depends on ARCH_OMAP1 && ARCH_OMAP15XX
75 help
76 Support for NetStar PBX. Say Y here if you have such a board.
77
78config MACH_OMAP_PALMTE 72config MACH_OMAP_PALMTE
79 bool "Palm Tungsten E" 73 bool "Palm Tungsten E"
80 depends on ARCH_OMAP1 && ARCH_OMAP15XX 74 depends on ARCH_OMAP1 && ARCH_OMAP15XX
@@ -85,6 +79,20 @@ config MACH_OMAP_PALMTE
85 informations. 79 informations.
86 Say Y here if you have such a PDA, say NO otherwise. 80 Say Y here if you have such a PDA, say NO otherwise.
87 81
82config MACH_NOKIA770
83 bool "Nokia 770"
84 depends on ARCH_OMAP1 && ARCH_OMAP16XX
85 help
86 Support for the Nokia 770 Internet Tablet. Say Y here if you
87 have such a device.
88
89config MACH_AMS_DELTA
90 bool "Amstrad E3 (Delta)"
91 depends on ARCH_OMAP1 && ARCH_OMAP15XX
92 help
93 Support for the Amstrad E3 (codename Delta) videophone. Say Y here
94 if you have such a device.
95
88config MACH_OMAP_GENERIC 96config MACH_OMAP_GENERIC
89 bool "Generic OMAP board" 97 bool "Generic OMAP board"
90 depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX) 98 depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX)
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index b0b00156faae..9ea719550ad3 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -3,7 +3,13 @@
3# 3#
4 4
5# Common support 5# Common support
6obj-y := io.o id.o clock.o irq.o time.o mux.o serial.o devices.o 6obj-y := io.o id.o clock.o irq.o mux.o serial.o devices.o
7
8obj-$(CONFIG_OMAP_MPU_TIMER) += time.o
9
10# Power Management
11obj-$(CONFIG_PM) += pm.o sleep.o
12
7led-y := leds.o 13led-y := leds.o
8 14
9# Specific board support 15# Specific board support
@@ -14,8 +20,9 @@ obj-$(CONFIG_MACH_OMAP_PERSEUS2) += board-perseus2.o
14obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o 20obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o
15obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o 21obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o
16obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o 22obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o
17obj-$(CONFIG_MACH_NETSTAR) += board-netstar.o
18obj-$(CONFIG_MACH_OMAP_PALMTE) += board-palmte.o 23obj-$(CONFIG_MACH_OMAP_PALMTE) += board-palmte.o
24obj-$(CONFIG_MACH_NOKIA770) += board-nokia770.o
25obj-$(CONFIG_MACH_AMS_DELTA) += board-ams-delta.o
19 26
20ifeq ($(CONFIG_ARCH_OMAP15XX),y) 27ifeq ($(CONFIG_ARCH_OMAP15XX),y)
21# Innovator-1510 FPGA 28# Innovator-1510 FPGA
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
new file mode 100644
index 000000000000..6178f046f128
--- /dev/null
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -0,0 +1,116 @@
1/*
2 * linux/arch/arm/mach-omap1/board-ams-delta.c
3 *
4 * Modified from board-generic.c
5 *
6 * Board specific inits for the Amstrad E3 (codename Delta) videophone
7 *
8 * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/platform_device.h>
18
19#include <asm/hardware.h>
20#include <asm/mach-types.h>
21#include <asm/mach/arch.h>
22#include <asm/mach/map.h>
23
24#include <asm/arch/board-ams-delta.h>
25#include <asm/arch/gpio.h>
26#include <asm/arch/mux.h>
27#include <asm/arch/usb.h>
28#include <asm/arch/board.h>
29#include <asm/arch/common.h>
30
31static u8 ams_delta_latch1_reg;
32static u16 ams_delta_latch2_reg;
33
34void ams_delta_latch1_write(u8 mask, u8 value)
35{
36 ams_delta_latch1_reg &= ~mask;
37 ams_delta_latch1_reg |= value;
38 *(volatile __u8 *) AMS_DELTA_LATCH1_VIRT = ams_delta_latch1_reg;
39}
40
41void ams_delta_latch2_write(u16 mask, u16 value)
42{
43 ams_delta_latch2_reg &= ~mask;
44 ams_delta_latch2_reg |= value;
45 *(volatile __u16 *) AMS_DELTA_LATCH2_VIRT = ams_delta_latch2_reg;
46}
47
48static void __init ams_delta_init_irq(void)
49{
50 omap1_init_common_hw();
51 omap_init_irq();
52 omap_gpio_init();
53}
54
55static struct map_desc ams_delta_io_desc[] __initdata = {
56 // AMS_DELTA_LATCH1
57 {
58 .virtual = AMS_DELTA_LATCH1_VIRT,
59 .pfn = __phys_to_pfn(AMS_DELTA_LATCH1_PHYS),
60 .length = 0x01000000,
61 .type = MT_DEVICE
62 },
63 // AMS_DELTA_LATCH2
64 {
65 .virtual = AMS_DELTA_LATCH2_VIRT,
66 .pfn = __phys_to_pfn(AMS_DELTA_LATCH2_PHYS),
67 .length = 0x01000000,
68 .type = MT_DEVICE
69 },
70 // AMS_DELTA_MODEM
71 {
72 .virtual = AMS_DELTA_MODEM_VIRT,
73 .pfn = __phys_to_pfn(AMS_DELTA_MODEM_PHYS),
74 .length = 0x01000000,
75 .type = MT_DEVICE
76 }
77};
78
79static struct omap_uart_config ams_delta_uart_config __initdata = {
80 .enabled_uarts = 1,
81};
82
83static struct omap_board_config_kernel ams_delta_config[] = {
84 { OMAP_TAG_UART, &ams_delta_uart_config },
85};
86
87static void __init ams_delta_init(void)
88{
89 iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc));
90
91 omap_board_config = ams_delta_config;
92 omap_board_config_size = ARRAY_SIZE(ams_delta_config);
93 omap_serial_init();
94
95 /* Clear latch2 (NAND, LCD, modem enable) */
96 ams_delta_latch2_write(~0, 0);
97}
98
99static void __init ams_delta_map_io(void)
100{
101 omap1_map_common_io();
102}
103
104MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)")
105 /* Maintainer: Jonathan McDowell <noodles@earth.li> */
106 .phys_io = 0xfff00000,
107 .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
108 .boot_params = 0x10000100,
109 .map_io = ams_delta_map_io,
110 .init_irq = ams_delta_init_irq,
111 .init_machine = ams_delta_init,
112 .timer = &omap_timer,
113MACHINE_END
114
115EXPORT_SYMBOL(ams_delta_latch1_write);
116EXPORT_SYMBOL(ams_delta_latch2_write);
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c
index a177e78b2b87..33d01adab1ed 100644
--- a/arch/arm/mach-omap1/board-generic.c
+++ b/arch/arm/mach-omap1/board-generic.c
@@ -88,7 +88,7 @@ static struct omap_board_config_kernel generic_config[] = {
88static void __init omap_generic_init(void) 88static void __init omap_generic_init(void)
89{ 89{
90#ifdef CONFIG_ARCH_OMAP15XX 90#ifdef CONFIG_ARCH_OMAP15XX
91 if (cpu_is_omap1510()) { 91 if (cpu_is_omap15xx()) {
92 generic_config[0].data = &generic1510_usb_config; 92 generic_config[0].data = &generic1510_usb_config;
93 } 93 }
94#endif 94#endif
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index 89f0cc74a519..cd3a06dfc0a8 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -24,7 +24,9 @@
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/mtd/mtd.h> 26#include <linux/mtd/mtd.h>
27#include <linux/mtd/nand.h>
27#include <linux/mtd/partitions.h> 28#include <linux/mtd/partitions.h>
29#include <linux/input.h>
28 30
29#include <asm/hardware.h> 31#include <asm/hardware.h>
30#include <asm/mach-types.h> 32#include <asm/mach-types.h>
@@ -35,12 +37,55 @@
35#include <asm/arch/gpio.h> 37#include <asm/arch/gpio.h>
36#include <asm/arch/mux.h> 38#include <asm/arch/mux.h>
37#include <asm/arch/tc.h> 39#include <asm/arch/tc.h>
40#include <asm/arch/irda.h>
38#include <asm/arch/usb.h> 41#include <asm/arch/usb.h>
42#include <asm/arch/keypad.h>
39#include <asm/arch/common.h> 43#include <asm/arch/common.h>
44#include <asm/arch/mcbsp.h>
45#include <asm/arch/omap-alsa.h>
40 46
41extern int omap_gpio_init(void); 47extern int omap_gpio_init(void);
42 48
43static struct mtd_partition h2_partitions[] = { 49static int h2_keymap[] = {
50 KEY(0, 0, KEY_LEFT),
51 KEY(0, 1, KEY_RIGHT),
52 KEY(0, 2, KEY_3),
53 KEY(0, 3, KEY_F10),
54 KEY(0, 4, KEY_F5),
55 KEY(0, 5, KEY_9),
56 KEY(1, 0, KEY_DOWN),
57 KEY(1, 1, KEY_UP),
58 KEY(1, 2, KEY_2),
59 KEY(1, 3, KEY_F9),
60 KEY(1, 4, KEY_F7),
61 KEY(1, 5, KEY_0),
62 KEY(2, 0, KEY_ENTER),
63 KEY(2, 1, KEY_6),
64 KEY(2, 2, KEY_1),
65 KEY(2, 3, KEY_F2),
66 KEY(2, 4, KEY_F6),
67 KEY(2, 5, KEY_HOME),
68 KEY(3, 0, KEY_8),
69 KEY(3, 1, KEY_5),
70 KEY(3, 2, KEY_F12),
71 KEY(3, 3, KEY_F3),
72 KEY(3, 4, KEY_F8),
73 KEY(3, 5, KEY_END),
74 KEY(4, 0, KEY_7),
75 KEY(4, 1, KEY_4),
76 KEY(4, 2, KEY_F11),
77 KEY(4, 3, KEY_F1),
78 KEY(4, 4, KEY_F4),
79 KEY(4, 5, KEY_ESC),
80 KEY(5, 0, KEY_F13),
81 KEY(5, 1, KEY_F14),
82 KEY(5, 2, KEY_F15),
83 KEY(5, 3, KEY_F16),
84 KEY(5, 4, KEY_SLEEP),
85 0
86};
87
88static struct mtd_partition h2_nor_partitions[] = {
44 /* bootloader (U-Boot, etc) in first sector */ 89 /* bootloader (U-Boot, etc) in first sector */
45 { 90 {
46 .name = "bootloader", 91 .name = "bootloader",
@@ -71,26 +116,26 @@ static struct mtd_partition h2_partitions[] = {
71 } 116 }
72}; 117};
73 118
74static struct flash_platform_data h2_flash_data = { 119static struct flash_platform_data h2_nor_data = {
75 .map_name = "cfi_probe", 120 .map_name = "cfi_probe",
76 .width = 2, 121 .width = 2,
77 .parts = h2_partitions, 122 .parts = h2_nor_partitions,
78 .nr_parts = ARRAY_SIZE(h2_partitions), 123 .nr_parts = ARRAY_SIZE(h2_nor_partitions),
79}; 124};
80 125
81static struct resource h2_flash_resource = { 126static struct resource h2_nor_resource = {
82 /* This is on CS3, wherever it's mapped */ 127 /* This is on CS3, wherever it's mapped */
83 .flags = IORESOURCE_MEM, 128 .flags = IORESOURCE_MEM,
84}; 129};
85 130
86static struct platform_device h2_flash_device = { 131static struct platform_device h2_nor_device = {
87 .name = "omapflash", 132 .name = "omapflash",
88 .id = 0, 133 .id = 0,
89 .dev = { 134 .dev = {
90 .platform_data = &h2_flash_data, 135 .platform_data = &h2_nor_data,
91 }, 136 },
92 .num_resources = 1, 137 .num_resources = 1,
93 .resource = &h2_flash_resource, 138 .resource = &h2_nor_resource,
94}; 139};
95 140
96static struct resource h2_smc91x_resources[] = { 141static struct resource h2_smc91x_resources[] = {
@@ -113,9 +158,119 @@ static struct platform_device h2_smc91x_device = {
113 .resource = h2_smc91x_resources, 158 .resource = h2_smc91x_resources,
114}; 159};
115 160
161static struct resource h2_kp_resources[] = {
162 [0] = {
163 .start = INT_KEYBOARD,
164 .end = INT_KEYBOARD,
165 .flags = IORESOURCE_IRQ,
166 },
167};
168
169static struct omap_kp_platform_data h2_kp_data = {
170 .rows = 8,
171 .cols = 8,
172 .keymap = h2_keymap,
173 .rep = 1,
174};
175
176static struct platform_device h2_kp_device = {
177 .name = "omap-keypad",
178 .id = -1,
179 .dev = {
180 .platform_data = &h2_kp_data,
181 },
182 .num_resources = ARRAY_SIZE(h2_kp_resources),
183 .resource = h2_kp_resources,
184};
185
186#define H2_IRDA_FIRSEL_GPIO_PIN 17
187
188#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE)
189static int h2_transceiver_mode(struct device *dev, int state)
190{
191 if (state & IR_SIRMODE)
192 omap_set_gpio_dataout(H2_IRDA_FIRSEL_GPIO_PIN, 0);
193 else /* MIR/FIR */
194 omap_set_gpio_dataout(H2_IRDA_FIRSEL_GPIO_PIN, 1);
195
196 return 0;
197}
198#endif
199
200static struct omap_irda_config h2_irda_data = {
201 .transceiver_cap = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE,
202 .rx_channel = OMAP_DMA_UART3_RX,
203 .tx_channel = OMAP_DMA_UART3_TX,
204 .dest_start = UART3_THR,
205 .src_start = UART3_RHR,
206 .tx_trigger = 0,
207 .rx_trigger = 0,
208};
209
210static struct resource h2_irda_resources[] = {
211 [0] = {
212 .start = INT_UART3,
213 .end = INT_UART3,
214 .flags = IORESOURCE_IRQ,
215 },
216};
217static struct platform_device h2_irda_device = {
218 .name = "omapirda",
219 .id = 0,
220 .dev = {
221 .platform_data = &h2_irda_data,
222 },
223 .num_resources = ARRAY_SIZE(h2_irda_resources),
224 .resource = h2_irda_resources,
225};
226
227static struct platform_device h2_lcd_device = {
228 .name = "lcd_h2",
229 .id = -1,
230};
231
232static struct omap_mcbsp_reg_cfg mcbsp_regs = {
233 .spcr2 = FREE | FRST | GRST | XRST | XINTM(3),
234 .spcr1 = RINTM(3) | RRST,
235 .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) |
236 RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(1),
237 .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16),
238 .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
239 XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(1) | XFIG,
240 .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16),
241 .srgr1 = FWID(15),
242 .srgr2 = GSYNC | CLKSP | FSGM | FPER(31),
243
244 .pcr0 = CLKXM | CLKRM | FSXP | FSRP | CLKXP | CLKRP,
245 //.pcr0 = CLKXP | CLKRP, /* mcbsp: slave */
246};
247
248static struct omap_alsa_codec_config alsa_config = {
249 .name = "H2 TSC2101",
250 .mcbsp_regs_alsa = &mcbsp_regs,
251 .codec_configure_dev = NULL, // tsc2101_configure,
252 .codec_set_samplerate = NULL, // tsc2101_set_samplerate,
253 .codec_clock_setup = NULL, // tsc2101_clock_setup,
254 .codec_clock_on = NULL, // tsc2101_clock_on,
255 .codec_clock_off = NULL, // tsc2101_clock_off,
256 .get_default_samplerate = NULL, // tsc2101_get_default_samplerate,
257};
258
259static struct platform_device h2_mcbsp1_device = {
260 .name = "omap_alsa_mcbsp",
261 .id = 1,
262 .dev = {
263 .platform_data = &alsa_config,
264 },
265};
266
116static struct platform_device *h2_devices[] __initdata = { 267static struct platform_device *h2_devices[] __initdata = {
117 &h2_flash_device, 268 &h2_nor_device,
118 &h2_smc91x_device, 269 &h2_smc91x_device,
270 &h2_irda_device,
271 &h2_kp_device,
272 &h2_lcd_device,
273 &h2_mcbsp1_device,
119}; 274};
120 275
121static void __init h2_init_smc91x(void) 276static void __init h2_init_smc91x(void)
@@ -164,7 +319,6 @@ static struct omap_uart_config h2_uart_config __initdata = {
164}; 319};
165 320
166static struct omap_lcd_config h2_lcd_config __initdata = { 321static struct omap_lcd_config h2_lcd_config __initdata = {
167 .panel_name = "h2",
168 .ctrl_name = "internal", 322 .ctrl_name = "internal",
169}; 323};
170 324
@@ -177,16 +331,34 @@ static struct omap_board_config_kernel h2_config[] = {
177 331
178static void __init h2_init(void) 332static void __init h2_init(void)
179{ 333{
180 /* NOTE: revC boards support NAND-boot, which can put NOR on CS2B 334 /* Here we assume the NOR boot config: NOR on CS3 (possibly swapped
181 * and NAND (either 16bit or 8bit) on CS3. 335 * to address 0 by a dip switch), NAND on CS2B. The NAND driver will
336 * notice whether a NAND chip is enabled at probe time.
337 *
338 * FIXME revC boards (and H3) support NAND-boot, with a dip switch to
339 * put NOR on CS2B and NAND (which on H2 may be 16bit) on CS3. Try
340 * detecting that in code here, to avoid probing every possible flash
341 * configuration...
182 */ 342 */
183 h2_flash_resource.end = h2_flash_resource.start = omap_cs3_phys(); 343 h2_nor_resource.end = h2_nor_resource.start = omap_cs3_phys();
184 h2_flash_resource.end += SZ_32M - 1; 344 h2_nor_resource.end += SZ_32M - 1;
345
346 omap_cfg_reg(L3_1610_FLASH_CS2B_OE);
347 omap_cfg_reg(M8_1610_FLASH_CS2B_WE);
185 348
186 /* MMC: card detect and WP */ 349 /* MMC: card detect and WP */
187 // omap_cfg_reg(U19_ARMIO1); /* CD */ 350 // omap_cfg_reg(U19_ARMIO1); /* CD */
188 omap_cfg_reg(BALLOUT_V8_ARMIO3); /* WP */ 351 omap_cfg_reg(BALLOUT_V8_ARMIO3); /* WP */
189 352
353 /* Irda */
354#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE)
355 omap_writel(omap_readl(FUNC_MUX_CTRL_A) | 7, FUNC_MUX_CTRL_A);
356 if (!(omap_request_gpio(H2_IRDA_FIRSEL_GPIO_PIN))) {
357 omap_set_gpio_direction(H2_IRDA_FIRSEL_GPIO_PIN, 0);
358 h2_irda_data.transceiver_mode = h2_transceiver_mode;
359 }
360#endif
361
190 platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices)); 362 platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices));
191 omap_board_config = h2_config; 363 omap_board_config = h2_config;
192 omap_board_config_size = ARRAY_SIZE(h2_config); 364 omap_board_config_size = ARRAY_SIZE(h2_config);
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index d9f386265996..4b8d0ec73cb7 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -21,8 +21,11 @@
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/errno.h> 23#include <linux/errno.h>
24#include <linux/workqueue.h>
24#include <linux/mtd/mtd.h> 25#include <linux/mtd/mtd.h>
26#include <linux/mtd/nand.h>
25#include <linux/mtd/partitions.h> 27#include <linux/mtd/partitions.h>
28#include <linux/input.h>
26 29
27#include <asm/setup.h> 30#include <asm/setup.h>
28#include <asm/page.h> 31#include <asm/page.h>
@@ -33,15 +36,59 @@
33#include <asm/mach/map.h> 36#include <asm/mach/map.h>
34 37
35#include <asm/arch/gpio.h> 38#include <asm/arch/gpio.h>
39#include <asm/arch/gpioexpander.h>
36#include <asm/arch/irqs.h> 40#include <asm/arch/irqs.h>
37#include <asm/arch/mux.h> 41#include <asm/arch/mux.h>
38#include <asm/arch/tc.h> 42#include <asm/arch/tc.h>
43#include <asm/arch/irda.h>
39#include <asm/arch/usb.h> 44#include <asm/arch/usb.h>
45#include <asm/arch/keypad.h>
46#include <asm/arch/dma.h>
40#include <asm/arch/common.h> 47#include <asm/arch/common.h>
41 48
42extern int omap_gpio_init(void); 49extern int omap_gpio_init(void);
43 50
44static struct mtd_partition h3_partitions[] = { 51static int h3_keymap[] = {
52 KEY(0, 0, KEY_LEFT),
53 KEY(0, 1, KEY_RIGHT),
54 KEY(0, 2, KEY_3),
55 KEY(0, 3, KEY_F10),
56 KEY(0, 4, KEY_F5),
57 KEY(0, 5, KEY_9),
58 KEY(1, 0, KEY_DOWN),
59 KEY(1, 1, KEY_UP),
60 KEY(1, 2, KEY_2),
61 KEY(1, 3, KEY_F9),
62 KEY(1, 4, KEY_F7),
63 KEY(1, 5, KEY_0),
64 KEY(2, 0, KEY_ENTER),
65 KEY(2, 1, KEY_6),
66 KEY(2, 2, KEY_1),
67 KEY(2, 3, KEY_F2),
68 KEY(2, 4, KEY_F6),
69 KEY(2, 5, KEY_HOME),
70 KEY(3, 0, KEY_8),
71 KEY(3, 1, KEY_5),
72 KEY(3, 2, KEY_F12),
73 KEY(3, 3, KEY_F3),
74 KEY(3, 4, KEY_F8),
75 KEY(3, 5, KEY_END),
76 KEY(4, 0, KEY_7),
77 KEY(4, 1, KEY_4),
78 KEY(4, 2, KEY_F11),
79 KEY(4, 3, KEY_F1),
80 KEY(4, 4, KEY_F4),
81 KEY(4, 5, KEY_ESC),
82 KEY(5, 0, KEY_F13),
83 KEY(5, 1, KEY_F14),
84 KEY(5, 2, KEY_F15),
85 KEY(5, 3, KEY_F16),
86 KEY(5, 4, KEY_SLEEP),
87 0
88};
89
90
91static struct mtd_partition nor_partitions[] = {
45 /* bootloader (U-Boot, etc) in first sector */ 92 /* bootloader (U-Boot, etc) in first sector */
46 { 93 {
47 .name = "bootloader", 94 .name = "bootloader",
@@ -72,26 +119,80 @@ static struct mtd_partition h3_partitions[] = {
72 } 119 }
73}; 120};
74 121
75static struct flash_platform_data h3_flash_data = { 122static struct flash_platform_data nor_data = {
76 .map_name = "cfi_probe", 123 .map_name = "cfi_probe",
77 .width = 2, 124 .width = 2,
78 .parts = h3_partitions, 125 .parts = nor_partitions,
79 .nr_parts = ARRAY_SIZE(h3_partitions), 126 .nr_parts = ARRAY_SIZE(nor_partitions),
80}; 127};
81 128
82static struct resource h3_flash_resource = { 129static struct resource nor_resource = {
83 /* This is on CS3, wherever it's mapped */ 130 /* This is on CS3, wherever it's mapped */
84 .flags = IORESOURCE_MEM, 131 .flags = IORESOURCE_MEM,
85}; 132};
86 133
87static struct platform_device flash_device = { 134static struct platform_device nor_device = {
88 .name = "omapflash", 135 .name = "omapflash",
89 .id = 0, 136 .id = 0,
90 .dev = { 137 .dev = {
91 .platform_data = &h3_flash_data, 138 .platform_data = &nor_data,
139 },
140 .num_resources = 1,
141 .resource = &nor_resource,
142};
143
144static struct mtd_partition nand_partitions[] = {
145#if 0
146 /* REVISIT: enable these partitions if you make NAND BOOT work */
147 {
148 .name = "xloader",
149 .offset = 0,
150 .size = 64 * 1024,
151 .mask_flags = MTD_WRITEABLE, /* force read-only */
152 },
153 {
154 .name = "bootloader",
155 .offset = MTDPART_OFS_APPEND,
156 .size = 256 * 1024,
157 .mask_flags = MTD_WRITEABLE, /* force read-only */
158 },
159 {
160 .name = "params",
161 .offset = MTDPART_OFS_APPEND,
162 .size = 192 * 1024,
163 },
164 {
165 .name = "kernel",
166 .offset = MTDPART_OFS_APPEND,
167 .size = 2 * SZ_1M,
168 },
169#endif
170 {
171 .name = "filesystem",
172 .size = MTDPART_SIZ_FULL,
173 .offset = MTDPART_OFS_APPEND,
174 },
175};
176
177/* dip switches control NAND chip access: 8 bit, 16 bit, or neither */
178static struct nand_platform_data nand_data = {
179 .options = NAND_SAMSUNG_LP_OPTIONS,
180 .parts = nand_partitions,
181 .nr_parts = ARRAY_SIZE(nand_partitions),
182};
183
184static struct resource nand_resource = {
185 .flags = IORESOURCE_MEM,
186};
187
188static struct platform_device nand_device = {
189 .name = "omapnand",
190 .id = 0,
191 .dev = {
192 .platform_data = &nand_data,
92 }, 193 },
93 .num_resources = 1, 194 .num_resources = 1,
94 .resource = &h3_flash_resource, 195 .resource = &nand_resource,
95}; 196};
96 197
97static struct resource smc91x_resources[] = { 198static struct resource smc91x_resources[] = {
@@ -138,10 +239,136 @@ static struct platform_device intlat_device = {
138 .resource = intlat_resources, 239 .resource = intlat_resources,
139}; 240};
140 241
242static struct resource h3_kp_resources[] = {
243 [0] = {
244 .start = INT_KEYBOARD,
245 .end = INT_KEYBOARD,
246 .flags = IORESOURCE_IRQ,
247 },
248};
249
250static struct omap_kp_platform_data h3_kp_data = {
251 .rows = 8,
252 .cols = 8,
253 .keymap = h3_keymap,
254 .rep = 1,
255};
256
257static struct platform_device h3_kp_device = {
258 .name = "omap-keypad",
259 .id = -1,
260 .dev = {
261 .platform_data = &h3_kp_data,
262 },
263 .num_resources = ARRAY_SIZE(h3_kp_resources),
264 .resource = h3_kp_resources,
265};
266
267
268/* Select between the IrDA and aGPS module
269 */
270static int h3_select_irda(struct device *dev, int state)
271{
272 unsigned char expa;
273 int err = 0;
274
275 if ((err = read_gpio_expa(&expa, 0x26))) {
276 printk(KERN_ERR "Error reading from I/O EXPANDER \n");
277 return err;
278 }
279
280 /* 'P6' enable/disable IRDA_TX and IRDA_RX */
281 if (state & IR_SEL) { /* IrDA */
282 if ((err = write_gpio_expa(expa | 0x40, 0x26))) {
283 printk(KERN_ERR "Error writing to I/O EXPANDER \n");
284 return err;
285 }
286 } else {
287 if ((err = write_gpio_expa(expa & ~0x40, 0x26))) {
288 printk(KERN_ERR "Error writing to I/O EXPANDER \n");
289 return err;
290 }
291 }
292 return err;
293}
294
295static void set_trans_mode(void *data)
296{
297 int *mode = data;
298 unsigned char expa;
299 int err = 0;
300
301 if ((err = read_gpio_expa(&expa, 0x27)) != 0) {
302 printk(KERN_ERR "Error reading from I/O expander\n");
303 }
304
305 expa &= ~0x03;
306
307 if (*mode & IR_SIRMODE) {
308 expa |= 0x01;
309 } else { /* MIR/FIR */
310 expa |= 0x03;
311 }
312
313 if ((err = write_gpio_expa(expa, 0x27)) != 0) {
314 printk(KERN_ERR "Error writing to I/O expander\n");
315 }
316}
317
318static int h3_transceiver_mode(struct device *dev, int mode)
319{
320 struct omap_irda_config *irda_config = dev->platform_data;
321
322 cancel_delayed_work(&irda_config->gpio_expa);
323 PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode);
324 schedule_work(&irda_config->gpio_expa);
325
326 return 0;
327}
328
329static struct omap_irda_config h3_irda_data = {
330 .transceiver_cap = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE,
331 .transceiver_mode = h3_transceiver_mode,
332 .select_irda = h3_select_irda,
333 .rx_channel = OMAP_DMA_UART3_RX,
334 .tx_channel = OMAP_DMA_UART3_TX,
335 .dest_start = UART3_THR,
336 .src_start = UART3_RHR,
337 .tx_trigger = 0,
338 .rx_trigger = 0,
339};
340
341static struct resource h3_irda_resources[] = {
342 [0] = {
343 .start = INT_UART3,
344 .end = INT_UART3,
345 .flags = IORESOURCE_IRQ,
346 },
347};
348
349static struct platform_device h3_irda_device = {
350 .name = "omapirda",
351 .id = 0,
352 .dev = {
353 .platform_data = &h3_irda_data,
354 },
355 .num_resources = ARRAY_SIZE(h3_irda_resources),
356 .resource = h3_irda_resources,
357};
358
359static struct platform_device h3_lcd_device = {
360 .name = "lcd_h3",
361 .id = -1,
362};
363
141static struct platform_device *devices[] __initdata = { 364static struct platform_device *devices[] __initdata = {
142 &flash_device, 365 &nor_device,
366 &nand_device,
143 &smc91x_device, 367 &smc91x_device,
144 &intlat_device, 368 &intlat_device,
369 &h3_irda_device,
370 &h3_kp_device,
371 &h3_lcd_device,
145}; 372};
146 373
147static struct omap_usb_config h3_usb_config __initdata = { 374static struct omap_usb_config h3_usb_config __initdata = {
@@ -171,7 +398,6 @@ static struct omap_uart_config h3_uart_config __initdata = {
171}; 398};
172 399
173static struct omap_lcd_config h3_lcd_config __initdata = { 400static struct omap_lcd_config h3_lcd_config __initdata = {
174 .panel_name = "h3",
175 .ctrl_name = "internal", 401 .ctrl_name = "internal",
176}; 402};
177 403
@@ -182,11 +408,36 @@ static struct omap_board_config_kernel h3_config[] = {
182 { OMAP_TAG_LCD, &h3_lcd_config }, 408 { OMAP_TAG_LCD, &h3_lcd_config },
183}; 409};
184 410
411#define H3_NAND_RB_GPIO_PIN 10
412
413static int nand_dev_ready(struct nand_platform_data *data)
414{
415 return omap_get_gpio_datain(H3_NAND_RB_GPIO_PIN);
416}
417
185static void __init h3_init(void) 418static void __init h3_init(void)
186{ 419{
187 h3_flash_resource.end = h3_flash_resource.start = omap_cs3_phys(); 420 /* Here we assume the NOR boot config: NOR on CS3 (possibly swapped
188 h3_flash_resource.end += OMAP_CS3_SIZE - 1; 421 * to address 0 by a dip switch), NAND on CS2B. The NAND driver will
189 (void) platform_add_devices(devices, ARRAY_SIZE(devices)); 422 * notice whether a NAND chip is enabled at probe time.
423 *
424 * H3 support NAND-boot, with a dip switch to put NOR on CS2B and NAND
425 * (which on H2 may be 16bit) on CS3. Try detecting that in code here,
426 * to avoid probing every possible flash configuration...
427 */
428 nor_resource.end = nor_resource.start = omap_cs3_phys();
429 nor_resource.end += SZ_32M - 1;
430
431 nand_resource.end = nand_resource.start = OMAP_CS2B_PHYS;
432 nand_resource.end += SZ_4K - 1;
433 if (!(omap_request_gpio(H3_NAND_RB_GPIO_PIN)))
434 nand_data.dev_ready = nand_dev_ready;
435
436 /* GPIO10 Func_MUX_CTRL reg bit 29:27, Configure V2 to mode1 as GPIO */
437 /* GPIO10 pullup/down register, Enable pullup on GPIO10 */
438 omap_cfg_reg(V2_1710_GPIO10);
439
440 platform_add_devices(devices, ARRAY_SIZE(devices));
190 omap_board_config = h3_config; 441 omap_board_config = h3_config;
191 omap_board_config_size = ARRAY_SIZE(h3_config); 442 omap_board_config_size = ARRAY_SIZE(h3_config);
192 omap_serial_init(); 443 omap_serial_init();
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index a04e4332915e..e90c137a4cf3 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -22,6 +22,7 @@
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/mtd/mtd.h> 23#include <linux/mtd/mtd.h>
24#include <linux/mtd/partitions.h> 24#include <linux/mtd/partitions.h>
25#include <linux/input.h>
25 26
26#include <asm/hardware.h> 27#include <asm/hardware.h>
27#include <asm/mach-types.h> 28#include <asm/mach-types.h>
@@ -34,8 +35,22 @@
34#include <asm/arch/gpio.h> 35#include <asm/arch/gpio.h>
35#include <asm/arch/tc.h> 36#include <asm/arch/tc.h>
36#include <asm/arch/usb.h> 37#include <asm/arch/usb.h>
38#include <asm/arch/keypad.h>
37#include <asm/arch/common.h> 39#include <asm/arch/common.h>
38 40
41static int innovator_keymap[] = {
42 KEY(0, 0, KEY_F1),
43 KEY(0, 3, KEY_DOWN),
44 KEY(1, 1, KEY_F2),
45 KEY(1, 2, KEY_RIGHT),
46 KEY(2, 0, KEY_F3),
47 KEY(2, 1, KEY_F4),
48 KEY(2, 2, KEY_UP),
49 KEY(3, 2, KEY_ENTER),
50 KEY(3, 3, KEY_LEFT),
51 0
52};
53
39static struct mtd_partition innovator_partitions[] = { 54static struct mtd_partition innovator_partitions[] = {
40 /* bootloader (U-Boot, etc) in first sector */ 55 /* bootloader (U-Boot, etc) in first sector */
41 { 56 {
@@ -97,6 +112,31 @@ static struct platform_device innovator_flash_device = {
97 .resource = &innovator_flash_resource, 112 .resource = &innovator_flash_resource,
98}; 113};
99 114
115static struct resource innovator_kp_resources[] = {
116 [0] = {
117 .start = INT_KEYBOARD,
118 .end = INT_KEYBOARD,
119 .flags = IORESOURCE_IRQ,
120 },
121};
122
123static struct omap_kp_platform_data innovator_kp_data = {
124 .rows = 8,
125 .cols = 8,
126 .keymap = innovator_keymap,
127};
128
129static struct platform_device innovator_kp_device = {
130 .name = "omap-keypad",
131 .id = -1,
132 .dev = {
133 .platform_data = &innovator_kp_data,
134 },
135 .num_resources = ARRAY_SIZE(innovator_kp_resources),
136 .resource = innovator_kp_resources,
137};
138
139
100#ifdef CONFIG_ARCH_OMAP15XX 140#ifdef CONFIG_ARCH_OMAP15XX
101 141
102/* Only FPGA needs to be mapped here. All others are done with ioremap */ 142/* Only FPGA needs to be mapped here. All others are done with ioremap */
@@ -129,9 +169,16 @@ static struct platform_device innovator1510_smc91x_device = {
129 .resource = innovator1510_smc91x_resources, 169 .resource = innovator1510_smc91x_resources,
130}; 170};
131 171
172static struct platform_device innovator1510_lcd_device = {
173 .name = "lcd_inn1510",
174 .id = -1,
175};
176
132static struct platform_device *innovator1510_devices[] __initdata = { 177static struct platform_device *innovator1510_devices[] __initdata = {
133 &innovator_flash_device, 178 &innovator_flash_device,
134 &innovator1510_smc91x_device, 179 &innovator1510_smc91x_device,
180 &innovator_kp_device,
181 &innovator1510_lcd_device,
135}; 182};
136 183
137#endif /* CONFIG_ARCH_OMAP15XX */ 184#endif /* CONFIG_ARCH_OMAP15XX */
@@ -158,9 +205,16 @@ static struct platform_device innovator1610_smc91x_device = {
158 .resource = innovator1610_smc91x_resources, 205 .resource = innovator1610_smc91x_resources,
159}; 206};
160 207
208static struct platform_device innovator1610_lcd_device = {
209 .name = "inn1610_lcd",
210 .id = -1,
211};
212
161static struct platform_device *innovator1610_devices[] __initdata = { 213static struct platform_device *innovator1610_devices[] __initdata = {
162 &innovator_flash_device, 214 &innovator_flash_device,
163 &innovator1610_smc91x_device, 215 &innovator1610_smc91x_device,
216 &innovator_kp_device,
217 &innovator1610_lcd_device,
164}; 218};
165 219
166#endif /* CONFIG_ARCH_OMAP16XX */ 220#endif /* CONFIG_ARCH_OMAP16XX */
@@ -206,7 +260,6 @@ static struct omap_usb_config innovator1510_usb_config __initdata = {
206}; 260};
207 261
208static struct omap_lcd_config innovator1510_lcd_config __initdata = { 262static struct omap_lcd_config innovator1510_lcd_config __initdata = {
209 .panel_name = "inn1510",
210 .ctrl_name = "internal", 263 .ctrl_name = "internal",
211}; 264};
212#endif 265#endif
@@ -228,7 +281,6 @@ static struct omap_usb_config h2_usb_config __initdata = {
228}; 281};
229 282
230static struct omap_lcd_config innovator1610_lcd_config __initdata = { 283static struct omap_lcd_config innovator1610_lcd_config __initdata = {
231 .panel_name = "inn1610",
232 .ctrl_name = "internal", 284 .ctrl_name = "internal",
233}; 285};
234#endif 286#endif
diff --git a/arch/arm/mach-omap1/board-netstar.c b/arch/arm/mach-omap1/board-netstar.c
deleted file mode 100644
index 7520e602d7a2..000000000000
--- a/arch/arm/mach-omap1/board-netstar.c
+++ /dev/null
@@ -1,160 +0,0 @@
1/*
2 * Modified from board-generic.c
3 *
4 * Copyright (C) 2004 2N Telekomunikace, Ladislav Michl <michl@2n.cz>
5 *
6 * Code for Netstar OMAP board.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/delay.h>
14#include <linux/platform_device.h>
15#include <linux/interrupt.h>
16#include <linux/init.h>
17#include <linux/kernel.h>
18#include <linux/notifier.h>
19#include <linux/reboot.h>
20
21#include <asm/hardware.h>
22#include <asm/mach-types.h>
23#include <asm/mach/arch.h>
24#include <asm/mach/map.h>
25
26#include <asm/arch/gpio.h>
27#include <asm/arch/mux.h>
28#include <asm/arch/usb.h>
29#include <asm/arch/common.h>
30
31extern void __init omap_init_time(void);
32extern int omap_gpio_init(void);
33
34static struct resource netstar_smc91x_resources[] = {
35 [0] = {
36 .start = OMAP_CS1_PHYS + 0x300,
37 .end = OMAP_CS1_PHYS + 0x300 + 16,
38 .flags = IORESOURCE_MEM,
39 },
40 [1] = {
41 .start = OMAP_GPIO_IRQ(8),
42 .end = OMAP_GPIO_IRQ(8),
43 .flags = IORESOURCE_IRQ,
44 },
45};
46
47static struct platform_device netstar_smc91x_device = {
48 .name = "smc91x",
49 .id = 0,
50 .num_resources = ARRAY_SIZE(netstar_smc91x_resources),
51 .resource = netstar_smc91x_resources,
52};
53
54static struct platform_device *netstar_devices[] __initdata = {
55 &netstar_smc91x_device,
56};
57
58static struct omap_uart_config netstar_uart_config __initdata = {
59 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
60};
61
62static struct omap_board_config_kernel netstar_config[] = {
63 { OMAP_TAG_UART, &netstar_uart_config },
64};
65
66static void __init netstar_init_irq(void)
67{
68 omap1_init_common_hw();
69 omap_init_irq();
70 omap_gpio_init();
71}
72
73static void __init netstar_init(void)
74{
75 /* green LED */
76 omap_request_gpio(4);
77 omap_set_gpio_direction(4, 0);
78 /* smc91x reset */
79 omap_request_gpio(7);
80 omap_set_gpio_direction(7, 0);
81 omap_set_gpio_dataout(7, 1);
82 udelay(2); /* wait at least 100ns */
83 omap_set_gpio_dataout(7, 0);
84 mdelay(50); /* 50ms until PHY ready */
85 /* smc91x interrupt pin */
86 omap_request_gpio(8);
87
88 omap_request_gpio(12);
89 omap_request_gpio(13);
90 omap_request_gpio(14);
91 omap_request_gpio(15);
92 set_irq_type(OMAP_GPIO_IRQ(12), IRQT_FALLING);
93 set_irq_type(OMAP_GPIO_IRQ(13), IRQT_FALLING);
94 set_irq_type(OMAP_GPIO_IRQ(14), IRQT_FALLING);
95 set_irq_type(OMAP_GPIO_IRQ(15), IRQT_FALLING);
96
97 platform_add_devices(netstar_devices, ARRAY_SIZE(netstar_devices));
98
99 /* Switch on green LED */
100 omap_set_gpio_dataout(4, 0);
101 /* Switch off red LED */
102 omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */
103 omap_writeb(0x80, OMAP_LPG1_LCR);
104
105 omap_board_config = netstar_config;
106 omap_board_config_size = ARRAY_SIZE(netstar_config);
107 omap_serial_init();
108}
109
110static void __init netstar_map_io(void)
111{
112 omap1_map_common_io();
113}
114
115#define MACHINE_PANICED 1
116#define MACHINE_REBOOTING 2
117#define MACHINE_REBOOT 4
118static unsigned long machine_state;
119
120static int panic_event(struct notifier_block *this, unsigned long event,
121 void *ptr)
122{
123 if (test_and_set_bit(MACHINE_PANICED, &machine_state))
124 return NOTIFY_DONE;
125
126 /* Switch off green LED */
127 omap_set_gpio_dataout(4, 1);
128 /* Flash red LED */
129 omap_writeb(0x78, OMAP_LPG1_LCR);
130 omap_writeb(0x01, OMAP_LPG1_PMR); /* Enable clock */
131
132 return NOTIFY_DONE;
133}
134
135static struct notifier_block panic_block = {
136 .notifier_call = panic_event,
137};
138
139static int __init netstar_late_init(void)
140{
141 /* TODO: Setup front panel switch here */
142
143 /* Setup panic notifier */
144 atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
145
146 return 0;
147}
148
149postcore_initcall(netstar_late_init);
150
151MACHINE_START(NETSTAR, "NetStar OMAP5910")
152 /* Maintainer: Ladislav Michl <michl@2n.cz> */
153 .phys_io = 0xfff00000,
154 .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
155 .boot_params = 0x10000100,
156 .map_io = netstar_map_io,
157 .init_irq = netstar_init_irq,
158 .init_machine = netstar_init,
159 .timer = &omap_timer,
160MACHINE_END
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
new file mode 100644
index 000000000000..02b980d77b12
--- /dev/null
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -0,0 +1,268 @@
1/*
2 * linux/arch/arm/mach-omap1/board-nokia770.c
3 *
4 * Modified from board-generic.c
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/platform_device.h>
14#include <linux/input.h>
15#include <linux/clk.h>
16
17#include <linux/spi/spi.h>
18#include <linux/spi/ads7846.h>
19
20#include <asm/hardware.h>
21#include <asm/mach-types.h>
22#include <asm/mach/arch.h>
23#include <asm/mach/map.h>
24
25#include <asm/arch/gpio.h>
26#include <asm/arch/mux.h>
27#include <asm/arch/usb.h>
28#include <asm/arch/board.h>
29#include <asm/arch/keypad.h>
30#include <asm/arch/common.h>
31#include <asm/arch/dsp_common.h>
32#include <asm/arch/aic23.h>
33#include <asm/arch/gpio.h>
34
35static void __init omap_nokia770_init_irq(void)
36{
37 /* On Nokia 770, the SleepX signal is masked with an
38 * MPUIO line by default. It has to be unmasked for it
39 * to become functional */
40
41 /* SleepX mask direction */
42 omap_writew((omap_readw(0xfffb5008) & ~2), 0xfffb5008);
43 /* Unmask SleepX signal */
44 omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004);
45
46 omap1_init_common_hw();
47 omap_init_irq();
48}
49
50static int nokia770_keymap[] = {
51 KEY(0, 1, GROUP_0 | KEY_UP),
52 KEY(0, 2, GROUP_1 | KEY_F5),
53 KEY(1, 0, GROUP_0 | KEY_LEFT),
54 KEY(1, 1, GROUP_0 | KEY_ENTER),
55 KEY(1, 2, GROUP_0 | KEY_RIGHT),
56 KEY(2, 0, GROUP_1 | KEY_ESC),
57 KEY(2, 1, GROUP_0 | KEY_DOWN),
58 KEY(2, 2, GROUP_1 | KEY_F4),
59 KEY(3, 0, GROUP_2 | KEY_F7),
60 KEY(3, 1, GROUP_2 | KEY_F8),
61 KEY(3, 2, GROUP_2 | KEY_F6),
62 0
63};
64
65static struct resource nokia770_kp_resources[] = {
66 [0] = {
67 .start = INT_KEYBOARD,
68 .end = INT_KEYBOARD,
69 .flags = IORESOURCE_IRQ,
70 },
71};
72
73static struct omap_kp_platform_data nokia770_kp_data = {
74 .rows = 8,
75 .cols = 8,
76 .keymap = nokia770_keymap
77};
78
79static struct platform_device nokia770_kp_device = {
80 .name = "omap-keypad",
81 .id = -1,
82 .dev = {
83 .platform_data = &nokia770_kp_data,
84 },
85 .num_resources = ARRAY_SIZE(nokia770_kp_resources),
86 .resource = nokia770_kp_resources,
87};
88
89static struct platform_device *nokia770_devices[] __initdata = {
90 &nokia770_kp_device,
91};
92
93static struct ads7846_platform_data nokia770_ads7846_platform_data __initdata = {
94 .x_max = 0x0fff,
95 .y_max = 0x0fff,
96 .x_plate_ohms = 180,
97 .pressure_max = 255,
98 .debounce_max = 10,
99 .debounce_tol = 3,
100};
101
102static struct spi_board_info nokia770_spi_board_info[] __initdata = {
103 [0] = {
104 .modalias = "lcd_lph8923",
105 .bus_num = 2,
106 .chip_select = 3,
107 .max_speed_hz = 12000000,
108 },
109 [1] = {
110 .modalias = "ads7846",
111 .bus_num = 2,
112 .chip_select = 0,
113 .max_speed_hz = 2500000,
114 .irq = OMAP_GPIO_IRQ(15),
115 .platform_data = &nokia770_ads7846_platform_data,
116 },
117};
118
119
120/* assume no Mini-AB port */
121
122static struct omap_usb_config nokia770_usb_config __initdata = {
123 .otg = 1,
124 .register_host = 1,
125 .register_dev = 1,
126 .hmc_mode = 16,
127 .pins[0] = 6,
128};
129
130static struct omap_mmc_config nokia770_mmc_config __initdata = {
131 .mmc[0] = {
132 .enabled = 0,
133 .wire4 = 0,
134 .wp_pin = -1,
135 .power_pin = -1,
136 .switch_pin = -1,
137 },
138 .mmc[1] = {
139 .enabled = 0,
140 .wire4 = 0,
141 .wp_pin = -1,
142 .power_pin = -1,
143 .switch_pin = -1,
144 },
145};
146
147static struct omap_board_config_kernel nokia770_config[] = {
148 { OMAP_TAG_USB, NULL },
149 { OMAP_TAG_MMC, &nokia770_mmc_config },
150};
151
152/*
153 * audio power control
154 */
155#define HEADPHONE_GPIO 14
156#define AMPLIFIER_CTRL_GPIO 58
157
158static struct clk *dspxor_ck;
159static DECLARE_MUTEX(audio_pwr_sem);
160/*
161 * audio_pwr_state
162 * +--+-------------------------+---------------------------------------+
163 * |-1|down |power-up request -> 0 |
164 * +--+-------------------------+---------------------------------------+
165 * | 0|up |power-down(1) request -> 1 |
166 * | | |power-down(2) request -> (ignore) |
167 * +--+-------------------------+---------------------------------------+
168 * | 1|up, |power-up request -> 0 |
169 * | |received down(1) request |power-down(2) request -> -1 |
170 * +--+-------------------------+---------------------------------------+
171 */
172static int audio_pwr_state = -1;
173
174/*
175 * audio_pwr_up / down should be called under audio_pwr_sem
176 */
177static void nokia770_audio_pwr_up(void)
178{
179 clk_enable(dspxor_ck);
180
181 /* Turn on codec */
182 tlv320aic23_power_up();
183
184 if (omap_get_gpio_datain(HEADPHONE_GPIO))
185 /* HP not connected, turn on amplifier */
186 omap_set_gpio_dataout(AMPLIFIER_CTRL_GPIO, 1);
187 else
188 /* HP connected, do not turn on amplifier */
189 printk("HP connected\n");
190}
191
192static void codec_delayed_power_down(void *arg)
193{
194 down(&audio_pwr_sem);
195 if (audio_pwr_state == -1)
196 tlv320aic23_power_down();
197 clk_disable(dspxor_ck);
198 up(&audio_pwr_sem);
199}
200
201static DECLARE_WORK(codec_power_down_work, codec_delayed_power_down, NULL);
202
203static void nokia770_audio_pwr_down(void)
204{
205 /* Turn off amplifier */
206 omap_set_gpio_dataout(AMPLIFIER_CTRL_GPIO, 0);
207
208 /* Turn off codec: schedule delayed work */
209 schedule_delayed_work(&codec_power_down_work, HZ / 20); /* 50ms */
210}
211
212void nokia770_audio_pwr_up_request(int stage)
213{
214 down(&audio_pwr_sem);
215 if (audio_pwr_state == -1)
216 nokia770_audio_pwr_up();
217 /* force audio_pwr_state = 0, even if it was 1. */
218 audio_pwr_state = 0;
219 up(&audio_pwr_sem);
220}
221
222void nokia770_audio_pwr_down_request(int stage)
223{
224 down(&audio_pwr_sem);
225 switch (stage) {
226 case 1:
227 if (audio_pwr_state == 0)
228 audio_pwr_state = 1;
229 break;
230 case 2:
231 if (audio_pwr_state == 1) {
232 nokia770_audio_pwr_down();
233 audio_pwr_state = -1;
234 }
235 break;
236 }
237 up(&audio_pwr_sem);
238}
239
240static void __init omap_nokia770_init(void)
241{
242 nokia770_config[0].data = &nokia770_usb_config;
243
244 platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices));
245 spi_register_board_info(nokia770_spi_board_info,
246 ARRAY_SIZE(nokia770_spi_board_info));
247 omap_board_config = nokia770_config;
248 omap_board_config_size = ARRAY_SIZE(nokia770_config);
249 omap_serial_init();
250 omap_dsp_audio_pwr_up_request = nokia770_audio_pwr_up_request;
251 omap_dsp_audio_pwr_down_request = nokia770_audio_pwr_down_request;
252 dspxor_ck = clk_get(0, "dspxor_ck");
253}
254
255static void __init omap_nokia770_map_io(void)
256{
257 omap1_map_common_io();
258}
259
260MACHINE_START(NOKIA770, "Nokia 770")
261 .phys_io = 0xfff00000,
262 .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
263 .boot_params = 0x10000100,
264 .map_io = omap_nokia770_map_io,
265 .init_irq = omap_nokia770_init_irq,
266 .init_machine = omap_nokia770_init,
267 .timer = &omap_timer,
268MACHINE_END
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index 543fa136106d..1160093e8ef6 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -33,6 +33,7 @@
33 33
34#include <linux/mtd/mtd.h> 34#include <linux/mtd/mtd.h>
35#include <linux/mtd/partitions.h> 35#include <linux/mtd/partitions.h>
36#include <linux/input.h>
36 37
37#include <asm/hardware.h> 38#include <asm/hardware.h>
38#include <asm/mach-types.h> 39#include <asm/mach-types.h>
@@ -44,7 +45,24 @@
44#include <asm/arch/usb.h> 45#include <asm/arch/usb.h>
45#include <asm/arch/mux.h> 46#include <asm/arch/mux.h>
46#include <asm/arch/tc.h> 47#include <asm/arch/tc.h>
48#include <asm/arch/keypad.h>
47#include <asm/arch/common.h> 49#include <asm/arch/common.h>
50#include <asm/arch/mcbsp.h>
51#include <asm/arch/omap-alsa.h>
52
53static int osk_keymap[] = {
54 KEY(0, 0, KEY_F1),
55 KEY(0, 3, KEY_UP),
56 KEY(1, 1, KEY_LEFTCTRL),
57 KEY(1, 2, KEY_LEFT),
58 KEY(2, 0, KEY_SPACE),
59 KEY(2, 1, KEY_ESC),
60 KEY(2, 2, KEY_DOWN),
61 KEY(3, 2, KEY_ENTER),
62 KEY(3, 3, KEY_RIGHT),
63 0
64};
65
48 66
49static struct mtd_partition osk_partitions[] = { 67static struct mtd_partition osk_partitions[] = {
50 /* bootloader (U-Boot, etc) in first sector */ 68 /* bootloader (U-Boot, etc) in first sector */
@@ -133,9 +151,69 @@ static struct platform_device osk5912_cf_device = {
133 .resource = osk5912_cf_resources, 151 .resource = osk5912_cf_resources,
134}; 152};
135 153
154#define DEFAULT_BITPERSAMPLE 16
155
156static struct omap_mcbsp_reg_cfg mcbsp_regs = {
157 .spcr2 = FREE | FRST | GRST | XRST | XINTM(3),
158 .spcr1 = RINTM(3) | RRST,
159 .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) |
160 RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(0),
161 .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16),
162 .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
163 XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG,
164 .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16),
165 .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1),
166 .srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1),
167 /*.pcr0 = FSXM | FSRM | CLKXM | CLKRM | CLKXP | CLKRP,*/ /* mcbsp: master */
168 .pcr0 = CLKXP | CLKRP, /* mcbsp: slave */
169};
170
171static struct omap_alsa_codec_config alsa_config = {
172 .name = "OSK AIC23",
173 .mcbsp_regs_alsa = &mcbsp_regs,
174 .codec_configure_dev = NULL, // aic23_configure,
175 .codec_set_samplerate = NULL, // aic23_set_samplerate,
176 .codec_clock_setup = NULL, // aic23_clock_setup,
177 .codec_clock_on = NULL, // aic23_clock_on,
178 .codec_clock_off = NULL, // aic23_clock_off,
179 .get_default_samplerate = NULL, // aic23_get_default_samplerate,
180};
181
136static struct platform_device osk5912_mcbsp1_device = { 182static struct platform_device osk5912_mcbsp1_device = {
137 .name = "omap_mcbsp", 183 .name = "omap_alsa_mcbsp",
138 .id = 1, 184 .id = 1,
185 .dev = {
186 .platform_data = &alsa_config,
187 },
188};
189
190static struct resource osk5912_kp_resources[] = {
191 [0] = {
192 .start = INT_KEYBOARD,
193 .end = INT_KEYBOARD,
194 .flags = IORESOURCE_IRQ,
195 },
196};
197
198static struct omap_kp_platform_data osk_kp_data = {
199 .rows = 8,
200 .cols = 8,
201 .keymap = osk_keymap,
202};
203
204static struct platform_device osk5912_kp_device = {
205 .name = "omap-keypad",
206 .id = -1,
207 .dev = {
208 .platform_data = &osk_kp_data,
209 },
210 .num_resources = ARRAY_SIZE(osk5912_kp_resources),
211 .resource = osk5912_kp_resources,
212};
213
214static struct platform_device osk5912_lcd_device = {
215 .name = "lcd_osk",
216 .id = -1,
139}; 217};
140 218
141static struct platform_device *osk5912_devices[] __initdata = { 219static struct platform_device *osk5912_devices[] __initdata = {
@@ -143,6 +221,8 @@ static struct platform_device *osk5912_devices[] __initdata = {
143 &osk5912_smc91x_device, 221 &osk5912_smc91x_device,
144 &osk5912_cf_device, 222 &osk5912_cf_device,
145 &osk5912_mcbsp1_device, 223 &osk5912_mcbsp1_device,
224 &osk5912_kp_device,
225 &osk5912_lcd_device,
146}; 226};
147 227
148static void __init osk_init_smc91x(void) 228static void __init osk_init_smc91x(void)
@@ -197,7 +277,6 @@ static struct omap_uart_config osk_uart_config __initdata = {
197}; 277};
198 278
199static struct omap_lcd_config osk_lcd_config __initdata = { 279static struct omap_lcd_config osk_lcd_config __initdata = {
200 .panel_name = "osk",
201 .ctrl_name = "internal", 280 .ctrl_name = "internal",
202}; 281};
203 282
@@ -255,8 +334,18 @@ static void __init osk_mistral_init(void)
255static void __init osk_mistral_init(void) { } 334static void __init osk_mistral_init(void) { }
256#endif 335#endif
257 336
337#define EMIFS_CS3_VAL (0x88013141)
338
258static void __init osk_init(void) 339static void __init osk_init(void)
259{ 340{
341 /* Workaround for wrong CS3 (NOR flash) timing
342 * There are some U-Boot versions out there which configure
343 * wrong CS3 memory timings. This mainly leads to CRC
344 * or similiar errors if you use NOR flash (e.g. with JFFS2)
345 */
346 if (EMIFS_CCS(3) != EMIFS_CS3_VAL)
347 EMIFS_CCS(3) = EMIFS_CS3_VAL;
348
260 osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys(); 349 osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys();
261 osk_flash_resource.end += SZ_32M - 1; 350 osk_flash_resource.end += SZ_32M - 1;
262 platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices)); 351 platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices));
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index e488f7236775..4bc8a62909b9 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -38,6 +38,15 @@ static void __init omap_generic_init_irq(void)
38 omap_init_irq(); 38 omap_init_irq();
39} 39}
40 40
41static struct platform_device palmte_lcd_device = {
42 .name = "lcd_palmte",
43 .id = -1,
44};
45
46static struct platform_device *devices[] __initdata = {
47 &palmte_lcd_device,
48};
49
41static struct omap_usb_config palmte_usb_config __initdata = { 50static struct omap_usb_config palmte_usb_config __initdata = {
42 .register_dev = 1, 51 .register_dev = 1,
43 .hmc_mode = 0, 52 .hmc_mode = 0,
@@ -55,7 +64,6 @@ static struct omap_mmc_config palmte_mmc_config __initdata = {
55}; 64};
56 65
57static struct omap_lcd_config palmte_lcd_config __initdata = { 66static struct omap_lcd_config palmte_lcd_config __initdata = {
58 .panel_name = "palmte",
59 .ctrl_name = "internal", 67 .ctrl_name = "internal",
60}; 68};
61 69
@@ -69,6 +77,8 @@ static void __init omap_generic_init(void)
69{ 77{
70 omap_board_config = palmte_config; 78 omap_board_config = palmte_config;
71 omap_board_config_size = ARRAY_SIZE(palmte_config); 79 omap_board_config_size = ARRAY_SIZE(palmte_config);
80
81 platform_add_devices(devices, ARRAY_SIZE(devices));
72} 82}
73 83
74static void __init omap_generic_map_io(void) 84static void __init omap_generic_map_io(void)
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index 3913a3cc0ce6..64b45d8ae357 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -16,7 +16,9 @@
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/mtd/mtd.h> 18#include <linux/mtd/mtd.h>
19#include <linux/mtd/nand.h>
19#include <linux/mtd/partitions.h> 20#include <linux/mtd/partitions.h>
21#include <linux/input.h>
20 22
21#include <asm/hardware.h> 23#include <asm/hardware.h>
22#include <asm/mach-types.h> 24#include <asm/mach-types.h>
@@ -28,9 +30,44 @@
28#include <asm/arch/gpio.h> 30#include <asm/arch/gpio.h>
29#include <asm/arch/mux.h> 31#include <asm/arch/mux.h>
30#include <asm/arch/fpga.h> 32#include <asm/arch/fpga.h>
33#include <asm/arch/keypad.h>
31#include <asm/arch/common.h> 34#include <asm/arch/common.h>
32#include <asm/arch/board.h> 35#include <asm/arch/board.h>
33 36
37static int p2_keymap[] = {
38 KEY(0,0,KEY_UP),
39 KEY(0,1,KEY_RIGHT),
40 KEY(0,2,KEY_LEFT),
41 KEY(0,3,KEY_DOWN),
42 KEY(0,4,KEY_CENTER),
43 KEY(0,5,KEY_0_5),
44 KEY(1,0,KEY_SOFT2),
45 KEY(1,1,KEY_SEND),
46 KEY(1,2,KEY_END),
47 KEY(1,3,KEY_VOLUMEDOWN),
48 KEY(1,4,KEY_VOLUMEUP),
49 KEY(1,5,KEY_RECORD),
50 KEY(2,0,KEY_SOFT1),
51 KEY(2,1,KEY_3),
52 KEY(2,2,KEY_6),
53 KEY(2,3,KEY_9),
54 KEY(2,4,KEY_SHARP),
55 KEY(2,5,KEY_2_5),
56 KEY(3,0,KEY_BACK),
57 KEY(3,1,KEY_2),
58 KEY(3,2,KEY_5),
59 KEY(3,3,KEY_8),
60 KEY(3,4,KEY_0),
61 KEY(3,5,KEY_HEADSETHOOK),
62 KEY(4,0,KEY_HOME),
63 KEY(4,1,KEY_1),
64 KEY(4,2,KEY_4),
65 KEY(4,3,KEY_7),
66 KEY(4,4,KEY_STAR),
67 KEY(4,5,KEY_POWER),
68 0
69};
70
34static struct resource smc91x_resources[] = { 71static struct resource smc91x_resources[] = {
35 [0] = { 72 [0] = {
36 .start = H2P2_DBG_FPGA_ETHR_START, /* Physical */ 73 .start = H2P2_DBG_FPGA_ETHR_START, /* Physical */
@@ -44,7 +81,7 @@ static struct resource smc91x_resources[] = {
44 }, 81 },
45}; 82};
46 83
47static struct mtd_partition p2_partitions[] = { 84static struct mtd_partition nor_partitions[] = {
48 /* bootloader (U-Boot, etc) in first sector */ 85 /* bootloader (U-Boot, etc) in first sector */
49 { 86 {
50 .name = "bootloader", 87 .name = "bootloader",
@@ -75,27 +112,47 @@ static struct mtd_partition p2_partitions[] = {
75 }, 112 },
76}; 113};
77 114
78static struct flash_platform_data p2_flash_data = { 115static struct flash_platform_data nor_data = {
79 .map_name = "cfi_probe", 116 .map_name = "cfi_probe",
80 .width = 2, 117 .width = 2,
81 .parts = p2_partitions, 118 .parts = nor_partitions,
82 .nr_parts = ARRAY_SIZE(p2_partitions), 119 .nr_parts = ARRAY_SIZE(nor_partitions),
83}; 120};
84 121
85static struct resource p2_flash_resource = { 122static struct resource nor_resource = {
86 .start = OMAP_CS0_PHYS, 123 .start = OMAP_CS0_PHYS,
87 .end = OMAP_CS0_PHYS + SZ_32M - 1, 124 .end = OMAP_CS0_PHYS + SZ_32M - 1,
88 .flags = IORESOURCE_MEM, 125 .flags = IORESOURCE_MEM,
89}; 126};
90 127
91static struct platform_device p2_flash_device = { 128static struct platform_device nor_device = {
92 .name = "omapflash", 129 .name = "omapflash",
93 .id = 0, 130 .id = 0,
94 .dev = { 131 .dev = {
95 .platform_data = &p2_flash_data, 132 .platform_data = &nor_data,
133 },
134 .num_resources = 1,
135 .resource = &nor_resource,
136};
137
138static struct nand_platform_data nand_data = {
139 .options = NAND_SAMSUNG_LP_OPTIONS,
140};
141
142static struct resource nand_resource = {
143 .start = OMAP_CS3_PHYS,
144 .end = OMAP_CS3_PHYS + SZ_4K - 1,
145 .flags = IORESOURCE_MEM,
146};
147
148static struct platform_device nand_device = {
149 .name = "omapnand",
150 .id = 0,
151 .dev = {
152 .platform_data = &nand_data,
96 }, 153 },
97 .num_resources = 1, 154 .num_resources = 1,
98 .resource = &p2_flash_resource, 155 .resource = &nand_resource,
99}; 156};
100 157
101static struct platform_device smc91x_device = { 158static struct platform_device smc91x_device = {
@@ -105,17 +162,55 @@ static struct platform_device smc91x_device = {
105 .resource = smc91x_resources, 162 .resource = smc91x_resources,
106}; 163};
107 164
165static struct resource kp_resources[] = {
166 [0] = {
167 .start = INT_730_MPUIO_KEYPAD,
168 .end = INT_730_MPUIO_KEYPAD,
169 .flags = IORESOURCE_IRQ,
170 },
171};
172
173static struct omap_kp_platform_data kp_data = {
174 .rows = 8,
175 .cols = 8,
176 .keymap = p2_keymap,
177};
178
179static struct platform_device kp_device = {
180 .name = "omap-keypad",
181 .id = -1,
182 .dev = {
183 .platform_data = &kp_data,
184 },
185 .num_resources = ARRAY_SIZE(kp_resources),
186 .resource = kp_resources,
187};
188
189static struct platform_device lcd_device = {
190 .name = "lcd_p2",
191 .id = -1,
192};
193
108static struct platform_device *devices[] __initdata = { 194static struct platform_device *devices[] __initdata = {
109 &p2_flash_device, 195 &nor_device,
196 &nand_device,
110 &smc91x_device, 197 &smc91x_device,
198 &kp_device,
199 &lcd_device,
111}; 200};
112 201
202#define P2_NAND_RB_GPIO_PIN 62
203
204static int nand_dev_ready(struct nand_platform_data *data)
205{
206 return omap_get_gpio_datain(P2_NAND_RB_GPIO_PIN);
207}
208
113static struct omap_uart_config perseus2_uart_config __initdata = { 209static struct omap_uart_config perseus2_uart_config __initdata = {
114 .enabled_uarts = ((1 << 0) | (1 << 1)), 210 .enabled_uarts = ((1 << 0) | (1 << 1)),
115}; 211};
116 212
117static struct omap_lcd_config perseus2_lcd_config __initdata = { 213static struct omap_lcd_config perseus2_lcd_config __initdata = {
118 .panel_name = "p2",
119 .ctrl_name = "internal", 214 .ctrl_name = "internal",
120}; 215};
121 216
@@ -126,7 +221,13 @@ static struct omap_board_config_kernel perseus2_config[] = {
126 221
127static void __init omap_perseus2_init(void) 222static void __init omap_perseus2_init(void)
128{ 223{
129 (void) platform_add_devices(devices, ARRAY_SIZE(devices)); 224 if (!(omap_request_gpio(P2_NAND_RB_GPIO_PIN)))
225 nand_data.dev_ready = nand_dev_ready;
226
227 omap_cfg_reg(L3_1610_FLASH_CS2B_OE);
228 omap_cfg_reg(M8_1610_FLASH_CS2B_WE);
229
230 platform_add_devices(devices, ARRAY_SIZE(devices));
130 231
131 omap_board_config = perseus2_config; 232 omap_board_config = perseus2_config;
132 omap_board_config_size = ARRAY_SIZE(perseus2_config); 233 omap_board_config_size = ARRAY_SIZE(perseus2_config);
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index 52e4a9d69642..447a586eb334 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -155,9 +155,9 @@ static struct omap_uart_config voiceblue_uart_config __initdata = {
155}; 155};
156 156
157static struct omap_board_config_kernel voiceblue_config[] = { 157static struct omap_board_config_kernel voiceblue_config[] = {
158 { OMAP_TAG_USB, &voiceblue_usb_config }, 158 { OMAP_TAG_USB, &voiceblue_usb_config },
159 { OMAP_TAG_MMC, &voiceblue_mmc_config }, 159 { OMAP_TAG_MMC, &voiceblue_mmc_config },
160 { OMAP_TAG_UART, &voiceblue_uart_config }, 160 { OMAP_TAG_UART, &voiceblue_uart_config },
161}; 161};
162 162
163static void __init voiceblue_init_irq(void) 163static void __init voiceblue_init_irq(void)
@@ -235,7 +235,7 @@ static struct notifier_block panic_block = {
235static int __init voiceblue_setup(void) 235static int __init voiceblue_setup(void)
236{ 236{
237 /* Setup panic notifier */ 237 /* Setup panic notifier */
238 atomic_notifier_chain_register(&panic_notifier_list, &panic_block); 238 notifier_chain_register(&panic_notifier_list, &panic_block);
239 239
240 return 0; 240 return 0;
241} 241}
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index 75110ba10424..619db18144ea 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -345,7 +345,7 @@ static unsigned calc_ext_dsor(unsigned long rate)
345 */ 345 */
346 for (dsor = 2; dsor < 96; ++dsor) { 346 for (dsor = 2; dsor < 96; ++dsor) {
347 if ((dsor & 1) && dsor > 8) 347 if ((dsor & 1) && dsor > 8)
348 continue; 348 continue;
349 if (rate >= 96000000 / dsor) 349 if (rate >= 96000000 / dsor)
350 break; 350 break;
351 } 351 }
@@ -687,6 +687,11 @@ int __init omap1_clk_init(void)
687 clk_register(*clkp); 687 clk_register(*clkp);
688 continue; 688 continue;
689 } 689 }
690
691 if (((*clkp)->flags &CLOCK_IN_OMAP310) && cpu_is_omap310()) {
692 clk_register(*clkp);
693 continue;
694 }
690 } 695 }
691 696
692 info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config); 697 info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
@@ -784,7 +789,7 @@ int __init omap1_clk_init(void)
784 clk_enable(&armxor_ck.clk); 789 clk_enable(&armxor_ck.clk);
785 clk_enable(&armtim_ck.clk); /* This should be done by timer code */ 790 clk_enable(&armtim_ck.clk); /* This should be done by timer code */
786 791
787 if (cpu_is_omap1510()) 792 if (cpu_is_omap15xx())
788 clk_enable(&arm_gpio_ck); 793 clk_enable(&arm_gpio_ck);
789 794
790 return 0; 795 return 0;
diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h
index 4f18d1b94449..b7c68819c4e7 100644
--- a/arch/arm/mach-omap1/clock.h
+++ b/arch/arm/mach-omap1/clock.h
@@ -151,7 +151,7 @@ static struct clk ck_ref = {
151 .name = "ck_ref", 151 .name = "ck_ref",
152 .rate = 12000000, 152 .rate = 12000000,
153 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 153 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
154 ALWAYS_ENABLED, 154 CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
155 .enable = &omap1_clk_enable_generic, 155 .enable = &omap1_clk_enable_generic,
156 .disable = &omap1_clk_disable_generic, 156 .disable = &omap1_clk_disable_generic,
157}; 157};
@@ -160,7 +160,7 @@ static struct clk ck_dpll1 = {
160 .name = "ck_dpll1", 160 .name = "ck_dpll1",
161 .parent = &ck_ref, 161 .parent = &ck_ref,
162 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 162 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
163 RATE_PROPAGATES | ALWAYS_ENABLED, 163 CLOCK_IN_OMAP310 | RATE_PROPAGATES | ALWAYS_ENABLED,
164 .enable = &omap1_clk_enable_generic, 164 .enable = &omap1_clk_enable_generic,
165 .disable = &omap1_clk_disable_generic, 165 .disable = &omap1_clk_disable_generic,
166}; 166};
@@ -183,7 +183,8 @@ static struct clk arm_ck = {
183 .name = "arm_ck", 183 .name = "arm_ck",
184 .parent = &ck_dpll1, 184 .parent = &ck_dpll1,
185 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 185 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
186 RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED, 186 CLOCK_IN_OMAP310 | RATE_CKCTL | RATE_PROPAGATES |
187 ALWAYS_ENABLED,
187 .rate_offset = CKCTL_ARMDIV_OFFSET, 188 .rate_offset = CKCTL_ARMDIV_OFFSET,
188 .recalc = &omap1_ckctl_recalc, 189 .recalc = &omap1_ckctl_recalc,
189 .enable = &omap1_clk_enable_generic, 190 .enable = &omap1_clk_enable_generic,
@@ -195,7 +196,8 @@ static struct arm_idlect1_clk armper_ck = {
195 .name = "armper_ck", 196 .name = "armper_ck",
196 .parent = &ck_dpll1, 197 .parent = &ck_dpll1,
197 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 198 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
198 RATE_CKCTL | CLOCK_IDLE_CONTROL, 199 CLOCK_IN_OMAP310 | RATE_CKCTL |
200 CLOCK_IDLE_CONTROL,
199 .enable_reg = (void __iomem *)ARM_IDLECT2, 201 .enable_reg = (void __iomem *)ARM_IDLECT2,
200 .enable_bit = EN_PERCK, 202 .enable_bit = EN_PERCK,
201 .rate_offset = CKCTL_PERDIV_OFFSET, 203 .rate_offset = CKCTL_PERDIV_OFFSET,
@@ -209,7 +211,7 @@ static struct arm_idlect1_clk armper_ck = {
209static struct clk arm_gpio_ck = { 211static struct clk arm_gpio_ck = {
210 .name = "arm_gpio_ck", 212 .name = "arm_gpio_ck",
211 .parent = &ck_dpll1, 213 .parent = &ck_dpll1,
212 .flags = CLOCK_IN_OMAP1510, 214 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
213 .enable_reg = (void __iomem *)ARM_IDLECT2, 215 .enable_reg = (void __iomem *)ARM_IDLECT2,
214 .enable_bit = EN_GPIOCK, 216 .enable_bit = EN_GPIOCK,
215 .recalc = &followparent_recalc, 217 .recalc = &followparent_recalc,
@@ -222,7 +224,7 @@ static struct arm_idlect1_clk armxor_ck = {
222 .name = "armxor_ck", 224 .name = "armxor_ck",
223 .parent = &ck_ref, 225 .parent = &ck_ref,
224 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 226 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
225 CLOCK_IDLE_CONTROL, 227 CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
226 .enable_reg = (void __iomem *)ARM_IDLECT2, 228 .enable_reg = (void __iomem *)ARM_IDLECT2,
227 .enable_bit = EN_XORPCK, 229 .enable_bit = EN_XORPCK,
228 .recalc = &followparent_recalc, 230 .recalc = &followparent_recalc,
@@ -237,7 +239,7 @@ static struct arm_idlect1_clk armtim_ck = {
237 .name = "armtim_ck", 239 .name = "armtim_ck",
238 .parent = &ck_ref, 240 .parent = &ck_ref,
239 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 241 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
240 CLOCK_IDLE_CONTROL, 242 CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
241 .enable_reg = (void __iomem *)ARM_IDLECT2, 243 .enable_reg = (void __iomem *)ARM_IDLECT2,
242 .enable_bit = EN_TIMCK, 244 .enable_bit = EN_TIMCK,
243 .recalc = &followparent_recalc, 245 .recalc = &followparent_recalc,
@@ -252,7 +254,7 @@ static struct arm_idlect1_clk armwdt_ck = {
252 .name = "armwdt_ck", 254 .name = "armwdt_ck",
253 .parent = &ck_ref, 255 .parent = &ck_ref,
254 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 256 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
255 CLOCK_IDLE_CONTROL, 257 CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
256 .enable_reg = (void __iomem *)ARM_IDLECT2, 258 .enable_reg = (void __iomem *)ARM_IDLECT2,
257 .enable_bit = EN_WDTCK, 259 .enable_bit = EN_WDTCK,
258 .recalc = &omap1_watchdog_recalc, 260 .recalc = &omap1_watchdog_recalc,
@@ -344,9 +346,9 @@ static struct arm_idlect1_clk tc_ck = {
344 .name = "tc_ck", 346 .name = "tc_ck",
345 .parent = &ck_dpll1, 347 .parent = &ck_dpll1,
346 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 348 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
347 CLOCK_IN_OMAP730 | RATE_CKCTL | 349 CLOCK_IN_OMAP730 | CLOCK_IN_OMAP310 |
348 RATE_PROPAGATES | ALWAYS_ENABLED | 350 RATE_CKCTL | RATE_PROPAGATES |
349 CLOCK_IDLE_CONTROL, 351 ALWAYS_ENABLED | CLOCK_IDLE_CONTROL,
350 .rate_offset = CKCTL_TCDIV_OFFSET, 352 .rate_offset = CKCTL_TCDIV_OFFSET,
351 .recalc = &omap1_ckctl_recalc, 353 .recalc = &omap1_ckctl_recalc,
352 .enable = &omap1_clk_enable_generic, 354 .enable = &omap1_clk_enable_generic,
@@ -358,7 +360,8 @@ static struct arm_idlect1_clk tc_ck = {
358static struct clk arminth_ck1510 = { 360static struct clk arminth_ck1510 = {
359 .name = "arminth_ck", 361 .name = "arminth_ck",
360 .parent = &tc_ck.clk, 362 .parent = &tc_ck.clk,
361 .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED, 363 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
364 ALWAYS_ENABLED,
362 .recalc = &followparent_recalc, 365 .recalc = &followparent_recalc,
363 /* Note: On 1510 the frequency follows TC_CK 366 /* Note: On 1510 the frequency follows TC_CK
364 * 367 *
@@ -372,7 +375,8 @@ static struct clk tipb_ck = {
372 /* No-idle controlled by "tc_ck" */ 375 /* No-idle controlled by "tc_ck" */
373 .name = "tibp_ck", 376 .name = "tibp_ck",
374 .parent = &tc_ck.clk, 377 .parent = &tc_ck.clk,
375 .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED, 378 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
379 ALWAYS_ENABLED,
376 .recalc = &followparent_recalc, 380 .recalc = &followparent_recalc,
377 .enable = &omap1_clk_enable_generic, 381 .enable = &omap1_clk_enable_generic,
378 .disable = &omap1_clk_disable_generic, 382 .disable = &omap1_clk_disable_generic,
@@ -417,7 +421,7 @@ static struct clk dma_ck = {
417 .name = "dma_ck", 421 .name = "dma_ck",
418 .parent = &tc_ck.clk, 422 .parent = &tc_ck.clk,
419 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 423 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
420 ALWAYS_ENABLED, 424 CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
421 .recalc = &followparent_recalc, 425 .recalc = &followparent_recalc,
422 .enable = &omap1_clk_enable_generic, 426 .enable = &omap1_clk_enable_generic,
423 .disable = &omap1_clk_disable_generic, 427 .disable = &omap1_clk_disable_generic,
@@ -437,7 +441,7 @@ static struct arm_idlect1_clk api_ck = {
437 .name = "api_ck", 441 .name = "api_ck",
438 .parent = &tc_ck.clk, 442 .parent = &tc_ck.clk,
439 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 443 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
440 CLOCK_IDLE_CONTROL, 444 CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
441 .enable_reg = (void __iomem *)ARM_IDLECT2, 445 .enable_reg = (void __iomem *)ARM_IDLECT2,
442 .enable_bit = EN_APICK, 446 .enable_bit = EN_APICK,
443 .recalc = &followparent_recalc, 447 .recalc = &followparent_recalc,
@@ -451,7 +455,8 @@ static struct arm_idlect1_clk lb_ck = {
451 .clk = { 455 .clk = {
452 .name = "lb_ck", 456 .name = "lb_ck",
453 .parent = &tc_ck.clk, 457 .parent = &tc_ck.clk,
454 .flags = CLOCK_IN_OMAP1510 | CLOCK_IDLE_CONTROL, 458 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
459 CLOCK_IDLE_CONTROL,
455 .enable_reg = (void __iomem *)ARM_IDLECT2, 460 .enable_reg = (void __iomem *)ARM_IDLECT2,
456 .enable_bit = EN_LBCK, 461 .enable_bit = EN_LBCK,
457 .recalc = &followparent_recalc, 462 .recalc = &followparent_recalc,
@@ -495,8 +500,8 @@ static struct arm_idlect1_clk lcd_ck_1510 = {
495 .clk = { 500 .clk = {
496 .name = "lcd_ck", 501 .name = "lcd_ck",
497 .parent = &ck_dpll1, 502 .parent = &ck_dpll1,
498 .flags = CLOCK_IN_OMAP1510 | RATE_CKCTL | 503 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
499 CLOCK_IDLE_CONTROL, 504 RATE_CKCTL | CLOCK_IDLE_CONTROL,
500 .enable_reg = (void __iomem *)ARM_IDLECT2, 505 .enable_reg = (void __iomem *)ARM_IDLECT2,
501 .enable_bit = EN_LCDCK, 506 .enable_bit = EN_LCDCK,
502 .rate_offset = CKCTL_LCDDIV_OFFSET, 507 .rate_offset = CKCTL_LCDDIV_OFFSET,
@@ -512,8 +517,9 @@ static struct clk uart1_1510 = {
512 /* Direct from ULPD, no real parent */ 517 /* Direct from ULPD, no real parent */
513 .parent = &armper_ck.clk, 518 .parent = &armper_ck.clk,
514 .rate = 12000000, 519 .rate = 12000000,
515 .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | 520 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
516 ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT, 521 ENABLE_REG_32BIT | ALWAYS_ENABLED |
522 CLOCK_NO_IDLE_PARENT,
517 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, 523 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
518 .enable_bit = 29, /* Chooses between 12MHz and 48MHz */ 524 .enable_bit = 29, /* Chooses between 12MHz and 48MHz */
519 .set_rate = &omap1_set_uart_rate, 525 .set_rate = &omap1_set_uart_rate,
@@ -544,8 +550,8 @@ static struct clk uart2_ck = {
544 .parent = &armper_ck.clk, 550 .parent = &armper_ck.clk,
545 .rate = 12000000, 551 .rate = 12000000,
546 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 552 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
547 ENABLE_REG_32BIT | ALWAYS_ENABLED | 553 CLOCK_IN_OMAP310 | ENABLE_REG_32BIT |
548 CLOCK_NO_IDLE_PARENT, 554 ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT,
549 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, 555 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
550 .enable_bit = 30, /* Chooses between 12MHz and 48MHz */ 556 .enable_bit = 30, /* Chooses between 12MHz and 48MHz */
551 .set_rate = &omap1_set_uart_rate, 557 .set_rate = &omap1_set_uart_rate,
@@ -559,8 +565,9 @@ static struct clk uart3_1510 = {
559 /* Direct from ULPD, no real parent */ 565 /* Direct from ULPD, no real parent */
560 .parent = &armper_ck.clk, 566 .parent = &armper_ck.clk,
561 .rate = 12000000, 567 .rate = 12000000,
562 .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | 568 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
563 ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT, 569 ENABLE_REG_32BIT | ALWAYS_ENABLED |
570 CLOCK_NO_IDLE_PARENT,
564 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, 571 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
565 .enable_bit = 31, /* Chooses between 12MHz and 48MHz */ 572 .enable_bit = 31, /* Chooses between 12MHz and 48MHz */
566 .set_rate = &omap1_set_uart_rate, 573 .set_rate = &omap1_set_uart_rate,
@@ -590,7 +597,7 @@ static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
590 /* Direct from ULPD, no parent */ 597 /* Direct from ULPD, no parent */
591 .rate = 6000000, 598 .rate = 6000000,
592 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 599 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
593 RATE_FIXED | ENABLE_REG_32BIT, 600 CLOCK_IN_OMAP310 | RATE_FIXED | ENABLE_REG_32BIT,
594 .enable_reg = (void __iomem *)ULPD_CLOCK_CTRL, 601 .enable_reg = (void __iomem *)ULPD_CLOCK_CTRL,
595 .enable_bit = USB_MCLK_EN_BIT, 602 .enable_bit = USB_MCLK_EN_BIT,
596 .enable = &omap1_clk_enable_generic, 603 .enable = &omap1_clk_enable_generic,
@@ -601,7 +608,7 @@ static struct clk usb_hhc_ck1510 = {
601 .name = "usb_hhc_ck", 608 .name = "usb_hhc_ck",
602 /* Direct from ULPD, no parent */ 609 /* Direct from ULPD, no parent */
603 .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */ 610 .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
604 .flags = CLOCK_IN_OMAP1510 | 611 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
605 RATE_FIXED | ENABLE_REG_32BIT, 612 RATE_FIXED | ENABLE_REG_32BIT,
606 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, 613 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
607 .enable_bit = USB_HOST_HHC_UHOST_EN, 614 .enable_bit = USB_HOST_HHC_UHOST_EN,
@@ -637,7 +644,9 @@ static struct clk mclk_1510 = {
637 .name = "mclk", 644 .name = "mclk",
638 /* Direct from ULPD, no parent. May be enabled by ext hardware. */ 645 /* Direct from ULPD, no parent. May be enabled by ext hardware. */
639 .rate = 12000000, 646 .rate = 12000000,
640 .flags = CLOCK_IN_OMAP1510 | RATE_FIXED, 647 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | RATE_FIXED,
648 .enable_reg = (void __iomem *)SOFT_REQ_REG,
649 .enable_bit = 6,
641 .enable = &omap1_clk_enable_generic, 650 .enable = &omap1_clk_enable_generic,
642 .disable = &omap1_clk_disable_generic, 651 .disable = &omap1_clk_disable_generic,
643}; 652};
@@ -659,7 +668,7 @@ static struct clk bclk_1510 = {
659 .name = "bclk", 668 .name = "bclk",
660 /* Direct from ULPD, no parent. May be enabled by ext hardware. */ 669 /* Direct from ULPD, no parent. May be enabled by ext hardware. */
661 .rate = 12000000, 670 .rate = 12000000,
662 .flags = CLOCK_IN_OMAP1510 | RATE_FIXED, 671 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | RATE_FIXED,
663 .enable = &omap1_clk_enable_generic, 672 .enable = &omap1_clk_enable_generic,
664 .disable = &omap1_clk_disable_generic, 673 .disable = &omap1_clk_disable_generic,
665}; 674};
@@ -678,12 +687,14 @@ static struct clk bclk_16xx = {
678}; 687};
679 688
680static struct clk mmc1_ck = { 689static struct clk mmc1_ck = {
681 .name = "mmc1_ck", 690 .name = "mmc_ck",
691 .id = 1,
682 /* Functional clock is direct from ULPD, interface clock is ARMPER */ 692 /* Functional clock is direct from ULPD, interface clock is ARMPER */
683 .parent = &armper_ck.clk, 693 .parent = &armper_ck.clk,
684 .rate = 48000000, 694 .rate = 48000000,
685 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 695 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
686 RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, 696 CLOCK_IN_OMAP310 | RATE_FIXED | ENABLE_REG_32BIT |
697 CLOCK_NO_IDLE_PARENT,
687 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, 698 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
688 .enable_bit = 23, 699 .enable_bit = 23,
689 .enable = &omap1_clk_enable_generic, 700 .enable = &omap1_clk_enable_generic,
@@ -691,7 +702,8 @@ static struct clk mmc1_ck = {
691}; 702};
692 703
693static struct clk mmc2_ck = { 704static struct clk mmc2_ck = {
694 .name = "mmc2_ck", 705 .name = "mmc_ck",
706 .id = 2,
695 /* Functional clock is direct from ULPD, interface clock is ARMPER */ 707 /* Functional clock is direct from ULPD, interface clock is ARMPER */
696 .parent = &armper_ck.clk, 708 .parent = &armper_ck.clk,
697 .rate = 48000000, 709 .rate = 48000000,
@@ -706,7 +718,7 @@ static struct clk mmc2_ck = {
706static struct clk virtual_ck_mpu = { 718static struct clk virtual_ck_mpu = {
707 .name = "mpu", 719 .name = "mpu",
708 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 720 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
709 VIRTUAL_CLOCK | ALWAYS_ENABLED, 721 CLOCK_IN_OMAP310 | VIRTUAL_CLOCK | ALWAYS_ENABLED,
710 .parent = &arm_ck, /* Is smarter alias for */ 722 .parent = &arm_ck, /* Is smarter alias for */
711 .recalc = &followparent_recalc, 723 .recalc = &followparent_recalc,
712 .set_rate = &omap1_select_table_rate, 724 .set_rate = &omap1_select_table_rate,
@@ -715,6 +727,20 @@ static struct clk virtual_ck_mpu = {
715 .disable = &omap1_clk_disable_generic, 727 .disable = &omap1_clk_disable_generic,
716}; 728};
717 729
730/* virtual functional clock domain for I2C. Just for making sure that ARMXOR_CK
731remains active during MPU idle whenever this is enabled */
732static struct clk i2c_fck = {
733 .name = "i2c_fck",
734 .id = 1,
735 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
736 VIRTUAL_CLOCK | CLOCK_NO_IDLE_PARENT |
737 ALWAYS_ENABLED,
738 .parent = &armxor_ck.clk,
739 .recalc = &followparent_recalc,
740 .enable = &omap1_clk_enable_generic,
741 .disable = &omap1_clk_disable_generic,
742};
743
718static struct clk * onchip_clks[] = { 744static struct clk * onchip_clks[] = {
719 /* non-ULPD clocks */ 745 /* non-ULPD clocks */
720 &ck_ref, 746 &ck_ref,
@@ -763,6 +789,7 @@ static struct clk * onchip_clks[] = {
763 &mmc2_ck, 789 &mmc2_ck,
764 /* Virtual clocks */ 790 /* Virtual clocks */
765 &virtual_ck_mpu, 791 &virtual_ck_mpu,
792 &i2c_fck,
766}; 793};
767 794
768#endif 795#endif
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index ecbc47514adc..876c38da14f7 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -99,6 +99,45 @@ static void omap_init_rtc(void)
99static inline void omap_init_rtc(void) {} 99static inline void omap_init_rtc(void) {}
100#endif 100#endif
101 101
102#if defined(CONFIG_OMAP_STI)
103
104#define OMAP1_STI_BASE IO_ADDRESS(0xfffea000)
105#define OMAP1_STI_CHANNEL_BASE (OMAP1_STI_BASE + 0x400)
106
107static struct resource sti_resources[] = {
108 {
109 .start = OMAP1_STI_BASE,
110 .end = OMAP1_STI_BASE + SZ_1K - 1,
111 .flags = IORESOURCE_MEM,
112 },
113 {
114 .start = OMAP1_STI_CHANNEL_BASE,
115 .end = OMAP1_STI_CHANNEL_BASE + SZ_1K - 1,
116 .flags = IORESOURCE_MEM,
117 },
118 {
119 .start = INT_1610_STI,
120 .flags = IORESOURCE_IRQ,
121 }
122};
123
124static struct platform_device sti_device = {
125 .name = "sti",
126 .id = -1,
127 .dev = {
128 .release = omap_nop_release,
129 },
130 .num_resources = ARRAY_SIZE(sti_resources),
131 .resource = sti_resources,
132};
133
134static inline void omap_init_sti(void)
135{
136 platform_device_register(&sti_device);
137}
138#else
139static inline void omap_init_sti(void) {}
140#endif
102 141
103/*-------------------------------------------------------------------------*/ 142/*-------------------------------------------------------------------------*/
104 143
@@ -129,6 +168,7 @@ static int __init omap1_init_devices(void)
129 */ 168 */
130 omap_init_irda(); 169 omap_init_irda();
131 omap_init_rtc(); 170 omap_init_rtc();
171 omap_init_sti();
132 172
133 return 0; 173 return 0;
134} 174}
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
index 82d556be79c5..be3a2a4ee2b8 100644
--- a/arch/arm/mach-omap1/io.c
+++ b/arch/arm/mach-omap1/io.c
@@ -18,6 +18,7 @@
18#include <asm/io.h> 18#include <asm/io.h>
19#include <asm/arch/mux.h> 19#include <asm/arch/mux.h>
20#include <asm/arch/tc.h> 20#include <asm/arch/tc.h>
21#include <asm/arch/omapfb.h>
21 22
22extern int omap1_clk_init(void); 23extern int omap1_clk_init(void);
23extern void omap_check_revision(void); 24extern void omap_check_revision(void);
@@ -110,7 +111,7 @@ void __init omap1_map_common_io(void)
110 } 111 }
111#endif 112#endif
112#ifdef CONFIG_ARCH_OMAP15XX 113#ifdef CONFIG_ARCH_OMAP15XX
113 if (cpu_is_omap1510()) { 114 if (cpu_is_omap15xx()) {
114 iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc)); 115 iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc));
115 } 116 }
116#endif 117#endif
@@ -121,6 +122,7 @@ void __init omap1_map_common_io(void)
121#endif 122#endif
122 123
123 omap_sram_init(); 124 omap_sram_init();
125 omapfb_reserve_mem();
124} 126}
125 127
126/* 128/*
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c
index ed65a7d2e941..a0431c00fa81 100644
--- a/arch/arm/mach-omap1/irq.c
+++ b/arch/arm/mach-omap1/irq.c
@@ -60,7 +60,7 @@ struct omap_irq_bank {
60 unsigned long wake_enable; 60 unsigned long wake_enable;
61}; 61};
62 62
63static unsigned int irq_bank_count = 0; 63static unsigned int irq_bank_count;
64static struct omap_irq_bank *irq_banks; 64static struct omap_irq_bank *irq_banks;
65 65
66static inline unsigned int irq_bank_readl(int bank, int offset) 66static inline unsigned int irq_bank_readl(int bank, int offset)
@@ -142,28 +142,28 @@ static void omap_irq_set_cfg(int irq, int fiq, int priority, int trigger)
142 142
143#ifdef CONFIG_ARCH_OMAP730 143#ifdef CONFIG_ARCH_OMAP730
144static struct omap_irq_bank omap730_irq_banks[] = { 144static struct omap_irq_bank omap730_irq_banks[] = {
145 { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3f8e22f }, 145 { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3f8e22f },
146 { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb9c1f2 }, 146 { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb9c1f2 },
147 { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0x800040f3 }, 147 { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0x800040f3 },
148}; 148};
149#endif 149#endif
150 150
151#ifdef CONFIG_ARCH_OMAP15XX 151#ifdef CONFIG_ARCH_OMAP15XX
152static struct omap_irq_bank omap1510_irq_banks[] = { 152static struct omap_irq_bank omap1510_irq_banks[] = {
153 { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3febfff }, 153 { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3febfff },
154 { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xffbfffed }, 154 { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xffbfffed },
155}; 155};
156static struct omap_irq_bank omap310_irq_banks[] = { 156static struct omap_irq_bank omap310_irq_banks[] = {
157 { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3faefc3 }, 157 { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3faefc3 },
158 { .base_reg = OMAP_IH2_BASE, .trigger_map = 0x65b3c061 }, 158 { .base_reg = OMAP_IH2_BASE, .trigger_map = 0x65b3c061 },
159}; 159};
160#endif 160#endif
161 161
162#if defined(CONFIG_ARCH_OMAP16XX) 162#if defined(CONFIG_ARCH_OMAP16XX)
163 163
164static struct omap_irq_bank omap1610_irq_banks[] = { 164static struct omap_irq_bank omap1610_irq_banks[] = {
165 { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3fefe8f }, 165 { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3fefe8f },
166 { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb7c1fd }, 166 { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb7c1fd },
167 { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0xffffb7ff }, 167 { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0xffffb7ff },
168 { .base_reg = OMAP_IH2_BASE + 0x200, .trigger_map = 0xffffffff }, 168 { .base_reg = OMAP_IH2_BASE + 0x200, .trigger_map = 0xffffffff },
169}; 169};
diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c
index d4b8d624e742..10fe0b3efcac 100644
--- a/arch/arm/mach-omap1/mux.c
+++ b/arch/arm/mach-omap1/mux.c
@@ -35,16 +35,20 @@
35 35
36#ifdef CONFIG_ARCH_OMAP730 36#ifdef CONFIG_ARCH_OMAP730
37struct pin_config __initdata_or_module omap730_pins[] = { 37struct pin_config __initdata_or_module omap730_pins[] = {
38MUX_CFG_730("E2_730_KBR0", 12, 21, 0, 0, 20, 1, NA, 0, 0) 38MUX_CFG_730("E2_730_KBR0", 12, 21, 0, 20, 1, 0)
39MUX_CFG_730("J7_730_KBR1", 12, 25, 0, 0, 24, 1, NA, 0, 0) 39MUX_CFG_730("J7_730_KBR1", 12, 25, 0, 24, 1, 0)
40MUX_CFG_730("E1_730_KBR2", 12, 29, 0, 0, 28, 1, NA, 0, 0) 40MUX_CFG_730("E1_730_KBR2", 12, 29, 0, 28, 1, 0)
41MUX_CFG_730("F3_730_KBR3", 13, 1, 0, 0, 0, 1, NA, 0, 0) 41MUX_CFG_730("F3_730_KBR3", 13, 1, 0, 0, 1, 0)
42MUX_CFG_730("D2_730_KBR4", 13, 5, 0, 0, 4, 1, NA, 0, 0) 42MUX_CFG_730("D2_730_KBR4", 13, 5, 0, 4, 1, 0)
43MUX_CFG_730("C2_730_KBC0", 13, 9, 0, 0, 8, 1, NA, 0, 0) 43MUX_CFG_730("C2_730_KBC0", 13, 9, 0, 8, 1, 0)
44MUX_CFG_730("D3_730_KBC1", 13, 13, 0, 0, 12, 1, NA, 0, 0) 44MUX_CFG_730("D3_730_KBC1", 13, 13, 0, 12, 1, 0)
45MUX_CFG_730("E4_730_KBC2", 13, 17, 0, 0, 16, 1, NA, 0, 0) 45MUX_CFG_730("E4_730_KBC2", 13, 17, 0, 16, 1, 0)
46MUX_CFG_730("F4_730_KBC3", 13, 21, 0, 0, 20, 1, NA, 0, 0) 46MUX_CFG_730("F4_730_KBC3", 13, 21, 0, 20, 1, 0)
47MUX_CFG_730("E3_730_KBC4", 13, 25, 0, 0, 24, 1, NA, 0, 0) 47MUX_CFG_730("E3_730_KBC4", 13, 25, 0, 24, 1, 0)
48
49MUX_CFG_730("AA17_730_USB_DM", 2, 21, 0, 20, 0, 0)
50MUX_CFG_730("W16_730_USB_PU_EN", 2, 25, 0, 24, 0, 0)
51MUX_CFG_730("W17_730_USB_VBUSI", 2, 29, 0, 28, 0, 0)
48}; 52};
49#endif 53#endif
50 54
@@ -73,8 +77,8 @@ MUX_CFG("UART3_BCLK", A, 0, 0, 2, 6, 0, NA, 0, 0)
73MUX_CFG("Y15_1610_UART3_RTS", A, 0, 1, 2, 6, 0, NA, 0, 0) 77MUX_CFG("Y15_1610_UART3_RTS", A, 0, 1, 2, 6, 0, NA, 0, 0)
74 78
75/* PWT & PWL, conflicts with UART3 */ 79/* PWT & PWL, conflicts with UART3 */
76MUX_CFG("PWT", 6, 0, 2, 0, 30, 0, NA, 0, 0) 80MUX_CFG("PWT", 6, 0, 2, 0, 30, 0, NA, 0, 0)
77MUX_CFG("PWL", 6, 3, 1, 0, 31, 1, NA, 0, 0) 81MUX_CFG("PWL", 6, 3, 1, 0, 31, 1, NA, 0, 0)
78 82
79/* USB internal master generic */ 83/* USB internal master generic */
80MUX_CFG("R18_USB_VBUS", 7, 9, 2, 1, 11, 0, NA, 0, 1) 84MUX_CFG("R18_USB_VBUS", 7, 9, 2, 1, 11, 0, NA, 0, 1)
@@ -151,7 +155,7 @@ MUX_CFG("MCBSP3_CLKX", 9, 3, 1, 1, 29, 0, NA, 0, 1)
151 155
152/* Misc ballouts */ 156/* Misc ballouts */
153MUX_CFG("BALLOUT_V8_ARMIO3", B, 18, 0, 2, 25, 1, NA, 0, 1) 157MUX_CFG("BALLOUT_V8_ARMIO3", B, 18, 0, 2, 25, 1, NA, 0, 1)
154MUX_CFG("N20_HDQ", 6, 18, 1, 1, 4, 0, 1, 4, 0) 158MUX_CFG("N20_HDQ", 6, 18, 1, 1, 4, 0, 1, 4, 0)
155 159
156/* OMAP-1610 MMC2 */ 160/* OMAP-1610 MMC2 */
157MUX_CFG("W8_1610_MMC2_DAT0", B, 21, 6, 2, 23, 1, 2, 1, 1) 161MUX_CFG("W8_1610_MMC2_DAT0", B, 21, 6, 2, 23, 1, 2, 1, 1)
diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
new file mode 100644
index 000000000000..ddf6b07dc9c7
--- /dev/null
+++ b/arch/arm/mach-omap1/pm.c
@@ -0,0 +1,770 @@
1/*
2 * linux/arch/arm/mach-omap1/pm.c
3 *
4 * OMAP Power Management Routines
5 *
6 * Original code for the SA11x0:
7 * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
8 *
9 * Modified for the PXA250 by Nicolas Pitre:
10 * Copyright (c) 2002 Monta Vista Software, Inc.
11 *
12 * Modified for the OMAP1510 by David Singleton:
13 * Copyright (c) 2002 Monta Vista Software, Inc.
14 *
15 * Cleanup 2004 for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com>
16 *
17 * This program is free software; you can redistribute it and/or modify it
18 * under the terms of the GNU General Public License as published by the
19 * Free Software Foundation; either version 2 of the License, or (at your
20 * option) any later version.
21 *
22 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
25 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * You should have received a copy of the GNU General Public License along
34 * with this program; if not, write to the Free Software Foundation, Inc.,
35 * 675 Mass Ave, Cambridge, MA 02139, USA.
36 */
37
38#include <linux/pm.h>
39#include <linux/sched.h>
40#include <linux/proc_fs.h>
41#include <linux/pm.h>
42#include <linux/interrupt.h>
43#include <linux/sysfs.h>
44#include <linux/module.h>
45
46#include <asm/io.h>
47#include <asm/irq.h>
48#include <asm/atomic.h>
49#include <asm/mach/time.h>
50#include <asm/mach/irq.h>
51#include <asm/mach-types.h>
52
53#include <asm/arch/irqs.h>
54#include <asm/arch/clock.h>
55#include <asm/arch/sram.h>
56#include <asm/arch/tc.h>
57#include <asm/arch/pm.h>
58#include <asm/arch/mux.h>
59#include <asm/arch/tps65010.h>
60#include <asm/arch/dma.h>
61#include <asm/arch/dsp_common.h>
62#include <asm/arch/dmtimer.h>
63
64static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
65static unsigned short dsp_sleep_save[DSP_SLEEP_SAVE_SIZE];
66static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
67static unsigned int mpui730_sleep_save[MPUI730_SLEEP_SAVE_SIZE];
68static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
69static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
70
71static unsigned short enable_dyn_sleep = 1;
72
73static ssize_t omap_pm_sleep_while_idle_show(struct subsystem * subsys, char *buf)
74{
75 return sprintf(buf, "%hu\n", enable_dyn_sleep);
76}
77
78static ssize_t omap_pm_sleep_while_idle_store(struct subsystem * subsys,
79 const char * buf,
80 size_t n)
81{
82 unsigned short value;
83 if (sscanf(buf, "%hu", &value) != 1 ||
84 (value != 0 && value != 1)) {
85 printk(KERN_ERR "idle_sleep_store: Invalid value\n");
86 return -EINVAL;
87 }
88 enable_dyn_sleep = value;
89 return n;
90}
91
92static struct subsys_attribute sleep_while_idle_attr = {
93 .attr = {
94 .name = __stringify(sleep_while_idle),
95 .mode = 0644,
96 },
97 .show = omap_pm_sleep_while_idle_show,
98 .store = omap_pm_sleep_while_idle_store,
99};
100
101extern struct subsystem power_subsys;
102static void (*omap_sram_idle)(void) = NULL;
103static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL;
104
105/*
106 * Let's power down on idle, but only if we are really
107 * idle, because once we start down the path of
108 * going idle we continue to do idle even if we get
109 * a clock tick interrupt . .
110 */
111void omap_pm_idle(void)
112{
113 extern __u32 arm_idlect1_mask;
114 __u32 use_idlect1 = arm_idlect1_mask;
115#ifndef CONFIG_OMAP_MPU_TIMER
116 int do_sleep;
117#endif
118
119 local_irq_disable();
120 local_fiq_disable();
121 if (need_resched()) {
122 local_fiq_enable();
123 local_irq_enable();
124 return;
125 }
126
127 /*
128 * Since an interrupt may set up a timer, we don't want to
129 * reprogram the hardware timer with interrupts enabled.
130 * Re-enable interrupts only after returning from idle.
131 */
132 timer_dyn_reprogram();
133
134#ifdef CONFIG_OMAP_MPU_TIMER
135#warning Enable 32kHz OS timer in order to allow sleep states in idle
136 use_idlect1 = use_idlect1 & ~(1 << 9);
137#else
138
139 do_sleep = 0;
140 while (enable_dyn_sleep) {
141
142#ifdef CONFIG_CBUS_TAHVO_USB
143 extern int vbus_active;
144 /* Clock requirements? */
145 if (vbus_active)
146 break;
147#endif
148 do_sleep = 1;
149 break;
150 }
151
152#ifdef CONFIG_OMAP_DM_TIMER
153 use_idlect1 = omap_dm_timer_modify_idlect_mask(use_idlect1);
154#endif
155
156 if (omap_dma_running()) {
157 use_idlect1 &= ~(1 << 6);
158 if (omap_lcd_dma_ext_running())
159 use_idlect1 &= ~(1 << 12);
160 }
161
162 /* We should be able to remove the do_sleep variable and multiple
163 * tests above as soon as drivers, timer and DMA code have been fixed.
164 * Even the sleep block count should become obsolete. */
165 if ((use_idlect1 != ~0) || !do_sleep) {
166
167 __u32 saved_idlect1 = omap_readl(ARM_IDLECT1);
168 if (cpu_is_omap15xx())
169 use_idlect1 &= OMAP1510_BIG_SLEEP_REQUEST;
170 else
171 use_idlect1 &= OMAP1610_IDLECT1_SLEEP_VAL;
172 omap_writel(use_idlect1, ARM_IDLECT1);
173 __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4");
174 omap_writel(saved_idlect1, ARM_IDLECT1);
175
176 local_fiq_enable();
177 local_irq_enable();
178 return;
179 }
180 omap_sram_suspend(omap_readl(ARM_IDLECT1),
181 omap_readl(ARM_IDLECT2));
182#endif
183
184 local_fiq_enable();
185 local_irq_enable();
186}
187
188/*
189 * Configuration of the wakeup event is board specific. For the
190 * moment we put it into this helper function. Later it may move
191 * to board specific files.
192 */
193static void omap_pm_wakeup_setup(void)
194{
195 u32 level1_wake = 0;
196 u32 level2_wake = OMAP_IRQ_BIT(INT_UART2);
197
198 /*
199 * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade,
200 * and the L2 wakeup interrupts: keypad and UART2. Note that the
201 * drivers must still separately call omap_set_gpio_wakeup() to
202 * wake up to a GPIO interrupt.
203 */
204 if (cpu_is_omap730())
205 level1_wake = OMAP_IRQ_BIT(INT_730_GPIO_BANK1) |
206 OMAP_IRQ_BIT(INT_730_IH2_IRQ);
207 else if (cpu_is_omap15xx())
208 level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
209 OMAP_IRQ_BIT(INT_1510_IH2_IRQ);
210 else if (cpu_is_omap16xx())
211 level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
212 OMAP_IRQ_BIT(INT_1610_IH2_IRQ);
213
214 omap_writel(~level1_wake, OMAP_IH1_MIR);
215
216 if (cpu_is_omap730()) {
217 omap_writel(~level2_wake, OMAP_IH2_0_MIR);
218 omap_writel(~(OMAP_IRQ_BIT(INT_730_WAKE_UP_REQ) |
219 OMAP_IRQ_BIT(INT_730_MPUIO_KEYPAD)),
220 OMAP_IH2_1_MIR);
221 } else if (cpu_is_omap15xx()) {
222 level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
223 omap_writel(~level2_wake, OMAP_IH2_MIR);
224 } else if (cpu_is_omap16xx()) {
225 level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
226 omap_writel(~level2_wake, OMAP_IH2_0_MIR);
227
228 /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */
229 omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ),
230 OMAP_IH2_1_MIR);
231 omap_writel(~0x0, OMAP_IH2_2_MIR);
232 omap_writel(~0x0, OMAP_IH2_3_MIR);
233 }
234
235 /* New IRQ agreement, recalculate in cascade order */
236 omap_writel(1, OMAP_IH2_CONTROL);
237 omap_writel(1, OMAP_IH1_CONTROL);
238}
239
240#define EN_DSPCK 13 /* ARM_CKCTL */
241#define EN_APICK 6 /* ARM_IDLECT2 */
242#define DSP_EN 1 /* ARM_RSTCT1 */
243
244void omap_pm_suspend(void)
245{
246 unsigned long arg0 = 0, arg1 = 0;
247
248 printk("PM: OMAP%x is trying to enter deep sleep...\n", system_rev);
249
250 omap_serial_wake_trigger(1);
251
252 if (machine_is_omap_osk()) {
253 /* Stop LED1 (D9) blink */
254 tps65010_set_led(LED1, OFF);
255 }
256
257 omap_writew(0xffff, ULPD_SOFT_DISABLE_REQ_REG);
258
259 /*
260 * Step 1: turn off interrupts (FIXME: NOTE: already disabled)
261 */
262
263 local_irq_disable();
264 local_fiq_disable();
265
266 /*
267 * Step 2: save registers
268 *
269 * The omap is a strange/beautiful device. The caches, memory
270 * and register state are preserved across power saves.
271 * We have to save and restore very little register state to
272 * idle the omap.
273 *
274 * Save interrupt, MPUI, ARM and UPLD control registers.
275 */
276
277 if (cpu_is_omap730()) {
278 MPUI730_SAVE(OMAP_IH1_MIR);
279 MPUI730_SAVE(OMAP_IH2_0_MIR);
280 MPUI730_SAVE(OMAP_IH2_1_MIR);
281 MPUI730_SAVE(MPUI_CTRL);
282 MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
283 MPUI730_SAVE(MPUI_DSP_API_CONFIG);
284 MPUI730_SAVE(EMIFS_CONFIG);
285 MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
286
287 } else if (cpu_is_omap15xx()) {
288 MPUI1510_SAVE(OMAP_IH1_MIR);
289 MPUI1510_SAVE(OMAP_IH2_MIR);
290 MPUI1510_SAVE(MPUI_CTRL);
291 MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
292 MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
293 MPUI1510_SAVE(EMIFS_CONFIG);
294 MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
295 } else if (cpu_is_omap16xx()) {
296 MPUI1610_SAVE(OMAP_IH1_MIR);
297 MPUI1610_SAVE(OMAP_IH2_0_MIR);
298 MPUI1610_SAVE(OMAP_IH2_1_MIR);
299 MPUI1610_SAVE(OMAP_IH2_2_MIR);
300 MPUI1610_SAVE(OMAP_IH2_3_MIR);
301 MPUI1610_SAVE(MPUI_CTRL);
302 MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
303 MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
304 MPUI1610_SAVE(EMIFS_CONFIG);
305 MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
306 }
307
308 ARM_SAVE(ARM_CKCTL);
309 ARM_SAVE(ARM_IDLECT1);
310 ARM_SAVE(ARM_IDLECT2);
311 if (!(cpu_is_omap15xx()))
312 ARM_SAVE(ARM_IDLECT3);
313 ARM_SAVE(ARM_EWUPCT);
314 ARM_SAVE(ARM_RSTCT1);
315 ARM_SAVE(ARM_RSTCT2);
316 ARM_SAVE(ARM_SYSST);
317 ULPD_SAVE(ULPD_CLOCK_CTRL);
318 ULPD_SAVE(ULPD_STATUS_REQ);
319
320 /* (Step 3 removed - we now allow deep sleep by default) */
321
322 /*
323 * Step 4: OMAP DSP Shutdown
324 */
325
326 /* stop DSP */
327 omap_writew(omap_readw(ARM_RSTCT1) & ~(1 << DSP_EN), ARM_RSTCT1);
328
329 /* shut down dsp_ck */
330 omap_writew(omap_readw(ARM_CKCTL) & ~(1 << EN_DSPCK), ARM_CKCTL);
331
332 /* temporarily enabling api_ck to access DSP registers */
333 omap_writew(omap_readw(ARM_IDLECT2) | 1 << EN_APICK, ARM_IDLECT2);
334
335 /* save DSP registers */
336 DSP_SAVE(DSP_IDLECT2);
337
338 /* Stop all DSP domain clocks */
339 __raw_writew(0, DSP_IDLECT2);
340
341 /*
342 * Step 5: Wakeup Event Setup
343 */
344
345 omap_pm_wakeup_setup();
346
347 /*
348 * Step 6: ARM and Traffic controller shutdown
349 */
350
351 /* disable ARM watchdog */
352 omap_writel(0x00F5, OMAP_WDT_TIMER_MODE);
353 omap_writel(0x00A0, OMAP_WDT_TIMER_MODE);
354
355 /*
356 * Step 6b: ARM and Traffic controller shutdown
357 *
358 * Step 6 continues here. Prepare jump to power management
359 * assembly code in internal SRAM.
360 *
361 * Since the omap_cpu_suspend routine has been copied to
362 * SRAM, we'll do an indirect procedure call to it and pass the
363 * contents of arm_idlect1 and arm_idlect2 so it can restore
364 * them when it wakes up and it will return.
365 */
366
367 arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1];
368 arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2];
369
370 /*
371 * Step 6c: ARM and Traffic controller shutdown
372 *
373 * Jump to assembly code. The processor will stay there
374 * until wake up.
375 */
376 omap_sram_suspend(arg0, arg1);
377
378 /*
379 * If we are here, processor is woken up!
380 */
381
382 /*
383 * Restore DSP clocks
384 */
385
386 /* again temporarily enabling api_ck to access DSP registers */
387 omap_writew(omap_readw(ARM_IDLECT2) | 1 << EN_APICK, ARM_IDLECT2);
388
389 /* Restore DSP domain clocks */
390 DSP_RESTORE(DSP_IDLECT2);
391
392 /*
393 * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did
394 */
395
396 if (!(cpu_is_omap15xx()))
397 ARM_RESTORE(ARM_IDLECT3);
398 ARM_RESTORE(ARM_CKCTL);
399 ARM_RESTORE(ARM_EWUPCT);
400 ARM_RESTORE(ARM_RSTCT1);
401 ARM_RESTORE(ARM_RSTCT2);
402 ARM_RESTORE(ARM_SYSST);
403 ULPD_RESTORE(ULPD_CLOCK_CTRL);
404 ULPD_RESTORE(ULPD_STATUS_REQ);
405
406 if (cpu_is_omap730()) {
407 MPUI730_RESTORE(EMIFS_CONFIG);
408 MPUI730_RESTORE(EMIFF_SDRAM_CONFIG);
409 MPUI730_RESTORE(OMAP_IH1_MIR);
410 MPUI730_RESTORE(OMAP_IH2_0_MIR);
411 MPUI730_RESTORE(OMAP_IH2_1_MIR);
412 } else if (cpu_is_omap15xx()) {
413 MPUI1510_RESTORE(MPUI_CTRL);
414 MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG);
415 MPUI1510_RESTORE(MPUI_DSP_API_CONFIG);
416 MPUI1510_RESTORE(EMIFS_CONFIG);
417 MPUI1510_RESTORE(EMIFF_SDRAM_CONFIG);
418 MPUI1510_RESTORE(OMAP_IH1_MIR);
419 MPUI1510_RESTORE(OMAP_IH2_MIR);
420 } else if (cpu_is_omap16xx()) {
421 MPUI1610_RESTORE(MPUI_CTRL);
422 MPUI1610_RESTORE(MPUI_DSP_BOOT_CONFIG);
423 MPUI1610_RESTORE(MPUI_DSP_API_CONFIG);
424 MPUI1610_RESTORE(EMIFS_CONFIG);
425 MPUI1610_RESTORE(EMIFF_SDRAM_CONFIG);
426
427 MPUI1610_RESTORE(OMAP_IH1_MIR);
428 MPUI1610_RESTORE(OMAP_IH2_0_MIR);
429 MPUI1610_RESTORE(OMAP_IH2_1_MIR);
430 MPUI1610_RESTORE(OMAP_IH2_2_MIR);
431 MPUI1610_RESTORE(OMAP_IH2_3_MIR);
432 }
433
434 omap_writew(0, ULPD_SOFT_DISABLE_REQ_REG);
435
436 /*
437 * Reenable interrupts
438 */
439
440 local_irq_enable();
441 local_fiq_enable();
442
443 omap_serial_wake_trigger(0);
444
445 printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev);
446
447 if (machine_is_omap_osk()) {
448 /* Let LED1 (D9) blink again */
449 tps65010_set_led(LED1, BLINK);
450 }
451}
452
453#if defined(DEBUG) && defined(CONFIG_PROC_FS)
454static int g_read_completed;
455
456/*
457 * Read system PM registers for debugging
458 */
459static int omap_pm_read_proc(
460 char *page_buffer,
461 char **my_first_byte,
462 off_t virtual_start,
463 int length,
464 int *eof,
465 void *data)
466{
467 int my_buffer_offset = 0;
468 char * const my_base = page_buffer;
469
470 ARM_SAVE(ARM_CKCTL);
471 ARM_SAVE(ARM_IDLECT1);
472 ARM_SAVE(ARM_IDLECT2);
473 if (!(cpu_is_omap15xx()))
474 ARM_SAVE(ARM_IDLECT3);
475 ARM_SAVE(ARM_EWUPCT);
476 ARM_SAVE(ARM_RSTCT1);
477 ARM_SAVE(ARM_RSTCT2);
478 ARM_SAVE(ARM_SYSST);
479
480 ULPD_SAVE(ULPD_IT_STATUS);
481 ULPD_SAVE(ULPD_CLOCK_CTRL);
482 ULPD_SAVE(ULPD_SOFT_REQ);
483 ULPD_SAVE(ULPD_STATUS_REQ);
484 ULPD_SAVE(ULPD_DPLL_CTRL);
485 ULPD_SAVE(ULPD_POWER_CTRL);
486
487 if (cpu_is_omap730()) {
488 MPUI730_SAVE(MPUI_CTRL);
489 MPUI730_SAVE(MPUI_DSP_STATUS);
490 MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
491 MPUI730_SAVE(MPUI_DSP_API_CONFIG);
492 MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
493 MPUI730_SAVE(EMIFS_CONFIG);
494 } else if (cpu_is_omap15xx()) {
495 MPUI1510_SAVE(MPUI_CTRL);
496 MPUI1510_SAVE(MPUI_DSP_STATUS);
497 MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
498 MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
499 MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
500 MPUI1510_SAVE(EMIFS_CONFIG);
501 } else if (cpu_is_omap16xx()) {
502 MPUI1610_SAVE(MPUI_CTRL);
503 MPUI1610_SAVE(MPUI_DSP_STATUS);
504 MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
505 MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
506 MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
507 MPUI1610_SAVE(EMIFS_CONFIG);
508 }
509
510 if (virtual_start == 0) {
511 g_read_completed = 0;
512
513 my_buffer_offset += sprintf(my_base + my_buffer_offset,
514 "ARM_CKCTL_REG: 0x%-8x \n"
515 "ARM_IDLECT1_REG: 0x%-8x \n"
516 "ARM_IDLECT2_REG: 0x%-8x \n"
517 "ARM_IDLECT3_REG: 0x%-8x \n"
518 "ARM_EWUPCT_REG: 0x%-8x \n"
519 "ARM_RSTCT1_REG: 0x%-8x \n"
520 "ARM_RSTCT2_REG: 0x%-8x \n"
521 "ARM_SYSST_REG: 0x%-8x \n"
522 "ULPD_IT_STATUS_REG: 0x%-4x \n"
523 "ULPD_CLOCK_CTRL_REG: 0x%-4x \n"
524 "ULPD_SOFT_REQ_REG: 0x%-4x \n"
525 "ULPD_DPLL_CTRL_REG: 0x%-4x \n"
526 "ULPD_STATUS_REQ_REG: 0x%-4x \n"
527 "ULPD_POWER_CTRL_REG: 0x%-4x \n",
528 ARM_SHOW(ARM_CKCTL),
529 ARM_SHOW(ARM_IDLECT1),
530 ARM_SHOW(ARM_IDLECT2),
531 ARM_SHOW(ARM_IDLECT3),
532 ARM_SHOW(ARM_EWUPCT),
533 ARM_SHOW(ARM_RSTCT1),
534 ARM_SHOW(ARM_RSTCT2),
535 ARM_SHOW(ARM_SYSST),
536 ULPD_SHOW(ULPD_IT_STATUS),
537 ULPD_SHOW(ULPD_CLOCK_CTRL),
538 ULPD_SHOW(ULPD_SOFT_REQ),
539 ULPD_SHOW(ULPD_DPLL_CTRL),
540 ULPD_SHOW(ULPD_STATUS_REQ),
541 ULPD_SHOW(ULPD_POWER_CTRL));
542
543 if (cpu_is_omap730()) {
544 my_buffer_offset += sprintf(my_base + my_buffer_offset,
545 "MPUI730_CTRL_REG 0x%-8x \n"
546 "MPUI730_DSP_STATUS_REG: 0x%-8x \n"
547 "MPUI730_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
548 "MPUI730_DSP_API_CONFIG_REG: 0x%-8x \n"
549 "MPUI730_SDRAM_CONFIG_REG: 0x%-8x \n"
550 "MPUI730_EMIFS_CONFIG_REG: 0x%-8x \n",
551 MPUI730_SHOW(MPUI_CTRL),
552 MPUI730_SHOW(MPUI_DSP_STATUS),
553 MPUI730_SHOW(MPUI_DSP_BOOT_CONFIG),
554 MPUI730_SHOW(MPUI_DSP_API_CONFIG),
555 MPUI730_SHOW(EMIFF_SDRAM_CONFIG),
556 MPUI730_SHOW(EMIFS_CONFIG));
557 } else if (cpu_is_omap15xx()) {
558 my_buffer_offset += sprintf(my_base + my_buffer_offset,
559 "MPUI1510_CTRL_REG 0x%-8x \n"
560 "MPUI1510_DSP_STATUS_REG: 0x%-8x \n"
561 "MPUI1510_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
562 "MPUI1510_DSP_API_CONFIG_REG: 0x%-8x \n"
563 "MPUI1510_SDRAM_CONFIG_REG: 0x%-8x \n"
564 "MPUI1510_EMIFS_CONFIG_REG: 0x%-8x \n",
565 MPUI1510_SHOW(MPUI_CTRL),
566 MPUI1510_SHOW(MPUI_DSP_STATUS),
567 MPUI1510_SHOW(MPUI_DSP_BOOT_CONFIG),
568 MPUI1510_SHOW(MPUI_DSP_API_CONFIG),
569 MPUI1510_SHOW(EMIFF_SDRAM_CONFIG),
570 MPUI1510_SHOW(EMIFS_CONFIG));
571 } else if (cpu_is_omap16xx()) {
572 my_buffer_offset += sprintf(my_base + my_buffer_offset,
573 "MPUI1610_CTRL_REG 0x%-8x \n"
574 "MPUI1610_DSP_STATUS_REG: 0x%-8x \n"
575 "MPUI1610_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
576 "MPUI1610_DSP_API_CONFIG_REG: 0x%-8x \n"
577 "MPUI1610_SDRAM_CONFIG_REG: 0x%-8x \n"
578 "MPUI1610_EMIFS_CONFIG_REG: 0x%-8x \n",
579 MPUI1610_SHOW(MPUI_CTRL),
580 MPUI1610_SHOW(MPUI_DSP_STATUS),
581 MPUI1610_SHOW(MPUI_DSP_BOOT_CONFIG),
582 MPUI1610_SHOW(MPUI_DSP_API_CONFIG),
583 MPUI1610_SHOW(EMIFF_SDRAM_CONFIG),
584 MPUI1610_SHOW(EMIFS_CONFIG));
585 }
586
587 g_read_completed++;
588 } else if (g_read_completed >= 1) {
589 *eof = 1;
590 return 0;
591 }
592 g_read_completed++;
593
594 *my_first_byte = page_buffer;
595 return my_buffer_offset;
596}
597
598static void omap_pm_init_proc(void)
599{
600 struct proc_dir_entry *entry;
601
602 entry = create_proc_read_entry("driver/omap_pm",
603 S_IWUSR | S_IRUGO, NULL,
604 omap_pm_read_proc, NULL);
605}
606
607#endif /* DEBUG && CONFIG_PROC_FS */
608
609static void (*saved_idle)(void) = NULL;
610
611/*
612 * omap_pm_prepare - Do preliminary suspend work.
613 * @state: suspend state we're entering.
614 *
615 */
616static int omap_pm_prepare(suspend_state_t state)
617{
618 int error = 0;
619
620 /* We cannot sleep in idle until we have resumed */
621 saved_idle = pm_idle;
622 pm_idle = NULL;
623
624 switch (state)
625 {
626 case PM_SUSPEND_STANDBY:
627 case PM_SUSPEND_MEM:
628 break;
629
630 case PM_SUSPEND_DISK:
631 return -ENOTSUPP;
632
633 default:
634 return -EINVAL;
635 }
636
637 return error;
638}
639
640
641/*
642 * omap_pm_enter - Actually enter a sleep state.
643 * @state: State we're entering.
644 *
645 */
646
647static int omap_pm_enter(suspend_state_t state)
648{
649 switch (state)
650 {
651 case PM_SUSPEND_STANDBY:
652 case PM_SUSPEND_MEM:
653 omap_pm_suspend();
654 break;
655
656 case PM_SUSPEND_DISK:
657 return -ENOTSUPP;
658
659 default:
660 return -EINVAL;
661 }
662
663 return 0;
664}
665
666
667/**
668 * omap_pm_finish - Finish up suspend sequence.
669 * @state: State we're coming out of.
670 *
671 * This is called after we wake back up (or if entering the sleep state
672 * failed).
673 */
674
675static int omap_pm_finish(suspend_state_t state)
676{
677 pm_idle = saved_idle;
678 return 0;
679}
680
681
682static irqreturn_t omap_wakeup_interrupt(int irq, void * dev,
683 struct pt_regs * regs)
684{
685 return IRQ_HANDLED;
686}
687
688static struct irqaction omap_wakeup_irq = {
689 .name = "peripheral wakeup",
690 .flags = SA_INTERRUPT,
691 .handler = omap_wakeup_interrupt
692};
693
694
695
696static struct pm_ops omap_pm_ops ={
697 .pm_disk_mode = 0,
698 .prepare = omap_pm_prepare,
699 .enter = omap_pm_enter,
700 .finish = omap_pm_finish,
701};
702
703static int __init omap_pm_init(void)
704{
705 printk("Power Management for TI OMAP.\n");
706
707 /*
708 * We copy the assembler sleep/wakeup routines to SRAM.
709 * These routines need to be in SRAM as that's the only
710 * memory the MPU can see when it wakes up.
711 */
712 if (cpu_is_omap730()) {
713 omap_sram_idle = omap_sram_push(omap730_idle_loop_suspend,
714 omap730_idle_loop_suspend_sz);
715 omap_sram_suspend = omap_sram_push(omap730_cpu_suspend,
716 omap730_cpu_suspend_sz);
717 } else if (cpu_is_omap15xx()) {
718 omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend,
719 omap1510_idle_loop_suspend_sz);
720 omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend,
721 omap1510_cpu_suspend_sz);
722 } else if (cpu_is_omap16xx()) {
723 omap_sram_idle = omap_sram_push(omap1610_idle_loop_suspend,
724 omap1610_idle_loop_suspend_sz);
725 omap_sram_suspend = omap_sram_push(omap1610_cpu_suspend,
726 omap1610_cpu_suspend_sz);
727 }
728
729 if (omap_sram_idle == NULL || omap_sram_suspend == NULL) {
730 printk(KERN_ERR "PM not initialized: Missing SRAM support\n");
731 return -ENODEV;
732 }
733
734 pm_idle = omap_pm_idle;
735
736 if (cpu_is_omap730())
737 setup_irq(INT_730_WAKE_UP_REQ, &omap_wakeup_irq);
738 else if (cpu_is_omap16xx())
739 setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq);
740
741 /* Program new power ramp-up time
742 * (0 for most boards since we don't lower voltage when in deep sleep)
743 */
744 omap_writew(ULPD_SETUP_ANALOG_CELL_3_VAL, ULPD_SETUP_ANALOG_CELL_3);
745
746 /* Setup ULPD POWER_CTRL_REG - enter deep sleep whenever possible */
747 omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL);
748
749 /* Configure IDLECT3 */
750 if (cpu_is_omap730())
751 omap_writel(OMAP730_IDLECT3_VAL, OMAP730_IDLECT3);
752 else if (cpu_is_omap16xx())
753 omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3);
754
755 pm_set_ops(&omap_pm_ops);
756
757#if defined(DEBUG) && defined(CONFIG_PROC_FS)
758 omap_pm_init_proc();
759#endif
760
761 subsys_create_file(&power_subsys, &sleep_while_idle_attr);
762
763 if (cpu_is_omap16xx()) {
764 /* configure LOW_PWR pin */
765 omap_cfg_reg(T20_1610_LOW_PWR);
766 }
767
768 return 0;
769}
770__initcall(omap_pm_init);
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
index e924e0c6a4ce..9b4cd698bec8 100644
--- a/arch/arm/mach-omap1/serial.c
+++ b/arch/arm/mach-omap1/serial.c
@@ -30,9 +30,9 @@
30#include <asm/arch/pm.h> 30#include <asm/arch/pm.h>
31#endif 31#endif
32 32
33static struct clk * uart1_ck = NULL; 33static struct clk * uart1_ck;
34static struct clk * uart2_ck = NULL; 34static struct clk * uart2_ck;
35static struct clk * uart3_ck = NULL; 35static struct clk * uart3_ck;
36 36
37static inline unsigned int omap_serial_in(struct plat_serial8250_port *up, 37static inline unsigned int omap_serial_in(struct plat_serial8250_port *up,
38 int offset) 38 int offset)
diff --git a/arch/arm/plat-omap/sleep.S b/arch/arm/mach-omap1/sleep.S
index 4cd7d292f854..e58295e2d3b2 100644
--- a/arch/arm/plat-omap/sleep.S
+++ b/arch/arm/mach-omap1/sleep.S
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/plat-omap/sleep.S 2 * linux/arch/arm/mach-omap1/sleep.S
3 * 3 *
4 * Low-level OMAP730/1510/1610 sleep/wakeUp support 4 * Low-level OMAP730/1510/1610 sleep/wakeUp support
5 * 5 *
@@ -383,60 +383,133 @@ ENTRY(omap1610_cpu_suspend)
383 mcr p15, 0, r0, c7, c10, 4 383 mcr p15, 0, r0, c7, c10, 4
384 nop 384 nop
385 385
386 @ load base address of Traffic Controller 386 @ Load base address of Traffic Controller
387 mov r6, #TCMIF_ASM_BASE & 0xff000000 387 mov r6, #TCMIF_ASM_BASE & 0xff000000
388 orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000 388 orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000
389 orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00 389 orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00
390 390
391 @ prepare to put SDRAM into self-refresh manually 391 @ Prepare to put SDRAM into self-refresh manually
392 ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] 392 ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
393 orr r9, r7, #SELF_REFRESH_MODE & 0xff000000 393 orr r9, r7, #SELF_REFRESH_MODE & 0xff000000
394 orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff 394 orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff
395 str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] 395 str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
396 396
397 @ prepare to put EMIFS to Sleep 397 @ Prepare to put EMIFS to Sleep
398 ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] 398 ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
399 orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff 399 orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff
400 str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] 400 str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
401 401
402 @ load base address of ARM_IDLECT1 and ARM_IDLECT2 402 @ Load base address of ARM_IDLECT1 and ARM_IDLECT2
403 mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 403 mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
404 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 404 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
405 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 405 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
406 406
407 @ turn off clock domains 407 @ Turn off clock domains
408 @ do not disable PERCK (0x04) 408 @ Do not disable PERCK (0x04)
409 mov r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff 409 mov r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff
410 orr r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00 410 orr r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00
411 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] 411 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
412 412
413 @ request ARM idle 413 @ Request ARM idle
414 mov r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff 414 mov r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff
415 orr r3, r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff00 415 orr r3, r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff00
416 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] 416 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
417 417
418 @ disable instruction cache
419 mrc p15, 0, r9, c1, c0, 0
420 bic r2, r9, #0x1000
421 mcr p15, 0, r2, c1, c0, 0
422 nop
423
424/* 418/*
425 * Let's wait for the next wake up event to wake us up. r0 can't be 419 * Let's wait for the next wake up event to wake us up. r0 can't be
426 * used here because r0 holds ARM_IDLECT1 420 * used here because r0 holds ARM_IDLECT1
427 */ 421 */
428 mov r2, #0 422 mov r2, #0
429 mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt 423 mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt
424
425 @ Errata (HEL3SU467, section 1.4.4) specifies nop-instructions
426 @ according to this formula:
427 @ 2 + (4*DPLL_MULT)/DPLL_DIV/ARMDIV
428 @ Max DPLL_MULT = 18
429 @ DPLL_DIV = 1
430 @ ARMDIV = 1
431 @ => 74 nop-instructions
432 nop
433 nop
434 nop
435 nop
436 nop
437 nop
438 nop
439 nop
440 nop
441 nop @10
442 nop
443 nop
444 nop
445 nop
446 nop
447 nop
448 nop
449 nop
450 nop
451 nop @20
452 nop
453 nop
454 nop
455 nop
456 nop
457 nop
458 nop
459 nop
460 nop
461 nop @30
462 nop
463 nop
464 nop
465 nop
466 nop
467 nop
468 nop
469 nop
470 nop
471 nop @40
472 nop
473 nop
474 nop
475 nop
476 nop
477 nop
478 nop
479 nop
480 nop
481 nop @50
482 nop
483 nop
484 nop
485 nop
486 nop
487 nop
488 nop
489 nop
490 nop
491 nop @60
492 nop
493 nop
494 nop
495 nop
496 nop
497 nop
498 nop
499 nop
500 nop
501 nop @70
502 nop
503 nop
504 nop
505 nop @74
430/* 506/*
431 * omap1610_cpu_suspend()'s resume point. 507 * omap1610_cpu_suspend()'s resume point.
432 * 508 *
433 * It will just start executing here, so we'll restore stuff from the 509 * It will just start executing here, so we'll restore stuff from the
434 * stack. 510 * stack.
435 */ 511 */
436 @ re-enable Icache 512 @ Restore the ARM_IDLECT1 and ARM_IDLECT2.
437 mcr p15, 0, r9, c1, c0, 0
438
439 @ reset the ARM_IDLECT1 and ARM_IDLECT2.
440 strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] 513 strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
441 strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] 514 strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
442 515
@@ -444,7 +517,7 @@ ENTRY(omap1610_cpu_suspend)
444 str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] 517 str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
445 str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] 518 str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
446 519
447 @ restore regs and return 520 @ Restore regs and return
448 ldmfd sp!, {r0 - r12, pc} 521 ldmfd sp!, {r0 - r12, pc}
449 522
450ENTRY(omap1610_cpu_suspend_sz) 523ENTRY(omap1610_cpu_suspend_sz)
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c
index cdbf4d7620c6..a85fe6066bc4 100644
--- a/arch/arm/mach-omap1/time.c
+++ b/arch/arm/mach-omap1/time.c
@@ -51,8 +51,6 @@
51 51
52struct sys_timer omap_timer; 52struct sys_timer omap_timer;
53 53
54#ifdef CONFIG_OMAP_MPU_TIMER
55
56/* 54/*
57 * --------------------------------------------------------------------------- 55 * ---------------------------------------------------------------------------
58 * MPU timer 56 * MPU timer
@@ -222,195 +220,6 @@ unsigned long long sched_clock(void)
222 220
223 return cycles_2_ns(ticks64); 221 return cycles_2_ns(ticks64);
224} 222}
225#endif /* CONFIG_OMAP_MPU_TIMER */
226
227#ifdef CONFIG_OMAP_32K_TIMER
228
229#ifdef CONFIG_ARCH_OMAP15XX
230#error OMAP 32KHz timer does not currently work on 15XX!
231#endif
232
233/*
234 * ---------------------------------------------------------------------------
235 * 32KHz OS timer
236 *
237 * This currently works only on 16xx, as 1510 does not have the continuous
238 * 32KHz synchronous timer. The 32KHz synchronous timer is used to keep track
239 * of time in addition to the 32KHz OS timer. Using only the 32KHz OS timer
240 * on 1510 would be possible, but the timer would not be as accurate as
241 * with the 32KHz synchronized timer.
242 * ---------------------------------------------------------------------------
243 */
244#define OMAP_32K_TIMER_BASE 0xfffb9000
245#define OMAP_32K_TIMER_CR 0x08
246#define OMAP_32K_TIMER_TVR 0x00
247#define OMAP_32K_TIMER_TCR 0x04
248
249#define OMAP_32K_TICKS_PER_HZ (32768 / HZ)
250
251/*
252 * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1
253 * so with HZ = 100, TVR = 327.68.
254 */
255#define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1)
256#define TIMER_32K_SYNCHRONIZED 0xfffbc410
257
258#define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \
259 (((nr_jiffies) * (clock_rate)) / HZ)
260
261static inline void omap_32k_timer_write(int val, int reg)
262{
263 omap_writew(val, reg + OMAP_32K_TIMER_BASE);
264}
265
266static inline unsigned long omap_32k_timer_read(int reg)
267{
268 return omap_readl(reg + OMAP_32K_TIMER_BASE) & 0xffffff;
269}
270
271/*
272 * The 32KHz synchronized timer is an additional timer on 16xx.
273 * It is always running.
274 */
275static inline unsigned long omap_32k_sync_timer_read(void)
276{
277 return omap_readl(TIMER_32K_SYNCHRONIZED);
278}
279
280static inline void omap_32k_timer_start(unsigned long load_val)
281{
282 omap_32k_timer_write(load_val, OMAP_32K_TIMER_TVR);
283 omap_32k_timer_write(0x0f, OMAP_32K_TIMER_CR);
284}
285
286static inline void omap_32k_timer_stop(void)
287{
288 omap_32k_timer_write(0x0, OMAP_32K_TIMER_CR);
289}
290
291/*
292 * Rounds down to nearest usec. Note that this will overflow for larger values.
293 */
294static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k)
295{
296 return (ticks_32k * 5*5*5*5*5*5) >> 9;
297}
298
299/*
300 * Rounds down to nearest nsec.
301 */
302static inline unsigned long long
303omap_32k_ticks_to_nsecs(unsigned long ticks_32k)
304{
305 return (unsigned long long) ticks_32k * 1000 * 5*5*5*5*5*5 >> 9;
306}
307
308static unsigned long omap_32k_last_tick = 0;
309
310/*
311 * Returns elapsed usecs since last 32k timer interrupt
312 */
313static unsigned long omap_32k_timer_gettimeoffset(void)
314{
315 unsigned long now = omap_32k_sync_timer_read();
316 return omap_32k_ticks_to_usecs(now - omap_32k_last_tick);
317}
318
319/*
320 * Returns current time from boot in nsecs. It's OK for this to wrap
321 * around for now, as it's just a relative time stamp.
322 */
323unsigned long long sched_clock(void)
324{
325 return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read());
326}
327
328/*
329 * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this
330 * function is also called from other interrupts to remove latency
331 * issues with dynamic tick. In the dynamic tick case, we need to lock
332 * with irqsave.
333 */
334static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
335 struct pt_regs *regs)
336{
337 unsigned long flags;
338 unsigned long now;
339
340 write_seqlock_irqsave(&xtime_lock, flags);
341 now = omap_32k_sync_timer_read();
342
343 while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) {
344 omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ;
345 timer_tick(regs);
346 }
347
348 /* Restart timer so we don't drift off due to modulo or dynamic tick.
349 * By default we program the next timer to be continuous to avoid
350 * latencies during high system load. During dynamic tick operation the
351 * continuous timer can be overridden from pm_idle to be longer.
352 */
353 omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now);
354 write_sequnlock_irqrestore(&xtime_lock, flags);
355
356 return IRQ_HANDLED;
357}
358
359#ifdef CONFIG_NO_IDLE_HZ
360/*
361 * Programs the next timer interrupt needed. Called when dynamic tick is
362 * enabled, and to reprogram the ticks to skip from pm_idle. Note that
363 * we can keep the timer continuous, and don't need to set it to run in
364 * one-shot mode. This is because the timer will get reprogrammed again
365 * after next interrupt.
366 */
367void omap_32k_timer_reprogram(unsigned long next_tick)
368{
369 omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1);
370}
371
372static struct irqaction omap_32k_timer_irq;
373extern struct timer_update_handler timer_update;
374
375static int omap_32k_timer_enable_dyn_tick(void)
376{
377 /* No need to reprogram timer, just use the next interrupt */
378 return 0;
379}
380
381static int omap_32k_timer_disable_dyn_tick(void)
382{
383 omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
384 return 0;
385}
386
387static struct dyn_tick_timer omap_dyn_tick_timer = {
388 .enable = omap_32k_timer_enable_dyn_tick,
389 .disable = omap_32k_timer_disable_dyn_tick,
390 .reprogram = omap_32k_timer_reprogram,
391 .handler = omap_32k_timer_interrupt,
392};
393#endif /* CONFIG_NO_IDLE_HZ */
394
395static struct irqaction omap_32k_timer_irq = {
396 .name = "32KHz timer",
397 .flags = SA_INTERRUPT | SA_TIMER,
398 .handler = omap_32k_timer_interrupt,
399};
400
401static __init void omap_init_32k_timer(void)
402{
403
404#ifdef CONFIG_NO_IDLE_HZ
405 omap_timer.dyn_tick = &omap_dyn_tick_timer;
406#endif
407
408 setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
409 omap_timer.offset = omap_32k_timer_gettimeoffset;
410 omap_32k_last_tick = omap_32k_sync_timer_read();
411 omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
412}
413#endif /* CONFIG_OMAP_32K_TIMER */
414 223
415/* 224/*
416 * --------------------------------------------------------------------------- 225 * ---------------------------------------------------------------------------
@@ -419,13 +228,7 @@ static __init void omap_init_32k_timer(void)
419 */ 228 */
420static void __init omap_timer_init(void) 229static void __init omap_timer_init(void)
421{ 230{
422#if defined(CONFIG_OMAP_MPU_TIMER)
423 omap_init_mpu_timer(); 231 omap_init_mpu_timer();
424#elif defined(CONFIG_OMAP_32K_TIMER)
425 omap_init_32k_timer();
426#else
427#error No system timer selected in Kconfig!
428#endif
429} 232}
430 233
431struct sys_timer omap_timer = { 234struct sys_timer omap_timer = {
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 578880943cf2..537dd2e6d380 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -20,3 +20,6 @@ config MACH_OMAP_H4
20 bool "OMAP 2420 H4 board" 20 bool "OMAP 2420 H4 board"
21 depends on ARCH_OMAP2 && ARCH_OMAP24XX 21 depends on ARCH_OMAP2 && ARCH_OMAP24XX
22 22
23config MACH_OMAP_APOLLON
24 bool "OMAP 2420 Apollon board"
25 depends on ARCH_OMAP2 && ARCH_OMAP24XX
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 42041166435c..111eaa64258f 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -3,11 +3,15 @@
3# 3#
4 4
5# Common support 5# Common support
6obj-y := irq.o id.o io.o sram-fn.o clock.o mux.o devices.o serial.o 6obj-y := irq.o id.o io.o sram-fn.o memory.o prcm.o clock.o mux.o devices.o serial.o
7 7
8obj-$(CONFIG_OMAP_MPU_TIMER) += timer-gp.o 8obj-$(CONFIG_OMAP_MPU_TIMER) += timer-gp.o
9 9
10# Power Management
11obj-$(CONFIG_PM) += pm.o sleep.o
12
10# Specific board support 13# Specific board support
11obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o 14obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
12obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o 15obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o
16obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o
13 17
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
new file mode 100644
index 000000000000..6c6ba172cdf6
--- /dev/null
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -0,0 +1,285 @@
1/*
2 * linux/arch/arm/mach-omap/omap2/board-apollon.c
3 *
4 * Copyright (C) 2005,2006 Samsung Electronics
5 * Author: Kyungmin Park <kyungmin.park@samsung.com>
6 *
7 * Modified from mach-omap/omap2/board-h4.c
8 *
9 * Code for apollon OMAP2 board. Should work on many OMAP2 systems where
10 * the bootloader passes the board-specific data to the kernel.
11 * Do not put any board specific code to this file; create a new machine
12 * type if you need custom low-level initializations.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/platform_device.h>
22#include <linux/mtd/mtd.h>
23#include <linux/mtd/partitions.h>
24#include <linux/mtd/onenand.h>
25#include <linux/interrupt.h>
26#include <linux/delay.h>
27
28#include <asm/hardware.h>
29#include <asm/mach-types.h>
30#include <asm/mach/arch.h>
31#include <asm/mach/flash.h>
32
33#include <asm/arch/gpio.h>
34#include <asm/arch/mux.h>
35#include <asm/arch/usb.h>
36#include <asm/arch/board.h>
37#include <asm/arch/common.h>
38#include "prcm-regs.h"
39
40/* LED & Switch macros */
41#define LED0_GPIO13 13
42#define LED1_GPIO14 14
43#define LED2_GPIO15 15
44#define SW_ENTER_GPIO16 16
45#define SW_UP_GPIO17 17
46#define SW_DOWN_GPIO58 58
47
48static struct mtd_partition apollon_partitions[] = {
49 {
50 .name = "X-Loader + U-Boot",
51 .offset = 0,
52 .size = SZ_128K,
53 .mask_flags = MTD_WRITEABLE,
54 },
55 {
56 .name = "params",
57 .offset = MTDPART_OFS_APPEND,
58 .size = SZ_128K,
59 },
60 {
61 .name = "kernel",
62 .offset = MTDPART_OFS_APPEND,
63 .size = SZ_2M,
64 },
65 {
66 .name = "rootfs",
67 .offset = MTDPART_OFS_APPEND,
68 .size = SZ_16M,
69 },
70 {
71 .name = "filesystem00",
72 .offset = MTDPART_OFS_APPEND,
73 .size = SZ_32M,
74 },
75 {
76 .name = "filesystem01",
77 .offset = MTDPART_OFS_APPEND,
78 .size = MTDPART_SIZ_FULL,
79 },
80};
81
82static struct flash_platform_data apollon_flash_data = {
83 .parts = apollon_partitions,
84 .nr_parts = ARRAY_SIZE(apollon_partitions),
85};
86
87static struct resource apollon_flash_resource = {
88 .start = APOLLON_CS0_BASE,
89 .end = APOLLON_CS0_BASE + SZ_128K,
90 .flags = IORESOURCE_MEM,
91};
92
93static struct platform_device apollon_onenand_device = {
94 .name = "onenand",
95 .id = -1,
96 .dev = {
97 .platform_data = &apollon_flash_data,
98 },
99 .num_resources = ARRAY_SIZE(&apollon_flash_resource),
100 .resource = &apollon_flash_resource,
101};
102
103static struct resource apollon_smc91x_resources[] = {
104 [0] = {
105 .start = APOLLON_ETHR_START, /* Physical */
106 .end = APOLLON_ETHR_START + 0xf,
107 .flags = IORESOURCE_MEM,
108 },
109 [1] = {
110 .start = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
111 .end = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
112 .flags = IORESOURCE_IRQ,
113 },
114};
115
116static struct platform_device apollon_smc91x_device = {
117 .name = "smc91x",
118 .id = -1,
119 .num_resources = ARRAY_SIZE(apollon_smc91x_resources),
120 .resource = apollon_smc91x_resources,
121};
122
123static struct platform_device apollon_lcd_device = {
124 .name = "apollon_lcd",
125 .id = -1,
126};
127
128static struct platform_device *apollon_devices[] __initdata = {
129 &apollon_onenand_device,
130 &apollon_smc91x_device,
131 &apollon_lcd_device,
132};
133
134static inline void __init apollon_init_smc91x(void)
135{
136 /* Make sure CS1 timings are correct */
137 GPMC_CONFIG1_1 = 0x00011203;
138 GPMC_CONFIG2_1 = 0x001f1f01;
139 GPMC_CONFIG3_1 = 0x00080803;
140 GPMC_CONFIG4_1 = 0x1c091c09;
141 GPMC_CONFIG5_1 = 0x041f1f1f;
142 GPMC_CONFIG6_1 = 0x000004c4;
143 GPMC_CONFIG7_1 = 0x00000f40 | (APOLLON_CS1_BASE >> 24);
144 udelay(100);
145
146 omap_cfg_reg(W4__24XX_GPIO74);
147 if (omap_request_gpio(APOLLON_ETHR_GPIO_IRQ) < 0) {
148 printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
149 APOLLON_ETHR_GPIO_IRQ);
150 return;
151 }
152 omap_set_gpio_direction(APOLLON_ETHR_GPIO_IRQ, 1);
153}
154
155static void __init omap_apollon_init_irq(void)
156{
157 omap2_init_common_hw();
158 omap_init_irq();
159 omap_gpio_init();
160 apollon_init_smc91x();
161}
162
163static struct omap_uart_config apollon_uart_config __initdata = {
164 .enabled_uarts = (1 << 0) | (0 << 1) | (0 << 2),
165};
166
167static struct omap_mmc_config apollon_mmc_config __initdata = {
168 .mmc [0] = {
169 .enabled = 0,
170 .wire4 = 0,
171 .wp_pin = -1,
172 .power_pin = -1,
173 .switch_pin = -1,
174 },
175};
176
177static struct omap_lcd_config apollon_lcd_config __initdata = {
178 .ctrl_name = "internal",
179};
180
181static struct omap_board_config_kernel apollon_config[] = {
182 { OMAP_TAG_UART, &apollon_uart_config },
183 { OMAP_TAG_MMC, &apollon_mmc_config },
184 { OMAP_TAG_LCD, &apollon_lcd_config },
185};
186
187static void __init apollon_led_init(void)
188{
189 /* LED0 - AA10 */
190 omap_cfg_reg(AA10_242X_GPIO13);
191 omap_request_gpio(LED0_GPIO13);
192 omap_set_gpio_direction(LED0_GPIO13, 0);
193 omap_set_gpio_dataout(LED0_GPIO13, 0);
194 /* LED1 - AA6 */
195 omap_cfg_reg(AA6_242X_GPIO14);
196 omap_request_gpio(LED1_GPIO14);
197 omap_set_gpio_direction(LED1_GPIO14, 0);
198 omap_set_gpio_dataout(LED1_GPIO14, 0);
199 /* LED2 - AA4 */
200 omap_cfg_reg(AA4_242X_GPIO15);
201 omap_request_gpio(LED2_GPIO15);
202 omap_set_gpio_direction(LED2_GPIO15, 0);
203 omap_set_gpio_dataout(LED2_GPIO15, 0);
204}
205
206static irqreturn_t apollon_sw_interrupt(int irq, void *ignored, struct pt_regs *regs)
207{
208 static unsigned int led0, led1, led2;
209
210 if (irq == OMAP_GPIO_IRQ(SW_ENTER_GPIO16))
211 omap_set_gpio_dataout(LED0_GPIO13, led0 ^= 1);
212 else if (irq == OMAP_GPIO_IRQ(SW_UP_GPIO17))
213 omap_set_gpio_dataout(LED1_GPIO14, led1 ^= 1);
214 else if (irq == OMAP_GPIO_IRQ(SW_DOWN_GPIO58))
215 omap_set_gpio_dataout(LED2_GPIO15, led2 ^= 1);
216
217 return IRQ_HANDLED;
218}
219
220static void __init apollon_sw_init(void)
221{
222 /* Enter SW - Y11 */
223 omap_cfg_reg(Y11_242X_GPIO16);
224 omap_request_gpio(SW_ENTER_GPIO16);
225 omap_set_gpio_direction(SW_ENTER_GPIO16, 1);
226 /* Up SW - AA12 */
227 omap_cfg_reg(AA12_242X_GPIO17);
228 omap_request_gpio(SW_UP_GPIO17);
229 omap_set_gpio_direction(SW_UP_GPIO17, 1);
230 /* Down SW - AA8 */
231 omap_cfg_reg(AA8_242X_GPIO58);
232 omap_request_gpio(SW_DOWN_GPIO58);
233 omap_set_gpio_direction(SW_DOWN_GPIO58, 1);
234
235 set_irq_type(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), IRQT_RISING);
236 if (request_irq(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), &apollon_sw_interrupt,
237 SA_SHIRQ, "enter sw",
238 &apollon_sw_interrupt))
239 return;
240 set_irq_type(OMAP_GPIO_IRQ(SW_UP_GPIO17), IRQT_RISING);
241 if (request_irq(OMAP_GPIO_IRQ(SW_UP_GPIO17), &apollon_sw_interrupt,
242 SA_SHIRQ, "up sw",
243 &apollon_sw_interrupt))
244 return;
245 set_irq_type(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), IRQT_RISING);
246 if (request_irq(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), &apollon_sw_interrupt,
247 SA_SHIRQ, "down sw",
248 &apollon_sw_interrupt))
249 return;
250}
251
252static void __init omap_apollon_init(void)
253{
254 apollon_led_init();
255 apollon_sw_init();
256
257 /* REVISIT: where's the correct place */
258 omap_cfg_reg(W19_24XX_SYS_NIRQ);
259
260 /*
261 * Make sure the serial ports are muxed on at this point.
262 * You have to mux them off in device drivers later on
263 * if not needed.
264 */
265 platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices));
266 omap_board_config = apollon_config;
267 omap_board_config_size = ARRAY_SIZE(apollon_config);
268 omap_serial_init();
269}
270
271static void __init omap_apollon_map_io(void)
272{
273 omap2_map_common_io();
274}
275
276MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")
277 /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
278 .phys_io = 0x48000000,
279 .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
280 .boot_params = 0x80000100,
281 .map_io = omap_apollon_map_io,
282 .init_irq = omap_apollon_init_irq,
283 .init_machine = omap_apollon_init,
284 .timer = &omap_timer,
285MACHINE_END
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index a300d634d8a5..4933fce766c8 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -17,6 +17,8 @@
17#include <linux/mtd/mtd.h> 17#include <linux/mtd/mtd.h>
18#include <linux/mtd/partitions.h> 18#include <linux/mtd/partitions.h>
19#include <linux/delay.h> 19#include <linux/delay.h>
20#include <linux/workqueue.h>
21#include <linux/input.h>
20 22
21#include <asm/hardware.h> 23#include <asm/hardware.h>
22#include <asm/mach-types.h> 24#include <asm/mach-types.h>
@@ -25,15 +27,57 @@
25#include <asm/mach/flash.h> 27#include <asm/mach/flash.h>
26 28
27#include <asm/arch/gpio.h> 29#include <asm/arch/gpio.h>
30#include <asm/arch/gpioexpander.h>
28#include <asm/arch/mux.h> 31#include <asm/arch/mux.h>
29#include <asm/arch/usb.h> 32#include <asm/arch/usb.h>
33#include <asm/arch/irda.h>
30#include <asm/arch/board.h> 34#include <asm/arch/board.h>
31#include <asm/arch/common.h> 35#include <asm/arch/common.h>
32#include <asm/arch/prcm.h> 36#include <asm/arch/keypad.h>
37#include <asm/arch/menelaus.h>
38#include <asm/arch/dma.h>
39#include "prcm-regs.h"
33 40
34#include <asm/io.h> 41#include <asm/io.h>
35#include <asm/delay.h> 42#include <asm/delay.h>
36 43
44static unsigned int row_gpios[6] = { 88, 89, 124, 11, 6, 96 };
45static unsigned int col_gpios[7] = { 90, 91, 100, 36, 12, 97, 98 };
46
47static int h4_keymap[] = {
48 KEY(0, 0, KEY_LEFT),
49 KEY(0, 1, KEY_RIGHT),
50 KEY(0, 2, KEY_A),
51 KEY(0, 3, KEY_B),
52 KEY(0, 4, KEY_C),
53 KEY(1, 0, KEY_DOWN),
54 KEY(1, 1, KEY_UP),
55 KEY(1, 2, KEY_E),
56 KEY(1, 3, KEY_F),
57 KEY(1, 4, KEY_G),
58 KEY(2, 0, KEY_ENTER),
59 KEY(2, 1, KEY_I),
60 KEY(2, 2, KEY_J),
61 KEY(2, 3, KEY_K),
62 KEY(2, 4, KEY_3),
63 KEY(3, 0, KEY_M),
64 KEY(3, 1, KEY_N),
65 KEY(3, 2, KEY_O),
66 KEY(3, 3, KEY_P),
67 KEY(3, 4, KEY_Q),
68 KEY(4, 0, KEY_R),
69 KEY(4, 1, KEY_4),
70 KEY(4, 2, KEY_T),
71 KEY(4, 3, KEY_U),
72 KEY(4, 4, KEY_ENTER),
73 KEY(5, 0, KEY_V),
74 KEY(5, 1, KEY_W),
75 KEY(5, 2, KEY_L),
76 KEY(5, 3, KEY_S),
77 KEY(5, 4, KEY_ENTER),
78 0
79};
80
37static struct mtd_partition h4_partitions[] = { 81static struct mtd_partition h4_partitions[] = {
38 /* bootloader (U-Boot, etc) in first sector */ 82 /* bootloader (U-Boot, etc) in first sector */
39 { 83 {
@@ -108,9 +152,123 @@ static struct platform_device h4_smc91x_device = {
108 .resource = h4_smc91x_resources, 152 .resource = h4_smc91x_resources,
109}; 153};
110 154
155/* Select between the IrDA and aGPS module
156 */
157static int h4_select_irda(struct device *dev, int state)
158{
159 unsigned char expa;
160 int err = 0;
161
162 if ((err = read_gpio_expa(&expa, 0x21))) {
163 printk(KERN_ERR "Error reading from I/O expander\n");
164 return err;
165 }
166
167 /* 'P6' enable/disable IRDA_TX and IRDA_RX */
168 if (state & IR_SEL) { /* IrDa */
169 if ((err = write_gpio_expa(expa | 0x01, 0x21))) {
170 printk(KERN_ERR "Error writing to I/O expander\n");
171 return err;
172 }
173 } else {
174 if ((err = write_gpio_expa(expa & ~0x01, 0x21))) {
175 printk(KERN_ERR "Error writing to I/O expander\n");
176 return err;
177 }
178 }
179 return err;
180}
181
182static void set_trans_mode(void *data)
183{
184 int *mode = data;
185 unsigned char expa;
186 int err = 0;
187
188 if ((err = read_gpio_expa(&expa, 0x20)) != 0) {
189 printk(KERN_ERR "Error reading from I/O expander\n");
190 }
191
192 expa &= ~0x01;
193
194 if (!(*mode & IR_SIRMODE)) { /* MIR/FIR */
195 expa |= 0x01;
196 }
197
198 if ((err = write_gpio_expa(expa, 0x20)) != 0) {
199 printk(KERN_ERR "Error writing to I/O expander\n");
200 }
201}
202
203static int h4_transceiver_mode(struct device *dev, int mode)
204{
205 struct omap_irda_config *irda_config = dev->platform_data;
206
207 cancel_delayed_work(&irda_config->gpio_expa);
208 PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode);
209 schedule_work(&irda_config->gpio_expa);
210
211 return 0;
212}
213
214static struct omap_irda_config h4_irda_data = {
215 .transceiver_cap = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE,
216 .transceiver_mode = h4_transceiver_mode,
217 .select_irda = h4_select_irda,
218 .rx_channel = OMAP24XX_DMA_UART3_RX,
219 .tx_channel = OMAP24XX_DMA_UART3_TX,
220 .dest_start = OMAP_UART3_BASE,
221 .src_start = OMAP_UART3_BASE,
222 .tx_trigger = OMAP24XX_DMA_UART3_TX,
223 .rx_trigger = OMAP24XX_DMA_UART3_RX,
224};
225
226static struct resource h4_irda_resources[] = {
227 [0] = {
228 .start = INT_24XX_UART3_IRQ,
229 .end = INT_24XX_UART3_IRQ,
230 .flags = IORESOURCE_IRQ,
231 },
232};
233
234static struct platform_device h4_irda_device = {
235 .name = "omapirda",
236 .id = -1,
237 .dev = {
238 .platform_data = &h4_irda_data,
239 },
240 .num_resources = 1,
241 .resource = h4_irda_resources,
242};
243
244static struct omap_kp_platform_data h4_kp_data = {
245 .rows = 6,
246 .cols = 7,
247 .keymap = h4_keymap,
248 .rep = 1,
249 .row_gpios = row_gpios,
250 .col_gpios = col_gpios,
251};
252
253static struct platform_device h4_kp_device = {
254 .name = "omap-keypad",
255 .id = -1,
256 .dev = {
257 .platform_data = &h4_kp_data,
258 },
259};
260
261static struct platform_device h4_lcd_device = {
262 .name = "lcd_h4",
263 .id = -1,
264};
265
111static struct platform_device *h4_devices[] __initdata = { 266static struct platform_device *h4_devices[] __initdata = {
112 &h4_smc91x_device, 267 &h4_smc91x_device,
113 &h4_flash_device, 268 &h4_flash_device,
269 &h4_irda_device,
270 &h4_kp_device,
271 &h4_lcd_device,
114}; 272};
115 273
116static inline void __init h4_init_smc91x(void) 274static inline void __init h4_init_smc91x(void)
@@ -157,7 +315,6 @@ static struct omap_mmc_config h4_mmc_config __initdata = {
157}; 315};
158 316
159static struct omap_lcd_config h4_lcd_config __initdata = { 317static struct omap_lcd_config h4_lcd_config __initdata = {
160 .panel_name = "h4",
161 .ctrl_name = "internal", 318 .ctrl_name = "internal",
162}; 319};
163 320
@@ -174,6 +331,19 @@ static void __init omap_h4_init(void)
174 * You have to mux them off in device drivers later on 331 * You have to mux them off in device drivers later on
175 * if not needed. 332 * if not needed.
176 */ 333 */
334#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE)
335 omap_cfg_reg(K15_24XX_UART3_TX);
336 omap_cfg_reg(K14_24XX_UART3_RX);
337#endif
338
339#if defined(CONFIG_KEYBOARD_OMAP) || defined(CONFIG_KEYBOARD_OMAP_MODULE)
340 if (omap_has_menelaus()) {
341 row_gpios[5] = 0;
342 col_gpios[2] = 15;
343 col_gpios[6] = 18;
344 }
345#endif
346
177 platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices)); 347 platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
178 omap_board_config = h4_config; 348 omap_board_config = h4_config;
179 omap_board_config_size = ARRAY_SIZE(h4_config); 349 omap_board_config_size = ARRAY_SIZE(h4_config);
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 180f675c9064..72eb4bf571ac 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -28,14 +28,14 @@
28 28
29#include <asm/arch/clock.h> 29#include <asm/arch/clock.h>
30#include <asm/arch/sram.h> 30#include <asm/arch/sram.h>
31#include <asm/arch/prcm.h>
32 31
32#include "prcm-regs.h"
33#include "memory.h"
33#include "clock.h" 34#include "clock.h"
34 35
35//#define DOWN_VARIABLE_DPLL 1 /* Experimental */ 36//#define DOWN_VARIABLE_DPLL 1 /* Experimental */
36 37
37static struct prcm_config *curr_prcm_set; 38static struct prcm_config *curr_prcm_set;
38static struct memory_timings mem_timings;
39static u32 curr_perf_level = PRCM_FULL_SPEED; 39static u32 curr_perf_level = PRCM_FULL_SPEED;
40 40
41/*------------------------------------------------------------------------- 41/*-------------------------------------------------------------------------
@@ -54,11 +54,13 @@ static void omap2_sys_clk_recalc(struct clk * clk)
54 54
55static u32 omap2_get_dpll_rate(struct clk * tclk) 55static u32 omap2_get_dpll_rate(struct clk * tclk)
56{ 56{
57 int dpll_clk, dpll_mult, dpll_div, amult; 57 long long dpll_clk;
58 int dpll_mult, dpll_div, amult;
58 59
59 dpll_mult = (CM_CLKSEL1_PLL >> 12) & 0x03ff; /* 10 bits */ 60 dpll_mult = (CM_CLKSEL1_PLL >> 12) & 0x03ff; /* 10 bits */
60 dpll_div = (CM_CLKSEL1_PLL >> 8) & 0x0f; /* 4 bits */ 61 dpll_div = (CM_CLKSEL1_PLL >> 8) & 0x0f; /* 4 bits */
61 dpll_clk = (tclk->parent->rate * dpll_mult) / (dpll_div + 1); 62 dpll_clk = (long long)tclk->parent->rate * dpll_mult;
63 do_div(dpll_clk, dpll_div + 1);
62 amult = CM_CLKSEL2_PLL & 0x3; 64 amult = CM_CLKSEL2_PLL & 0x3;
63 dpll_clk *= amult; 65 dpll_clk *= amult;
64 66
@@ -385,75 +387,23 @@ static u32 omap2_dll_force_needed(void)
385 return 0; 387 return 0;
386} 388}
387 389
388static void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
389{
390 unsigned long dll_cnt;
391 u32 fast_dll = 0;
392
393 mem_timings.m_type = !((SDRC_MR_0 & 0x3) == 0x1); /* DDR = 1, SDR = 0 */
394
395 /* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others.
396 * In the case of 2422, its ok to use CS1 instead of CS0.
397 */
398
399#if 0 /* FIXME: Enable after 24xx cpu detection works */
400 ctype = get_cpu_type();
401 if (cpu_is_omap2422())
402 mem_timings.base_cs = 1;
403 else
404#endif
405 mem_timings.base_cs = 0;
406
407 if (mem_timings.m_type != M_DDR)
408 return;
409
410 /* With DDR we need to determine the low frequency DLL value */
411 if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL))
412 mem_timings.dll_mode = M_UNLOCK;
413 else
414 mem_timings.dll_mode = M_LOCK;
415
416 if (mem_timings.base_cs == 0) {
417 fast_dll = SDRC_DLLA_CTRL;
418 dll_cnt = SDRC_DLLA_STATUS & 0xff00;
419 } else {
420 fast_dll = SDRC_DLLB_CTRL;
421 dll_cnt = SDRC_DLLB_STATUS & 0xff00;
422 }
423 if (force_lock_to_unlock_mode) {
424 fast_dll &= ~0xff00;
425 fast_dll |= dll_cnt; /* Current lock mode */
426 }
427 mem_timings.fast_dll_ctrl = fast_dll;
428
429 /* No disruptions, DDR will be offline & C-ABI not followed */
430 omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl,
431 mem_timings.fast_dll_ctrl,
432 mem_timings.base_cs,
433 force_lock_to_unlock_mode);
434 mem_timings.slow_dll_ctrl &= 0xff00; /* Keep lock value */
435
436 /* Turn status into unlock ctrl */
437 mem_timings.slow_dll_ctrl |=
438 ((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2));
439
440 /* 90 degree phase for anything below 133Mhz */
441 mem_timings.slow_dll_ctrl |= (1 << 1);
442}
443
444static u32 omap2_reprogram_sdrc(u32 level, u32 force) 390static u32 omap2_reprogram_sdrc(u32 level, u32 force)
445{ 391{
392 u32 slow_dll_ctrl, fast_dll_ctrl, m_type;
446 u32 prev = curr_perf_level, flags; 393 u32 prev = curr_perf_level, flags;
447 394
448 if ((curr_perf_level == level) && !force) 395 if ((curr_perf_level == level) && !force)
449 return prev; 396 return prev;
450 397
398 m_type = omap2_memory_get_type();
399 slow_dll_ctrl = omap2_memory_get_slow_dll_ctrl();
400 fast_dll_ctrl = omap2_memory_get_fast_dll_ctrl();
401
451 if (level == PRCM_HALF_SPEED) { 402 if (level == PRCM_HALF_SPEED) {
452 local_irq_save(flags); 403 local_irq_save(flags);
453 PRCM_VOLTSETUP = 0xffff; 404 PRCM_VOLTSETUP = 0xffff;
454 omap2_sram_reprogram_sdrc(PRCM_HALF_SPEED, 405 omap2_sram_reprogram_sdrc(PRCM_HALF_SPEED,
455 mem_timings.slow_dll_ctrl, 406 slow_dll_ctrl, m_type);
456 mem_timings.m_type);
457 curr_perf_level = PRCM_HALF_SPEED; 407 curr_perf_level = PRCM_HALF_SPEED;
458 local_irq_restore(flags); 408 local_irq_restore(flags);
459 } 409 }
@@ -461,8 +411,7 @@ static u32 omap2_reprogram_sdrc(u32 level, u32 force)
461 local_irq_save(flags); 411 local_irq_save(flags);
462 PRCM_VOLTSETUP = 0xffff; 412 PRCM_VOLTSETUP = 0xffff;
463 omap2_sram_reprogram_sdrc(PRCM_FULL_SPEED, 413 omap2_sram_reprogram_sdrc(PRCM_FULL_SPEED,
464 mem_timings.fast_dll_ctrl, 414 fast_dll_ctrl, m_type);
465 mem_timings.m_type);
466 curr_perf_level = PRCM_FULL_SPEED; 415 curr_perf_level = PRCM_FULL_SPEED;
467 local_irq_restore(flags); 416 local_irq_restore(flags);
468 } 417 }
@@ -650,7 +599,7 @@ static u32 omap2_get_clksel(u32 *div_sel, u32 *field_mask,
650 case 13: /* dss2 */ 599 case 13: /* dss2 */
651 mask = 0x1; break; 600 mask = 0x1; break;
652 case 25: /* usb */ 601 case 25: /* usb */
653 mask = 0xf; break; 602 mask = 0x7; break;
654 } 603 }
655 } 604 }
656 605
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 6cab20b1d3c1..6c78d471fab7 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -33,20 +33,6 @@ static u32 omap2_clksel_get_divisor(struct clk *clk);
33#define RATE_IN_242X (1 << 0) 33#define RATE_IN_242X (1 << 0)
34#define RATE_IN_243X (1 << 1) 34#define RATE_IN_243X (1 << 1)
35 35
36/* Memory timings */
37#define M_DDR 1
38#define M_LOCK_CTRL (1 << 2)
39#define M_UNLOCK 0
40#define M_LOCK 1
41
42struct memory_timings {
43 u32 m_type; /* ddr = 1, sdr = 0 */
44 u32 dll_mode; /* use lock mode = 1, unlock mode = 0 */
45 u32 slow_dll_ctrl; /* unlock mode, dll value for slow speed */
46 u32 fast_dll_ctrl; /* unlock mode, dll value for fast speed */
47 u32 base_cs; /* base chip select to use for calculations */
48};
49
50/* Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated. 36/* Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated.
51 * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,CM_CLKSEL_DSP 37 * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,CM_CLKSEL_DSP
52 * CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL CM_CLKSEL2_PLL, CM_CLKSEL_MDM 38 * CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL CM_CLKSEL2_PLL, CM_CLKSEL_MDM
@@ -731,6 +717,16 @@ static struct clk sys_clkout2 = {
731 .recalc = &omap2_clksel_recalc, 717 .recalc = &omap2_clksel_recalc,
732}; 718};
733 719
720static struct clk emul_ck = {
721 .name = "emul_ck",
722 .parent = &func_54m_ck,
723 .flags = CLOCK_IN_OMAP242X,
724 .enable_reg = (void __iomem *)&PRCM_CLKEMUL_CTRL,
725 .enable_bit = 0,
726 .recalc = &omap2_propagate_rate,
727
728};
729
734/* 730/*
735 * MPU clock domain 731 * MPU clock domain
736 * Clocks: 732 * Clocks:
@@ -1702,7 +1698,8 @@ static struct clk hdq_fck = {
1702}; 1698};
1703 1699
1704static struct clk i2c2_ick = { 1700static struct clk i2c2_ick = {
1705 .name = "i2c2_ick", 1701 .name = "i2c_ick",
1702 .id = 2,
1706 .parent = &l4_ck, 1703 .parent = &l4_ck,
1707 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 1704 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1708 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, 1705 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
@@ -1711,7 +1708,8 @@ static struct clk i2c2_ick = {
1711}; 1708};
1712 1709
1713static struct clk i2c2_fck = { 1710static struct clk i2c2_fck = {
1714 .name = "i2c2_fck", 1711 .name = "i2c_fck",
1712 .id = 2,
1715 .parent = &func_12m_ck, 1713 .parent = &func_12m_ck,
1716 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 1714 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1717 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, 1715 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
@@ -1729,7 +1727,8 @@ static struct clk i2chs2_fck = {
1729}; 1727};
1730 1728
1731static struct clk i2c1_ick = { 1729static struct clk i2c1_ick = {
1732 .name = "i2c1_ick", 1730 .name = "i2c_ick",
1731 .id = 1,
1733 .parent = &l4_ck, 1732 .parent = &l4_ck,
1734 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 1733 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1735 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, 1734 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
@@ -1738,7 +1737,8 @@ static struct clk i2c1_ick = {
1738}; 1737};
1739 1738
1740static struct clk i2c1_fck = { 1739static struct clk i2c1_fck = {
1741 .name = "i2c1_fck", 1740 .name = "i2c_fck",
1741 .id = 1,
1742 .parent = &func_12m_ck, 1742 .parent = &func_12m_ck,
1743 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 1743 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1744 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, 1744 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
@@ -1971,6 +1971,7 @@ static struct clk *onchip_clks[] = {
1971 &wdt1_osc_ck, 1971 &wdt1_osc_ck,
1972 &sys_clkout, 1972 &sys_clkout,
1973 &sys_clkout2, 1973 &sys_clkout2,
1974 &emul_ck,
1974 /* mpu domain clocks */ 1975 /* mpu domain clocks */
1975 &mpu_ck, 1976 &mpu_ck,
1976 /* dsp domain clocks */ 1977 /* dsp domain clocks */
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 7181edb89352..def9e5370edf 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -74,6 +74,47 @@ static void omap_init_i2c(void) {}
74 74
75#endif 75#endif
76 76
77#if defined(CONFIG_OMAP_STI)
78
79#define OMAP2_STI_BASE IO_ADDRESS(0x48068000)
80#define OMAP2_STI_CHANNEL_BASE 0x54000000
81#define OMAP2_STI_IRQ 4
82
83static struct resource sti_resources[] = {
84 {
85 .start = OMAP2_STI_BASE,
86 .end = OMAP2_STI_BASE + 0x7ff,
87 .flags = IORESOURCE_MEM,
88 },
89 {
90 .start = OMAP2_STI_CHANNEL_BASE,
91 .end = OMAP2_STI_CHANNEL_BASE + SZ_64K - 1,
92 .flags = IORESOURCE_MEM,
93 },
94 {
95 .start = OMAP2_STI_IRQ,
96 .flags = IORESOURCE_IRQ,
97 }
98};
99
100static struct platform_device sti_device = {
101 .name = "sti",
102 .id = -1,
103 .dev = {
104 .release = omap_nop_release,
105 },
106 .num_resources = ARRAY_SIZE(sti_resources),
107 .resource = sti_resources,
108};
109
110static inline void omap_init_sti(void)
111{
112 platform_device_register(&sti_device);
113}
114#else
115static inline void omap_init_sti(void) {}
116#endif
117
77/*-------------------------------------------------------------------------*/ 118/*-------------------------------------------------------------------------*/
78 119
79static int __init omap2_init_devices(void) 120static int __init omap2_init_devices(void)
@@ -82,6 +123,7 @@ static int __init omap2_init_devices(void)
82 * in alphabetical order so they're easier to sort through. 123 * in alphabetical order so they're easier to sort through.
83 */ 124 */
84 omap_init_i2c(); 125 omap_init_i2c();
126 omap_init_sti();
85 127
86 return 0; 128 return 0;
87} 129}
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 8ea67bf196a5..7d5711611f2f 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -16,9 +16,13 @@
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/init.h> 17#include <linux/init.h>
18 18
19#include <asm/mach/map.h> 19#include <asm/tlb.h>
20#include <asm/io.h> 20#include <asm/io.h>
21
22#include <asm/mach/map.h>
23
21#include <asm/arch/mux.h> 24#include <asm/arch/mux.h>
25#include <asm/arch/omapfb.h>
22 26
23extern void omap_sram_init(void); 27extern void omap_sram_init(void);
24extern int omap2_clk_init(void); 28extern int omap2_clk_init(void);
@@ -43,11 +47,24 @@ static struct map_desc omap2_io_desc[] __initdata = {
43 } 47 }
44}; 48};
45 49
46void __init omap_map_common_io(void) 50void __init omap2_map_common_io(void)
47{ 51{
48 iotable_init(omap2_io_desc, ARRAY_SIZE(omap2_io_desc)); 52 iotable_init(omap2_io_desc, ARRAY_SIZE(omap2_io_desc));
53
54 /* Normally devicemaps_init() would flush caches and tlb after
55 * mdesc->map_io(), but we must also do it here because of the CPU
56 * revision check below.
57 */
58 local_flush_tlb_all();
59 flush_cache_all();
60
49 omap2_check_revision(); 61 omap2_check_revision();
50 omap_sram_init(); 62 omap_sram_init();
63 omapfb_reserve_mem();
64}
65
66void __init omap2_init_common_hw(void)
67{
51 omap2_mux_init(); 68 omap2_mux_init();
52 omap2_clk_init(); 69 omap2_clk_init();
53} 70}
diff --git a/arch/arm/mach-omap2/memory.c b/arch/arm/mach-omap2/memory.c
new file mode 100644
index 000000000000..1d925d69fc35
--- /dev/null
+++ b/arch/arm/mach-omap2/memory.c
@@ -0,0 +1,102 @@
1/*
2 * linux/arch/arm/mach-omap2/memory.c
3 *
4 * Memory timing related functions for OMAP24XX
5 *
6 * Copyright (C) 2005 Texas Instruments Inc.
7 * Richard Woodruff <r-woodruff2@ti.com>
8 *
9 * Copyright (C) 2005 Nokia Corporation
10 * Tony Lindgren <tony@atomide.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/config.h>
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/device.h>
21#include <linux/list.h>
22#include <linux/errno.h>
23#include <linux/delay.h>
24#include <linux/clk.h>
25
26#include <asm/io.h>
27
28#include <asm/arch/clock.h>
29#include <asm/arch/sram.h>
30
31#include "prcm-regs.h"
32#include "memory.h"
33
34static struct memory_timings mem_timings;
35
36u32 omap2_memory_get_slow_dll_ctrl(void)
37{
38 return mem_timings.slow_dll_ctrl;
39}
40
41u32 omap2_memory_get_fast_dll_ctrl(void)
42{
43 return mem_timings.fast_dll_ctrl;
44}
45
46u32 omap2_memory_get_type(void)
47{
48 return mem_timings.m_type;
49}
50
51void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
52{
53 unsigned long dll_cnt;
54 u32 fast_dll = 0;
55
56 mem_timings.m_type = !((SDRC_MR_0 & 0x3) == 0x1); /* DDR = 1, SDR = 0 */
57
58 /* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others.
59 * In the case of 2422, its ok to use CS1 instead of CS0.
60 */
61 if (cpu_is_omap2422())
62 mem_timings.base_cs = 1;
63 else
64 mem_timings.base_cs = 0;
65
66 if (mem_timings.m_type != M_DDR)
67 return;
68
69 /* With DDR we need to determine the low frequency DLL value */
70 if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL))
71 mem_timings.dll_mode = M_UNLOCK;
72 else
73 mem_timings.dll_mode = M_LOCK;
74
75 if (mem_timings.base_cs == 0) {
76 fast_dll = SDRC_DLLA_CTRL;
77 dll_cnt = SDRC_DLLA_STATUS & 0xff00;
78 } else {
79 fast_dll = SDRC_DLLB_CTRL;
80 dll_cnt = SDRC_DLLB_STATUS & 0xff00;
81 }
82 if (force_lock_to_unlock_mode) {
83 fast_dll &= ~0xff00;
84 fast_dll |= dll_cnt; /* Current lock mode */
85 }
86 /* set fast timings with DLL filter disabled */
87 mem_timings.fast_dll_ctrl = (fast_dll | (3 << 8));
88
89 /* No disruptions, DDR will be offline & C-ABI not followed */
90 omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl,
91 mem_timings.fast_dll_ctrl,
92 mem_timings.base_cs,
93 force_lock_to_unlock_mode);
94 mem_timings.slow_dll_ctrl &= 0xff00; /* Keep lock value */
95
96 /* Turn status into unlock ctrl */
97 mem_timings.slow_dll_ctrl |=
98 ((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2));
99
100 /* 90 degree phase for anything below 133Mhz + disable DLL filter */
101 mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8));
102}
diff --git a/arch/arm/mach-omap2/memory.h b/arch/arm/mach-omap2/memory.h
new file mode 100644
index 000000000000..d212eea83a05
--- /dev/null
+++ b/arch/arm/mach-omap2/memory.h
@@ -0,0 +1,34 @@
1/*
2 * linux/arch/arm/mach-omap2/memory.h
3 *
4 * Interface for memory timing related functions for OMAP24XX
5 *
6 * Copyright (C) 2005 Texas Instruments Inc.
7 * Richard Woodruff <r-woodruff2@ti.com>
8 *
9 * Copyright (C) 2005 Nokia Corporation
10 * Tony Lindgren <tony@atomide.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17/* Memory timings */
18#define M_DDR 1
19#define M_LOCK_CTRL (1 << 2)
20#define M_UNLOCK 0
21#define M_LOCK 1
22
23struct memory_timings {
24 u32 m_type; /* ddr = 1, sdr = 0 */
25 u32 dll_mode; /* use lock mode = 1, unlock mode = 0 */
26 u32 slow_dll_ctrl; /* unlock mode, dll value for slow speed */
27 u32 fast_dll_ctrl; /* unlock mode, dll value for fast speed */
28 u32 base_cs; /* base chip select to use for calculations */
29};
30
31extern void omap2_init_memory_params(u32 force_lock_to_unlock_mode);
32extern u32 omap2_memory_get_slow_dll_ctrl(void);
33extern u32 omap2_memory_get_fast_dll_ctrl(void);
34extern u32 omap2_memory_get_type(void);
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index ea4654815dd1..1197dc38c20a 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -50,9 +50,54 @@ MUX_CFG_24XX("H19_24XX_I2C2_SDA", 0x114, 0, 0, 0, 1)
50/* Menelaus interrupt */ 50/* Menelaus interrupt */
51MUX_CFG_24XX("W19_24XX_SYS_NIRQ", 0x12c, 0, 1, 1, 1) 51MUX_CFG_24XX("W19_24XX_SYS_NIRQ", 0x12c, 0, 1, 1, 1)
52 52
53/* 24xx clocks */
54MUX_CFG_24XX("W14_24XX_SYS_CLKOUT", 0x137, 0, 1, 1, 1)
55
56/* 24xx McBSP */
57MUX_CFG_24XX("Y15_24XX_MCBSP2_CLKX", 0x124, 1, 1, 0, 1)
58MUX_CFG_24XX("R14_24XX_MCBSP2_FSX", 0x125, 1, 1, 0, 1)
59MUX_CFG_24XX("W15_24XX_MCBSP2_DR", 0x126, 1, 1, 0, 1)
60MUX_CFG_24XX("V15_24XX_MCBSP2_DX", 0x127, 1, 1, 0, 1)
61
53/* 24xx GPIO */ 62/* 24xx GPIO */
63MUX_CFG_24XX("M21_242X_GPIO11", 0x0c9, 3, 1, 1, 1)
64MUX_CFG_24XX("AA10_242X_GPIO13", 0x0e5, 3, 0, 0, 1)
65MUX_CFG_24XX("AA6_242X_GPIO14", 0x0e6, 3, 0, 0, 1)
66MUX_CFG_24XX("AA4_242X_GPIO15", 0x0e7, 3, 0, 0, 1)
67MUX_CFG_24XX("Y11_242X_GPIO16", 0x0e8, 3, 0, 0, 1)
68MUX_CFG_24XX("AA12_242X_GPIO17", 0x0e9, 3, 0, 0, 1)
69MUX_CFG_24XX("AA8_242X_GPIO58", 0x0ea, 3, 0, 0, 1)
54MUX_CFG_24XX("Y20_24XX_GPIO60", 0x12c, 3, 0, 0, 1) 70MUX_CFG_24XX("Y20_24XX_GPIO60", 0x12c, 3, 0, 0, 1)
71MUX_CFG_24XX("W4__24XX_GPIO74", 0x0f2, 3, 0, 0, 1)
55MUX_CFG_24XX("M15_24XX_GPIO92", 0x10a, 3, 0, 0, 1) 72MUX_CFG_24XX("M15_24XX_GPIO92", 0x10a, 3, 0, 0, 1)
73MUX_CFG_24XX("V14_24XX_GPIO117", 0x128, 3, 1, 0, 1)
74
75/* TSC IRQ */
76MUX_CFG_24XX("P20_24XX_TSC_IRQ", 0x108, 0, 0, 0, 1)
77
78/* UART3 */
79MUX_CFG_24XX("K15_24XX_UART3_TX", 0x118, 0, 0, 0, 1)
80MUX_CFG_24XX("K14_24XX_UART3_RX", 0x119, 0, 0, 0, 1)
81
82/* Keypad GPIO*/
83MUX_CFG_24XX("T19_24XX_KBR0", 0x106, 3, 1, 1, 1)
84MUX_CFG_24XX("R19_24XX_KBR1", 0x107, 3, 1, 1, 1)
85MUX_CFG_24XX("V18_24XX_KBR2", 0x139, 3, 1, 1, 1)
86MUX_CFG_24XX("M21_24XX_KBR3", 0xc9, 3, 1, 1, 1)
87MUX_CFG_24XX("E5__24XX_KBR4", 0x138, 3, 1, 1, 1)
88MUX_CFG_24XX("M18_24XX_KBR5", 0x10e, 3, 1, 1, 1)
89MUX_CFG_24XX("R20_24XX_KBC0", 0x108, 3, 0, 0, 1)
90MUX_CFG_24XX("M14_24XX_KBC1", 0x109, 3, 0, 0, 1)
91MUX_CFG_24XX("H19_24XX_KBC2", 0x114, 3, 0, 0, 1)
92MUX_CFG_24XX("V17_24XX_KBC3", 0x135, 3, 0, 0, 1)
93MUX_CFG_24XX("P21_24XX_KBC4", 0xca, 3, 0, 0, 1)
94MUX_CFG_24XX("L14_24XX_KBC5", 0x10f, 3, 0, 0, 1)
95MUX_CFG_24XX("N19_24XX_KBC6", 0x110, 3, 0, 0, 1)
96
97/* 24xx Menelaus Keypad GPIO */
98MUX_CFG_24XX("B3__24XX_KBR5", 0x30, 3, 1, 1, 1)
99MUX_CFG_24XX("AA4_24XX_KBC2", 0xe7, 3, 0, 0, 1)
100MUX_CFG_24XX("B13_24XX_KBC6", 0x110, 3, 0, 0, 1)
56 101
57}; 102};
58 103
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
new file mode 100644
index 000000000000..562168fa2b16
--- /dev/null
+++ b/arch/arm/mach-omap2/pm.c
@@ -0,0 +1,149 @@
1/*
2 * linux/arch/arm/mach-omap2/pm.c
3 *
4 * OMAP2 Power Management Routines
5 *
6 * Copyright (C) 2006 Nokia Corporation
7 * Tony Lindgren <tony@atomide.com>
8 *
9 * Copyright (C) 2005 Texas Instruments, Inc.
10 * Richard Woodruff <r-woodruff2@ti.com>
11 *
12 * Based on pm.c for omap1
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18
19#include <linux/pm.h>
20#include <linux/sched.h>
21#include <linux/proc_fs.h>
22#include <linux/pm.h>
23#include <linux/interrupt.h>
24#include <linux/sysfs.h>
25#include <linux/module.h>
26
27#include <asm/io.h>
28#include <asm/irq.h>
29#include <asm/atomic.h>
30#include <asm/mach/time.h>
31#include <asm/mach/irq.h>
32#include <asm/mach-types.h>
33
34#include <asm/arch/irqs.h>
35#include <asm/arch/clock.h>
36#include <asm/arch/sram.h>
37#include <asm/arch/pm.h>
38
39static struct clk *vclk;
40static void (*omap2_sram_idle)(void);
41static void (*omap2_sram_suspend)(int dllctrl, int cpu_rev);
42static void (*saved_idle)(void);
43
44void omap2_pm_idle(void)
45{
46 local_irq_disable();
47 local_fiq_disable();
48 if (need_resched()) {
49 local_fiq_enable();
50 local_irq_enable();
51 return;
52 }
53
54 /*
55 * Since an interrupt may set up a timer, we don't want to
56 * reprogram the hardware timer with interrupts enabled.
57 * Re-enable interrupts only after returning from idle.
58 */
59 timer_dyn_reprogram();
60
61 omap2_sram_idle();
62 local_fiq_enable();
63 local_irq_enable();
64}
65
66static int omap2_pm_prepare(suspend_state_t state)
67{
68 int error = 0;
69
70 /* We cannot sleep in idle until we have resumed */
71 saved_idle = pm_idle;
72 pm_idle = NULL;
73
74 switch (state)
75 {
76 case PM_SUSPEND_STANDBY:
77 case PM_SUSPEND_MEM:
78 break;
79
80 case PM_SUSPEND_DISK:
81 return -ENOTSUPP;
82
83 default:
84 return -EINVAL;
85 }
86
87 return error;
88}
89
90static int omap2_pm_enter(suspend_state_t state)
91{
92 switch (state)
93 {
94 case PM_SUSPEND_STANDBY:
95 case PM_SUSPEND_MEM:
96 /* FIXME: Add suspend */
97 break;
98
99 case PM_SUSPEND_DISK:
100 return -ENOTSUPP;
101
102 default:
103 return -EINVAL;
104 }
105
106 return 0;
107}
108
109static int omap2_pm_finish(suspend_state_t state)
110{
111 pm_idle = saved_idle;
112 return 0;
113}
114
115static struct pm_ops omap_pm_ops = {
116 .pm_disk_mode = 0,
117 .prepare = omap2_pm_prepare,
118 .enter = omap2_pm_enter,
119 .finish = omap2_pm_finish,
120};
121
122int __init omap2_pm_init(void)
123{
124 printk("Power Management for TI OMAP.\n");
125
126 vclk = clk_get(NULL, "virt_prcm_set");
127 if (IS_ERR(vclk)) {
128 printk(KERN_ERR "Could not get PM vclk\n");
129 return -ENODEV;
130 }
131
132 /*
133 * We copy the assembler sleep/wakeup routines to SRAM.
134 * These routines need to be in SRAM as that's the only
135 * memory the MPU can see when it wakes up.
136 */
137 omap2_sram_idle = omap_sram_push(omap24xx_idle_loop_suspend,
138 omap24xx_idle_loop_suspend_sz);
139
140 omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend,
141 omap24xx_cpu_suspend_sz);
142
143 pm_set_ops(&omap_pm_ops);
144 pm_idle = omap2_pm_idle;
145
146 return 0;
147}
148
149__initcall(omap2_pm_init);
diff --git a/arch/arm/mach-omap2/prcm.h b/arch/arm/mach-omap2/prcm-regs.h
index 2eb89b936c83..22ac7be4f782 100644
--- a/arch/arm/mach-omap2/prcm.h
+++ b/arch/arm/mach-omap2/prcm-regs.h
@@ -1,5 +1,7 @@
1/* 1/*
2 * prcm.h - Access definations for use in OMAP24XX clock and power management 2 * linux/arch/arm/mach-omap2/prcm-reg.h
3 *
4 * OMAP24XX Power Reset and Clock Management (PRCM) registers
3 * 5 *
4 * Copyright (C) 2005 Texas Instruments, Inc. 6 * Copyright (C) 2005 Texas Instruments, Inc.
5 * 7 *
@@ -18,8 +20,8 @@
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 21 */
20 22
21#ifndef __ASM_ARM_ARCH_DPM_PRCM_H 23#ifndef __ARCH_ARM_MACH_OMAP2_PRCM_H
22#define __ASM_ARM_ARCH_DPM_PRCM_H 24#define __ARCH_ARM_MACH_OMAP2_PRCM_H
23 25
24/* SET_PERFORMANCE_LEVEL PARAMETERS */ 26/* SET_PERFORMANCE_LEVEL PARAMETERS */
25#define PRCM_HALF_SPEED 1 27#define PRCM_HALF_SPEED 1
@@ -159,54 +161,63 @@
159#define CM_FCLKEN_MDM PRCM_REG32(0xC00) 161#define CM_FCLKEN_MDM PRCM_REG32(0xC00)
160#define CM_ICLKEN_MDM PRCM_REG32(0xC10) 162#define CM_ICLKEN_MDM PRCM_REG32(0xC10)
161#define CM_IDLEST_MDM PRCM_REG32(0xC20) 163#define CM_IDLEST_MDM PRCM_REG32(0xC20)
164#define CM_AUTOIDLE_MDM PRCM_REG32(0xC30)
162#define CM_CLKSEL_MDM PRCM_REG32(0xC40) 165#define CM_CLKSEL_MDM PRCM_REG32(0xC40)
163 166#define CM_CLKSTCTRL_MDM PRCM_REG32(0xC48)
164/* FIXME: Move to header for 2430 */ 167#define RM_RSTCTRL_MDM PRCM_REG32(0xC50)
165#define DISP_BASE (OMAP24XX_L4_IO_BASE+0x50000) 168#define RM_RSTST_MDM PRCM_REG32(0xC58)
169#define PM_WKEN_MDM PRCM_REG32(0xCA0)
170#define PM_WKST_MDM PRCM_REG32(0xCB0)
171#define PM_WKDEP_MDM PRCM_REG32(0xCC8)
172#define PM_PWSTCTRL_MDM PRCM_REG32(0xCE0)
173#define PM_PWSTST_MDM PRCM_REG32(0xCE4)
174
175#define OMAP24XX_L4_IO_BASE 0x48000000
176
177#define DISP_BASE (OMAP24XX_L4_IO_BASE + 0x50000)
166#define DISP_REG32(offset) __REG32(DISP_BASE + (offset)) 178#define DISP_REG32(offset) __REG32(DISP_BASE + (offset))
167 179
168#define GPMC_BASE (OMAP24XX_GPMC_BASE) 180#define OMAP24XX_GPMC_BASE (L3_24XX_BASE + 0xa000)
169#define GPMC_REG32(offset) __REG32(GPMC_BASE + (offset)) 181#define GPMC_REG32(offset) __REG32(OMAP24XX_GPMC_BASE + (offset))
170 182
171#define GPT1_BASE (OMAP24XX_GPT1) 183/* FIXME: Move these to timer code */
184#define GPT1_BASE (0x48028000)
172#define GPT1_REG32(offset) __REG32(GPT1_BASE + (offset)) 185#define GPT1_REG32(offset) __REG32(GPT1_BASE + (offset))
173 186
174/* Misc sysconfig */ 187/* Misc sysconfig */
175#define DISPC_SYSCONFIG DISP_REG32(0x410) 188#define DISPC_SYSCONFIG DISP_REG32(0x410)
176#define SPI_BASE (OMAP24XX_L4_IO_BASE+0x98000) 189#define SPI_BASE (OMAP24XX_L4_IO_BASE + 0x98000)
177#define MCSPI1_SYSCONFIG __REG32(SPI_BASE + 0x10) 190#define MCSPI1_SYSCONFIG __REG32(SPI_BASE + 0x10)
178#define MCSPI2_SYSCONFIG __REG32(SPI_BASE+0x2000 + 0x10) 191#define MCSPI2_SYSCONFIG __REG32(SPI_BASE + 0x2000 + 0x10)
179 192#define MCSPI3_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0xb8010)
180//#define DSP_MMU_SYSCONFIG 0x5A000010 193
181#define CAMERA_MMU_SYSCONFIG __REG32(DISP_BASE+0x2C10) 194#define CAMERA_MMU_SYSCONFIG __REG32(DISP_BASE + 0x2C10)
182//#define IVA_MMU_SYSCONFIG 0x5D000010 195#define CAMERA_DMA_SYSCONFIG __REG32(DISP_BASE + 0x282C)
183//#define DSP_DMA_SYSCONFIG 0x00FCC02C 196#define SYSTEM_DMA_SYSCONFIG __REG32(DISP_BASE + 0x602C)
184#define CAMERA_DMA_SYSCONFIG __REG32(DISP_BASE+0x282C)
185#define SYSTEM_DMA_SYSCONFIG __REG32(DISP_BASE+0x602C)
186#define GPMC_SYSCONFIG GPMC_REG32(0x010) 197#define GPMC_SYSCONFIG GPMC_REG32(0x010)
187#define MAILBOXES_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x94010) 198#define MAILBOXES_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0x94010)
188#define UART1_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6A054) 199#define UART1_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0x6A054)
189#define UART2_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6C054) 200#define UART2_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0x6C054)
190#define UART3_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6E054) 201#define UART3_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0x6E054)
191//#define IVA_SYSCONFIG 0x5C060010 202#define SDRC_SYSCONFIG __REG32(OMAP24XX_SDRC_BASE + 0x10)
192#define SDRC_SYSCONFIG __REG32(OMAP24XX_SDRC_BASE+0x10) 203#define OMAP24XX_SMS_BASE (L3_24XX_BASE + 0x8000)
193#define SMS_SYSCONFIG __REG32(OMAP24XX_SMS_BASE+0x10) 204#define SMS_SYSCONFIG __REG32(OMAP24XX_SMS_BASE + 0x10)
194#define SSI_SYSCONFIG __REG32(DISP_BASE+0x8010) 205#define SSI_SYSCONFIG __REG32(DISP_BASE + 0x8010)
195//#define VLYNQ_SYSCONFIG 0x67FFFE10
196 206
197/* rkw - good cannidates for PM_ to start what nm was trying */ 207/* rkw - good cannidates for PM_ to start what nm was trying */
198#define OMAP24XX_GPT2 (OMAP24XX_L4_IO_BASE+0x2A000) 208#define OMAP24XX_GPT2 (OMAP24XX_L4_IO_BASE + 0x2A000)
199#define OMAP24XX_GPT3 (OMAP24XX_L4_IO_BASE+0x78000) 209#define OMAP24XX_GPT3 (OMAP24XX_L4_IO_BASE + 0x78000)
200#define OMAP24XX_GPT4 (OMAP24XX_L4_IO_BASE+0x7A000) 210#define OMAP24XX_GPT4 (OMAP24XX_L4_IO_BASE + 0x7A000)
201#define OMAP24XX_GPT5 (OMAP24XX_L4_IO_BASE+0x7C000) 211#define OMAP24XX_GPT5 (OMAP24XX_L4_IO_BASE + 0x7C000)
202#define OMAP24XX_GPT6 (OMAP24XX_L4_IO_BASE+0x7E000) 212#define OMAP24XX_GPT6 (OMAP24XX_L4_IO_BASE + 0x7E000)
203#define OMAP24XX_GPT7 (OMAP24XX_L4_IO_BASE+0x80000) 213#define OMAP24XX_GPT7 (OMAP24XX_L4_IO_BASE + 0x80000)
204#define OMAP24XX_GPT8 (OMAP24XX_L4_IO_BASE+0x82000) 214#define OMAP24XX_GPT8 (OMAP24XX_L4_IO_BASE + 0x82000)
205#define OMAP24XX_GPT9 (OMAP24XX_L4_IO_BASE+0x84000) 215#define OMAP24XX_GPT9 (OMAP24XX_L4_IO_BASE + 0x84000)
206#define OMAP24XX_GPT10 (OMAP24XX_L4_IO_BASE+0x86000) 216#define OMAP24XX_GPT10 (OMAP24XX_L4_IO_BASE + 0x86000)
207#define OMAP24XX_GPT11 (OMAP24XX_L4_IO_BASE+0x88000) 217#define OMAP24XX_GPT11 (OMAP24XX_L4_IO_BASE + 0x88000)
208#define OMAP24XX_GPT12 (OMAP24XX_L4_IO_BASE+0x8A000) 218#define OMAP24XX_GPT12 (OMAP24XX_L4_IO_BASE + 0x8A000)
209 219
220/* FIXME: Move these to timer code */
210#define GPTIMER1_SYSCONFIG GPT1_REG32(0x010) 221#define GPTIMER1_SYSCONFIG GPT1_REG32(0x010)
211#define GPTIMER2_SYSCONFIG __REG32(OMAP24XX_GPT2 + 0x10) 222#define GPTIMER2_SYSCONFIG __REG32(OMAP24XX_GPT2 + 0x10)
212#define GPTIMER3_SYSCONFIG __REG32(OMAP24XX_GPT3 + 0x10) 223#define GPTIMER3_SYSCONFIG __REG32(OMAP24XX_GPT3 + 0x10)
@@ -220,12 +231,18 @@
220#define GPTIMER11_SYSCONFIG __REG32(OMAP24XX_GPT11 + 0x10) 231#define GPTIMER11_SYSCONFIG __REG32(OMAP24XX_GPT11 + 0x10)
221#define GPTIMER12_SYSCONFIG __REG32(OMAP24XX_GPT12 + 0x10) 232#define GPTIMER12_SYSCONFIG __REG32(OMAP24XX_GPT12 + 0x10)
222 233
223#define GPIOX_BASE(X) (OMAP24XX_GPIO_BASE+(0x2000*((X)-1))) 234/* FIXME: Move these to gpio code */
235#define OMAP24XX_GPIO_BASE 0x48018000
236#define GPIOX_BASE(X) (OMAP24XX_GPIO_BASE + (0x2000 * ((X) - 1)))
237
238#define GPIO1_SYSCONFIG __REG32((GPIOX_BASE(1) + 0x10))
239#define GPIO2_SYSCONFIG __REG32((GPIOX_BASE(2) + 0x10))
240#define GPIO3_SYSCONFIG __REG32((GPIOX_BASE(3) + 0x10))
241#define GPIO4_SYSCONFIG __REG32((GPIOX_BASE(4) + 0x10))
224 242
225#define GPIO1_SYSCONFIG __REG32((GPIOX_BASE(1)+0x10)) 243#if defined(CONFIG_ARCH_OMAP243X)
226#define GPIO2_SYSCONFIG __REG32((GPIOX_BASE(2)+0x10)) 244#define GPIO5_SYSCONFIG __REG32((OMAP24XX_GPIO5_BASE + 0x10))
227#define GPIO3_SYSCONFIG __REG32((GPIOX_BASE(3)+0x10)) 245#endif
228#define GPIO4_SYSCONFIG __REG32((GPIOX_BASE(4)+0x10))
229 246
230/* GP TIMER 1 */ 247/* GP TIMER 1 */
231#define GPTIMER1_TISTAT GPT1_REG32(0x014) 248#define GPTIMER1_TISTAT GPT1_REG32(0x014)
@@ -243,15 +260,15 @@
243#define GPTIMER1_TCAR2 GPT1_REG32(0x044) 260#define GPTIMER1_TCAR2 GPT1_REG32(0x044)
244 261
245/* rkw -- base fix up please... */ 262/* rkw -- base fix up please... */
246#define GPTIMER3_TISR __REG32(OMAP24XX_L4_IO_BASE+0x78018) 263#define GPTIMER3_TISR __REG32(OMAP24XX_L4_IO_BASE + 0x78018)
247 264
248/* SDRC */ 265/* SDRC */
249#define SDRC_DLLA_CTRL __REG32(OMAP24XX_SDRC_BASE+0x060) 266#define SDRC_DLLA_CTRL __REG32(OMAP24XX_SDRC_BASE + 0x060)
250#define SDRC_DLLA_STATUS __REG32(OMAP24XX_SDRC_BASE+0x064) 267#define SDRC_DLLA_STATUS __REG32(OMAP24XX_SDRC_BASE + 0x064)
251#define SDRC_DLLB_CTRL __REG32(OMAP24XX_SDRC_BASE+0x068) 268#define SDRC_DLLB_CTRL __REG32(OMAP24XX_SDRC_BASE + 0x068)
252#define SDRC_DLLB_STATUS __REG32(OMAP24XX_SDRC_BASE+0x06C) 269#define SDRC_DLLB_STATUS __REG32(OMAP24XX_SDRC_BASE + 0x06C)
253#define SDRC_POWER __REG32(OMAP24XX_SDRC_BASE+0x070) 270#define SDRC_POWER __REG32(OMAP24XX_SDRC_BASE + 0x070)
254#define SDRC_MR_0 __REG32(OMAP24XX_SDRC_BASE+0x084) 271#define SDRC_MR_0 __REG32(OMAP24XX_SDRC_BASE + 0x084)
255 272
256/* GPIO 1 */ 273/* GPIO 1 */
257#define GPIO1_BASE GPIOX_BASE(1) 274#define GPIO1_BASE GPIOX_BASE(1)
@@ -278,6 +295,8 @@
278#define GPIO2_DATAIN GPIO2_REG32(0x038) 295#define GPIO2_DATAIN GPIO2_REG32(0x038)
279#define GPIO2_OE GPIO2_REG32(0x034) 296#define GPIO2_OE GPIO2_REG32(0x034)
280#define GPIO2_DATAOUT GPIO2_REG32(0x03C) 297#define GPIO2_DATAOUT GPIO2_REG32(0x03C)
298#define GPIO2_DEBOUNCENABLE GPIO2_REG32(0x050)
299#define GPIO2_DEBOUNCINGTIME GPIO2_REG32(0x054)
281 300
282/* GPIO 3 */ 301/* GPIO 3 */
283#define GPIO3_BASE GPIOX_BASE(3) 302#define GPIO3_BASE GPIOX_BASE(3)
@@ -294,6 +313,8 @@
294#define GPIO3_DATAOUT GPIO3_REG32(0x03C) 313#define GPIO3_DATAOUT GPIO3_REG32(0x03C)
295#define GPIO3_DEBOUNCENABLE GPIO3_REG32(0x050) 314#define GPIO3_DEBOUNCENABLE GPIO3_REG32(0x050)
296#define GPIO3_DEBOUNCINGTIME GPIO3_REG32(0x054) 315#define GPIO3_DEBOUNCINGTIME GPIO3_REG32(0x054)
316#define GPIO3_DEBOUNCENABLE GPIO3_REG32(0x050)
317#define GPIO3_DEBOUNCINGTIME GPIO3_REG32(0x054)
297 318
298/* GPIO 4 */ 319/* GPIO 4 */
299#define GPIO4_BASE GPIOX_BASE(4) 320#define GPIO4_BASE GPIOX_BASE(4)
@@ -311,10 +332,26 @@
311#define GPIO4_DEBOUNCENABLE GPIO4_REG32(0x050) 332#define GPIO4_DEBOUNCENABLE GPIO4_REG32(0x050)
312#define GPIO4_DEBOUNCINGTIME GPIO4_REG32(0x054) 333#define GPIO4_DEBOUNCINGTIME GPIO4_REG32(0x054)
313 334
335#if defined(CONFIG_ARCH_OMAP243X)
336/* GPIO 5 */
337#define GPIO5_REG32(offset) __REG32((OMAP24XX_GPIO5_BASE + (offset)))
338#define GPIO5_IRQENABLE1 GPIO5_REG32(0x01C)
339#define GPIO5_IRQSTATUS1 GPIO5_REG32(0x018)
340#define GPIO5_IRQENABLE2 GPIO5_REG32(0x02C)
341#define GPIO5_IRQSTATUS2 GPIO5_REG32(0x028)
342#define GPIO5_WAKEUPENABLE GPIO5_REG32(0x020)
343#define GPIO5_RISINGDETECT GPIO5_REG32(0x048)
344#define GPIO5_FALLINGDETECT GPIO5_REG32(0x04C)
345#define GPIO5_DATAIN GPIO5_REG32(0x038)
346#define GPIO5_OE GPIO5_REG32(0x034)
347#define GPIO5_DATAOUT GPIO5_REG32(0x03C)
348#define GPIO5_DEBOUNCENABLE GPIO5_REG32(0x050)
349#define GPIO5_DEBOUNCINGTIME GPIO5_REG32(0x054)
350#endif
314 351
315/* IO CONFIG */ 352/* IO CONFIG */
316#define CONTROL_BASE (OMAP24XX_CTRL_BASE) 353#define OMAP24XX_CTRL_BASE (L4_24XX_BASE)
317#define CONTROL_REG32(offset) __REG32(CONTROL_BASE + (offset)) 354#define CONTROL_REG32(offset) __REG32(OMAP24XX_CTRL_BASE + (offset))
318 355
319#define CONTROL_PADCONF_SPI1_NCS2 CONTROL_REG32(0x104) 356#define CONTROL_PADCONF_SPI1_NCS2 CONTROL_REG32(0x104)
320#define CONTROL_PADCONF_SYS_XTALOUT CONTROL_REG32(0x134) 357#define CONTROL_PADCONF_SYS_XTALOUT CONTROL_REG32(0x134)
@@ -322,15 +359,18 @@
322#define CONTROL_PADCONF_MCBSP1_DX CONTROL_REG32(0x10C) 359#define CONTROL_PADCONF_MCBSP1_DX CONTROL_REG32(0x10C)
323#define CONTROL_PADCONF_GPMC_NCS4 CONTROL_REG32(0x090) 360#define CONTROL_PADCONF_GPMC_NCS4 CONTROL_REG32(0x090)
324#define CONTROL_PADCONF_DSS_D5 CONTROL_REG32(0x0B8) 361#define CONTROL_PADCONF_DSS_D5 CONTROL_REG32(0x0B8)
325#define CONTROL_PADCONF_DSS_D9 CONTROL_REG32(0x0BC) 362#define CONTROL_PADCONF_DSS_D9 CONTROL_REG32(0x0BC) /* 2420 */
326#define CONTROL_PADCONF_DSS_D13 CONTROL_REG32(0x0C0) 363#define CONTROL_PADCONF_DSS_D13 CONTROL_REG32(0x0C0)
327#define CONTROL_PADCONF_DSS_VSYNC CONTROL_REG32(0x0CC) 364#define CONTROL_PADCONF_DSS_VSYNC CONTROL_REG32(0x0CC)
365#define CONTROL_PADCONF_SYS_NIRQW0 CONTROL_REG32(0x0BC) /* 2430 */
366#define CONTROL_PADCONF_SSI1_FLAG_TX CONTROL_REG32(0x108) /* 2430 */
328 367
329/* CONTROL */ 368/* CONTROL */
330#define CONTROL_DEVCONF CONTROL_REG32(0x274) 369#define CONTROL_DEVCONF CONTROL_REG32(0x274)
370#define CONTROL_DEVCONF1 CONTROL_REG32(0x2E8)
331 371
332/* INTERRUPT CONTROLLER */ 372/* INTERRUPT CONTROLLER */
333#define INTC_BASE (OMAP24XX_L4_IO_BASE+0xfe000) 373#define INTC_BASE ((L4_24XX_BASE) + 0xfe000)
334#define INTC_REG32(offset) __REG32(INTC_BASE + (offset)) 374#define INTC_REG32(offset) __REG32(INTC_BASE + (offset))
335 375
336#define INTC1_U_BASE INTC_REG32(0x000) 376#define INTC1_U_BASE INTC_REG32(0x000)
@@ -348,10 +388,12 @@
348#define INTC_ISR_CLEAR2 INTC_REG32(0x0D4) 388#define INTC_ISR_CLEAR2 INTC_REG32(0x0D4)
349#define INTC_SIR_IRQ INTC_REG32(0x040) 389#define INTC_SIR_IRQ INTC_REG32(0x040)
350#define INTC_CONTROL INTC_REG32(0x048) 390#define INTC_CONTROL INTC_REG32(0x048)
351#define INTC_ILR11 INTC_REG32(0x12C) 391#define INTC_ILR11 INTC_REG32(0x12C) /* PRCM on MPU PIC */
392#define INTC_ILR30 INTC_REG32(0x178)
393#define INTC_ILR31 INTC_REG32(0x17C)
352#define INTC_ILR32 INTC_REG32(0x180) 394#define INTC_ILR32 INTC_REG32(0x180)
353#define INTC_ILR37 INTC_REG32(0x194) 395#define INTC_ILR37 INTC_REG32(0x194) /* GPIO4 on MPU PIC */
354#define INTC_SYSCONFIG INTC_REG32(0x010) 396#define INTC_SYSCONFIG INTC_REG32(0x010) /* GPT1 on MPU PIC */
355 397
356/* RAM FIREWALL */ 398/* RAM FIREWALL */
357#define RAMFW_BASE (0x68005000) 399#define RAMFW_BASE (0x68005000)
@@ -373,6 +415,24 @@
373#define GPMC_CONFIG6_0 GPMC_REG32(0x074) 415#define GPMC_CONFIG6_0 GPMC_REG32(0x074)
374#define GPMC_CONFIG7_0 GPMC_REG32(0x078) 416#define GPMC_CONFIG7_0 GPMC_REG32(0x078)
375 417
418/* GPMC CS1 */
419#define GPMC_CONFIG1_1 GPMC_REG32(0x090)
420#define GPMC_CONFIG2_1 GPMC_REG32(0x094)
421#define GPMC_CONFIG3_1 GPMC_REG32(0x098)
422#define GPMC_CONFIG4_1 GPMC_REG32(0x09C)
423#define GPMC_CONFIG5_1 GPMC_REG32(0x0a0)
424#define GPMC_CONFIG6_1 GPMC_REG32(0x0a4)
425#define GPMC_CONFIG7_1 GPMC_REG32(0x0a8)
426
427/* GPMC CS3 */
428#define GPMC_CONFIG1_3 GPMC_REG32(0x0F0)
429#define GPMC_CONFIG2_3 GPMC_REG32(0x0F4)
430#define GPMC_CONFIG3_3 GPMC_REG32(0x0F8)
431#define GPMC_CONFIG4_3 GPMC_REG32(0x0FC)
432#define GPMC_CONFIG5_3 GPMC_REG32(0x100)
433#define GPMC_CONFIG6_3 GPMC_REG32(0x104)
434#define GPMC_CONFIG7_3 GPMC_REG32(0x108)
435
376/* DSS */ 436/* DSS */
377#define DSS_CONTROL DISP_REG32(0x040) 437#define DSS_CONTROL DISP_REG32(0x040)
378#define DISPC_CONTROL DISP_REG32(0x440) 438#define DISPC_CONTROL DISP_REG32(0x440)
@@ -405,11 +465,15 @@
405#define DISPC_DATA_CYCLE2 DISP_REG32(0x5D8) 465#define DISPC_DATA_CYCLE2 DISP_REG32(0x5D8)
406#define DISPC_DATA_CYCLE3 DISP_REG32(0x5DC) 466#define DISPC_DATA_CYCLE3 DISP_REG32(0x5DC)
407 467
408/* Wake up define for board */ 468/* HSUSB Suspend */
409#define GPIO97 (1 << 1) 469#define HSUSB_CTRL __REG8(0x480AC001)
410#define GPIO88 (1 << 24) 470#define USBOTG_POWER __REG32(0x480AC000)
471
472/* HS MMC */
473#define MMCHS1_SYSCONFIG __REG32(0x4809C010)
474#define MMCHS2_SYSCONFIG __REG32(0x480b4010)
411 475
412#endif /* __ASSEMBLER__ */ 476#endif /* __ASSEMBLER__ */
413 477
414#endif 478#endif
415 479
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c
new file mode 100644
index 000000000000..8893479dc7e0
--- /dev/null
+++ b/arch/arm/mach-omap2/prcm.c
@@ -0,0 +1,40 @@
1/*
2 * linux/arch/arm/mach-omap2/prcm.c
3 *
4 * OMAP 24xx Power Reset and Clock Management (PRCM) functions
5 *
6 * Copyright (C) 2005 Nokia Corporation
7 *
8 * Written by Tony Lindgren <tony.lindgren@nokia.com>
9 *
10 * Some pieces of code Copyright (C) 2005 Texas Instruments, Inc.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16#include <linux/config.h>
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/clk.h>
20
21#include "prcm-regs.h"
22
23u32 omap_prcm_get_reset_sources(void)
24{
25 return RM_RSTST_WKUP & 0x7f;
26}
27EXPORT_SYMBOL(omap_prcm_get_reset_sources);
28
29/* Resets clock rates and reboots the system. Only called from system.h */
30void omap_prcm_arch_reset(char mode)
31{
32 u32 rate;
33 struct clk *vclk, *sclk;
34
35 vclk = clk_get(NULL, "virt_prcm_set");
36 sclk = clk_get(NULL, "sys_ck");
37 rate = clk_get_rate(sclk);
38 clk_set_rate(vclk, rate); /* go to bypass for OMAP limitation */
39 RM_RSTCTRL_WKUP |= 2;
40}
diff --git a/arch/arm/mach-omap2/sleep.S b/arch/arm/mach-omap2/sleep.S
new file mode 100644
index 000000000000..00299cbeb911
--- /dev/null
+++ b/arch/arm/mach-omap2/sleep.S
@@ -0,0 +1,144 @@
1/*
2 * linux/arch/arm/mach-omap2/sleep.S
3 *
4 * (C) Copyright 2004
5 * Texas Instruments, <www.ti.com>
6 * Richard Woodruff <r-woodruff2@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24#include <linux/config.h>
25#include <linux/linkage.h>
26#include <asm/assembler.h>
27#include <asm/arch/io.h>
28#include <asm/arch/pm.h>
29
30#define A_32KSYNC_CR_V IO_ADDRESS(OMAP_TIMER32K_BASE+0x10)
31#define A_PRCM_VOLTCTRL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x50)
32#define A_PRCM_CLKCFG_CTRL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x80)
33#define A_CM_CLKEN_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x500)
34#define A_CM_IDLEST_CKGEN_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x520)
35#define A_CM_CLKSEL1_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x540)
36#define A_CM_CLKSEL2_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x544)
37
38#define A_SDRC_DLLA_CTRL_V IO_ADDRESS(OMAP24XX_SDRC_BASE+0x60)
39#define A_SDRC_POWER_V IO_ADDRESS(OMAP24XX_SDRC_BASE+0x70)
40#define A_SDRC_RFR_CTRL_V IO_ADDRESS(OMAP24XX_SDRC_BASE+0xA4)
41#define A_SDRC0_V (0xC0000000)
42#define A_SDRC_MANUAL_V IO_ADDRESS(OMAP24XX_SDRC_BASE+0xA8)
43
44 .text
45
46/*
47 * Forces OMAP into idle state
48 *
49 * omap24xx_idle_loop_suspend() - This bit of code just executes the WFI
50 * for normal idles.
51 *
52 * Note: This code get's copied to internal SRAM at boot. When the OMAP
53 * wakes up it continues execution at the point it went to sleep.
54 */
55ENTRY(omap24xx_idle_loop_suspend)
56 stmfd sp!, {r0, lr} @ save registers on stack
57 mov r0, #0 @ clear for mcr setup
58 mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt
59 ldmfd sp!, {r0, pc} @ restore regs and return
60
61ENTRY(omap24xx_idle_loop_suspend_sz)
62 .word . - omap24xx_idle_loop_suspend
63
64/*
65 * omap242x_cpu_suspend() - Forces OMAP into deep sleep state by completing
66 * SDRC shutdown then ARM shutdown. Upon wake MPU is back on so just restore
67 * SDRC.
68 *
69 * Input:
70 * R0 : DLL ctrl value pre-Sleep
71 * R1 : Processor+Revision
72 * 2420: 0x21 = 242xES1, 0x26 = 242xES2.2
73 * 2430: 0x31 = 2430ES1, 0x32 = 2430ES2
74 *
75 * The if the DPLL is going to AutoIdle. It seems like the DPLL may be back on
76 * when we get called, but the DLL probably isn't. We will wait a bit more in
77 * case the DPLL isn't quite there yet. The code will wait on DLL for DDR even
78 * if in unlocked mode.
79 *
80 * For less than 242x-ES2.2 upon wake from a sleep mode where the external
81 * oscillator was stopped, a timing bug exists where a non-stabilized 12MHz
82 * clock can pass into the PRCM can cause problems at DSP and IVA.
83 * To work around this the code will switch to the 32kHz source prior to sleep.
84 * Post sleep we will shift back to using the DPLL. Apparently,
85 * CM_IDLEST_CLKGEN does not reflect the full clock change so you need to wait
86 * 3x12MHz + 3x32kHz clocks for a full switch.
87 *
88 * The DLL load value is not kept in RETENTION or OFF. It needs to be restored
89 * at wake
90 */
91ENTRY(omap24xx_cpu_suspend)
92 stmfd sp!, {r0 - r12, lr} @ save registers on stack
93 mov r3, #0x0 @ clear for mrc call
94 mcr p15, 0, r3, c7, c10, 4 @ memory barrier, hope SDR/DDR finished
95 nop
96 nop
97 ldr r3, A_SDRC_POWER @ addr of sdrc power
98 ldr r4, [r3] @ value of sdrc power
99 orr r4, r4, #0x40 @ enable self refresh on idle req
100 mov r5, #0x2000 @ set delay (DPLL relock + DLL relock)
101 str r4, [r3] @ make it so
102 mov r2, #0
103 nop
104 mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt
105 nop
106loop:
107 subs r5, r5, #0x1 @ awake, wait just a bit
108 bne loop
109
110 /* The DPLL has on before we take the DDR out of self refresh */
111 bic r4, r4, #0x40 @ now clear self refresh bit.
112 str r4, [r3] @ put vlaue back.
113 ldr r4, A_SDRC0 @ make a clock happen
114 ldr r4, [r4]
115 nop @ start auto refresh only after clk ok
116 movs r0, r0 @ see if DDR or SDR
117 ldrne r1, A_SDRC_DLLA_CTRL_S @ get addr of DLL ctrl
118 strne r0, [r1] @ rewrite DLLA to force DLL reload
119 addne r1, r1, #0x8 @ move to DLLB
120 strne r0, [r1] @ rewrite DLLB to force DLL reload
121
122 mov r5, #0x1000
123loop2:
124 subs r5, r5, #0x1
125 bne loop2
126 /* resume*/
127 ldmfd sp!, {r0 - r12, pc} @ restore regs and return
128
129A_SDRC_POWER:
130 .word A_SDRC_POWER_V
131A_SDRC0:
132 .word A_SDRC0_V
133A_CM_CLKSEL2_PLL_S:
134 .word A_CM_CLKSEL2_PLL_V
135A_CM_CLKEN_PLL:
136 .word A_CM_CLKEN_PLL_V
137A_SDRC_DLLA_CTRL_S:
138 .word A_SDRC_DLLA_CTRL_V
139A_SDRC_MANUAL_S:
140 .word A_SDRC_MANUAL_V
141
142ENTRY(omap24xx_cpu_suspend_sz)
143 .word . - omap24xx_cpu_suspend
144
diff --git a/arch/arm/mach-omap2/sram-fn.S b/arch/arm/mach-omap2/sram-fn.S
index 2a869e203342..d261e4ff4d9b 100644
--- a/arch/arm/mach-omap2/sram-fn.S
+++ b/arch/arm/mach-omap2/sram-fn.S
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-omap1/sram.S 2 * linux/arch/arm/mach-omap2/sram.S
3 * 3 *
4 * Omap2 specific functions that need to be run in internal SRAM 4 * Omap2 specific functions that need to be run in internal SRAM
5 * 5 *
@@ -28,7 +28,7 @@
28#include <asm/arch/io.h> 28#include <asm/arch/io.h>
29#include <asm/hardware.h> 29#include <asm/hardware.h>
30 30
31#include <asm/arch/prcm.h> 31#include "prcm-regs.h"
32 32
33#define TIMER_32KSYNCT_CR_V IO_ADDRESS(OMAP24XX_32KSYNCT_BASE + 0x010) 33#define TIMER_32KSYNCT_CR_V IO_ADDRESS(OMAP24XX_32KSYNCT_BASE + 0x010)
34 34
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index b45560a8f6c4..a042473deedd 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -307,6 +307,10 @@ static void __init fixup_poodle(struct machine_desc *desc,
307 struct tag *tags, char **cmdline, struct meminfo *mi) 307 struct tag *tags, char **cmdline, struct meminfo *mi)
308{ 308{
309 sharpsl_save_param(); 309 sharpsl_save_param();
310 mi->nr_banks=1;
311 mi->bank[0].start = 0xa0000000;
312 mi->bank[0].node = 0;
313 mi->bank[0].size = (32*1024*1024);
310} 314}
311 315
312MACHINE_START(POODLE, "SHARP Poodle") 316MACHINE_START(POODLE, "SHARP Poodle")
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index ed07c4149d82..ce7d81000695 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -50,9 +50,15 @@ config MACH_N30
50 50
51 <http://zoo.weinigel.se/n30>. 51 <http://zoo.weinigel.se/n30>.
52 52
53config MACH_SMDK
54 bool
55 help
56 Common machine code for SMDK2410 and SMDK2440
57
53config ARCH_SMDK2410 58config ARCH_SMDK2410
54 bool "SMDK2410/A9M2410" 59 bool "SMDK2410/A9M2410"
55 select CPU_S3C2410 60 select CPU_S3C2410
61 select MACH_SMDK
56 help 62 help
57 Say Y here if you are using the SMDK2410 or the derived module A9M2410 63 Say Y here if you are using the SMDK2410 or the derived module A9M2410
58 <http://www.fsforth.de> 64 <http://www.fsforth.de>
@@ -60,6 +66,7 @@ config ARCH_SMDK2410
60config ARCH_S3C2440 66config ARCH_S3C2440
61 bool "SMDK2440" 67 bool "SMDK2440"
62 select CPU_S3C2440 68 select CPU_S3C2440
69 select MACH_SMDK
63 help 70 help
64 Say Y here if you are using the SMDK2440. 71 Say Y here if you are using the SMDK2440.
65 72
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile
index 1b3b476e5637..3e5712db6b52 100644
--- a/arch/arm/mach-s3c2410/Makefile
+++ b/arch/arm/mach-s3c2410/Makefile
@@ -48,3 +48,5 @@ obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o
48obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o 48obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o
49obj-$(CONFIG_MACH_OTOM) += mach-otom.o 49obj-$(CONFIG_MACH_OTOM) += mach-otom.o
50obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o 50obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
51
52obj-$(CONFIG_MACH_SMDK) += common-smdk.o \ No newline at end of file
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
index fec02c92f95f..b7f85e6d6b76 100644
--- a/arch/arm/mach-s3c2410/clock.c
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -249,7 +249,7 @@ static int s3c24xx_upll_enable(struct clk *clk, int enable)
249 249
250 /* if we started the UPLL, then allow to settle */ 250 /* if we started the UPLL, then allow to settle */
251 251
252 if (enable && !(orig & S3C2410_CLKSLOW_UCLK_OFF)) 252 if (enable && (orig & S3C2410_CLKSLOW_UCLK_OFF))
253 udelay(200); 253 udelay(200);
254 254
255 return 0; 255 return 0;
diff --git a/arch/arm/mach-s3c2410/common-smdk.c b/arch/arm/mach-s3c2410/common-smdk.c
new file mode 100644
index 000000000000..36b8291b5e03
--- /dev/null
+++ b/arch/arm/mach-s3c2410/common-smdk.c
@@ -0,0 +1,134 @@
1/* linux/arch/arm/mach-s3c2410/common-smdk.c
2 *
3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * Common code for SMDK2410 and SMDK2440 boards
7 *
8 * http://www.fluff.org/ben/smdk2440/
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/kernel.h>
16#include <linux/types.h>
17#include <linux/interrupt.h>
18#include <linux/list.h>
19#include <linux/timer.h>
20#include <linux/init.h>
21#include <linux/platform_device.h>
22
23#include <linux/mtd/mtd.h>
24#include <linux/mtd/nand.h>
25#include <linux/mtd/nand_ecc.h>
26#include <linux/mtd/partitions.h>
27
28#include <asm/mach/arch.h>
29#include <asm/mach/map.h>
30#include <asm/mach/irq.h>
31
32#include <asm/hardware.h>
33#include <asm/io.h>
34#include <asm/irq.h>
35
36#include <asm/arch/regs-gpio.h>
37
38#include <asm/arch/nand.h>
39
40#include "devs.h"
41#include "pm.h"
42
43/* NAND parititon from 2.4.18-swl5 */
44
45static struct mtd_partition smdk_default_nand_part[] = {
46 [0] = {
47 .name = "Boot Agent",
48 .size = SZ_16K,
49 .offset = 0,
50 },
51 [1] = {
52 .name = "S3C2410 flash parition 1",
53 .offset = 0,
54 .size = SZ_2M,
55 },
56 [2] = {
57 .name = "S3C2410 flash partition 2",
58 .offset = SZ_4M,
59 .size = SZ_4M,
60 },
61 [3] = {
62 .name = "S3C2410 flash partition 3",
63 .offset = SZ_8M,
64 .size = SZ_2M,
65 },
66 [4] = {
67 .name = "S3C2410 flash partition 4",
68 .offset = SZ_1M * 10,
69 .size = SZ_4M,
70 },
71 [5] = {
72 .name = "S3C2410 flash partition 5",
73 .offset = SZ_1M * 14,
74 .size = SZ_1M * 10,
75 },
76 [6] = {
77 .name = "S3C2410 flash partition 6",
78 .offset = SZ_1M * 24,
79 .size = SZ_1M * 24,
80 },
81 [7] = {
82 .name = "S3C2410 flash partition 7",
83 .offset = SZ_1M * 48,
84 .size = SZ_16M,
85 }
86};
87
88static struct s3c2410_nand_set smdk_nand_sets[] = {
89 [0] = {
90 .name = "NAND",
91 .nr_chips = 1,
92 .nr_partitions = ARRAY_SIZE(smdk_default_nand_part),
93 .partitions = smdk_default_nand_part,
94 },
95};
96
97/* choose a set of timings which should suit most 512Mbit
98 * chips and beyond.
99*/
100
101static struct s3c2410_platform_nand smdk_nand_info = {
102 .tacls = 20,
103 .twrph0 = 60,
104 .twrph1 = 20,
105 .nr_sets = ARRAY_SIZE(smdk_nand_sets),
106 .sets = smdk_nand_sets,
107};
108
109/* devices we initialise */
110
111static struct platform_device __initdata *smdk_devs[] = {
112 &s3c_device_nand,
113};
114
115void __init smdk_machine_init(void)
116{
117 /* Configure the LEDs (even if we have no LED support)*/
118
119 s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP);
120 s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP);
121 s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP);
122 s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_OUTP);
123
124 s3c2410_gpio_setpin(S3C2410_GPF4, 1);
125 s3c2410_gpio_setpin(S3C2410_GPF5, 1);
126 s3c2410_gpio_setpin(S3C2410_GPF6, 1);
127 s3c2410_gpio_setpin(S3C2410_GPF7, 1);
128
129 s3c_device_nand.dev.platform_data = &smdk_nand_info;
130
131 platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs));
132
133 s3c2410_pm_init();
134}
diff --git a/arch/arm/mach-s3c2410/common-smdk.h b/arch/arm/mach-s3c2410/common-smdk.h
new file mode 100644
index 000000000000..0e3a3be330a3
--- /dev/null
+++ b/arch/arm/mach-s3c2410/common-smdk.h
@@ -0,0 +1,15 @@
1/* linux/arch/arm/mach-s3c2410/common-smdk.h
2 *
3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * Common code for SMDK2410 and SMDK2440 boards
7 *
8 * http://www.fluff.org/ben/smdk2440/
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15extern void smdk_machine_init(void);
diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c
index 3e327b8e46be..cc97fbf66291 100644
--- a/arch/arm/mach-s3c2410/mach-anubis.c
+++ b/arch/arm/mach-s3c2410/mach-anubis.c
@@ -232,8 +232,8 @@ static void anubis_nand_select(struct s3c2410_nand_set *set, int slot)
232 232
233static struct s3c2410_platform_nand anubis_nand_info = { 233static struct s3c2410_platform_nand anubis_nand_info = {
234 .tacls = 25, 234 .tacls = 25,
235 .twrph0 = 80, 235 .twrph0 = 55,
236 .twrph1 = 80, 236 .twrph1 = 40,
237 .nr_sets = ARRAY_SIZE(anubis_nand_sets), 237 .nr_sets = ARRAY_SIZE(anubis_nand_sets),
238 .sets = anubis_nand_sets, 238 .sets = anubis_nand_sets,
239 .select_chip = anubis_nand_select, 239 .select_chip = anubis_nand_select,
diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c
index 0260ed5ab946..306afc1d7cd3 100644
--- a/arch/arm/mach-s3c2410/mach-rx3715.c
+++ b/arch/arm/mach-s3c2410/mach-rx3715.c
@@ -32,6 +32,11 @@
32#include <linux/serial_core.h> 32#include <linux/serial_core.h>
33#include <linux/serial.h> 33#include <linux/serial.h>
34 34
35#include <linux/mtd/mtd.h>
36#include <linux/mtd/nand.h>
37#include <linux/mtd/nand_ecc.h>
38#include <linux/mtd/partitions.h>
39
35#include <asm/mach/arch.h> 40#include <asm/mach/arch.h>
36#include <asm/mach/map.h> 41#include <asm/mach/map.h>
37#include <asm/mach/irq.h> 42#include <asm/mach/irq.h>
@@ -46,6 +51,7 @@
46#include <asm/arch/regs-gpio.h> 51#include <asm/arch/regs-gpio.h>
47#include <asm/arch/regs-lcd.h> 52#include <asm/arch/regs-lcd.h>
48 53
54#include <asm/arch/nand.h>
49#include <asm/arch/fb.h> 55#include <asm/arch/fb.h>
50 56
51#include "clock.h" 57#include "clock.h"
@@ -170,12 +176,39 @@ static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = {
170 }, 176 },
171}; 177};
172 178
179static struct mtd_partition rx3715_nand_part[] = {
180 [0] = {
181 .name = "Whole Flash",
182 .offset = 0,
183 .size = MTDPART_SIZ_FULL,
184 .mask_flags = MTD_WRITEABLE,
185 }
186};
187
188static struct s3c2410_nand_set rx3715_nand_sets[] = {
189 [0] = {
190 .name = "Internal",
191 .nr_chips = 1,
192 .nr_partitions = ARRAY_SIZE(rx3715_nand_part),
193 .partitions = rx3715_nand_part,
194 },
195};
196
197static struct s3c2410_platform_nand rx3715_nand_info = {
198 .tacls = 25,
199 .twrph0 = 50,
200 .twrph1 = 15,
201 .nr_sets = ARRAY_SIZE(rx3715_nand_sets),
202 .sets = rx3715_nand_sets,
203};
204
173static struct platform_device *rx3715_devices[] __initdata = { 205static struct platform_device *rx3715_devices[] __initdata = {
174 &s3c_device_usb, 206 &s3c_device_usb,
175 &s3c_device_lcd, 207 &s3c_device_lcd,
176 &s3c_device_wdt, 208 &s3c_device_wdt,
177 &s3c_device_i2c, 209 &s3c_device_i2c,
178 &s3c_device_iis, 210 &s3c_device_iis,
211 &s3c_device_nand,
179}; 212};
180 213
181static struct s3c24xx_board rx3715_board __initdata = { 214static struct s3c24xx_board rx3715_board __initdata = {
@@ -185,6 +218,8 @@ static struct s3c24xx_board rx3715_board __initdata = {
185 218
186static void __init rx3715_map_io(void) 219static void __init rx3715_map_io(void)
187{ 220{
221 s3c_device_nand.dev.platform_data = &rx3715_nand_info;
222
188 s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc)); 223 s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
189 s3c24xx_init_clocks(16934000); 224 s3c24xx_init_clocks(16934000);
190 s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs)); 225 s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c
index 1e76e1fdfcea..2db932d72c5a 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2410.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2410.c
@@ -28,7 +28,8 @@
28 * Ben Dooks <ben@simtec.co.uk> 28 * Ben Dooks <ben@simtec.co.uk>
29 * 29 *
30 * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA 30 * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
31 * 20-Sep-2005 BJD Added static to non-exported items 31 * 20-Sep-2005 BJD Added static to non-exported items
32 * 01-Apr-2006 BJD Moved init code to common smdk
32 * 33 *
33 ***********************************************************************/ 34 ***********************************************************************/
34 35
@@ -54,6 +55,8 @@
54#include "devs.h" 55#include "devs.h"
55#include "cpu.h" 56#include "cpu.h"
56 57
58#include "common-smdk.h"
59
57static struct map_desc smdk2410_iodesc[] __initdata = { 60static struct map_desc smdk2410_iodesc[] __initdata = {
58 /* nothing here yet */ 61 /* nothing here yet */
59}; 62};
@@ -107,11 +110,6 @@ static void __init smdk2410_map_io(void)
107 s3c24xx_set_board(&smdk2410_board); 110 s3c24xx_set_board(&smdk2410_board);
108} 111}
109 112
110static void __init smdk2410_init_irq(void)
111{
112 s3c24xx_init_irq();
113}
114
115MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch 113MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
116 * to SMDK2410 */ 114 * to SMDK2410 */
117 /* Maintainer: Jonas Dietsche */ 115 /* Maintainer: Jonas Dietsche */
@@ -119,7 +117,8 @@ MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switc
119 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, 117 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
120 .boot_params = S3C2410_SDRAM_PA + 0x100, 118 .boot_params = S3C2410_SDRAM_PA + 0x100,
121 .map_io = smdk2410_map_io, 119 .map_io = smdk2410_map_io,
122 .init_irq = smdk2410_init_irq, 120 .init_irq = s3c24xx_init_irq,
121 .init_machine = smdk_machine_init,
123 .timer = &s3c24xx_timer, 122 .timer = &s3c24xx_timer,
124MACHINE_END 123MACHINE_END
125 124
diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c
index f4315721c3b8..5fffd1d51047 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2440.c
@@ -53,7 +53,8 @@
53#include "clock.h" 53#include "clock.h"
54#include "devs.h" 54#include "devs.h"
55#include "cpu.h" 55#include "cpu.h"
56#include "pm.h" 56
57#include "common-smdk.h"
57 58
58static struct map_desc smdk2440_iodesc[] __initdata = { 59static struct map_desc smdk2440_iodesc[] __initdata = {
59 /* ISA IO Space map (memory space selected by A24) */ 60 /* ISA IO Space map (memory space selected by A24) */
@@ -197,21 +198,9 @@ static void __init smdk2440_map_io(void)
197 198
198static void __init smdk2440_machine_init(void) 199static void __init smdk2440_machine_init(void)
199{ 200{
200 /* Configure the LEDs (even if we have no LED support)*/
201
202 s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP);
203 s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP);
204 s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP);
205 s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_OUTP);
206
207 s3c2410_gpio_setpin(S3C2410_GPF4, 0);
208 s3c2410_gpio_setpin(S3C2410_GPF5, 0);
209 s3c2410_gpio_setpin(S3C2410_GPF6, 0);
210 s3c2410_gpio_setpin(S3C2410_GPF7, 0);
211
212 s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg); 201 s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg);
213 202
214 s3c2410_pm_init(); 203 smdk_machine_init();
215} 204}
216 205
217MACHINE_START(S3C2440, "SMDK2440") 206MACHINE_START(S3C2440, "SMDK2440")
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 102454082474..676b5c5b75bb 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -11,7 +11,8 @@
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
12 * 12 *
13 * ChangeLog: 13 * ChangeLog:
14 * 03-06-2004 John Lenz <jelenz@wisc.edu> 14 * 2006 Pavel Machek <pavel@suse.cz>
15 * 03-06-2004 John Lenz <lenz@cs.wisc.edu>
15 * 06-04-2002 Chris Larson <kergoth@digitalnemesis.net> 16 * 06-04-2002 Chris Larson <kergoth@digitalnemesis.net>
16 * 04-16-2001 Lineo Japan,Inc. ... 17 * 04-16-2001 Lineo Japan,Inc. ...
17 */ 18 */
@@ -87,12 +88,75 @@ static struct mcp_plat_data collie_mcp_data = {
87 .sclk_rate = 11981000, 88 .sclk_rate = 11981000,
88}; 89};
89 90
91#ifdef CONFIG_SHARP_LOCOMO
92/*
93 * low-level UART features.
94 */
95static struct locomo_dev *uart_dev = NULL;
96
97static void collie_uart_set_mctrl(struct uart_port *port, u_int mctrl)
98{
99 if (!uart_dev) return;
100
101 if (mctrl & TIOCM_RTS)
102 locomo_gpio_write(uart_dev, LOCOMO_GPIO_RTS, 0);
103 else
104 locomo_gpio_write(uart_dev, LOCOMO_GPIO_RTS, 1);
105
106 if (mctrl & TIOCM_DTR)
107 locomo_gpio_write(uart_dev, LOCOMO_GPIO_DTR, 0);
108 else
109 locomo_gpio_write(uart_dev, LOCOMO_GPIO_DTR, 1);
110}
111
112static u_int collie_uart_get_mctrl(struct uart_port *port)
113{
114 int ret = TIOCM_CD;
115 unsigned int r;
116 if (!uart_dev) return ret;
117
118 r = locomo_gpio_read_output(uart_dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR);
119 if (r & LOCOMO_GPIO_CTS)
120 ret |= TIOCM_CTS;
121 if (r & LOCOMO_GPIO_DSR)
122 ret |= TIOCM_DSR;
123
124 return ret;
125}
90 126
91static struct sa1100_port_fns collie_port_fns __initdata = { 127static struct sa1100_port_fns collie_port_fns __initdata = {
92 .set_mctrl = collie_uart_set_mctrl, 128 .set_mctrl = collie_uart_set_mctrl,
93 .get_mctrl = collie_uart_get_mctrl, 129 .get_mctrl = collie_uart_get_mctrl,
94}; 130};
95 131
132static int collie_uart_probe(struct locomo_dev *dev)
133{
134 uart_dev = dev;
135 return 0;
136}
137
138static int collie_uart_remove(struct locomo_dev *dev)
139{
140 uart_dev = NULL;
141 return 0;
142}
143
144static struct locomo_driver collie_uart_driver = {
145 .drv = {
146 .name = "collie_uart",
147 },
148 .devid = LOCOMO_DEVID_UART,
149 .probe = collie_uart_probe,
150 .remove = collie_uart_remove,
151};
152
153static int __init collie_uart_init(void) {
154 return locomo_driver_register(&collie_uart_driver);
155}
156device_initcall(collie_uart_init);
157
158#endif
159
96 160
97static struct resource locomo_resources[] = { 161static struct resource locomo_resources[] = {
98 [0] = { 162 [0] = {
@@ -218,6 +282,12 @@ static void __init collie_map_io(void)
218{ 282{
219 sa1100_map_io(); 283 sa1100_map_io();
220 iotable_init(collie_io_desc, ARRAY_SIZE(collie_io_desc)); 284 iotable_init(collie_io_desc, ARRAY_SIZE(collie_io_desc));
285
286#ifdef CONFIG_SHARP_LOCOMO
287 sa1100_register_uart_fns(&collie_port_fns);
288#endif
289 sa1100_register_uart(0, 3);
290 sa1100_register_uart(1, 1);
221} 291}
222 292
223MACHINE_START(COLLIE, "Sharp-Collie") 293MACHINE_START(COLLIE, "Sharp-Collie")
diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c
index 8a1bfcd50087..50e6b6bfb2e2 100644
--- a/arch/arm/mm/consistent.c
+++ b/arch/arm/mm/consistent.c
@@ -18,6 +18,7 @@
18#include <linux/device.h> 18#include <linux/device.h>
19#include <linux/dma-mapping.h> 19#include <linux/dma-mapping.h>
20 20
21#include <asm/memory.h>
21#include <asm/cacheflush.h> 22#include <asm/cacheflush.h>
22#include <asm/tlbflush.h> 23#include <asm/tlbflush.h>
23#include <asm/sizes.h> 24#include <asm/sizes.h>
@@ -272,6 +273,17 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
272void * 273void *
273dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) 274dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
274{ 275{
276 if (arch_is_coherent()) {
277 void *virt;
278
279 virt = kmalloc(size, gfp);
280 if (!virt)
281 return NULL;
282 *handle = virt_to_dma(dev, virt);
283
284 return virt;
285 }
286
275 return __dma_alloc(dev, size, handle, gfp, 287 return __dma_alloc(dev, size, handle, gfp,
276 pgprot_noncached(pgprot_kernel)); 288 pgprot_noncached(pgprot_kernel));
277} 289}
@@ -350,6 +362,11 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr
350 362
351 WARN_ON(irqs_disabled()); 363 WARN_ON(irqs_disabled());
352 364
365 if (arch_is_coherent()) {
366 kfree(cpu_addr);
367 return;
368 }
369
353 size = PAGE_ALIGN(size); 370 size = PAGE_ALIGN(size);
354 371
355 spin_lock_irqsave(&consistent_lock, flags); 372 spin_lock_irqsave(&consistent_lock, flags);
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index 5e5d05bcad50..f14b2d0f3690 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -389,6 +389,17 @@ void __init build_mem_type_table(void)
389 kern_pgprot = user_pgprot = cp->pte; 389 kern_pgprot = user_pgprot = cp->pte;
390 390
391 /* 391 /*
392 * Enable CPU-specific coherency if supported.
393 * (Only available on XSC3 at the moment.)
394 */
395 if (arch_is_coherent()) {
396 if (cpu_is_xsc3()) {
397 mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
398 mem_types[MT_MEMORY].prot_pte |= L_PTE_COHERENT;
399 }
400 }
401
402 /*
392 * ARMv6 and above have extended page tables. 403 * ARMv6 and above have extended page tables.
393 */ 404 */
394 if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) { 405 if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) {
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index b9dfce57c272..80873b36c3f7 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -371,7 +371,7 @@ ENTRY(cpu_xsc3_switch_mm)
371ENTRY(cpu_xsc3_set_pte) 371ENTRY(cpu_xsc3_set_pte)
372 str r1, [r0], #-2048 @ linux version 372 str r1, [r0], #-2048 @ linux version
373 373
374 bic r2, r1, #0xff0 374 bic r2, r1, #0xdf0 @ Keep C, B, coherency bits
375 orr r2, r2, #PTE_TYPE_EXT @ extended page 375 orr r2, r2, #PTE_TYPE_EXT @ extended page
376 376
377 eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY 377 eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 0887bb2a2551..ec49495e651e 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -70,13 +70,13 @@ config OMAP_MPU_TIMER
70 70
71config OMAP_32K_TIMER 71config OMAP_32K_TIMER
72 bool "Use 32KHz timer" 72 bool "Use 32KHz timer"
73 depends on ARCH_OMAP16XX 73 depends on ARCH_OMAP16XX || ARCH_OMAP24XX
74 help 74 help
75 Select this option if you want to enable the OMAP 32KHz timer. 75 Select this option if you want to enable the OMAP 32KHz timer.
76 This timer saves power compared to the OMAP_MPU_TIMER, and has 76 This timer saves power compared to the OMAP_MPU_TIMER, and has
77 support for no tick during idle. The 32KHz timer provides less 77 support for no tick during idle. The 32KHz timer provides less
78 intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is 78 intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is
79 currently only available for OMAP-16xx. 79 currently only available for OMAP16XX and 24XX.
80 80
81endchoice 81endchoice
82 82
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 9ccf1943fc94..2896b4546411 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -3,16 +3,16 @@
3# 3#
4 4
5# Common support 5# Common support
6obj-y := common.o sram.o sram-fn.o clock.o devices.o dma.o mux.o gpio.o mcbsp.o usb.o 6obj-y := common.o sram.o sram-fn.o clock.o devices.o dma.o mux.o gpio.o mcbsp.o usb.o fb.o
7obj-m := 7obj-m :=
8obj-n := 8obj-n :=
9obj- := 9obj- :=
10 10
11obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o
12
11# OCPI interconnect support for 1710, 1610 and 5912 13# OCPI interconnect support for 1710, 1610 and 5912
12obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o 14obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
13 15
14# Power Management
15obj-$(CONFIG_PM) += pm.o sleep.o
16 16
17obj-$(CONFIG_CPU_FREQ) += cpu-omap.o 17obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
18obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o 18obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 3c2bfc0efdaf..06485c193ee3 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -21,6 +21,7 @@
21#include <linux/string.h> 21#include <linux/string.h>
22#include <linux/clk.h> 22#include <linux/clk.h>
23#include <linux/mutex.h> 23#include <linux/mutex.h>
24#include <linux/platform_device.h>
24 25
25#include <asm/io.h> 26#include <asm/io.h>
26#include <asm/semaphore.h> 27#include <asm/semaphore.h>
@@ -37,17 +38,37 @@ static struct clk_functions *arch_clock;
37 * Standard clock functions defined in include/linux/clk.h 38 * Standard clock functions defined in include/linux/clk.h
38 *-------------------------------------------------------------------------*/ 39 *-------------------------------------------------------------------------*/
39 40
41/*
42 * Returns a clock. Note that we first try to use device id on the bus
43 * and clock name. If this fails, we try to use clock name only.
44 */
40struct clk * clk_get(struct device *dev, const char *id) 45struct clk * clk_get(struct device *dev, const char *id)
41{ 46{
42 struct clk *p, *clk = ERR_PTR(-ENOENT); 47 struct clk *p, *clk = ERR_PTR(-ENOENT);
48 int idno;
49
50 if (dev == NULL || dev->bus != &platform_bus_type)
51 idno = -1;
52 else
53 idno = to_platform_device(dev)->id;
43 54
44 mutex_lock(&clocks_mutex); 55 mutex_lock(&clocks_mutex);
56
57 list_for_each_entry(p, &clocks, node) {
58 if (p->id == idno &&
59 strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
60 clk = p;
61 break;
62 }
63 }
64
45 list_for_each_entry(p, &clocks, node) { 65 list_for_each_entry(p, &clocks, node) {
46 if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { 66 if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
47 clk = p; 67 clk = p;
48 break; 68 break;
49 } 69 }
50 } 70 }
71
51 mutex_unlock(&clocks_mutex); 72 mutex_unlock(&clocks_mutex);
52 73
53 return clk; 74 return clk;
@@ -59,6 +80,9 @@ int clk_enable(struct clk *clk)
59 unsigned long flags; 80 unsigned long flags;
60 int ret = 0; 81 int ret = 0;
61 82
83 if (clk == NULL || IS_ERR(clk))
84 return -EINVAL;
85
62 spin_lock_irqsave(&clockfw_lock, flags); 86 spin_lock_irqsave(&clockfw_lock, flags);
63 if (arch_clock->clk_enable) 87 if (arch_clock->clk_enable)
64 ret = arch_clock->clk_enable(clk); 88 ret = arch_clock->clk_enable(clk);
@@ -72,6 +96,9 @@ void clk_disable(struct clk *clk)
72{ 96{
73 unsigned long flags; 97 unsigned long flags;
74 98
99 if (clk == NULL || IS_ERR(clk))
100 return;
101
75 spin_lock_irqsave(&clockfw_lock, flags); 102 spin_lock_irqsave(&clockfw_lock, flags);
76 if (arch_clock->clk_disable) 103 if (arch_clock->clk_disable)
77 arch_clock->clk_disable(clk); 104 arch_clock->clk_disable(clk);
@@ -84,6 +111,9 @@ int clk_get_usecount(struct clk *clk)
84 unsigned long flags; 111 unsigned long flags;
85 int ret = 0; 112 int ret = 0;
86 113
114 if (clk == NULL || IS_ERR(clk))
115 return 0;
116
87 spin_lock_irqsave(&clockfw_lock, flags); 117 spin_lock_irqsave(&clockfw_lock, flags);
88 ret = clk->usecount; 118 ret = clk->usecount;
89 spin_unlock_irqrestore(&clockfw_lock, flags); 119 spin_unlock_irqrestore(&clockfw_lock, flags);
@@ -97,6 +127,9 @@ unsigned long clk_get_rate(struct clk *clk)
97 unsigned long flags; 127 unsigned long flags;
98 unsigned long ret = 0; 128 unsigned long ret = 0;
99 129
130 if (clk == NULL || IS_ERR(clk))
131 return 0;
132
100 spin_lock_irqsave(&clockfw_lock, flags); 133 spin_lock_irqsave(&clockfw_lock, flags);
101 ret = clk->rate; 134 ret = clk->rate;
102 spin_unlock_irqrestore(&clockfw_lock, flags); 135 spin_unlock_irqrestore(&clockfw_lock, flags);
@@ -121,6 +154,9 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
121 unsigned long flags; 154 unsigned long flags;
122 long ret = 0; 155 long ret = 0;
123 156
157 if (clk == NULL || IS_ERR(clk))
158 return ret;
159
124 spin_lock_irqsave(&clockfw_lock, flags); 160 spin_lock_irqsave(&clockfw_lock, flags);
125 if (arch_clock->clk_round_rate) 161 if (arch_clock->clk_round_rate)
126 ret = arch_clock->clk_round_rate(clk, rate); 162 ret = arch_clock->clk_round_rate(clk, rate);
@@ -133,7 +169,10 @@ EXPORT_SYMBOL(clk_round_rate);
133int clk_set_rate(struct clk *clk, unsigned long rate) 169int clk_set_rate(struct clk *clk, unsigned long rate)
134{ 170{
135 unsigned long flags; 171 unsigned long flags;
136 int ret = 0; 172 int ret = -EINVAL;
173
174 if (clk == NULL || IS_ERR(clk))
175 return ret;
137 176
138 spin_lock_irqsave(&clockfw_lock, flags); 177 spin_lock_irqsave(&clockfw_lock, flags);
139 if (arch_clock->clk_set_rate) 178 if (arch_clock->clk_set_rate)
@@ -147,7 +186,10 @@ EXPORT_SYMBOL(clk_set_rate);
147int clk_set_parent(struct clk *clk, struct clk *parent) 186int clk_set_parent(struct clk *clk, struct clk *parent)
148{ 187{
149 unsigned long flags; 188 unsigned long flags;
150 int ret = 0; 189 int ret = -EINVAL;
190
191 if (clk == NULL || IS_ERR(clk) || parent == NULL || IS_ERR(parent))
192 return ret;
151 193
152 spin_lock_irqsave(&clockfw_lock, flags); 194 spin_lock_irqsave(&clockfw_lock, flags);
153 if (arch_clock->clk_set_parent) 195 if (arch_clock->clk_set_parent)
@@ -163,6 +205,9 @@ struct clk *clk_get_parent(struct clk *clk)
163 unsigned long flags; 205 unsigned long flags;
164 struct clk * ret = NULL; 206 struct clk * ret = NULL;
165 207
208 if (clk == NULL || IS_ERR(clk))
209 return ret;
210
166 spin_lock_irqsave(&clockfw_lock, flags); 211 spin_lock_irqsave(&clockfw_lock, flags);
167 if (arch_clock->clk_get_parent) 212 if (arch_clock->clk_get_parent)
168 ret = arch_clock->clk_get_parent(clk); 213 ret = arch_clock->clk_get_parent(clk);
@@ -199,6 +244,9 @@ __setup("mpurate=", omap_clk_setup);
199/* Used for clocks that always have same value as the parent clock */ 244/* Used for clocks that always have same value as the parent clock */
200void followparent_recalc(struct clk *clk) 245void followparent_recalc(struct clk *clk)
201{ 246{
247 if (clk == NULL || IS_ERR(clk))
248 return;
249
202 clk->rate = clk->parent->rate; 250 clk->rate = clk->parent->rate;
203} 251}
204 252
@@ -207,6 +255,9 @@ void propagate_rate(struct clk * tclk)
207{ 255{
208 struct clk *clkp; 256 struct clk *clkp;
209 257
258 if (tclk == NULL || IS_ERR(tclk))
259 return;
260
210 list_for_each_entry(clkp, &clocks, node) { 261 list_for_each_entry(clkp, &clocks, node) {
211 if (likely(clkp->parent != tclk)) 262 if (likely(clkp->parent != tclk))
212 continue; 263 continue;
@@ -217,6 +268,9 @@ void propagate_rate(struct clk * tclk)
217 268
218int clk_register(struct clk *clk) 269int clk_register(struct clk *clk)
219{ 270{
271 if (clk == NULL || IS_ERR(clk))
272 return -EINVAL;
273
220 mutex_lock(&clocks_mutex); 274 mutex_lock(&clocks_mutex);
221 list_add(&clk->node, &clocks); 275 list_add(&clk->node, &clocks);
222 if (clk->init) 276 if (clk->init)
@@ -229,6 +283,9 @@ EXPORT_SYMBOL(clk_register);
229 283
230void clk_unregister(struct clk *clk) 284void clk_unregister(struct clk *clk)
231{ 285{
286 if (clk == NULL || IS_ERR(clk))
287 return;
288
232 mutex_lock(&clocks_mutex); 289 mutex_lock(&clocks_mutex);
233 list_del(&clk->node); 290 list_del(&clk->node);
234 mutex_unlock(&clocks_mutex); 291 mutex_unlock(&clocks_mutex);
@@ -239,6 +296,9 @@ void clk_deny_idle(struct clk *clk)
239{ 296{
240 unsigned long flags; 297 unsigned long flags;
241 298
299 if (clk == NULL || IS_ERR(clk))
300 return;
301
242 spin_lock_irqsave(&clockfw_lock, flags); 302 spin_lock_irqsave(&clockfw_lock, flags);
243 if (arch_clock->clk_deny_idle) 303 if (arch_clock->clk_deny_idle)
244 arch_clock->clk_deny_idle(clk); 304 arch_clock->clk_deny_idle(clk);
@@ -250,6 +310,9 @@ void clk_allow_idle(struct clk *clk)
250{ 310{
251 unsigned long flags; 311 unsigned long flags;
252 312
313 if (clk == NULL || IS_ERR(clk))
314 return;
315
253 spin_lock_irqsave(&clockfw_lock, flags); 316 spin_lock_irqsave(&clockfw_lock, flags);
254 if (arch_clock->clk_allow_idle) 317 if (arch_clock->clk_allow_idle)
255 arch_clock->clk_allow_idle(clk); 318 arch_clock->clk_allow_idle(clk);
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 9dcce904b608..079b67deac0f 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -24,6 +24,7 @@
24#include <asm/arch/board.h> 24#include <asm/arch/board.h>
25#include <asm/arch/mux.h> 25#include <asm/arch/mux.h>
26#include <asm/arch/gpio.h> 26#include <asm/arch/gpio.h>
27#include <asm/arch/menelaus.h>
27 28
28 29
29void omap_nop_release(struct device *dev) 30void omap_nop_release(struct device *dev)
@@ -98,6 +99,62 @@ static inline void omap_init_i2c(void) {}
98#endif 99#endif
99 100
100/*-------------------------------------------------------------------------*/ 101/*-------------------------------------------------------------------------*/
102#if defined(CONFIG_KEYBOARD_OMAP) || defined(CONFIG_KEYBOARD_OMAP_MODULE)
103
104static void omap_init_kp(void)
105{
106 if (machine_is_omap_h2() || machine_is_omap_h3()) {
107 omap_cfg_reg(F18_1610_KBC0);
108 omap_cfg_reg(D20_1610_KBC1);
109 omap_cfg_reg(D19_1610_KBC2);
110 omap_cfg_reg(E18_1610_KBC3);
111 omap_cfg_reg(C21_1610_KBC4);
112
113 omap_cfg_reg(G18_1610_KBR0);
114 omap_cfg_reg(F19_1610_KBR1);
115 omap_cfg_reg(H14_1610_KBR2);
116 omap_cfg_reg(E20_1610_KBR3);
117 omap_cfg_reg(E19_1610_KBR4);
118 omap_cfg_reg(N19_1610_KBR5);
119 } else if (machine_is_omap_perseus2()) {
120 omap_cfg_reg(E2_730_KBR0);
121 omap_cfg_reg(J7_730_KBR1);
122 omap_cfg_reg(E1_730_KBR2);
123 omap_cfg_reg(F3_730_KBR3);
124 omap_cfg_reg(D2_730_KBR4);
125
126 omap_cfg_reg(C2_730_KBC0);
127 omap_cfg_reg(D3_730_KBC1);
128 omap_cfg_reg(E4_730_KBC2);
129 omap_cfg_reg(F4_730_KBC3);
130 omap_cfg_reg(E3_730_KBC4);
131 } else if (machine_is_omap_h4()) {
132 omap_cfg_reg(T19_24XX_KBR0);
133 omap_cfg_reg(R19_24XX_KBR1);
134 omap_cfg_reg(V18_24XX_KBR2);
135 omap_cfg_reg(M21_24XX_KBR3);
136 omap_cfg_reg(E5__24XX_KBR4);
137 if (omap_has_menelaus()) {
138 omap_cfg_reg(B3__24XX_KBR5);
139 omap_cfg_reg(AA4_24XX_KBC2);
140 omap_cfg_reg(B13_24XX_KBC6);
141 } else {
142 omap_cfg_reg(M18_24XX_KBR5);
143 omap_cfg_reg(H19_24XX_KBC2);
144 omap_cfg_reg(N19_24XX_KBC6);
145 }
146 omap_cfg_reg(R20_24XX_KBC0);
147 omap_cfg_reg(M14_24XX_KBC1);
148 omap_cfg_reg(V17_24XX_KBC3);
149 omap_cfg_reg(P21_24XX_KBC4);
150 omap_cfg_reg(L14_24XX_KBC5);
151 }
152}
153#else
154static inline void omap_init_kp(void) {}
155#endif
156
157/*-------------------------------------------------------------------------*/
101 158
102#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) 159#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
103 160
@@ -240,6 +297,55 @@ static void __init omap_init_mmc(void)
240static inline void omap_init_mmc(void) {} 297static inline void omap_init_mmc(void) {}
241#endif 298#endif
242 299
300/*-------------------------------------------------------------------------*/
301
302/* Numbering for the SPI-capable controllers when used for SPI:
303 * spi = 1
304 * uwire = 2
305 * mmc1..2 = 3..4
306 * mcbsp1..3 = 5..7
307 */
308
309#if defined(CONFIG_SPI_OMAP_UWIRE) || defined(CONFIG_SPI_OMAP_UWIRE_MODULE)
310
311#define OMAP_UWIRE_BASE 0xfffb3000
312
313static struct resource uwire_resources[] = {
314 {
315 .start = OMAP_UWIRE_BASE,
316 .end = OMAP_UWIRE_BASE + 0x20,
317 .flags = IORESOURCE_MEM,
318 },
319};
320
321static struct platform_device omap_uwire_device = {
322 .name = "omap_uwire",
323 .id = -1,
324 .dev = {
325 .release = omap_nop_release,
326 },
327 .num_resources = ARRAY_SIZE(uwire_resources),
328 .resource = uwire_resources,
329};
330
331static void omap_init_uwire(void)
332{
333 /* FIXME define and use a boot tag; not all boards will be hooking
334 * up devices to the microwire controller, and multi-board configs
335 * mean that CONFIG_SPI_OMAP_UWIRE may be configured anyway...
336 */
337
338 /* board-specific code must configure chipselects (only a few
339 * are normally used) and SCLK/SDI/SDO (each has two choices).
340 */
341 (void) platform_device_register(&omap_uwire_device);
342}
343#else
344static inline void omap_init_uwire(void) {}
345#endif
346
347/*-------------------------------------------------------------------------*/
348
243#if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE) 349#if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
244 350
245#ifdef CONFIG_ARCH_OMAP24XX 351#ifdef CONFIG_ARCH_OMAP24XX
@@ -310,40 +416,6 @@ static void omap_init_rng(void)
310static inline void omap_init_rng(void) {} 416static inline void omap_init_rng(void) {}
311#endif 417#endif
312 418
313#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
314
315static struct omap_lcd_config omap_fb_conf;
316
317static u64 omap_fb_dma_mask = ~(u32)0;
318
319static struct platform_device omap_fb_device = {
320 .name = "omapfb",
321 .id = -1,
322 .dev = {
323 .release = omap_nop_release,
324 .dma_mask = &omap_fb_dma_mask,
325 .coherent_dma_mask = ~(u32)0,
326 .platform_data = &omap_fb_conf,
327 },
328 .num_resources = 0,
329};
330
331static inline void omap_init_fb(void)
332{
333 const struct omap_lcd_config *conf;
334
335 conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
336 if (conf != NULL)
337 omap_fb_conf = *conf;
338 platform_device_register(&omap_fb_device);
339}
340
341#else
342
343static inline void omap_init_fb(void) {}
344
345#endif
346
347/* 419/*
348 * This gets called after board-specific INIT_MACHINE, and initializes most 420 * This gets called after board-specific INIT_MACHINE, and initializes most
349 * on-chip peripherals accessible on this board (except for few like USB): 421 * on-chip peripherals accessible on this board (except for few like USB):
@@ -369,9 +441,10 @@ static int __init omap_init_devices(void)
369 /* please keep these calls, and their implementations above, 441 /* please keep these calls, and their implementations above,
370 * in alphabetical order so they're easier to sort through. 442 * in alphabetical order so they're easier to sort through.
371 */ 443 */
372 omap_init_fb();
373 omap_init_i2c(); 444 omap_init_i2c();
445 omap_init_kp();
374 omap_init_mmc(); 446 omap_init_mmc();
447 omap_init_uwire();
375 omap_init_wdt(); 448 omap_init_wdt();
376 omap_init_rng(); 449 omap_init_rng();
377 450
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index a4e5ac77f6df..5dac4230360d 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -1258,6 +1258,11 @@ void omap_stop_lcd_dma(void)
1258 omap_writew(w, OMAP1610_DMA_LCD_CTRL); 1258 omap_writew(w, OMAP1610_DMA_LCD_CTRL);
1259} 1259}
1260 1260
1261int omap_lcd_dma_ext_running(void)
1262{
1263 return lcd_dma.ext_ctrl && lcd_dma.active;
1264}
1265
1261/*----------------------------------------------------------------------------*/ 1266/*----------------------------------------------------------------------------*/
1262 1267
1263static int __init omap_init_dma(void) 1268static int __init omap_init_dma(void)
@@ -1389,6 +1394,7 @@ EXPORT_SYMBOL(omap_free_lcd_dma);
1389EXPORT_SYMBOL(omap_enable_lcd_dma); 1394EXPORT_SYMBOL(omap_enable_lcd_dma);
1390EXPORT_SYMBOL(omap_setup_lcd_dma); 1395EXPORT_SYMBOL(omap_setup_lcd_dma);
1391EXPORT_SYMBOL(omap_stop_lcd_dma); 1396EXPORT_SYMBOL(omap_stop_lcd_dma);
1397EXPORT_SYMBOL(omap_lcd_dma_ext_running);
1392EXPORT_SYMBOL(omap_set_lcd_dma_b1); 1398EXPORT_SYMBOL(omap_set_lcd_dma_b1);
1393EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer); 1399EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer);
1394EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller); 1400EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller);
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 38d7ebf87920..eba3cb52ad87 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -97,6 +97,32 @@ int omap_dm_timers_active(void)
97} 97}
98 98
99 99
100/**
101 * omap_dm_timer_modify_idlect_mask - Check if any running timers use ARMXOR
102 * @inputmask: current value of idlect mask
103 */
104__u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
105{
106 int n;
107
108 /* If ARMXOR cannot be idled this function call is unnecessary */
109 if (!(inputmask & (1 << 1)))
110 return inputmask;
111
112 /* If any active timer is using ARMXOR return modified mask */
113 for (n = 0; dm_timers[n].base; ++n)
114 if (omap_dm_timer_read_reg(&dm_timers[n], OMAP_TIMER_CTRL_REG)&
115 OMAP_TIMER_CTRL_ST) {
116 if (((omap_readl(MOD_CONF_CTRL_1)>>(n*2)) & 0x03) == 0)
117 inputmask &= ~(1 << 1);
118 else
119 inputmask &= ~(1 << 2);
120 }
121
122 return inputmask;
123}
124
125
100void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) 126void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
101{ 127{
102 int n = (timer - dm_timers) << 1; 128 int n = (timer - dm_timers) << 1;
diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
new file mode 100644
index 000000000000..305e9b990b71
--- /dev/null
+++ b/arch/arm/plat-omap/fb.c
@@ -0,0 +1,80 @@
1#include <linux/config.h>
2#include <linux/module.h>
3#include <linux/kernel.h>
4#include <linux/init.h>
5#include <linux/platform_device.h>
6#include <linux/bootmem.h>
7
8#include <asm/hardware.h>
9#include <asm/io.h>
10#include <asm/mach-types.h>
11#include <asm/mach/map.h>
12
13#include <asm/arch/board.h>
14#include <asm/arch/sram.h>
15#include <asm/arch/omapfb.h>
16
17#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
18
19static struct omapfb_platform_data omapfb_config;
20
21static u64 omap_fb_dma_mask = ~(u32)0;
22
23static struct platform_device omap_fb_device = {
24 .name = "omapfb",
25 .id = -1,
26 .dev = {
27 .dma_mask = &omap_fb_dma_mask,
28 .coherent_dma_mask = ~(u32)0,
29 .platform_data = &omapfb_config,
30 },
31 .num_resources = 0,
32};
33
34/* called from map_io */
35void omapfb_reserve_mem(void)
36{
37 const struct omap_fbmem_config *fbmem_conf;
38
39 omapfb_config.fbmem.fb_sram_start = omap_fb_sram_start;
40 omapfb_config.fbmem.fb_sram_size = omap_fb_sram_size;
41
42 fbmem_conf = omap_get_config(OMAP_TAG_FBMEM, struct omap_fbmem_config);
43
44 if (fbmem_conf != NULL) {
45 /* indicate that the bootloader already initialized the
46 * fb device, so we'll skip that part in the fb driver
47 */
48 omapfb_config.fbmem.fb_sdram_start = fbmem_conf->fb_sdram_start;
49 omapfb_config.fbmem.fb_sdram_size = fbmem_conf->fb_sdram_size;
50 if (fbmem_conf->fb_sdram_size) {
51 pr_info("Reserving %u bytes SDRAM for frame buffer\n",
52 fbmem_conf->fb_sdram_size);
53 reserve_bootmem(fbmem_conf->fb_sdram_start,
54 fbmem_conf->fb_sdram_size);
55 }
56 }
57}
58
59static inline int omap_init_fb(void)
60{
61 const struct omap_lcd_config *conf;
62
63 conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
64 if (conf == NULL)
65 return 0;
66
67 omapfb_config.lcd = *conf;
68
69 return platform_device_register(&omap_fb_device);
70}
71
72arch_initcall(omap_init_fb);
73
74#else
75
76void omapfb_reserve_mem(void) {}
77
78#endif
79
80
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index b4d5b9e4bfce..d3c8ea7eecfd 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -174,7 +174,7 @@ static int gpio_bank_count;
174static inline struct gpio_bank *get_gpio_bank(int gpio) 174static inline struct gpio_bank *get_gpio_bank(int gpio)
175{ 175{
176#ifdef CONFIG_ARCH_OMAP15XX 176#ifdef CONFIG_ARCH_OMAP15XX
177 if (cpu_is_omap1510()) { 177 if (cpu_is_omap15xx()) {
178 if (OMAP_GPIO_IS_MPUIO(gpio)) 178 if (OMAP_GPIO_IS_MPUIO(gpio))
179 return &gpio_bank[0]; 179 return &gpio_bank[0];
180 return &gpio_bank[1]; 180 return &gpio_bank[1];
@@ -223,7 +223,7 @@ static inline int gpio_valid(int gpio)
223 return 0; 223 return 0;
224 } 224 }
225#ifdef CONFIG_ARCH_OMAP15XX 225#ifdef CONFIG_ARCH_OMAP15XX
226 if (cpu_is_omap1510() && gpio < 16) 226 if (cpu_is_omap15xx() && gpio < 16)
227 return 0; 227 return 0;
228#endif 228#endif
229#if defined(CONFIG_ARCH_OMAP16XX) 229#if defined(CONFIG_ARCH_OMAP16XX)
@@ -402,13 +402,13 @@ static inline void set_24xx_gpio_triggering(void __iomem *base, int gpio, int tr
402 u32 gpio_bit = 1 << gpio; 402 u32 gpio_bit = 1 << gpio;
403 403
404 MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, 404 MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit,
405 trigger & IRQT_LOW); 405 trigger & __IRQT_LOWLVL);
406 MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit, 406 MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit,
407 trigger & IRQT_HIGH); 407 trigger & __IRQT_HIGHLVL);
408 MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit, 408 MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit,
409 trigger & IRQT_RISING); 409 trigger & __IRQT_RISEDGE);
410 MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, 410 MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit,
411 trigger & IRQT_FALLING); 411 trigger & __IRQT_FALEDGE);
412 /* FIXME: Possibly do 'set_irq_handler(j, do_level_IRQ)' if only level 412 /* FIXME: Possibly do 'set_irq_handler(j, do_level_IRQ)' if only level
413 * triggering requested. */ 413 * triggering requested. */
414} 414}
@@ -422,9 +422,9 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
422 case METHOD_MPUIO: 422 case METHOD_MPUIO:
423 reg += OMAP_MPUIO_GPIO_INT_EDGE; 423 reg += OMAP_MPUIO_GPIO_INT_EDGE;
424 l = __raw_readl(reg); 424 l = __raw_readl(reg);
425 if (trigger == IRQT_RISING) 425 if (trigger & __IRQT_RISEDGE)
426 l |= 1 << gpio; 426 l |= 1 << gpio;
427 else if (trigger == IRQT_FALLING) 427 else if (trigger & __IRQT_FALEDGE)
428 l &= ~(1 << gpio); 428 l &= ~(1 << gpio);
429 else 429 else
430 goto bad; 430 goto bad;
@@ -432,9 +432,9 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
432 case METHOD_GPIO_1510: 432 case METHOD_GPIO_1510:
433 reg += OMAP1510_GPIO_INT_CONTROL; 433 reg += OMAP1510_GPIO_INT_CONTROL;
434 l = __raw_readl(reg); 434 l = __raw_readl(reg);
435 if (trigger == IRQT_RISING) 435 if (trigger & __IRQT_RISEDGE)
436 l |= 1 << gpio; 436 l |= 1 << gpio;
437 else if (trigger == IRQT_FALLING) 437 else if (trigger & __IRQT_FALEDGE)
438 l &= ~(1 << gpio); 438 l &= ~(1 << gpio);
439 else 439 else
440 goto bad; 440 goto bad;
@@ -446,20 +446,21 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
446 reg += OMAP1610_GPIO_EDGE_CTRL1; 446 reg += OMAP1610_GPIO_EDGE_CTRL1;
447 gpio &= 0x07; 447 gpio &= 0x07;
448 /* We allow only edge triggering, i.e. two lowest bits */ 448 /* We allow only edge triggering, i.e. two lowest bits */
449 if (trigger & ~IRQT_BOTHEDGE) 449 if (trigger & (__IRQT_LOWLVL | __IRQT_HIGHLVL))
450 BUG(); 450 BUG();
451 /* NOTE: knows __IRQT_{FAL,RIS}EDGE match OMAP hardware */
452 trigger &= 0x03;
453 l = __raw_readl(reg); 451 l = __raw_readl(reg);
454 l &= ~(3 << (gpio << 1)); 452 l &= ~(3 << (gpio << 1));
455 l |= trigger << (gpio << 1); 453 if (trigger & __IRQT_RISEDGE)
454 l |= 2 << (gpio << 1);
455 if (trigger & __IRQT_FALEDGE)
456 l |= 1 << (gpio << 1);
456 break; 457 break;
457 case METHOD_GPIO_730: 458 case METHOD_GPIO_730:
458 reg += OMAP730_GPIO_INT_CONTROL; 459 reg += OMAP730_GPIO_INT_CONTROL;
459 l = __raw_readl(reg); 460 l = __raw_readl(reg);
460 if (trigger == IRQT_RISING) 461 if (trigger & __IRQT_RISEDGE)
461 l |= 1 << gpio; 462 l |= 1 << gpio;
462 else if (trigger == IRQT_FALLING) 463 else if (trigger & __IRQT_FALEDGE)
463 l &= ~(1 << gpio); 464 l &= ~(1 << gpio);
464 else 465 else
465 goto bad; 466 goto bad;
@@ -491,7 +492,9 @@ static int gpio_irq_type(unsigned irq, unsigned type)
491 if (check_gpio(gpio) < 0) 492 if (check_gpio(gpio) < 0)
492 return -EINVAL; 493 return -EINVAL;
493 494
494 if (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL|IRQT_PROBE)) 495 if (type & IRQT_PROBE)
496 return -EINVAL;
497 if (!cpu_is_omap24xx() && (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL)))
495 return -EINVAL; 498 return -EINVAL;
496 499
497 bank = get_gpio_bank(gpio); 500 bank = get_gpio_bank(gpio);
@@ -755,13 +758,32 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
755 if (bank->method == METHOD_GPIO_24XX) 758 if (bank->method == METHOD_GPIO_24XX)
756 isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1; 759 isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1;
757#endif 760#endif
758
759 while(1) { 761 while(1) {
760 isr = __raw_readl(isr_reg); 762 u32 isr_saved, level_mask = 0;
761 _enable_gpio_irqbank(bank, isr, 0); 763
762 _clear_gpio_irqbank(bank, isr); 764 isr_saved = isr = __raw_readl(isr_reg);
763 _enable_gpio_irqbank(bank, isr, 1); 765
764 desc->chip->unmask(irq); 766 if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO))
767 isr &= 0x0000ffff;
768
769 if (cpu_is_omap24xx())
770 level_mask =
771 __raw_readl(bank->base +
772 OMAP24XX_GPIO_LEVELDETECT0) |
773 __raw_readl(bank->base +
774 OMAP24XX_GPIO_LEVELDETECT1);
775
776 /* clear edge sensitive interrupts before handler(s) are
777 called so that we don't miss any interrupt occurred while
778 executing them */
779 _enable_gpio_irqbank(bank, isr_saved & ~level_mask, 0);
780 _clear_gpio_irqbank(bank, isr_saved & ~level_mask);
781 _enable_gpio_irqbank(bank, isr_saved & ~level_mask, 1);
782
783 /* if there is only edge sensitive GPIO pin interrupts
784 configured, we could unmask GPIO bank interrupt immediately */
785 if (!level_mask)
786 desc->chip->unmask(irq);
765 787
766 if (!isr) 788 if (!isr)
767 break; 789 break;
@@ -774,6 +796,20 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
774 d = irq_desc + gpio_irq; 796 d = irq_desc + gpio_irq;
775 desc_handle_irq(gpio_irq, d, regs); 797 desc_handle_irq(gpio_irq, d, regs);
776 } 798 }
799
800 if (cpu_is_omap24xx()) {
801 /* clear level sensitive interrupts after handler(s) */
802 _enable_gpio_irqbank(bank, isr_saved & level_mask, 0);
803 _clear_gpio_irqbank(bank, isr_saved & level_mask);
804 _enable_gpio_irqbank(bank, isr_saved & level_mask, 1);
805 }
806
807 /* if bank has any level sensitive GPIO pin interrupt
808 configured, we must unmask the bank interrupt only after
809 handler(s) are executed in order to avoid spurious bank
810 interrupt */
811 if (level_mask)
812 desc->chip->unmask(irq);
777 } 813 }
778} 814}
779 815
@@ -848,7 +884,7 @@ static int __init _omap_gpio_init(void)
848 884
849 initialized = 1; 885 initialized = 1;
850 886
851 if (cpu_is_omap1510()) { 887 if (cpu_is_omap15xx()) {
852 gpio_ick = clk_get(NULL, "arm_gpio_ck"); 888 gpio_ick = clk_get(NULL, "arm_gpio_ck");
853 if (IS_ERR(gpio_ick)) 889 if (IS_ERR(gpio_ick))
854 printk("Could not get arm_gpio_ck\n"); 890 printk("Could not get arm_gpio_ck\n");
@@ -869,7 +905,7 @@ static int __init _omap_gpio_init(void)
869 } 905 }
870 906
871#ifdef CONFIG_ARCH_OMAP15XX 907#ifdef CONFIG_ARCH_OMAP15XX
872 if (cpu_is_omap1510()) { 908 if (cpu_is_omap15xx()) {
873 printk(KERN_INFO "OMAP1510 GPIO hardware\n"); 909 printk(KERN_INFO "OMAP1510 GPIO hardware\n");
874 gpio_bank_count = 2; 910 gpio_bank_count = 2;
875 gpio_bank = gpio_bank_1510; 911 gpio_bank = gpio_bank_1510;
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 1cd2cace7e1b..196aac3ac329 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -34,7 +34,7 @@
34#ifdef CONFIG_MCBSP_DEBUG 34#ifdef CONFIG_MCBSP_DEBUG
35#define DBG(x...) printk(x) 35#define DBG(x...) printk(x)
36#else 36#else
37#define DBG(x...) do { } while (0) 37#define DBG(x...) do { } while (0)
38#endif 38#endif
39 39
40struct omap_mcbsp { 40struct omap_mcbsp {
@@ -44,6 +44,7 @@ struct omap_mcbsp {
44 omap_mcbsp_word_length rx_word_length; 44 omap_mcbsp_word_length rx_word_length;
45 omap_mcbsp_word_length tx_word_length; 45 omap_mcbsp_word_length tx_word_length;
46 46
47 omap_mcbsp_io_type_t io_type; /* IRQ or poll */
47 /* IRQ based TX/RX */ 48 /* IRQ based TX/RX */
48 int rx_irq; 49 int rx_irq;
49 int tx_irq; 50 int tx_irq;
@@ -64,10 +65,19 @@ struct omap_mcbsp {
64}; 65};
65 66
66static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT]; 67static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT];
68#ifdef CONFIG_ARCH_OMAP1
67static struct clk *mcbsp_dsp_ck = 0; 69static struct clk *mcbsp_dsp_ck = 0;
68static struct clk *mcbsp_api_ck = 0; 70static struct clk *mcbsp_api_ck = 0;
69static struct clk *mcbsp_dspxor_ck = 0; 71static struct clk *mcbsp_dspxor_ck = 0;
70 72#endif
73#ifdef CONFIG_ARCH_OMAP2
74static struct clk *mcbsp1_ick = 0;
75static struct clk *mcbsp1_fck = 0;
76static struct clk *mcbsp2_ick = 0;
77static struct clk *mcbsp2_fck = 0;
78static struct clk *sys_ck = 0;
79static struct clk *sys_clkout = 0;
80#endif
71 81
72static void omap_mcbsp_dump_reg(u8 id) 82static void omap_mcbsp_dump_reg(u8 id)
73{ 83{
@@ -88,7 +98,6 @@ static void omap_mcbsp_dump_reg(u8 id)
88 DBG("***********************\n"); 98 DBG("***********************\n");
89} 99}
90 100
91
92static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id, struct pt_regs *regs) 101static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
93{ 102{
94 struct omap_mcbsp * mcbsp_tx = (struct omap_mcbsp *)(dev_id); 103 struct omap_mcbsp * mcbsp_tx = (struct omap_mcbsp *)(dev_id);
@@ -109,7 +118,6 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id, struct pt_re
109 return IRQ_HANDLED; 118 return IRQ_HANDLED;
110} 119}
111 120
112
113static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data) 121static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
114{ 122{
115 struct omap_mcbsp * mcbsp_dma_tx = (struct omap_mcbsp *)(data); 123 struct omap_mcbsp * mcbsp_dma_tx = (struct omap_mcbsp *)(data);
@@ -176,7 +184,7 @@ static int omap_mcbsp_check(unsigned int id)
176 return 0; 184 return 0;
177 } 185 }
178 186
179 if (cpu_is_omap1510() || cpu_is_omap16xx()) { 187 if (cpu_is_omap15xx() || cpu_is_omap16xx() || cpu_is_omap24xx()) {
180 if (id > OMAP_MAX_MCBSP_COUNT) { 188 if (id > OMAP_MAX_MCBSP_COUNT) {
181 printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1); 189 printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
182 return -1; 190 return -1;
@@ -187,9 +195,10 @@ static int omap_mcbsp_check(unsigned int id)
187 return -1; 195 return -1;
188} 196}
189 197
198#ifdef CONFIG_ARCH_OMAP1
190static void omap_mcbsp_dsp_request(void) 199static void omap_mcbsp_dsp_request(void)
191{ 200{
192 if (cpu_is_omap1510() || cpu_is_omap16xx()) { 201 if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
193 clk_enable(mcbsp_dsp_ck); 202 clk_enable(mcbsp_dsp_ck);
194 clk_enable(mcbsp_api_ck); 203 clk_enable(mcbsp_api_ck);
195 204
@@ -207,12 +216,49 @@ static void omap_mcbsp_dsp_request(void)
207 216
208static void omap_mcbsp_dsp_free(void) 217static void omap_mcbsp_dsp_free(void)
209{ 218{
210 if (cpu_is_omap1510() || cpu_is_omap16xx()) { 219 if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
211 clk_disable(mcbsp_dspxor_ck); 220 clk_disable(mcbsp_dspxor_ck);
212 clk_disable(mcbsp_dsp_ck); 221 clk_disable(mcbsp_dsp_ck);
213 clk_disable(mcbsp_api_ck); 222 clk_disable(mcbsp_api_ck);
214 } 223 }
215} 224}
225#endif
226
227#ifdef CONFIG_ARCH_OMAP2
228static void omap2_mcbsp2_mux_setup(void)
229{
230 omap_cfg_reg(Y15_24XX_MCBSP2_CLKX);
231 omap_cfg_reg(R14_24XX_MCBSP2_FSX);
232 omap_cfg_reg(W15_24XX_MCBSP2_DR);
233 omap_cfg_reg(V15_24XX_MCBSP2_DX);
234 omap_cfg_reg(V14_24XX_GPIO117);
235 omap_cfg_reg(W14_24XX_SYS_CLKOUT);
236}
237#endif
238
239/*
240 * We can choose between IRQ based or polled IO.
241 * This needs to be called before omap_mcbsp_request().
242 */
243int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type)
244{
245 if (omap_mcbsp_check(id) < 0)
246 return -EINVAL;
247
248 spin_lock(&mcbsp[id].lock);
249
250 if (!mcbsp[id].free) {
251 printk (KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", id + 1);
252 spin_unlock(&mcbsp[id].lock);
253 return -EINVAL;
254 }
255
256 mcbsp[id].io_type = io_type;
257
258 spin_unlock(&mcbsp[id].lock);
259
260 return 0;
261}
216 262
217int omap_mcbsp_request(unsigned int id) 263int omap_mcbsp_request(unsigned int id)
218{ 264{
@@ -221,12 +267,26 @@ int omap_mcbsp_request(unsigned int id)
221 if (omap_mcbsp_check(id) < 0) 267 if (omap_mcbsp_check(id) < 0)
222 return -EINVAL; 268 return -EINVAL;
223 269
270#ifdef CONFIG_ARCH_OMAP1
224 /* 271 /*
225 * On 1510, 1610 and 1710, McBSP1 and McBSP3 272 * On 1510, 1610 and 1710, McBSP1 and McBSP3
226 * are DSP public peripherals. 273 * are DSP public peripherals.
227 */ 274 */
228 if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) 275 if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
229 omap_mcbsp_dsp_request(); 276 omap_mcbsp_dsp_request();
277#endif
278
279#ifdef CONFIG_ARCH_OMAP2
280 if (cpu_is_omap24xx()) {
281 if (id == OMAP_MCBSP1) {
282 clk_enable(mcbsp1_ick);
283 clk_enable(mcbsp1_fck);
284 } else {
285 clk_enable(mcbsp2_ick);
286 clk_enable(mcbsp2_fck);
287 }
288 }
289#endif
230 290
231 spin_lock(&mcbsp[id].lock); 291 spin_lock(&mcbsp[id].lock);
232 if (!mcbsp[id].free) { 292 if (!mcbsp[id].free) {
@@ -238,30 +298,33 @@ int omap_mcbsp_request(unsigned int id)
238 mcbsp[id].free = 0; 298 mcbsp[id].free = 0;
239 spin_unlock(&mcbsp[id].lock); 299 spin_unlock(&mcbsp[id].lock);
240 300
241 /* We need to get IRQs here */ 301 if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) {
242 err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0, 302 /* We need to get IRQs here */
243 "McBSP", 303 err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0,
244 (void *) (&mcbsp[id])); 304 "McBSP",
245 if (err != 0) { 305 (void *) (&mcbsp[id]));
246 printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n", 306 if (err != 0) {
247 mcbsp[id].tx_irq, mcbsp[id].id); 307 printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n",
248 return err; 308 mcbsp[id].tx_irq, mcbsp[id].id);
249 } 309 return err;
310 }
250 311
251 init_completion(&(mcbsp[id].tx_irq_completion)); 312 init_completion(&(mcbsp[id].tx_irq_completion));
252 313
253 314
254 err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0, 315 err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0,
255 "McBSP", 316 "McBSP",
256 (void *) (&mcbsp[id])); 317 (void *) (&mcbsp[id]));
257 if (err != 0) { 318 if (err != 0) {
258 printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n", 319 printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n",
259 mcbsp[id].rx_irq, mcbsp[id].id); 320 mcbsp[id].rx_irq, mcbsp[id].id);
260 free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); 321 free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
261 return err; 322 return err;
323 }
324
325 init_completion(&(mcbsp[id].rx_irq_completion));
262 } 326 }
263 327
264 init_completion(&(mcbsp[id].rx_irq_completion));
265 return 0; 328 return 0;
266 329
267} 330}
@@ -271,8 +334,24 @@ void omap_mcbsp_free(unsigned int id)
271 if (omap_mcbsp_check(id) < 0) 334 if (omap_mcbsp_check(id) < 0)
272 return; 335 return;
273 336
274 if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) 337#ifdef CONFIG_ARCH_OMAP1
275 omap_mcbsp_dsp_free(); 338 if (cpu_class_is_omap1()) {
339 if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
340 omap_mcbsp_dsp_free();
341 }
342#endif
343
344#ifdef CONFIG_ARCH_OMAP2
345 if (cpu_is_omap24xx()) {
346 if (id == OMAP_MCBSP1) {
347 clk_disable(mcbsp1_ick);
348 clk_disable(mcbsp1_fck);
349 } else {
350 clk_disable(mcbsp2_ick);
351 clk_disable(mcbsp2_fck);
352 }
353 }
354#endif
276 355
277 spin_lock(&mcbsp[id].lock); 356 spin_lock(&mcbsp[id].lock);
278 if (mcbsp[id].free) { 357 if (mcbsp[id].free) {
@@ -284,9 +363,11 @@ void omap_mcbsp_free(unsigned int id)
284 mcbsp[id].free = 1; 363 mcbsp[id].free = 1;
285 spin_unlock(&mcbsp[id].lock); 364 spin_unlock(&mcbsp[id].lock);
286 365
287 /* Free IRQs */ 366 if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) {
288 free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id])); 367 /* Free IRQs */
289 free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); 368 free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id]));
369 free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
370 }
290} 371}
291 372
292/* 373/*
@@ -461,6 +542,115 @@ u32 omap_mcbsp_recv_word(unsigned int id)
461} 542}
462 543
463 544
545int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
546{
547 u32 io_base = mcbsp[id].io_base;
548 omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length;
549 omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length;
550 u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
551
552 if (tx_word_length != rx_word_length)
553 return -EINVAL;
554
555 /* First we wait for the transmitter to be ready */
556 spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
557 while (!(spcr2 & XRDY)) {
558 spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
559 if (attempts++ > 1000) {
560 /* We must reset the transmitter */
561 OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST));
562 udelay(10);
563 OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
564 udelay(10);
565 printk("McBSP transmitter not ready\n");
566 return -EAGAIN;
567 }
568 }
569
570 /* Now we can push the data */
571 if (tx_word_length > OMAP_MCBSP_WORD_16)
572 OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16);
573 OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff);
574
575 /* We wait for the receiver to be ready */
576 spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
577 while (!(spcr1 & RRDY)) {
578 spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
579 if (attempts++ > 1000) {
580 /* We must reset the receiver */
581 OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST));
582 udelay(10);
583 OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
584 udelay(10);
585 printk("McBSP receiver not ready\n");
586 return -EAGAIN;
587 }
588 }
589
590 /* Receiver is ready, let's read the dummy data */
591 if (rx_word_length > OMAP_MCBSP_WORD_16)
592 word_msb = OMAP_MCBSP_READ(io_base, DRR2);
593 word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
594
595 return 0;
596}
597
598int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word)
599{
600 u32 io_base = mcbsp[id].io_base, clock_word = 0;
601 omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length;
602 omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length;
603 u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
604
605 if (tx_word_length != rx_word_length)
606 return -EINVAL;
607
608 /* First we wait for the transmitter to be ready */
609 spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
610 while (!(spcr2 & XRDY)) {
611 spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
612 if (attempts++ > 1000) {
613 /* We must reset the transmitter */
614 OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST));
615 udelay(10);
616 OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
617 udelay(10);
618 printk("McBSP transmitter not ready\n");
619 return -EAGAIN;
620 }
621 }
622
623 /* We first need to enable the bus clock */
624 if (tx_word_length > OMAP_MCBSP_WORD_16)
625 OMAP_MCBSP_WRITE(io_base, DXR2, clock_word >> 16);
626 OMAP_MCBSP_WRITE(io_base, DXR1, clock_word & 0xffff);
627
628 /* We wait for the receiver to be ready */
629 spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
630 while (!(spcr1 & RRDY)) {
631 spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
632 if (attempts++ > 1000) {
633 /* We must reset the receiver */
634 OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST));
635 udelay(10);
636 OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
637 udelay(10);
638 printk("McBSP receiver not ready\n");
639 return -EAGAIN;
640 }
641 }
642
643 /* Receiver is ready, there is something for us */
644 if (rx_word_length > OMAP_MCBSP_WORD_16)
645 word_msb = OMAP_MCBSP_READ(io_base, DRR2);
646 word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
647
648 word[0] = (word_lsb | (word_msb << 16));
649
650 return 0;
651}
652
653
464/* 654/*
465 * Simple DMA based buffer rx/tx routines. 655 * Simple DMA based buffer rx/tx routines.
466 * Nothing fancy, just a single buffer tx/rx through DMA. 656 * Nothing fancy, just a single buffer tx/rx through DMA.
@@ -471,6 +661,9 @@ u32 omap_mcbsp_recv_word(unsigned int id)
471int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length) 661int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length)
472{ 662{
473 int dma_tx_ch; 663 int dma_tx_ch;
664 int src_port = 0;
665 int dest_port = 0;
666 int sync_dev = 0;
474 667
475 if (omap_mcbsp_check(id) < 0) 668 if (omap_mcbsp_check(id) < 0)
476 return -EINVAL; 669 return -EINVAL;
@@ -487,20 +680,27 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng
487 680
488 init_completion(&(mcbsp[id].tx_dma_completion)); 681 init_completion(&(mcbsp[id].tx_dma_completion));
489 682
683 if (cpu_class_is_omap1()) {
684 src_port = OMAP_DMA_PORT_TIPB;
685 dest_port = OMAP_DMA_PORT_EMIFF;
686 }
687 if (cpu_is_omap24xx())
688 sync_dev = mcbsp[id].dma_tx_sync;
689
490 omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch, 690 omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch,
491 OMAP_DMA_DATA_TYPE_S16, 691 OMAP_DMA_DATA_TYPE_S16,
492 length >> 1, 1, 692 length >> 1, 1,
493 OMAP_DMA_SYNC_ELEMENT, 693 OMAP_DMA_SYNC_ELEMENT,
494 0, 0); 694 sync_dev, 0);
495 695
496 omap_set_dma_dest_params(mcbsp[id].dma_tx_lch, 696 omap_set_dma_dest_params(mcbsp[id].dma_tx_lch,
497 OMAP_DMA_PORT_TIPB, 697 src_port,
498 OMAP_DMA_AMODE_CONSTANT, 698 OMAP_DMA_AMODE_CONSTANT,
499 mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1, 699 mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1,
500 0, 0); 700 0, 0);
501 701
502 omap_set_dma_src_params(mcbsp[id].dma_tx_lch, 702 omap_set_dma_src_params(mcbsp[id].dma_tx_lch,
503 OMAP_DMA_PORT_EMIFF, 703 dest_port,
504 OMAP_DMA_AMODE_POST_INC, 704 OMAP_DMA_AMODE_POST_INC,
505 buffer, 705 buffer,
506 0, 0); 706 0, 0);
@@ -514,6 +714,9 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng
514int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length) 714int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length)
515{ 715{
516 int dma_rx_ch; 716 int dma_rx_ch;
717 int src_port = 0;
718 int dest_port = 0;
719 int sync_dev = 0;
517 720
518 if (omap_mcbsp_check(id) < 0) 721 if (omap_mcbsp_check(id) < 0)
519 return -EINVAL; 722 return -EINVAL;
@@ -530,20 +733,27 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng
530 733
531 init_completion(&(mcbsp[id].rx_dma_completion)); 734 init_completion(&(mcbsp[id].rx_dma_completion));
532 735
736 if (cpu_class_is_omap1()) {
737 src_port = OMAP_DMA_PORT_TIPB;
738 dest_port = OMAP_DMA_PORT_EMIFF;
739 }
740 if (cpu_is_omap24xx())
741 sync_dev = mcbsp[id].dma_rx_sync;
742
533 omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch, 743 omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch,
534 OMAP_DMA_DATA_TYPE_S16, 744 OMAP_DMA_DATA_TYPE_S16,
535 length >> 1, 1, 745 length >> 1, 1,
536 OMAP_DMA_SYNC_ELEMENT, 746 OMAP_DMA_SYNC_ELEMENT,
537 0, 0); 747 sync_dev, 0);
538 748
539 omap_set_dma_src_params(mcbsp[id].dma_rx_lch, 749 omap_set_dma_src_params(mcbsp[id].dma_rx_lch,
540 OMAP_DMA_PORT_TIPB, 750 src_port,
541 OMAP_DMA_AMODE_CONSTANT, 751 OMAP_DMA_AMODE_CONSTANT,
542 mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1, 752 mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1,
543 0, 0); 753 0, 0);
544 754
545 omap_set_dma_dest_params(mcbsp[id].dma_rx_lch, 755 omap_set_dma_dest_params(mcbsp[id].dma_rx_lch,
546 OMAP_DMA_PORT_EMIFF, 756 dest_port,
547 OMAP_DMA_AMODE_POST_INC, 757 OMAP_DMA_AMODE_POST_INC,
548 buffer, 758 buffer,
549 0, 0); 759 0, 0);
@@ -688,6 +898,23 @@ static const struct omap_mcbsp_info mcbsp_1610[] = {
688}; 898};
689#endif 899#endif
690 900
901#if defined(CONFIG_ARCH_OMAP24XX)
902static const struct omap_mcbsp_info mcbsp_24xx[] = {
903 [0] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP1_BASE),
904 .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX,
905 .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
906 .rx_irq = INT_24XX_MCBSP1_IRQ_RX,
907 .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
908 },
909 [1] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP2_BASE),
910 .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX,
911 .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
912 .rx_irq = INT_24XX_MCBSP2_IRQ_RX,
913 .tx_irq = INT_24XX_MCBSP2_IRQ_TX,
914 },
915};
916#endif
917
691static int __init omap_mcbsp_init(void) 918static int __init omap_mcbsp_init(void)
692{ 919{
693 int mcbsp_count = 0, i; 920 int mcbsp_count = 0, i;
@@ -695,6 +922,7 @@ static int __init omap_mcbsp_init(void)
695 922
696 printk("Initializing OMAP McBSP system\n"); 923 printk("Initializing OMAP McBSP system\n");
697 924
925#ifdef CONFIG_ARCH_OMAP1
698 mcbsp_dsp_ck = clk_get(0, "dsp_ck"); 926 mcbsp_dsp_ck = clk_get(0, "dsp_ck");
699 if (IS_ERR(mcbsp_dsp_ck)) { 927 if (IS_ERR(mcbsp_dsp_ck)) {
700 printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n"); 928 printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n");
@@ -710,6 +938,29 @@ static int __init omap_mcbsp_init(void)
710 printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n"); 938 printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n");
711 return PTR_ERR(mcbsp_dspxor_ck); 939 return PTR_ERR(mcbsp_dspxor_ck);
712 } 940 }
941#endif
942#ifdef CONFIG_ARCH_OMAP2
943 mcbsp1_ick = clk_get(0, "mcbsp1_ick");
944 if (IS_ERR(mcbsp1_ick)) {
945 printk(KERN_ERR "mcbsp: could not acquire mcbsp1_ick handle.\n");
946 return PTR_ERR(mcbsp1_ick);
947 }
948 mcbsp1_fck = clk_get(0, "mcbsp1_fck");
949 if (IS_ERR(mcbsp1_fck)) {
950 printk(KERN_ERR "mcbsp: could not acquire mcbsp1_fck handle.\n");
951 return PTR_ERR(mcbsp1_fck);
952 }
953 mcbsp2_ick = clk_get(0, "mcbsp2_ick");
954 if (IS_ERR(mcbsp2_ick)) {
955 printk(KERN_ERR "mcbsp: could not acquire mcbsp2_ick handle.\n");
956 return PTR_ERR(mcbsp2_ick);
957 }
958 mcbsp2_fck = clk_get(0, "mcbsp2_fck");
959 if (IS_ERR(mcbsp2_fck)) {
960 printk(KERN_ERR "mcbsp: could not acquire mcbsp2_fck handle.\n");
961 return PTR_ERR(mcbsp2_fck);
962 }
963#endif
713 964
714#ifdef CONFIG_ARCH_OMAP730 965#ifdef CONFIG_ARCH_OMAP730
715 if (cpu_is_omap730()) { 966 if (cpu_is_omap730()) {
@@ -718,7 +969,7 @@ static int __init omap_mcbsp_init(void)
718 } 969 }
719#endif 970#endif
720#ifdef CONFIG_ARCH_OMAP15XX 971#ifdef CONFIG_ARCH_OMAP15XX
721 if (cpu_is_omap1510()) { 972 if (cpu_is_omap15xx()) {
722 mcbsp_info = mcbsp_1510; 973 mcbsp_info = mcbsp_1510;
723 mcbsp_count = ARRAY_SIZE(mcbsp_1510); 974 mcbsp_count = ARRAY_SIZE(mcbsp_1510);
724 } 975 }
@@ -729,6 +980,19 @@ static int __init omap_mcbsp_init(void)
729 mcbsp_count = ARRAY_SIZE(mcbsp_1610); 980 mcbsp_count = ARRAY_SIZE(mcbsp_1610);
730 } 981 }
731#endif 982#endif
983#if defined(CONFIG_ARCH_OMAP24XX)
984 if (cpu_is_omap24xx()) {
985 mcbsp_info = mcbsp_24xx;
986 mcbsp_count = ARRAY_SIZE(mcbsp_24xx);
987
988 /* REVISIT: where's the right place? */
989 omap2_mcbsp2_mux_setup();
990 sys_ck = clk_get(0, "sys_ck");
991 sys_clkout = clk_get(0, "sys_clkout");
992 clk_set_parent(sys_clkout, sys_ck);
993 clk_enable(sys_clkout);
994 }
995#endif
732 for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) { 996 for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) {
733 if (i >= mcbsp_count) { 997 if (i >= mcbsp_count) {
734 mcbsp[i].io_base = 0; 998 mcbsp[i].io_base = 0;
@@ -741,6 +1005,7 @@ static int __init omap_mcbsp_init(void)
741 mcbsp[i].dma_rx_lch = -1; 1005 mcbsp[i].dma_rx_lch = -1;
742 1006
743 mcbsp[i].io_base = mcbsp_info[i].virt_base; 1007 mcbsp[i].io_base = mcbsp_info[i].virt_base;
1008 mcbsp[i].io_type = OMAP_MCBSP_IRQ_IO; /* Default I/O is IRQ based */
744 mcbsp[i].tx_irq = mcbsp_info[i].tx_irq; 1009 mcbsp[i].tx_irq = mcbsp_info[i].tx_irq;
745 mcbsp[i].rx_irq = mcbsp_info[i].rx_irq; 1010 mcbsp[i].rx_irq = mcbsp_info[i].rx_irq;
746 mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync; 1011 mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync;
@@ -751,11 +1016,11 @@ static int __init omap_mcbsp_init(void)
751 return 0; 1016 return 0;
752} 1017}
753 1018
754
755arch_initcall(omap_mcbsp_init); 1019arch_initcall(omap_mcbsp_init);
756 1020
757EXPORT_SYMBOL(omap_mcbsp_config); 1021EXPORT_SYMBOL(omap_mcbsp_config);
758EXPORT_SYMBOL(omap_mcbsp_request); 1022EXPORT_SYMBOL(omap_mcbsp_request);
1023EXPORT_SYMBOL(omap_mcbsp_set_io_type);
759EXPORT_SYMBOL(omap_mcbsp_free); 1024EXPORT_SYMBOL(omap_mcbsp_free);
760EXPORT_SYMBOL(omap_mcbsp_start); 1025EXPORT_SYMBOL(omap_mcbsp_start);
761EXPORT_SYMBOL(omap_mcbsp_stop); 1026EXPORT_SYMBOL(omap_mcbsp_stop);
@@ -763,4 +1028,6 @@ EXPORT_SYMBOL(omap_mcbsp_xmit_word);
763EXPORT_SYMBOL(omap_mcbsp_recv_word); 1028EXPORT_SYMBOL(omap_mcbsp_recv_word);
764EXPORT_SYMBOL(omap_mcbsp_xmit_buffer); 1029EXPORT_SYMBOL(omap_mcbsp_xmit_buffer);
765EXPORT_SYMBOL(omap_mcbsp_recv_buffer); 1030EXPORT_SYMBOL(omap_mcbsp_recv_buffer);
1031EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll);
1032EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll);
766EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); 1033EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
diff --git a/arch/arm/plat-omap/ocpi.c b/arch/arm/plat-omap/ocpi.c
index 5cc6775c789c..37792d43738b 100644
--- a/arch/arm/plat-omap/ocpi.c
+++ b/arch/arm/plat-omap/ocpi.c
@@ -62,9 +62,6 @@ int ocpi_enable(void)
62 if (!cpu_is_omap16xx()) 62 if (!cpu_is_omap16xx())
63 return -ENODEV; 63 return -ENODEV;
64 64
65 /* Make sure there's clock for OCPI */
66 clk_enable(ocpi_ck);
67
68 /* Enable access for OHCI in OCPI */ 65 /* Enable access for OHCI in OCPI */
69 val = omap_readl(OCPI_PROT); 66 val = omap_readl(OCPI_PROT);
70 val &= ~0xff; 67 val &= ~0xff;
diff --git a/arch/arm/plat-omap/pm.c b/arch/arm/plat-omap/pm.c
index 093efd786f21..1a24e2c10714 100644
--- a/arch/arm/plat-omap/pm.c
+++ b/arch/arm/plat-omap/pm.c
@@ -38,6 +38,7 @@
38#include <linux/pm.h> 38#include <linux/pm.h>
39#include <linux/sched.h> 39#include <linux/sched.h>
40#include <linux/proc_fs.h> 40#include <linux/proc_fs.h>
41#include <linux/pm.h>
41#include <linux/interrupt.h> 42#include <linux/interrupt.h>
42 43
43#include <asm/io.h> 44#include <asm/io.h>
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index ee82763b02b8..b7bf09b1b412 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -16,24 +16,94 @@
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/init.h> 17#include <linux/init.h>
18 18
19#include <asm/mach/map.h>
20#include <asm/tlb.h> 19#include <asm/tlb.h>
21#include <asm/io.h> 20#include <asm/io.h>
22#include <asm/cacheflush.h> 21#include <asm/cacheflush.h>
23 22
23#include <asm/mach/map.h>
24
24#include <asm/arch/sram.h> 25#include <asm/arch/sram.h>
26#include <asm/arch/board.h>
25 27
26#define OMAP1_SRAM_PA 0x20000000 28#define OMAP1_SRAM_PA 0x20000000
27#define OMAP1_SRAM_VA 0xd0000000 29#define OMAP1_SRAM_VA 0xd0000000
28#define OMAP2_SRAM_PA 0x40200000 30#define OMAP2_SRAM_PA 0x40200000
31#define OMAP2_SRAM_PUB_PA 0x4020f800
29#define OMAP2_SRAM_VA 0xd0000000 32#define OMAP2_SRAM_VA 0xd0000000
33#define OMAP2_SRAM_PUB_VA 0xd0000800
30 34
35#if defined(CONFIG_ARCH_OMAP24XX)
36#define SRAM_BOOTLOADER_SZ 0x00
37#else
31#define SRAM_BOOTLOADER_SZ 0x80 38#define SRAM_BOOTLOADER_SZ 0x80
39#endif
40
41#define VA_REQINFOPERM0 IO_ADDRESS(0x68005048)
42#define VA_READPERM0 IO_ADDRESS(0x68005050)
43#define VA_WRITEPERM0 IO_ADDRESS(0x68005058)
44#define VA_CONTROL_STAT IO_ADDRESS(0x480002F8)
45#define GP_DEVICE 0x300
46#define TYPE_MASK 0x700
47
48#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1)))
32 49
33static unsigned long omap_sram_base; 50static unsigned long omap_sram_base;
34static unsigned long omap_sram_size; 51static unsigned long omap_sram_size;
35static unsigned long omap_sram_ceil; 52static unsigned long omap_sram_ceil;
36 53
54unsigned long omap_fb_sram_start;
55unsigned long omap_fb_sram_size;
56
57/* Depending on the target RAMFS firewall setup, the public usable amount of
58 * SRAM varies. The default accessable size for all device types is 2k. A GP
59 * device allows ARM11 but not other initators for full size. This
60 * functionality seems ok until some nice security API happens.
61 */
62static int is_sram_locked(void)
63{
64 int type = 0;
65
66 if (cpu_is_omap242x())
67 type = __raw_readl(VA_CONTROL_STAT) & TYPE_MASK;
68
69 if (type == GP_DEVICE) {
70 /* RAMFW: R/W access to all initators for all qualifier sets */
71 if (cpu_is_omap242x()) {
72 __raw_writel(0xFF, VA_REQINFOPERM0); /* all q-vects */
73 __raw_writel(0xCFDE, VA_READPERM0); /* all i-read */
74 __raw_writel(0xCFDE, VA_WRITEPERM0); /* all i-write */
75 }
76 return 0;
77 } else
78 return 1; /* assume locked with no PPA or security driver */
79}
80
81void get_fb_sram_conf(unsigned long start_avail, unsigned size_avail,
82 unsigned long *start, unsigned long *size)
83{
84 const struct omap_fbmem_config *fbmem_conf;
85
86 fbmem_conf = omap_get_config(OMAP_TAG_FBMEM, struct omap_fbmem_config);
87 if (fbmem_conf != NULL) {
88 *start = fbmem_conf->fb_sram_start;
89 *size = fbmem_conf->fb_sram_size;
90 } else {
91 *size = 0;
92 *start = 0;
93 }
94
95 if (*size && (
96 *start < start_avail ||
97 *start + *size > start_avail + size_avail)) {
98 printk(KERN_ERR "invalid FB SRAM configuration\n");
99 *start = start_avail;
100 *size = size_avail;
101 }
102
103 if (*size)
104 pr_info("Reserving %lu bytes SRAM for frame buffer\n", *size);
105}
106
37/* 107/*
38 * The amount of SRAM depends on the core type. 108 * The amount of SRAM depends on the core type.
39 * Note that we cannot try to test for SRAM here because writes 109 * Note that we cannot try to test for SRAM here because writes
@@ -42,26 +112,45 @@ static unsigned long omap_sram_ceil;
42 */ 112 */
43void __init omap_detect_sram(void) 113void __init omap_detect_sram(void)
44{ 114{
45 if (!cpu_is_omap24xx()) 115 unsigned long sram_start;
116
117 if (cpu_is_omap24xx()) {
118 if (is_sram_locked()) {
119 omap_sram_base = OMAP2_SRAM_PUB_VA;
120 sram_start = OMAP2_SRAM_PUB_PA;
121 omap_sram_size = 0x800; /* 2K */
122 } else {
123 omap_sram_base = OMAP2_SRAM_VA;
124 sram_start = OMAP2_SRAM_PA;
125 if (cpu_is_omap242x())
126 omap_sram_size = 0xa0000; /* 640K */
127 else if (cpu_is_omap243x())
128 omap_sram_size = 0x10000; /* 64K */
129 }
130 } else {
46 omap_sram_base = OMAP1_SRAM_VA; 131 omap_sram_base = OMAP1_SRAM_VA;
47 else 132 sram_start = OMAP1_SRAM_PA;
48 omap_sram_base = OMAP2_SRAM_VA; 133
49 134 if (cpu_is_omap730())
50 if (cpu_is_omap730()) 135 omap_sram_size = 0x32000; /* 200K */
51 omap_sram_size = 0x32000; /* 200K */ 136 else if (cpu_is_omap15xx())
52 else if (cpu_is_omap15xx()) 137 omap_sram_size = 0x30000; /* 192K */
53 omap_sram_size = 0x30000; /* 192K */ 138 else if (cpu_is_omap1610() || cpu_is_omap1621() ||
54 else if (cpu_is_omap1610() || cpu_is_omap1621() || cpu_is_omap1710()) 139 cpu_is_omap1710())
55 omap_sram_size = 0x4000; /* 16K */ 140 omap_sram_size = 0x4000; /* 16K */
56 else if (cpu_is_omap1611()) 141 else if (cpu_is_omap1611())
57 omap_sram_size = 0x3e800; /* 250K */ 142 omap_sram_size = 0x3e800; /* 250K */
58 else if (cpu_is_omap2420()) 143 else {
59 omap_sram_size = 0xa0014; /* 640K */ 144 printk(KERN_ERR "Could not detect SRAM size\n");
60 else { 145 omap_sram_size = 0x4000;
61 printk(KERN_ERR "Could not detect SRAM size\n"); 146 }
62 omap_sram_size = 0x4000;
63 } 147 }
64 148 get_fb_sram_conf(sram_start + SRAM_BOOTLOADER_SZ,
149 omap_sram_size - SRAM_BOOTLOADER_SZ,
150 &omap_fb_sram_start, &omap_fb_sram_size);
151 if (omap_fb_sram_size)
152 omap_sram_size -= sram_start + omap_sram_size -
153 omap_fb_sram_start;
65 omap_sram_ceil = omap_sram_base + omap_sram_size; 154 omap_sram_ceil = omap_sram_base + omap_sram_size;
66} 155}
67 156
@@ -80,12 +169,20 @@ static struct map_desc omap_sram_io_desc[] __initdata = {
80 */ 169 */
81void __init omap_map_sram(void) 170void __init omap_map_sram(void)
82{ 171{
172 unsigned long base;
173
83 if (omap_sram_size == 0) 174 if (omap_sram_size == 0)
84 return; 175 return;
85 176
86 if (cpu_is_omap24xx()) { 177 if (cpu_is_omap24xx()) {
87 omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA; 178 omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA;
88 omap_sram_io_desc[0].pfn = __phys_to_pfn(OMAP2_SRAM_PA); 179
180 if (is_sram_locked())
181 base = OMAP2_SRAM_PUB_PA;
182 else
183 base = OMAP2_SRAM_PA;
184 base = ROUND_DOWN(base, PAGE_SIZE);
185 omap_sram_io_desc[0].pfn = __phys_to_pfn(base);
89 } 186 }
90 187
91 omap_sram_io_desc[0].length = (omap_sram_size + PAGE_SIZE-1)/PAGE_SIZE; 188 omap_sram_io_desc[0].length = (omap_sram_size + PAGE_SIZE-1)/PAGE_SIZE;
@@ -93,7 +190,8 @@ void __init omap_map_sram(void)
93 iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc)); 190 iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc));
94 191
95 printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n", 192 printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n",
96 omap_sram_io_desc[0].pfn, omap_sram_io_desc[0].virtual, 193 __pfn_to_phys(omap_sram_io_desc[0].pfn),
194 omap_sram_io_desc[0].virtual,
97 omap_sram_io_desc[0].length); 195 omap_sram_io_desc[0].length);
98 196
99 /* 197 /*
@@ -118,8 +216,9 @@ void * omap_sram_push(void * start, unsigned long size)
118 printk(KERN_ERR "Not enough space in SRAM\n"); 216 printk(KERN_ERR "Not enough space in SRAM\n");
119 return NULL; 217 return NULL;
120 } 218 }
219
121 omap_sram_ceil -= size; 220 omap_sram_ceil -= size;
122 omap_sram_ceil &= ~0x3; 221 omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, sizeof(void *));
123 memcpy((void *)omap_sram_ceil, start, size); 222 memcpy((void *)omap_sram_ceil, start, size);
124 223
125 return (void *)omap_sram_ceil; 224 return (void *)omap_sram_ceil;
diff --git a/arch/arm/plat-omap/timer32k.c b/arch/arm/plat-omap/timer32k.c
new file mode 100644
index 000000000000..b2a943bf11ef
--- /dev/null
+++ b/arch/arm/plat-omap/timer32k.c
@@ -0,0 +1,325 @@
1/*
2 * linux/arch/arm/plat-omap/timer32k.c
3 *
4 * OMAP 32K Timer
5 *
6 * Copyright (C) 2004 - 2005 Nokia Corporation
7 * Partial timer rewrite and additional dynamic tick timer support by
8 * Tony Lindgen <tony@atomide.com> and
9 * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
10 *
11 * MPU timer code based on the older MPU timer code for OMAP
12 * Copyright (C) 2000 RidgeRun, Inc.
13 * Author: Greg Lonnon <glonnon@ridgerun.com>
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
19 *
20 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
21 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
23 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * You should have received a copy of the GNU General Public License along
32 * with this program; if not, write to the Free Software Foundation, Inc.,
33 * 675 Mass Ave, Cambridge, MA 02139, USA.
34 */
35
36#include <linux/config.h>
37#include <linux/kernel.h>
38#include <linux/init.h>
39#include <linux/delay.h>
40#include <linux/interrupt.h>
41#include <linux/sched.h>
42#include <linux/spinlock.h>
43#include <linux/err.h>
44#include <linux/clk.h>
45
46#include <asm/system.h>
47#include <asm/hardware.h>
48#include <asm/io.h>
49#include <asm/leds.h>
50#include <asm/irq.h>
51#include <asm/mach/irq.h>
52#include <asm/mach/time.h>
53
54struct sys_timer omap_timer;
55
56/*
57 * ---------------------------------------------------------------------------
58 * 32KHz OS timer
59 *
60 * This currently works only on 16xx, as 1510 does not have the continuous
61 * 32KHz synchronous timer. The 32KHz synchronous timer is used to keep track
62 * of time in addition to the 32KHz OS timer. Using only the 32KHz OS timer
63 * on 1510 would be possible, but the timer would not be as accurate as
64 * with the 32KHz synchronized timer.
65 * ---------------------------------------------------------------------------
66 */
67
68#if defined(CONFIG_ARCH_OMAP16XX)
69#define TIMER_32K_SYNCHRONIZED 0xfffbc410
70#elif defined(CONFIG_ARCH_OMAP24XX)
71#define TIMER_32K_SYNCHRONIZED 0x48004010
72#else
73#error OMAP 32KHz timer does not currently work on 15XX!
74#endif
75
76/* 16xx specific defines */
77#define OMAP1_32K_TIMER_BASE 0xfffb9000
78#define OMAP1_32K_TIMER_CR 0x08
79#define OMAP1_32K_TIMER_TVR 0x00
80#define OMAP1_32K_TIMER_TCR 0x04
81
82/* 24xx specific defines */
83#define OMAP2_GP_TIMER_BASE 0x48028000
84#define CM_CLKSEL_WKUP 0x48008440
85#define GP_TIMER_TIDR 0x00
86#define GP_TIMER_TISR 0x18
87#define GP_TIMER_TIER 0x1c
88#define GP_TIMER_TCLR 0x24
89#define GP_TIMER_TCRR 0x28
90#define GP_TIMER_TLDR 0x2c
91#define GP_TIMER_TTGR 0x30
92#define GP_TIMER_TSICR 0x40
93
94#define OMAP_32K_TICKS_PER_HZ (32768 / HZ)
95
96/*
97 * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1
98 * so with HZ = 128, TVR = 255.
99 */
100#define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1)
101
102#define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \
103 (((nr_jiffies) * (clock_rate)) / HZ)
104
105static inline void omap_32k_timer_write(int val, int reg)
106{
107 if (cpu_class_is_omap1())
108 omap_writew(val, OMAP1_32K_TIMER_BASE + reg);
109
110 if (cpu_is_omap24xx())
111 omap_writel(val, OMAP2_GP_TIMER_BASE + reg);
112}
113
114static inline unsigned long omap_32k_timer_read(int reg)
115{
116 if (cpu_class_is_omap1())
117 return omap_readl(OMAP1_32K_TIMER_BASE + reg) & 0xffffff;
118
119 if (cpu_is_omap24xx())
120 return omap_readl(OMAP2_GP_TIMER_BASE + reg);
121}
122
123/*
124 * The 32KHz synchronized timer is an additional timer on 16xx.
125 * It is always running.
126 */
127static inline unsigned long omap_32k_sync_timer_read(void)
128{
129 return omap_readl(TIMER_32K_SYNCHRONIZED);
130}
131
132static inline void omap_32k_timer_start(unsigned long load_val)
133{
134 if (cpu_class_is_omap1()) {
135 omap_32k_timer_write(load_val, OMAP1_32K_TIMER_TVR);
136 omap_32k_timer_write(0x0f, OMAP1_32K_TIMER_CR);
137 }
138
139 if (cpu_is_omap24xx()) {
140 omap_32k_timer_write(0xffffffff - load_val, GP_TIMER_TCRR);
141 omap_32k_timer_write((1 << 1), GP_TIMER_TIER);
142 omap_32k_timer_write((1 << 1) | 1, GP_TIMER_TCLR);
143 }
144}
145
146static inline void omap_32k_timer_stop(void)
147{
148 if (cpu_class_is_omap1())
149 omap_32k_timer_write(0x0, OMAP1_32K_TIMER_CR);
150
151 if (cpu_is_omap24xx())
152 omap_32k_timer_write(0x0, GP_TIMER_TCLR);
153}
154
155/*
156 * Rounds down to nearest usec. Note that this will overflow for larger values.
157 */
158static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k)
159{
160 return (ticks_32k * 5*5*5*5*5*5) >> 9;
161}
162
163/*
164 * Rounds down to nearest nsec.
165 */
166static inline unsigned long long
167omap_32k_ticks_to_nsecs(unsigned long ticks_32k)
168{
169 return (unsigned long long) ticks_32k * 1000 * 5*5*5*5*5*5 >> 9;
170}
171
172static unsigned long omap_32k_last_tick = 0;
173
174/*
175 * Returns elapsed usecs since last 32k timer interrupt
176 */
177static unsigned long omap_32k_timer_gettimeoffset(void)
178{
179 unsigned long now = omap_32k_sync_timer_read();
180 return omap_32k_ticks_to_usecs(now - omap_32k_last_tick);
181}
182
183/*
184 * Returns current time from boot in nsecs. It's OK for this to wrap
185 * around for now, as it's just a relative time stamp.
186 */
187unsigned long long sched_clock(void)
188{
189 return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read());
190}
191
192/*
193 * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this
194 * function is also called from other interrupts to remove latency
195 * issues with dynamic tick. In the dynamic tick case, we need to lock
196 * with irqsave.
197 */
198static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
199 struct pt_regs *regs)
200{
201 unsigned long flags;
202 unsigned long now;
203
204 write_seqlock_irqsave(&xtime_lock, flags);
205
206 if (cpu_is_omap24xx()) {
207 u32 status = omap_32k_timer_read(GP_TIMER_TISR);
208 omap_32k_timer_write(status, GP_TIMER_TISR);
209 }
210
211 now = omap_32k_sync_timer_read();
212
213 while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) {
214 omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ;
215 timer_tick(regs);
216 }
217
218 /* Restart timer so we don't drift off due to modulo or dynamic tick.
219 * By default we program the next timer to be continuous to avoid
220 * latencies during high system load. During dynamic tick operation the
221 * continuous timer can be overridden from pm_idle to be longer.
222 */
223 omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now);
224 write_sequnlock_irqrestore(&xtime_lock, flags);
225
226 return IRQ_HANDLED;
227}
228
229#ifdef CONFIG_NO_IDLE_HZ
230/*
231 * Programs the next timer interrupt needed. Called when dynamic tick is
232 * enabled, and to reprogram the ticks to skip from pm_idle. Note that
233 * we can keep the timer continuous, and don't need to set it to run in
234 * one-shot mode. This is because the timer will get reprogrammed again
235 * after next interrupt.
236 */
237void omap_32k_timer_reprogram(unsigned long next_tick)
238{
239 omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1);
240}
241
242static struct irqaction omap_32k_timer_irq;
243extern struct timer_update_handler timer_update;
244
245static int omap_32k_timer_enable_dyn_tick(void)
246{
247 /* No need to reprogram timer, just use the next interrupt */
248 return 0;
249}
250
251static int omap_32k_timer_disable_dyn_tick(void)
252{
253 omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
254 return 0;
255}
256
257static struct dyn_tick_timer omap_dyn_tick_timer = {
258 .enable = omap_32k_timer_enable_dyn_tick,
259 .disable = omap_32k_timer_disable_dyn_tick,
260 .reprogram = omap_32k_timer_reprogram,
261 .handler = omap_32k_timer_interrupt,
262};
263#endif /* CONFIG_NO_IDLE_HZ */
264
265static struct irqaction omap_32k_timer_irq = {
266 .name = "32KHz timer",
267 .flags = SA_INTERRUPT | SA_TIMER,
268 .handler = omap_32k_timer_interrupt,
269};
270
271static struct clk * gpt1_ick;
272static struct clk * gpt1_fck;
273
274static __init void omap_init_32k_timer(void)
275{
276#ifdef CONFIG_NO_IDLE_HZ
277 omap_timer.dyn_tick = &omap_dyn_tick_timer;
278#endif
279
280 if (cpu_class_is_omap1())
281 setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
282 if (cpu_is_omap24xx())
283 setup_irq(37, &omap_32k_timer_irq);
284 omap_timer.offset = omap_32k_timer_gettimeoffset;
285 omap_32k_last_tick = omap_32k_sync_timer_read();
286
287 /* REVISIT: Check 24xx TIOCP_CFG settings after idle works */
288 if (cpu_is_omap24xx()) {
289 omap_32k_timer_write(0, GP_TIMER_TCLR);
290 omap_writel(0, CM_CLKSEL_WKUP); /* 32KHz clock source */
291
292 gpt1_ick = clk_get(NULL, "gpt1_ick");
293 if (IS_ERR(gpt1_ick))
294 printk(KERN_ERR "Could not get gpt1_ick\n");
295 else
296 clk_enable(gpt1_ick);
297
298 gpt1_fck = clk_get(NULL, "gpt1_fck");
299 if (IS_ERR(gpt1_fck))
300 printk(KERN_ERR "Could not get gpt1_fck\n");
301 else
302 clk_enable(gpt1_fck);
303
304 mdelay(100); /* Wait for clocks to stabilize */
305
306 omap_32k_timer_write(0x7, GP_TIMER_TISR);
307 }
308
309 omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
310}
311
312/*
313 * ---------------------------------------------------------------------------
314 * Timer initialization
315 * ---------------------------------------------------------------------------
316 */
317static void __init omap_timer_init(void)
318{
319 omap_init_32k_timer();
320}
321
322struct sys_timer omap_timer = {
323 .init = omap_timer_init,
324 .offset = NULL, /* Initialized later */
325};
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c
index e3c5fca0aa8a..2b0cfce24a61 100644
--- a/arch/i386/kernel/crash.c
+++ b/arch/i386/kernel/crash.c
@@ -69,7 +69,7 @@ static void crash_save_this_cpu(struct pt_regs *regs, int cpu)
69 * for the data I pass, and I need tags 69 * for the data I pass, and I need tags
70 * on the data to indicate what information I have 70 * on the data to indicate what information I have
71 * squirrelled away. ELF notes happen to provide 71 * squirrelled away. ELF notes happen to provide
72 * all of that that no need to invent something new. 72 * all of that, so there is no need to invent something new.
73 */ 73 */
74 buf = (u32*)per_cpu_ptr(crash_notes, cpu); 74 buf = (u32*)per_cpu_ptr(crash_notes, cpu);
75 if (!buf) 75 if (!buf)
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 5b26af8597f3..e112d1a5dab6 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1740,7 +1740,7 @@ EXPORT_SYMBOL(blk_run_queue);
1740 1740
1741/** 1741/**
1742 * blk_cleanup_queue: - release a &request_queue_t when it is no longer needed 1742 * blk_cleanup_queue: - release a &request_queue_t when it is no longer needed
1743 * @q: the request queue to be released 1743 * @kobj: the kobj belonging of the request queue to be released
1744 * 1744 *
1745 * Description: 1745 * Description:
1746 * blk_cleanup_queue is the pair to blk_init_queue() or 1746 * blk_cleanup_queue is the pair to blk_init_queue() or
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
index 16e99db2e12d..d53f664a4dd8 100644
--- a/drivers/char/watchdog/Kconfig
+++ b/drivers/char/watchdog/Kconfig
@@ -60,6 +60,13 @@ config SOFT_WATCHDOG
60 60
61# ARM Architecture 61# ARM Architecture
62 62
63config AT91_WATCHDOG
64 tristate "AT91RM9200 watchdog"
65 depends on WATCHDOG && ARCH_AT91RM9200
66 help
67 Watchdog timer embedded into AT91RM9200 chips. This will reboot your
68 system when the timeout is reached.
69
63config 21285_WATCHDOG 70config 21285_WATCHDOG
64 tristate "DC21285 watchdog" 71 tristate "DC21285 watchdog"
65 depends on WATCHDOG && FOOTBRIDGE 72 depends on WATCHDOG && FOOTBRIDGE
diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile
index d6f27fde9905..6ab77b61a643 100644
--- a/drivers/char/watchdog/Makefile
+++ b/drivers/char/watchdog/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_WDTPCI) += wdt_pci.o
23obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o 23obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
24 24
25# ARM Architecture 25# ARM Architecture
26obj-$(CONFIG_AT91_WATCHDOG) += at91_wdt.o
26obj-$(CONFIG_21285_WATCHDOG) += wdt285.o 27obj-$(CONFIG_21285_WATCHDOG) += wdt285.o
27obj-$(CONFIG_977_WATCHDOG) += wdt977.o 28obj-$(CONFIG_977_WATCHDOG) += wdt977.o
28obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o 29obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o
diff --git a/drivers/char/watchdog/at91_wdt.c b/drivers/char/watchdog/at91_wdt.c
new file mode 100644
index 000000000000..ac83bc4b019a
--- /dev/null
+++ b/drivers/char/watchdog/at91_wdt.c
@@ -0,0 +1,228 @@
1/*
2 * Watchdog driver for Atmel AT91RM9200 (Thunder)
3 *
4 * Copyright (C) 2003 SAN People (Pty) Ltd
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/config.h>
13#include <linux/errno.h>
14#include <linux/fs.h>
15#include <linux/init.h>
16#include <linux/kernel.h>
17#include <linux/miscdevice.h>
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/types.h>
21#include <linux/watchdog.h>
22#include <asm/bitops.h>
23#include <asm/uaccess.h>
24
25
26#define WDT_DEFAULT_TIME 5 /* 5 seconds */
27#define WDT_MAX_TIME 256 /* 256 seconds */
28
29static int wdt_time = WDT_DEFAULT_TIME;
30static int nowayout = WATCHDOG_NOWAYOUT;
31
32module_param(wdt_time, int, 0);
33MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")");
34
35module_param(nowayout, int, 0);
36MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
37
38
39static unsigned long at91wdt_busy;
40
41/* ......................................................................... */
42
43/*
44 * Disable the watchdog.
45 */
46static void inline at91_wdt_stop(void)
47{
48 at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN);
49}
50
51/*
52 * Enable and reset the watchdog.
53 */
54static void inline at91_wdt_start(void)
55{
56 at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN | (((65536 * wdt_time) >> 8) & AT91_ST_WDV));
57 at91_sys_write(AT91_ST_CR, AT91_ST_WDRST);
58}
59
60/*
61 * Reload the watchdog timer. (ie, pat the watchdog)
62 */
63static void inline at91_wdt_reload(void)
64{
65 at91_sys_write(AT91_ST_CR, AT91_ST_WDRST);
66}
67
68/* ......................................................................... */
69
70/*
71 * Watchdog device is opened, and watchdog starts running.
72 */
73static int at91_wdt_open(struct inode *inode, struct file *file)
74{
75 if (test_and_set_bit(0, &at91wdt_busy))
76 return -EBUSY;
77
78 at91_wdt_start();
79 return nonseekable_open(inode, file);
80}
81
82/*
83 * Close the watchdog device.
84 * If CONFIG_WATCHDOG_NOWAYOUT is NOT defined then the watchdog is also
85 * disabled.
86 */
87static int at91_wdt_close(struct inode *inode, struct file *file)
88{
89 if (!nowayout)
90 at91_wdt_stop(); /* Disable the watchdog when file is closed */
91
92 clear_bit(0, &at91wdt_busy);
93 return 0;
94}
95
96/*
97 * Change the watchdog time interval.
98 */
99static int at91_wdt_settimeout(int new_time)
100{
101 /*
102 * All counting occurs at SLOW_CLOCK / 128 = 0.256 Hz
103 *
104 * Since WDV is a 16-bit counter, the maximum period is
105 * 65536 / 0.256 = 256 seconds.
106 */
107 if ((new_time <= 0) || (new_time > WDT_MAX_TIME))
108 return -EINVAL;
109
110 /* Set new watchdog time. It will be used when at91_wdt_start() is called. */
111 wdt_time = new_time;
112 return 0;
113}
114
115static struct watchdog_info at91_wdt_info = {
116 .identity = "at91 watchdog",
117 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
118};
119
120/*
121 * Handle commands from user-space.
122 */
123static int at91_wdt_ioctl(struct inode *inode, struct file *file,
124 unsigned int cmd, unsigned long arg)
125{
126 void __user *argp = (void __user *)arg;
127 int __user *p = argp;
128 int new_value;
129
130 switch(cmd) {
131 case WDIOC_KEEPALIVE:
132 at91_wdt_reload(); /* pat the watchdog */
133 return 0;
134
135 case WDIOC_GETSUPPORT:
136 return copy_to_user(argp, &at91_wdt_info, sizeof(at91_wdt_info)) ? -EFAULT : 0;
137
138 case WDIOC_SETTIMEOUT:
139 if (get_user(new_value, p))
140 return -EFAULT;
141
142 if (at91_wdt_settimeout(new_value))
143 return -EINVAL;
144
145 /* Enable new time value */
146 at91_wdt_start();
147
148 /* Return current value */
149 return put_user(wdt_time, p);
150
151 case WDIOC_GETTIMEOUT:
152 return put_user(wdt_time, p);
153
154 case WDIOC_GETSTATUS:
155 case WDIOC_GETBOOTSTATUS:
156 return put_user(0, p);
157
158 case WDIOC_SETOPTIONS:
159 if (get_user(new_value, p))
160 return -EFAULT;
161
162 if (new_value & WDIOS_DISABLECARD)
163 at91_wdt_stop();
164 if (new_value & WDIOS_ENABLECARD)
165 at91_wdt_start();
166 return 0;
167
168 default:
169 return -ENOIOCTLCMD;
170 }
171}
172
173/*
174 * Pat the watchdog whenever device is written to.
175 */
176static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos)
177{
178 at91_wdt_reload(); /* pat the watchdog */
179 return len;
180}
181
182/* ......................................................................... */
183
184static struct file_operations at91wdt_fops = {
185 .owner = THIS_MODULE,
186 .llseek = no_llseek,
187 .ioctl = at91_wdt_ioctl,
188 .open = at91_wdt_open,
189 .release = at91_wdt_close,
190 .write = at91_wdt_write,
191};
192
193static struct miscdevice at91wdt_miscdev = {
194 .minor = WATCHDOG_MINOR,
195 .name = "watchdog",
196 .fops = &at91wdt_fops,
197};
198
199static int __init at91_wdt_init(void)
200{
201 int res;
202
203 /* Check that the heartbeat value is within range; if not reset to the default */
204 if (at91_wdt_settimeout(wdt_time)) {
205 at91_wdt_settimeout(WDT_DEFAULT_TIME);
206 printk(KERN_INFO "at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time);
207 }
208
209 res = misc_register(&at91wdt_miscdev);
210 if (res)
211 return res;
212
213 printk("AT91 Watchdog Timer enabled (%d seconds, nowayout=%d)\n", wdt_time, nowayout);
214 return 0;
215}
216
217static void __exit at91_wdt_exit(void)
218{
219 misc_deregister(&at91wdt_miscdev);
220}
221
222module_init(at91_wdt_init);
223module_exit(at91_wdt_exit);
224
225MODULE_AUTHOR("Andrew Victor");
226MODULE_DESCRIPTION("Watchdog driver for Atmel AT91RM9200");
227MODULE_LICENSE("GPL");
228MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c
index 8d6b249ad66b..6d44ca68312d 100644
--- a/drivers/char/watchdog/pcwd.c
+++ b/drivers/char/watchdog/pcwd.c
@@ -66,15 +66,13 @@
66#include <linux/fs.h> /* For file operations */ 66#include <linux/fs.h> /* For file operations */
67#include <linux/ioport.h> /* For io-port access */ 67#include <linux/ioport.h> /* For io-port access */
68#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ 68#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */
69#include <linux/sched.h> /* TASK_INTERRUPTIBLE, set_current_state() and friends */
70#include <linux/slab.h> /* For kmalloc */
71 69
72#include <asm/uaccess.h> /* For copy_to_user/put_user/... */ 70#include <asm/uaccess.h> /* For copy_to_user/put_user/... */
73#include <asm/io.h> /* For inb/outb/... */ 71#include <asm/io.h> /* For inb/outb/... */
74 72
75/* Module and version information */ 73/* Module and version information */
76#define WATCHDOG_VERSION "1.16" 74#define WATCHDOG_VERSION "1.17"
77#define WATCHDOG_DATE "03 Jan 2006" 75#define WATCHDOG_DATE "12 Feb 2006"
78#define WATCHDOG_DRIVER_NAME "ISA-PC Watchdog" 76#define WATCHDOG_DRIVER_NAME "ISA-PC Watchdog"
79#define WATCHDOG_NAME "pcwd" 77#define WATCHDOG_NAME "pcwd"
80#define PFX WATCHDOG_NAME ": " 78#define PFX WATCHDOG_NAME ": "
@@ -96,15 +94,19 @@
96 * PCI-PC Watchdog card. 94 * PCI-PC Watchdog card.
97*/ 95*/
98/* Port 1 : Control Status #1 for the PC Watchdog card, revision A. */ 96/* Port 1 : Control Status #1 for the PC Watchdog card, revision A. */
99#define WD_WDRST 0x01 /* Previously reset state */ 97#define WD_WDRST 0x01 /* Previously reset state */
100#define WD_T110 0x02 /* Temperature overheat sense */ 98#define WD_T110 0x02 /* Temperature overheat sense */
101#define WD_HRTBT 0x04 /* Heartbeat sense */ 99#define WD_HRTBT 0x04 /* Heartbeat sense */
102#define WD_RLY2 0x08 /* External relay triggered */ 100#define WD_RLY2 0x08 /* External relay triggered */
103#define WD_SRLY2 0x80 /* Software external relay triggered */ 101#define WD_SRLY2 0x80 /* Software external relay triggered */
104/* Port 1 : Control Status #1 for the PC Watchdog card, revision C. */ 102/* Port 1 : Control Status #1 for the PC Watchdog card, revision C. */
105#define WD_REVC_WTRP 0x01 /* Watchdog Trip status */ 103#define WD_REVC_WTRP 0x01 /* Watchdog Trip status */
106#define WD_REVC_HRBT 0x02 /* Watchdog Heartbeat */ 104#define WD_REVC_HRBT 0x02 /* Watchdog Heartbeat */
107#define WD_REVC_TTRP 0x04 /* Temperature Trip status */ 105#define WD_REVC_TTRP 0x04 /* Temperature Trip status */
106#define WD_REVC_RL2A 0x08 /* Relay 2 activated by on-board processor */
107#define WD_REVC_RL1A 0x10 /* Relay 1 active */
108#define WD_REVC_R2DS 0x40 /* Relay 2 disable */
109#define WD_REVC_RLY2 0x80 /* Relay 2 activated? */
108/* Port 2 : Control Status #2 */ 110/* Port 2 : Control Status #2 */
109#define WD_WDIS 0x10 /* Watchdog Disabled */ 111#define WD_WDIS 0x10 /* Watchdog Disabled */
110#define WD_ENTP 0x20 /* Watchdog Enable Temperature Trip */ 112#define WD_ENTP 0x20 /* Watchdog Enable Temperature Trip */
@@ -122,9 +124,14 @@
122#define CMD_ISA_VERSION_HUNDRETH 0x03 124#define CMD_ISA_VERSION_HUNDRETH 0x03
123#define CMD_ISA_VERSION_MINOR 0x04 125#define CMD_ISA_VERSION_MINOR 0x04
124#define CMD_ISA_SWITCH_SETTINGS 0x05 126#define CMD_ISA_SWITCH_SETTINGS 0x05
127#define CMD_ISA_RESET_PC 0x06
128#define CMD_ISA_ARM_0 0x07
129#define CMD_ISA_ARM_30 0x08
130#define CMD_ISA_ARM_60 0x09
125#define CMD_ISA_DELAY_TIME_2SECS 0x0A 131#define CMD_ISA_DELAY_TIME_2SECS 0x0A
126#define CMD_ISA_DELAY_TIME_4SECS 0x0B 132#define CMD_ISA_DELAY_TIME_4SECS 0x0B
127#define CMD_ISA_DELAY_TIME_8SECS 0x0C 133#define CMD_ISA_DELAY_TIME_8SECS 0x0C
134#define CMD_ISA_RESET_RELAYS 0x0D
128 135
129/* 136/*
130 * We are using an kernel timer to do the pinging of the watchdog 137 * We are using an kernel timer to do the pinging of the watchdog
@@ -142,6 +149,7 @@ static atomic_t open_allowed = ATOMIC_INIT(1);
142static char expect_close; 149static char expect_close;
143static int temp_panic; 150static int temp_panic;
144static struct { /* this is private data for each ISA-PC watchdog card */ 151static struct { /* this is private data for each ISA-PC watchdog card */
152 char fw_ver_str[6]; /* The cards firmware version */
145 int revision; /* The card's revision */ 153 int revision; /* The card's revision */
146 int supports_temp; /* Wether or not the card has a temperature device */ 154 int supports_temp; /* Wether or not the card has a temperature device */
147 int command_mode; /* Wether or not the card is in command mode */ 155 int command_mode; /* Wether or not the card is in command mode */
@@ -153,6 +161,13 @@ static struct { /* this is private data for each ISA-PC watchdog card */
153} pcwd_private; 161} pcwd_private;
154 162
155/* module parameters */ 163/* module parameters */
164#define QUIET 0 /* Default */
165#define VERBOSE 1 /* Verbose */
166#define DEBUG 2 /* print fancy stuff too */
167static int debug = QUIET;
168module_param(debug, int, 0);
169MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)");
170
156#define WATCHDOG_HEARTBEAT 60 /* 60 sec default heartbeat */ 171#define WATCHDOG_HEARTBEAT 60 /* 60 sec default heartbeat */
157static int heartbeat = WATCHDOG_HEARTBEAT; 172static int heartbeat = WATCHDOG_HEARTBEAT;
158module_param(heartbeat, int, 0); 173module_param(heartbeat, int, 0);
@@ -172,6 +187,10 @@ static int send_isa_command(int cmd)
172 int control_status; 187 int control_status;
173 int port0, last_port0; /* Double read for stabilising */ 188 int port0, last_port0; /* Double read for stabilising */
174 189
190 if (debug >= DEBUG)
191 printk(KERN_DEBUG PFX "sending following data cmd=0x%02x\n",
192 cmd);
193
175 /* The WCMD bit must be 1 and the command is only 4 bits in size */ 194 /* The WCMD bit must be 1 and the command is only 4 bits in size */
176 control_status = (cmd & 0x0F) | WD_WCMD; 195 control_status = (cmd & 0x0F) | WD_WCMD;
177 outb_p(control_status, pcwd_private.io_addr + 2); 196 outb_p(control_status, pcwd_private.io_addr + 2);
@@ -188,6 +207,10 @@ static int send_isa_command(int cmd)
188 udelay (250); 207 udelay (250);
189 } 208 }
190 209
210 if (debug >= DEBUG)
211 printk(KERN_DEBUG PFX "received following data for cmd=0x%02x: port0=0x%02x last_port0=0x%02x\n",
212 cmd, port0, last_port0);
213
191 return port0; 214 return port0;
192} 215}
193 216
@@ -214,6 +237,10 @@ static int set_command_mode(void)
214 spin_unlock(&pcwd_private.io_lock); 237 spin_unlock(&pcwd_private.io_lock);
215 pcwd_private.command_mode = found; 238 pcwd_private.command_mode = found;
216 239
240 if (debug >= DEBUG)
241 printk(KERN_DEBUG PFX "command_mode=%d\n",
242 pcwd_private.command_mode);
243
217 return(found); 244 return(found);
218} 245}
219 246
@@ -226,6 +253,10 @@ static void unset_command_mode(void)
226 spin_unlock(&pcwd_private.io_lock); 253 spin_unlock(&pcwd_private.io_lock);
227 254
228 pcwd_private.command_mode = 0; 255 pcwd_private.command_mode = 0;
256
257 if (debug >= DEBUG)
258 printk(KERN_DEBUG PFX "command_mode=%d\n",
259 pcwd_private.command_mode);
229} 260}
230 261
231static inline void pcwd_check_temperature_support(void) 262static inline void pcwd_check_temperature_support(void)
@@ -234,27 +265,22 @@ static inline void pcwd_check_temperature_support(void)
234 pcwd_private.supports_temp = 1; 265 pcwd_private.supports_temp = 1;
235} 266}
236 267
237static inline char *get_firmware(void) 268static inline void pcwd_get_firmware(void)
238{ 269{
239 int one, ten, hund, minor; 270 int one, ten, hund, minor;
240 char *ret;
241 271
242 ret = kmalloc(6, GFP_KERNEL); 272 strcpy(pcwd_private.fw_ver_str, "ERROR");
243 if(ret == NULL)
244 return NULL;
245 273
246 if (set_command_mode()) { 274 if (set_command_mode()) {
247 one = send_isa_command(CMD_ISA_VERSION_INTEGER); 275 one = send_isa_command(CMD_ISA_VERSION_INTEGER);
248 ten = send_isa_command(CMD_ISA_VERSION_TENTH); 276 ten = send_isa_command(CMD_ISA_VERSION_TENTH);
249 hund = send_isa_command(CMD_ISA_VERSION_HUNDRETH); 277 hund = send_isa_command(CMD_ISA_VERSION_HUNDRETH);
250 minor = send_isa_command(CMD_ISA_VERSION_MINOR); 278 minor = send_isa_command(CMD_ISA_VERSION_MINOR);
251 sprintf(ret, "%c.%c%c%c", one, ten, hund, minor); 279 sprintf(pcwd_private.fw_ver_str, "%c.%c%c%c", one, ten, hund, minor);
252 } 280 }
253 else
254 sprintf(ret, "ERROR");
255
256 unset_command_mode(); 281 unset_command_mode();
257 return(ret); 282
283 return;
258} 284}
259 285
260static inline int pcwd_get_option_switches(void) 286static inline int pcwd_get_option_switches(void)
@@ -272,17 +298,15 @@ static inline int pcwd_get_option_switches(void)
272 298
273static void pcwd_show_card_info(void) 299static void pcwd_show_card_info(void)
274{ 300{
275 char *firmware;
276 int option_switches; 301 int option_switches;
277 302
278 /* Get some extra info from the hardware (in command/debug/diag mode) */ 303 /* Get some extra info from the hardware (in command/debug/diag mode) */
279 if (pcwd_private.revision == PCWD_REVISION_A) 304 if (pcwd_private.revision == PCWD_REVISION_A)
280 printk(KERN_INFO PFX "ISA-PC Watchdog (REV.A) detected at port 0x%04x\n", pcwd_private.io_addr); 305 printk(KERN_INFO PFX "ISA-PC Watchdog (REV.A) detected at port 0x%04x\n", pcwd_private.io_addr);
281 else if (pcwd_private.revision == PCWD_REVISION_C) { 306 else if (pcwd_private.revision == PCWD_REVISION_C) {
282 firmware = get_firmware(); 307 pcwd_get_firmware();
283 printk(KERN_INFO PFX "ISA-PC Watchdog (REV.C) detected at port 0x%04x (Firmware version: %s)\n", 308 printk(KERN_INFO PFX "ISA-PC Watchdog (REV.C) detected at port 0x%04x (Firmware version: %s)\n",
284 pcwd_private.io_addr, firmware); 309 pcwd_private.io_addr, pcwd_private.fw_ver_str);
285 kfree(firmware);
286 option_switches = pcwd_get_option_switches(); 310 option_switches = pcwd_get_option_switches();
287 printk(KERN_INFO PFX "Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n", 311 printk(KERN_INFO PFX "Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n",
288 option_switches, 312 option_switches,
@@ -362,6 +386,10 @@ static int pcwd_start(void)
362 return -EIO; 386 return -EIO;
363 } 387 }
364 } 388 }
389
390 if (debug >= VERBOSE)
391 printk(KERN_DEBUG PFX "Watchdog started\n");
392
365 return 0; 393 return 0;
366} 394}
367 395
@@ -386,6 +414,10 @@ static int pcwd_stop(void)
386 return -EIO; 414 return -EIO;
387 } 415 }
388 } 416 }
417
418 if (debug >= VERBOSE)
419 printk(KERN_DEBUG PFX "Watchdog stopped\n");
420
389 return 0; 421 return 0;
390} 422}
391 423
@@ -393,6 +425,10 @@ static int pcwd_keepalive(void)
393{ 425{
394 /* user land ping */ 426 /* user land ping */
395 pcwd_private.next_heartbeat = jiffies + (heartbeat * HZ); 427 pcwd_private.next_heartbeat = jiffies + (heartbeat * HZ);
428
429 if (debug >= DEBUG)
430 printk(KERN_DEBUG PFX "Watchdog keepalive signal send\n");
431
396 return 0; 432 return 0;
397} 433}
398 434
@@ -402,12 +438,17 @@ static int pcwd_set_heartbeat(int t)
402 return -EINVAL; 438 return -EINVAL;
403 439
404 heartbeat = t; 440 heartbeat = t;
441
442 if (debug >= VERBOSE)
443 printk(KERN_DEBUG PFX "New heartbeat: %d\n",
444 heartbeat);
445
405 return 0; 446 return 0;
406} 447}
407 448
408static int pcwd_get_status(int *status) 449static int pcwd_get_status(int *status)
409{ 450{
410 int card_status; 451 int control_status;
411 452
412 *status=0; 453 *status=0;
413 spin_lock(&pcwd_private.io_lock); 454 spin_lock(&pcwd_private.io_lock);
@@ -415,37 +456,39 @@ static int pcwd_get_status(int *status)
415 /* Rev A cards return status information from 456 /* Rev A cards return status information from
416 * the base register, which is used for the 457 * the base register, which is used for the
417 * temperature in other cards. */ 458 * temperature in other cards. */
418 card_status = inb(pcwd_private.io_addr); 459 control_status = inb(pcwd_private.io_addr);
419 else { 460 else {
420 /* Rev C cards return card status in the base 461 /* Rev C cards return card status in the base
421 * address + 1 register. And use different bits 462 * address + 1 register. And use different bits
422 * to indicate a card initiated reset, and an 463 * to indicate a card initiated reset, and an
423 * over-temperature condition. And the reboot 464 * over-temperature condition. And the reboot
424 * status can be reset. */ 465 * status can be reset. */
425 card_status = inb(pcwd_private.io_addr + 1); 466 control_status = inb(pcwd_private.io_addr + 1);
426 } 467 }
427 spin_unlock(&pcwd_private.io_lock); 468 spin_unlock(&pcwd_private.io_lock);
428 469
429 if (pcwd_private.revision == PCWD_REVISION_A) { 470 if (pcwd_private.revision == PCWD_REVISION_A) {
430 if (card_status & WD_WDRST) 471 if (control_status & WD_WDRST)
431 *status |= WDIOF_CARDRESET; 472 *status |= WDIOF_CARDRESET;
432 473
433 if (card_status & WD_T110) { 474 if (control_status & WD_T110) {
434 *status |= WDIOF_OVERHEAT; 475 *status |= WDIOF_OVERHEAT;
435 if (temp_panic) { 476 if (temp_panic) {
436 printk (KERN_INFO PFX "Temperature overheat trip!\n"); 477 printk (KERN_INFO PFX "Temperature overheat trip!\n");
437 kernel_power_off(); 478 kernel_power_off();
479 /* or should we just do a: panic(PFX "Temperature overheat trip!\n"); */
438 } 480 }
439 } 481 }
440 } else { 482 } else {
441 if (card_status & WD_REVC_WTRP) 483 if (control_status & WD_REVC_WTRP)
442 *status |= WDIOF_CARDRESET; 484 *status |= WDIOF_CARDRESET;
443 485
444 if (card_status & WD_REVC_TTRP) { 486 if (control_status & WD_REVC_TTRP) {
445 *status |= WDIOF_OVERHEAT; 487 *status |= WDIOF_OVERHEAT;
446 if (temp_panic) { 488 if (temp_panic) {
447 printk (KERN_INFO PFX "Temperature overheat trip!\n"); 489 printk (KERN_INFO PFX "Temperature overheat trip!\n");
448 kernel_power_off(); 490 kernel_power_off();
491 /* or should we just do a: panic(PFX "Temperature overheat trip!\n"); */
449 } 492 }
450 } 493 }
451 } 494 }
@@ -455,9 +498,25 @@ static int pcwd_get_status(int *status)
455 498
456static int pcwd_clear_status(void) 499static int pcwd_clear_status(void)
457{ 500{
501 int control_status;
502
458 if (pcwd_private.revision == PCWD_REVISION_C) { 503 if (pcwd_private.revision == PCWD_REVISION_C) {
459 spin_lock(&pcwd_private.io_lock); 504 spin_lock(&pcwd_private.io_lock);
460 outb_p(0x00, pcwd_private.io_addr + 1); /* clear reset status */ 505
506 if (debug >= VERBOSE)
507 printk(KERN_INFO PFX "clearing watchdog trip status\n");
508
509 control_status = inb_p(pcwd_private.io_addr + 1);
510
511 if (debug >= DEBUG) {
512 printk(KERN_DEBUG PFX "status was: 0x%02x\n", control_status);
513 printk(KERN_DEBUG PFX "sending: 0x%02x\n",
514 (control_status & WD_REVC_R2DS));
515 }
516
517 /* clear reset status & Keep Relay 2 disable state as it is */
518 outb_p((control_status & WD_REVC_R2DS), pcwd_private.io_addr + 1);
519
461 spin_unlock(&pcwd_private.io_lock); 520 spin_unlock(&pcwd_private.io_lock);
462 } 521 }
463 return 0; 522 return 0;
@@ -481,6 +540,11 @@ static int pcwd_get_temperature(int *temperature)
481 *temperature = ((inb(pcwd_private.io_addr)) * 9 / 5) + 32; 540 *temperature = ((inb(pcwd_private.io_addr)) * 9 / 5) + 32;
482 spin_unlock(&pcwd_private.io_lock); 541 spin_unlock(&pcwd_private.io_lock);
483 542
543 if (debug >= DEBUG) {
544 printk(KERN_DEBUG PFX "temperature is: %d F\n",
545 *temperature);
546 }
547
484 return 0; 548 return 0;
485} 549}
486 550
@@ -599,6 +663,8 @@ static ssize_t pcwd_write(struct file *file, const char __user *buf, size_t len,
599static int pcwd_open(struct inode *inode, struct file *file) 663static int pcwd_open(struct inode *inode, struct file *file)
600{ 664{
601 if (!atomic_dec_and_test(&open_allowed) ) { 665 if (!atomic_dec_and_test(&open_allowed) ) {
666 if (debug >= VERBOSE)
667 printk(KERN_ERR PFX "Attempt to open already opened device.\n");
602 atomic_inc( &open_allowed ); 668 atomic_inc( &open_allowed );
603 return -EBUSY; 669 return -EBUSY;
604 } 670 }
@@ -922,7 +988,8 @@ static void __exit pcwd_cleanup_module(void)
922{ 988{
923 if (pcwd_private.io_addr) 989 if (pcwd_private.io_addr)
924 pcwatchdog_exit(); 990 pcwatchdog_exit();
925 return; 991
992 printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
926} 993}
927 994
928module_init(pcwd_init_module); 995module_init(pcwd_init_module);
diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c
index 2700c5c45b8a..3fdfda9324fa 100644
--- a/drivers/char/watchdog/pcwd_usb.c
+++ b/drivers/char/watchdog/pcwd_usb.c
@@ -705,7 +705,8 @@ err_out_misc_deregister:
705err_out_unregister_reboot: 705err_out_unregister_reboot:
706 unregister_reboot_notifier(&usb_pcwd_notifier); 706 unregister_reboot_notifier(&usb_pcwd_notifier);
707error: 707error:
708 usb_pcwd_delete (usb_pcwd); 708 if (usb_pcwd)
709 usb_pcwd_delete(usb_pcwd);
709 usb_pcwd_device = NULL; 710 usb_pcwd_device = NULL;
710 return retval; 711 return retval;
711} 712}
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index 7636c1a58f9c..23a9e1ea8e32 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -33,7 +33,6 @@
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/timer.h> 34#include <linux/timer.h>
35#include <linux/dmi.h> 35#include <linux/dmi.h>
36#include <linux/mutex.h>
37#include <asm/io.h> 36#include <asm/io.h>
38 37
39#define HDAPS_LOW_PORT 0x1600 /* first port used by hdaps */ 38#define HDAPS_LOW_PORT 0x1600 /* first port used by hdaps */
@@ -71,10 +70,10 @@ static u8 km_activity;
71static int rest_x; 70static int rest_x;
72static int rest_y; 71static int rest_y;
73 72
74static DEFINE_MUTEX(hdaps_mutex); 73static DECLARE_MUTEX(hdaps_sem);
75 74
76/* 75/*
77 * __get_latch - Get the value from a given port. Callers must hold hdaps_mutex. 76 * __get_latch - Get the value from a given port. Callers must hold hdaps_sem.
78 */ 77 */
79static inline u8 __get_latch(u16 port) 78static inline u8 __get_latch(u16 port)
80{ 79{
@@ -83,7 +82,7 @@ static inline u8 __get_latch(u16 port)
83 82
84/* 83/*
85 * __check_latch - Check a port latch for a given value. Returns zero if the 84 * __check_latch - Check a port latch for a given value. Returns zero if the
86 * port contains the given value. Callers must hold hdaps_mutex. 85 * port contains the given value. Callers must hold hdaps_sem.
87 */ 86 */
88static inline int __check_latch(u16 port, u8 val) 87static inline int __check_latch(u16 port, u8 val)
89{ 88{
@@ -94,7 +93,7 @@ static inline int __check_latch(u16 port, u8 val)
94 93
95/* 94/*
96 * __wait_latch - Wait up to 100us for a port latch to get a certain value, 95 * __wait_latch - Wait up to 100us for a port latch to get a certain value,
97 * returning zero if the value is obtained. Callers must hold hdaps_mutex. 96 * returning zero if the value is obtained. Callers must hold hdaps_sem.
98 */ 97 */
99static int __wait_latch(u16 port, u8 val) 98static int __wait_latch(u16 port, u8 val)
100{ 99{
@@ -111,7 +110,7 @@ static int __wait_latch(u16 port, u8 val)
111 110
112/* 111/*
113 * __device_refresh - request a refresh from the accelerometer. Does not wait 112 * __device_refresh - request a refresh from the accelerometer. Does not wait
114 * for refresh to complete. Callers must hold hdaps_mutex. 113 * for refresh to complete. Callers must hold hdaps_sem.
115 */ 114 */
116static void __device_refresh(void) 115static void __device_refresh(void)
117{ 116{
@@ -125,7 +124,7 @@ static void __device_refresh(void)
125/* 124/*
126 * __device_refresh_sync - request a synchronous refresh from the 125 * __device_refresh_sync - request a synchronous refresh from the
127 * accelerometer. We wait for the refresh to complete. Returns zero if 126 * accelerometer. We wait for the refresh to complete. Returns zero if
128 * successful and nonzero on error. Callers must hold hdaps_mutex. 127 * successful and nonzero on error. Callers must hold hdaps_sem.
129 */ 128 */
130static int __device_refresh_sync(void) 129static int __device_refresh_sync(void)
131{ 130{
@@ -135,7 +134,7 @@ static int __device_refresh_sync(void)
135 134
136/* 135/*
137 * __device_complete - indicate to the accelerometer that we are done reading 136 * __device_complete - indicate to the accelerometer that we are done reading
138 * data, and then initiate an async refresh. Callers must hold hdaps_mutex. 137 * data, and then initiate an async refresh. Callers must hold hdaps_sem.
139 */ 138 */
140static inline void __device_complete(void) 139static inline void __device_complete(void)
141{ 140{
@@ -153,7 +152,7 @@ static int hdaps_readb_one(unsigned int port, u8 *val)
153{ 152{
154 int ret; 153 int ret;
155 154
156 mutex_lock(&hdaps_mutex); 155 down(&hdaps_sem);
157 156
158 /* do a sync refresh -- we need to be sure that we read fresh data */ 157 /* do a sync refresh -- we need to be sure that we read fresh data */
159 ret = __device_refresh_sync(); 158 ret = __device_refresh_sync();
@@ -164,7 +163,7 @@ static int hdaps_readb_one(unsigned int port, u8 *val)
164 __device_complete(); 163 __device_complete();
165 164
166out: 165out:
167 mutex_unlock(&hdaps_mutex); 166 up(&hdaps_sem);
168 return ret; 167 return ret;
169} 168}
170 169
@@ -199,9 +198,9 @@ static int hdaps_read_pair(unsigned int port1, unsigned int port2,
199{ 198{
200 int ret; 199 int ret;
201 200
202 mutex_lock(&hdaps_mutex); 201 down(&hdaps_sem);
203 ret = __hdaps_read_pair(port1, port2, val1, val2); 202 ret = __hdaps_read_pair(port1, port2, val1, val2);
204 mutex_unlock(&hdaps_mutex); 203 up(&hdaps_sem);
205 204
206 return ret; 205 return ret;
207} 206}
@@ -214,7 +213,7 @@ static int hdaps_device_init(void)
214{ 213{
215 int total, ret = -ENXIO; 214 int total, ret = -ENXIO;
216 215
217 mutex_lock(&hdaps_mutex); 216 down(&hdaps_sem);
218 217
219 outb(0x13, 0x1610); 218 outb(0x13, 0x1610);
220 outb(0x01, 0x161f); 219 outb(0x01, 0x161f);
@@ -280,7 +279,7 @@ static int hdaps_device_init(void)
280 } 279 }
281 280
282out: 281out:
283 mutex_unlock(&hdaps_mutex); 282 up(&hdaps_sem);
284 return ret; 283 return ret;
285} 284}
286 285
@@ -314,7 +313,7 @@ static struct platform_driver hdaps_driver = {
314}; 313};
315 314
316/* 315/*
317 * hdaps_calibrate - Set our "resting" values. Callers must hold hdaps_mutex. 316 * hdaps_calibrate - Set our "resting" values. Callers must hold hdaps_sem.
318 */ 317 */
319static void hdaps_calibrate(void) 318static void hdaps_calibrate(void)
320{ 319{
@@ -326,7 +325,7 @@ static void hdaps_mousedev_poll(unsigned long unused)
326 int x, y; 325 int x, y;
327 326
328 /* Cannot sleep. Try nonblockingly. If we fail, try again later. */ 327 /* Cannot sleep. Try nonblockingly. If we fail, try again later. */
329 if (!mutex_trylock(&hdaps_mutex)) { 328 if (down_trylock(&hdaps_sem)) {
330 mod_timer(&hdaps_timer,jiffies + HDAPS_POLL_PERIOD); 329 mod_timer(&hdaps_timer,jiffies + HDAPS_POLL_PERIOD);
331 return; 330 return;
332 } 331 }
@@ -341,7 +340,7 @@ static void hdaps_mousedev_poll(unsigned long unused)
341 mod_timer(&hdaps_timer, jiffies + HDAPS_POLL_PERIOD); 340 mod_timer(&hdaps_timer, jiffies + HDAPS_POLL_PERIOD);
342 341
343out: 342out:
344 mutex_unlock(&hdaps_mutex); 343 up(&hdaps_sem);
345} 344}
346 345
347 346
@@ -421,9 +420,9 @@ static ssize_t hdaps_calibrate_store(struct device *dev,
421 struct device_attribute *attr, 420 struct device_attribute *attr,
422 const char *buf, size_t count) 421 const char *buf, size_t count)
423{ 422{
424 mutex_lock(&hdaps_mutex); 423 down(&hdaps_sem);
425 hdaps_calibrate(); 424 hdaps_calibrate();
426 mutex_unlock(&hdaps_mutex); 425 up(&hdaps_sem);
427 426
428 return count; 427 return count;
429} 428}
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 2c765ca5aa50..f4206604db03 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -496,22 +496,17 @@ static struct sbp2_command_info *sbp2util_find_command_for_orb(
496/* 496/*
497 * This function finds the sbp2_command for a given outstanding SCpnt. 497 * This function finds the sbp2_command for a given outstanding SCpnt.
498 * Only looks at the inuse list. 498 * Only looks at the inuse list.
499 * Must be called with scsi_id->sbp2_command_orb_lock held.
499 */ 500 */
500static struct sbp2_command_info *sbp2util_find_command_for_SCpnt(struct scsi_id_instance_data *scsi_id, void *SCpnt) 501static struct sbp2_command_info *sbp2util_find_command_for_SCpnt(
502 struct scsi_id_instance_data *scsi_id, void *SCpnt)
501{ 503{
502 struct sbp2_command_info *command; 504 struct sbp2_command_info *command;
503 unsigned long flags;
504 505
505 spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); 506 if (!list_empty(&scsi_id->sbp2_command_orb_inuse))
506 if (!list_empty(&scsi_id->sbp2_command_orb_inuse)) { 507 list_for_each_entry(command, &scsi_id->sbp2_command_orb_inuse, list)
507 list_for_each_entry(command, &scsi_id->sbp2_command_orb_inuse, list) { 508 if (command->Current_SCpnt == SCpnt)
508 if (command->Current_SCpnt == SCpnt) {
509 spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
510 return command; 509 return command;
511 }
512 }
513 }
514 spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
515 return NULL; 510 return NULL;
516} 511}
517 512
@@ -580,17 +575,15 @@ static void sbp2util_free_command_dma(struct sbp2_command_info *command)
580 575
581/* 576/*
582 * This function moves a command to the completed orb list. 577 * This function moves a command to the completed orb list.
578 * Must be called with scsi_id->sbp2_command_orb_lock held.
583 */ 579 */
584static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_id, 580static void sbp2util_mark_command_completed(
585 struct sbp2_command_info *command) 581 struct scsi_id_instance_data *scsi_id,
582 struct sbp2_command_info *command)
586{ 583{
587 unsigned long flags;
588
589 spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags);
590 list_del(&command->list); 584 list_del(&command->list);
591 sbp2util_free_command_dma(command); 585 sbp2util_free_command_dma(command);
592 list_add_tail(&command->list, &scsi_id->sbp2_command_orb_completed); 586 list_add_tail(&command->list, &scsi_id->sbp2_command_orb_completed);
593 spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
594} 587}
595 588
596/* 589/*
@@ -2148,7 +2141,9 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
2148 * Matched status with command, now grab scsi command pointers and check status 2141 * Matched status with command, now grab scsi command pointers and check status
2149 */ 2142 */
2150 SCpnt = command->Current_SCpnt; 2143 SCpnt = command->Current_SCpnt;
2144 spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags);
2151 sbp2util_mark_command_completed(scsi_id, command); 2145 sbp2util_mark_command_completed(scsi_id, command);
2146 spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
2152 2147
2153 if (SCpnt) { 2148 if (SCpnt) {
2154 2149
@@ -2484,6 +2479,7 @@ static int sbp2scsi_abort(struct scsi_cmnd *SCpnt)
2484 (struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0]; 2479 (struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0];
2485 struct sbp2scsi_host_info *hi = scsi_id->hi; 2480 struct sbp2scsi_host_info *hi = scsi_id->hi;
2486 struct sbp2_command_info *command; 2481 struct sbp2_command_info *command;
2482 unsigned long flags;
2487 2483
2488 SBP2_ERR("aborting sbp2 command"); 2484 SBP2_ERR("aborting sbp2 command");
2489 scsi_print_command(SCpnt); 2485 scsi_print_command(SCpnt);
@@ -2494,6 +2490,7 @@ static int sbp2scsi_abort(struct scsi_cmnd *SCpnt)
2494 * Right now, just return any matching command structures 2490 * Right now, just return any matching command structures
2495 * to the free pool. 2491 * to the free pool.
2496 */ 2492 */
2493 spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags);
2497 command = sbp2util_find_command_for_SCpnt(scsi_id, SCpnt); 2494 command = sbp2util_find_command_for_SCpnt(scsi_id, SCpnt);
2498 if (command) { 2495 if (command) {
2499 SBP2_DEBUG("Found command to abort"); 2496 SBP2_DEBUG("Found command to abort");
@@ -2511,6 +2508,7 @@ static int sbp2scsi_abort(struct scsi_cmnd *SCpnt)
2511 command->Current_done(command->Current_SCpnt); 2508 command->Current_done(command->Current_SCpnt);
2512 } 2509 }
2513 } 2510 }
2511 spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
2514 2512
2515 /* 2513 /*
2516 * Initiate a fetch agent reset. 2514 * Initiate a fetch agent reset.
diff --git a/drivers/md/dm-target.c b/drivers/md/dm-target.c
index aecd9e0c2616..64fd8e79ea4c 100644
--- a/drivers/md/dm-target.c
+++ b/drivers/md/dm-target.c
@@ -78,8 +78,7 @@ void dm_put_target_type(struct target_type *t)
78 if (--ti->use == 0) 78 if (--ti->use == 0)
79 module_put(ti->tt.module); 79 module_put(ti->tt.module);
80 80
81 if (ti->use < 0) 81 BUG_ON(ti->use < 0);
82 BUG();
83 up_read(&_lock); 82 up_read(&_lock);
84 83
85 return; 84 return;
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 9b374c91db66..6081941de1b3 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1558,8 +1558,7 @@ static int init_resync(conf_t *conf)
1558 int buffs; 1558 int buffs;
1559 1559
1560 buffs = RESYNC_WINDOW / RESYNC_BLOCK_SIZE; 1560 buffs = RESYNC_WINDOW / RESYNC_BLOCK_SIZE;
1561 if (conf->r1buf_pool) 1561 BUG_ON(conf->r1buf_pool);
1562 BUG();
1563 conf->r1buf_pool = mempool_create(buffs, r1buf_pool_alloc, r1buf_pool_free, 1562 conf->r1buf_pool = mempool_create(buffs, r1buf_pool_alloc, r1buf_pool_free,
1564 conf->poolinfo); 1563 conf->poolinfo);
1565 if (!conf->r1buf_pool) 1564 if (!conf->r1buf_pool)
@@ -1732,8 +1731,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1732 !conf->fullsync && 1731 !conf->fullsync &&
1733 !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) 1732 !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
1734 break; 1733 break;
1735 if (sync_blocks < (PAGE_SIZE>>9)) 1734 BUG_ON(sync_blocks < (PAGE_SIZE>>9));
1736 BUG();
1737 if (len > (sync_blocks<<9)) 1735 if (len > (sync_blocks<<9))
1738 len = sync_blocks<<9; 1736 len = sync_blocks<<9;
1739 } 1737 }
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index ab90a6d12020..617012bc107a 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1117,8 +1117,7 @@ static int end_sync_read(struct bio *bio, unsigned int bytes_done, int error)
1117 for (i=0; i<conf->copies; i++) 1117 for (i=0; i<conf->copies; i++)
1118 if (r10_bio->devs[i].bio == bio) 1118 if (r10_bio->devs[i].bio == bio)
1119 break; 1119 break;
1120 if (i == conf->copies) 1120 BUG_ON(i == conf->copies);
1121 BUG();
1122 update_head_pos(i, r10_bio); 1121 update_head_pos(i, r10_bio);
1123 d = r10_bio->devs[i].devnum; 1122 d = r10_bio->devs[i].devnum;
1124 1123
@@ -1518,8 +1517,7 @@ static int init_resync(conf_t *conf)
1518 int buffs; 1517 int buffs;
1519 1518
1520 buffs = RESYNC_WINDOW / RESYNC_BLOCK_SIZE; 1519 buffs = RESYNC_WINDOW / RESYNC_BLOCK_SIZE;
1521 if (conf->r10buf_pool) 1520 BUG_ON(conf->r10buf_pool);
1522 BUG();
1523 conf->r10buf_pool = mempool_create(buffs, r10buf_pool_alloc, r10buf_pool_free, conf); 1521 conf->r10buf_pool = mempool_create(buffs, r10buf_pool_alloc, r10buf_pool_free, conf);
1524 if (!conf->r10buf_pool) 1522 if (!conf->r10buf_pool)
1525 return -ENOMEM; 1523 return -ENOMEM;
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index dae740adaf65..31843604049c 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -73,10 +73,8 @@ static void print_raid5_conf (raid5_conf_t *conf);
73static void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh) 73static void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh)
74{ 74{
75 if (atomic_dec_and_test(&sh->count)) { 75 if (atomic_dec_and_test(&sh->count)) {
76 if (!list_empty(&sh->lru)) 76 BUG_ON(!list_empty(&sh->lru));
77 BUG(); 77 BUG_ON(atomic_read(&conf->active_stripes)==0);
78 if (atomic_read(&conf->active_stripes)==0)
79 BUG();
80 if (test_bit(STRIPE_HANDLE, &sh->state)) { 78 if (test_bit(STRIPE_HANDLE, &sh->state)) {
81 if (test_bit(STRIPE_DELAYED, &sh->state)) 79 if (test_bit(STRIPE_DELAYED, &sh->state))
82 list_add_tail(&sh->lru, &conf->delayed_list); 80 list_add_tail(&sh->lru, &conf->delayed_list);
@@ -184,10 +182,8 @@ static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int
184 raid5_conf_t *conf = sh->raid_conf; 182 raid5_conf_t *conf = sh->raid_conf;
185 int i; 183 int i;
186 184
187 if (atomic_read(&sh->count) != 0) 185 BUG_ON(atomic_read(&sh->count) != 0);
188 BUG(); 186 BUG_ON(test_bit(STRIPE_HANDLE, &sh->state));
189 if (test_bit(STRIPE_HANDLE, &sh->state))
190 BUG();
191 187
192 CHECK_DEVLOCK(); 188 CHECK_DEVLOCK();
193 PRINTK("init_stripe called, stripe %llu\n", 189 PRINTK("init_stripe called, stripe %llu\n",
@@ -269,8 +265,7 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector
269 init_stripe(sh, sector, pd_idx, disks); 265 init_stripe(sh, sector, pd_idx, disks);
270 } else { 266 } else {
271 if (atomic_read(&sh->count)) { 267 if (atomic_read(&sh->count)) {
272 if (!list_empty(&sh->lru)) 268 BUG_ON(!list_empty(&sh->lru));
273 BUG();
274 } else { 269 } else {
275 if (!test_bit(STRIPE_HANDLE, &sh->state)) 270 if (!test_bit(STRIPE_HANDLE, &sh->state))
276 atomic_inc(&conf->active_stripes); 271 atomic_inc(&conf->active_stripes);
@@ -465,8 +460,7 @@ static int drop_one_stripe(raid5_conf_t *conf)
465 spin_unlock_irq(&conf->device_lock); 460 spin_unlock_irq(&conf->device_lock);
466 if (!sh) 461 if (!sh)
467 return 0; 462 return 0;
468 if (atomic_read(&sh->count)) 463 BUG_ON(atomic_read(&sh->count));
469 BUG();
470 shrink_buffers(sh, conf->pool_size); 464 shrink_buffers(sh, conf->pool_size);
471 kmem_cache_free(conf->slab_cache, sh); 465 kmem_cache_free(conf->slab_cache, sh);
472 atomic_dec(&conf->active_stripes); 466 atomic_dec(&conf->active_stripes);
@@ -882,8 +876,7 @@ static void compute_parity(struct stripe_head *sh, int method)
882 ptr[0] = page_address(sh->dev[pd_idx].page); 876 ptr[0] = page_address(sh->dev[pd_idx].page);
883 switch(method) { 877 switch(method) {
884 case READ_MODIFY_WRITE: 878 case READ_MODIFY_WRITE:
885 if (!test_bit(R5_UPTODATE, &sh->dev[pd_idx].flags)) 879 BUG_ON(!test_bit(R5_UPTODATE, &sh->dev[pd_idx].flags));
886 BUG();
887 for (i=disks ; i-- ;) { 880 for (i=disks ; i-- ;) {
888 if (i==pd_idx) 881 if (i==pd_idx)
889 continue; 882 continue;
@@ -896,7 +889,7 @@ static void compute_parity(struct stripe_head *sh, int method)
896 if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) 889 if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
897 wake_up(&conf->wait_for_overlap); 890 wake_up(&conf->wait_for_overlap);
898 891
899 if (sh->dev[i].written) BUG(); 892 BUG_ON(sh->dev[i].written);
900 sh->dev[i].written = chosen; 893 sh->dev[i].written = chosen;
901 check_xor(); 894 check_xor();
902 } 895 }
@@ -912,7 +905,7 @@ static void compute_parity(struct stripe_head *sh, int method)
912 if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) 905 if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
913 wake_up(&conf->wait_for_overlap); 906 wake_up(&conf->wait_for_overlap);
914 907
915 if (sh->dev[i].written) BUG(); 908 BUG_ON(sh->dev[i].written);
916 sh->dev[i].written = chosen; 909 sh->dev[i].written = chosen;
917 } 910 }
918 break; 911 break;
@@ -995,8 +988,7 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in
995 if (*bip && (*bip)->bi_sector < bi->bi_sector + ((bi->bi_size)>>9)) 988 if (*bip && (*bip)->bi_sector < bi->bi_sector + ((bi->bi_size)>>9))
996 goto overlap; 989 goto overlap;
997 990
998 if (*bip && bi->bi_next && (*bip) != bi->bi_next) 991 BUG_ON(*bip && bi->bi_next && (*bip) != bi->bi_next);
999 BUG();
1000 if (*bip) 992 if (*bip)
1001 bi->bi_next = *bip; 993 bi->bi_next = *bip;
1002 *bip = bi; 994 *bip = bi;
@@ -1430,8 +1422,7 @@ static void handle_stripe(struct stripe_head *sh)
1430 set_bit(STRIPE_HANDLE, &sh->state); 1422 set_bit(STRIPE_HANDLE, &sh->state);
1431 if (failed == 0) { 1423 if (failed == 0) {
1432 char *pagea; 1424 char *pagea;
1433 if (uptodate != disks) 1425 BUG_ON(uptodate != disks);
1434 BUG();
1435 compute_parity(sh, CHECK_PARITY); 1426 compute_parity(sh, CHECK_PARITY);
1436 uptodate--; 1427 uptodate--;
1437 pagea = page_address(sh->dev[sh->pd_idx].page); 1428 pagea = page_address(sh->dev[sh->pd_idx].page);
@@ -2096,8 +2087,7 @@ static void raid5d (mddev_t *mddev)
2096 2087
2097 list_del_init(first); 2088 list_del_init(first);
2098 atomic_inc(&sh->count); 2089 atomic_inc(&sh->count);
2099 if (atomic_read(&sh->count)!= 1) 2090 BUG_ON(atomic_read(&sh->count)!= 1);
2100 BUG();
2101 spin_unlock_irq(&conf->device_lock); 2091 spin_unlock_irq(&conf->device_lock);
2102 2092
2103 handled++; 2093 handled++;
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c
index ab64b37e4996..bc69355e0100 100644
--- a/drivers/md/raid6main.c
+++ b/drivers/md/raid6main.c
@@ -91,10 +91,8 @@ static void print_raid6_conf (raid6_conf_t *conf);
91static void __release_stripe(raid6_conf_t *conf, struct stripe_head *sh) 91static void __release_stripe(raid6_conf_t *conf, struct stripe_head *sh)
92{ 92{
93 if (atomic_dec_and_test(&sh->count)) { 93 if (atomic_dec_and_test(&sh->count)) {
94 if (!list_empty(&sh->lru)) 94 BUG_ON(!list_empty(&sh->lru));
95 BUG(); 95 BUG_ON(atomic_read(&conf->active_stripes)==0);
96 if (atomic_read(&conf->active_stripes)==0)
97 BUG();
98 if (test_bit(STRIPE_HANDLE, &sh->state)) { 96 if (test_bit(STRIPE_HANDLE, &sh->state)) {
99 if (test_bit(STRIPE_DELAYED, &sh->state)) 97 if (test_bit(STRIPE_DELAYED, &sh->state))
100 list_add_tail(&sh->lru, &conf->delayed_list); 98 list_add_tail(&sh->lru, &conf->delayed_list);
@@ -202,10 +200,8 @@ static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx)
202 raid6_conf_t *conf = sh->raid_conf; 200 raid6_conf_t *conf = sh->raid_conf;
203 int disks = conf->raid_disks, i; 201 int disks = conf->raid_disks, i;
204 202
205 if (atomic_read(&sh->count) != 0) 203 BUG_ON(atomic_read(&sh->count) != 0);
206 BUG(); 204 BUG_ON(test_bit(STRIPE_HANDLE, &sh->state));
207 if (test_bit(STRIPE_HANDLE, &sh->state))
208 BUG();
209 205
210 CHECK_DEVLOCK(); 206 CHECK_DEVLOCK();
211 PRINTK("init_stripe called, stripe %llu\n", 207 PRINTK("init_stripe called, stripe %llu\n",
@@ -284,13 +280,11 @@ static struct stripe_head *get_active_stripe(raid6_conf_t *conf, sector_t sector
284 init_stripe(sh, sector, pd_idx); 280 init_stripe(sh, sector, pd_idx);
285 } else { 281 } else {
286 if (atomic_read(&sh->count)) { 282 if (atomic_read(&sh->count)) {
287 if (!list_empty(&sh->lru)) 283 BUG_ON(!list_empty(&sh->lru));
288 BUG();
289 } else { 284 } else {
290 if (!test_bit(STRIPE_HANDLE, &sh->state)) 285 if (!test_bit(STRIPE_HANDLE, &sh->state))
291 atomic_inc(&conf->active_stripes); 286 atomic_inc(&conf->active_stripes);
292 if (list_empty(&sh->lru)) 287 BUG_ON(list_empty(&sh->lru));
293 BUG();
294 list_del_init(&sh->lru); 288 list_del_init(&sh->lru);
295 } 289 }
296 } 290 }
@@ -353,8 +347,7 @@ static int drop_one_stripe(raid6_conf_t *conf)
353 spin_unlock_irq(&conf->device_lock); 347 spin_unlock_irq(&conf->device_lock);
354 if (!sh) 348 if (!sh)
355 return 0; 349 return 0;
356 if (atomic_read(&sh->count)) 350 BUG_ON(atomic_read(&sh->count));
357 BUG();
358 shrink_buffers(sh, conf->raid_disks); 351 shrink_buffers(sh, conf->raid_disks);
359 kmem_cache_free(conf->slab_cache, sh); 352 kmem_cache_free(conf->slab_cache, sh);
360 atomic_dec(&conf->active_stripes); 353 atomic_dec(&conf->active_stripes);
@@ -780,7 +773,7 @@ static void compute_parity(struct stripe_head *sh, int method)
780 if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) 773 if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
781 wake_up(&conf->wait_for_overlap); 774 wake_up(&conf->wait_for_overlap);
782 775
783 if (sh->dev[i].written) BUG(); 776 BUG_ON(sh->dev[i].written);
784 sh->dev[i].written = chosen; 777 sh->dev[i].written = chosen;
785 } 778 }
786 break; 779 break;
@@ -970,8 +963,7 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in
970 if (*bip && (*bip)->bi_sector < bi->bi_sector + ((bi->bi_size)>>9)) 963 if (*bip && (*bip)->bi_sector < bi->bi_sector + ((bi->bi_size)>>9))
971 goto overlap; 964 goto overlap;
972 965
973 if (*bip && bi->bi_next && (*bip) != bi->bi_next) 966 BUG_ON(*bip && bi->bi_next && (*bip) != bi->bi_next);
974 BUG();
975 if (*bip) 967 if (*bip)
976 bi->bi_next = *bip; 968 bi->bi_next = *bip;
977 *bip = bi; 969 *bip = bi;
@@ -1906,8 +1898,7 @@ static void raid6d (mddev_t *mddev)
1906 1898
1907 list_del_init(first); 1899 list_del_init(first);
1908 atomic_inc(&sh->count); 1900 atomic_inc(&sh->count);
1909 if (atomic_read(&sh->count)!= 1) 1901 BUG_ON(atomic_read(&sh->count)!= 1);
1910 BUG();
1911 spin_unlock_irq(&conf->device_lock); 1902 spin_unlock_irq(&conf->device_lock);
1912 1903
1913 handled++; 1904 handled++;
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 7cc162e8978b..003b077c2324 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -91,4 +91,22 @@ config MMC_AU1X
91 91
92 If unsure, say N. 92 If unsure, say N.
93 93
94config MMC_AT91RM9200
95 tristate "AT91RM9200 SD/MMC Card Interface support"
96 depends on ARCH_AT91RM9200 && MMC
97 help
98 This selects the AT91RM9200 MCI controller.
99
100 If unsure, say N.
101
102config MMC_IMX
103 tristate "Motorola i.MX Multimedia Card Interface support"
104 depends on ARCH_IMX && MMC
105 help
106 This selects the Motorola i.MX Multimedia card Interface.
107 If you have a i.MX platform with a Multimedia Card slot,
108 say Y or M here.
109
110 If unsure, say N.
111
94endmenu 112endmenu
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index c7c34aadfc92..d2957e35cc6f 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -17,10 +17,12 @@ obj-$(CONFIG_MMC_BLOCK) += mmc_block.o
17# 17#
18obj-$(CONFIG_MMC_ARMMMCI) += mmci.o 18obj-$(CONFIG_MMC_ARMMMCI) += mmci.o
19obj-$(CONFIG_MMC_PXA) += pxamci.o 19obj-$(CONFIG_MMC_PXA) += pxamci.o
20obj-$(CONFIG_MMC_IMX) += imxmmc.o
20obj-$(CONFIG_MMC_SDHCI) += sdhci.o 21obj-$(CONFIG_MMC_SDHCI) += sdhci.o
21obj-$(CONFIG_MMC_WBSD) += wbsd.o 22obj-$(CONFIG_MMC_WBSD) += wbsd.o
22obj-$(CONFIG_MMC_AU1X) += au1xmmc.o 23obj-$(CONFIG_MMC_AU1X) += au1xmmc.o
23obj-$(CONFIG_MMC_OMAP) += omap.o 24obj-$(CONFIG_MMC_OMAP) += omap.o
25obj-$(CONFIG_MMC_AT91RM9200) += at91_mci.o
24 26
25mmc_core-y := mmc.o mmc_queue.o mmc_sysfs.o 27mmc_core-y := mmc.o mmc_queue.o mmc_sysfs.o
26 28
diff --git a/drivers/mmc/at91_mci.c b/drivers/mmc/at91_mci.c
new file mode 100644
index 000000000000..6061c2d101a0
--- /dev/null
+++ b/drivers/mmc/at91_mci.c
@@ -0,0 +1,988 @@
1/*
2 * linux/drivers/mmc/at91_mci.c - ATMEL AT91RM9200 MCI Driver
3 *
4 * Copyright (C) 2005 Cougar Creek Computing Devices Ltd, All Rights Reserved
5 *
6 * Copyright (C) 2006 Malcolm Noyes
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13/*
14 This is the AT91RM9200 MCI driver that has been tested with both MMC cards
15 and SD-cards. Boards that support write protect are now supported.
16 The CCAT91SBC001 board does not support SD cards.
17
18 The three entry points are at91_mci_request, at91_mci_set_ios
19 and at91_mci_get_ro.
20
21 SET IOS
22 This configures the device to put it into the correct mode and clock speed
23 required.
24
25 MCI REQUEST
26 MCI request processes the commands sent in the mmc_request structure. This
27 can consist of a processing command and a stop command in the case of
28 multiple block transfers.
29
30 There are three main types of request, commands, reads and writes.
31
32 Commands are straight forward. The command is submitted to the controller and
33 the request function returns. When the controller generates an interrupt to indicate
34 the command is finished, the response to the command are read and the mmc_request_done
35 function called to end the request.
36
37 Reads and writes work in a similar manner to normal commands but involve the PDC (DMA)
38 controller to manage the transfers.
39
40 A read is done from the controller directly to the scatterlist passed in from the request.
41 Due to a bug in the controller, when a read is completed, all the words are byte
42 swapped in the scatterlist buffers.
43
44 The sequence of read interrupts is: ENDRX, RXBUFF, CMDRDY
45
46 A write is slightly different in that the bytes to write are read from the scatterlist
47 into a dma memory buffer (this is in case the source buffer should be read only). The
48 entire write buffer is then done from this single dma memory buffer.
49
50 The sequence of write interrupts is: ENDTX, TXBUFE, NOTBUSY, CMDRDY
51
52 GET RO
53 Gets the status of the write protect pin, if available.
54*/
55
56#include <linux/config.h>
57#include <linux/module.h>
58#include <linux/moduleparam.h>
59#include <linux/init.h>
60#include <linux/ioport.h>
61#include <linux/platform_device.h>
62#include <linux/interrupt.h>
63#include <linux/blkdev.h>
64#include <linux/delay.h>
65#include <linux/err.h>
66#include <linux/dma-mapping.h>
67#include <linux/clk.h>
68
69#include <linux/mmc/host.h>
70#include <linux/mmc/protocol.h>
71
72#include <asm/io.h>
73#include <asm/irq.h>
74#include <asm/mach/mmc.h>
75#include <asm/arch/board.h>
76#include <asm/arch/gpio.h>
77#include <asm/arch/at91rm9200_mci.h>
78#include <asm/arch/at91rm9200_pdc.h>
79
80#define DRIVER_NAME "at91_mci"
81
82#undef SUPPORT_4WIRE
83
84#ifdef CONFIG_MMC_DEBUG
85#define DBG(fmt...) \
86 printk(fmt)
87#else
88#define DBG(fmt...) do { } while (0)
89#endif
90
91static struct clk *mci_clk;
92
93#define FL_SENT_COMMAND (1 << 0)
94#define FL_SENT_STOP (1 << 1)
95
96
97
98/*
99 * Read from a MCI register.
100 */
101static inline unsigned long at91_mci_read(unsigned int reg)
102{
103 void __iomem *mci_base = (void __iomem *)AT91_VA_BASE_MCI;
104
105 return __raw_readl(mci_base + reg);
106}
107
108/*
109 * Write to a MCI register.
110 */
111static inline void at91_mci_write(unsigned int reg, unsigned long value)
112{
113 void __iomem *mci_base = (void __iomem *)AT91_VA_BASE_MCI;
114
115 __raw_writel(value, mci_base + reg);
116}
117
118/*
119 * Low level type for this driver
120 */
121struct at91mci_host
122{
123 struct mmc_host *mmc;
124 struct mmc_command *cmd;
125 struct mmc_request *request;
126
127 struct at91_mmc_data *board;
128 int present;
129
130 /*
131 * Flag indicating when the command has been sent. This is used to
132 * work out whether or not to send the stop
133 */
134 unsigned int flags;
135 /* flag for current bus settings */
136 u32 bus_mode;
137
138 /* DMA buffer used for transmitting */
139 unsigned int* buffer;
140 dma_addr_t physical_address;
141 unsigned int total_length;
142
143 /* Latest in the scatterlist that has been enabled for transfer, but not freed */
144 int in_use_index;
145
146 /* Latest in the scatterlist that has been enabled for transfer */
147 int transfer_index;
148};
149
150/*
151 * Copy from sg to a dma block - used for transfers
152 */
153static inline void at91mci_sg_to_dma(struct at91mci_host *host, struct mmc_data *data)
154{
155 unsigned int len, i, size;
156 unsigned *dmabuf = host->buffer;
157
158 size = host->total_length;
159 len = data->sg_len;
160
161 /*
162 * Just loop through all entries. Size might not
163 * be the entire list though so make sure that
164 * we do not transfer too much.
165 */
166 for (i = 0; i < len; i++) {
167 struct scatterlist *sg;
168 int amount;
169 int index;
170 unsigned int *sgbuffer;
171
172 sg = &data->sg[i];
173
174 sgbuffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
175 amount = min(size, sg->length);
176 size -= amount;
177 amount /= 4;
178
179 for (index = 0; index < amount; index++)
180 *dmabuf++ = swab32(sgbuffer[index]);
181
182 kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ);
183
184 if (size == 0)
185 break;
186 }
187
188 /*
189 * Check that we didn't get a request to transfer
190 * more data than can fit into the SG list.
191 */
192 BUG_ON(size != 0);
193}
194
195/*
196 * Prepare a dma read
197 */
198static void at91mci_pre_dma_read(struct at91mci_host *host)
199{
200 int i;
201 struct scatterlist *sg;
202 struct mmc_command *cmd;
203 struct mmc_data *data;
204
205 DBG("pre dma read\n");
206
207 cmd = host->cmd;
208 if (!cmd) {
209 DBG("no command\n");
210 return;
211 }
212
213 data = cmd->data;
214 if (!data) {
215 DBG("no data\n");
216 return;
217 }
218
219 for (i = 0; i < 2; i++) {
220 /* nothing left to transfer */
221 if (host->transfer_index >= data->sg_len) {
222 DBG("Nothing left to transfer (index = %d)\n", host->transfer_index);
223 break;
224 }
225
226 /* Check to see if this needs filling */
227 if (i == 0) {
228 if (at91_mci_read(AT91_PDC_RCR) != 0) {
229 DBG("Transfer active in current\n");
230 continue;
231 }
232 }
233 else {
234 if (at91_mci_read(AT91_PDC_RNCR) != 0) {
235 DBG("Transfer active in next\n");
236 continue;
237 }
238 }
239
240 /* Setup the next transfer */
241 DBG("Using transfer index %d\n", host->transfer_index);
242
243 sg = &data->sg[host->transfer_index++];
244 DBG("sg = %p\n", sg);
245
246 sg->dma_address = dma_map_page(NULL, sg->page, sg->offset, sg->length, DMA_FROM_DEVICE);
247
248 DBG("dma address = %08X, length = %d\n", sg->dma_address, sg->length);
249
250 if (i == 0) {
251 at91_mci_write(AT91_PDC_RPR, sg->dma_address);
252 at91_mci_write(AT91_PDC_RCR, sg->length / 4);
253 }
254 else {
255 at91_mci_write(AT91_PDC_RNPR, sg->dma_address);
256 at91_mci_write(AT91_PDC_RNCR, sg->length / 4);
257 }
258 }
259
260 DBG("pre dma read done\n");
261}
262
263/*
264 * Handle after a dma read
265 */
266static void at91mci_post_dma_read(struct at91mci_host *host)
267{
268 struct mmc_command *cmd;
269 struct mmc_data *data;
270
271 DBG("post dma read\n");
272
273 cmd = host->cmd;
274 if (!cmd) {
275 DBG("no command\n");
276 return;
277 }
278
279 data = cmd->data;
280 if (!data) {
281 DBG("no data\n");
282 return;
283 }
284
285 while (host->in_use_index < host->transfer_index) {
286 unsigned int *buffer;
287 int index;
288 int len;
289
290 struct scatterlist *sg;
291
292 DBG("finishing index %d\n", host->in_use_index);
293
294 sg = &data->sg[host->in_use_index++];
295
296 DBG("Unmapping page %08X\n", sg->dma_address);
297
298 dma_unmap_page(NULL, sg->dma_address, sg->length, DMA_FROM_DEVICE);
299
300 /* Swap the contents of the buffer */
301 buffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
302 DBG("buffer = %p, length = %d\n", buffer, sg->length);
303
304 data->bytes_xfered += sg->length;
305
306 len = sg->length / 4;
307
308 for (index = 0; index < len; index++) {
309 buffer[index] = swab32(buffer[index]);
310 }
311 kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
312 flush_dcache_page(sg->page);
313 }
314
315 /* Is there another transfer to trigger? */
316 if (host->transfer_index < data->sg_len)
317 at91mci_pre_dma_read(host);
318 else {
319 at91_mci_write(AT91_MCI_IER, AT91_MCI_RXBUFF);
320 at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS);
321 }
322
323 DBG("post dma read done\n");
324}
325
326/*
327 * Handle transmitted data
328 */
329static void at91_mci_handle_transmitted(struct at91mci_host *host)
330{
331 struct mmc_command *cmd;
332 struct mmc_data *data;
333
334 DBG("Handling the transmit\n");
335
336 /* Disable the transfer */
337 at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS);
338
339 /* Now wait for cmd ready */
340 at91_mci_write(AT91_MCI_IDR, AT91_MCI_TXBUFE);
341 at91_mci_write(AT91_MCI_IER, AT91_MCI_NOTBUSY);
342
343 cmd = host->cmd;
344 if (!cmd) return;
345
346 data = cmd->data;
347 if (!data) return;
348
349 data->bytes_xfered = host->total_length;
350}
351
352/*
353 * Enable the controller
354 */
355static void at91_mci_enable(void)
356{
357 at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIEN);
358 at91_mci_write(AT91_MCI_IDR, 0xFFFFFFFF);
359 at91_mci_write(AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC);
360 at91_mci_write(AT91_MCI_MR, 0x834A);
361 at91_mci_write(AT91_MCI_SDCR, 0x0);
362}
363
364/*
365 * Disable the controller
366 */
367static void at91_mci_disable(void)
368{
369 at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIDIS | AT91_MCI_SWRST);
370}
371
372/*
373 * Send a command
374 * return the interrupts to enable
375 */
376static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_command *cmd)
377{
378 unsigned int cmdr, mr;
379 unsigned int block_length;
380 struct mmc_data *data = cmd->data;
381
382 unsigned int blocks;
383 unsigned int ier = 0;
384
385 host->cmd = cmd;
386
387 /* Not sure if this is needed */
388#if 0
389 if ((at91_mci_read(AT91_MCI_SR) & AT91_MCI_RTOE) && (cmd->opcode == 1)) {
390 DBG("Clearing timeout\n");
391 at91_mci_write(AT91_MCI_ARGR, 0);
392 at91_mci_write(AT91_MCI_CMDR, AT91_MCI_OPDCMD);
393 while (!(at91_mci_read(AT91_MCI_SR) & AT91_MCI_CMDRDY)) {
394 /* spin */
395 DBG("Clearing: SR = %08X\n", at91_mci_read(AT91_MCI_SR));
396 }
397 }
398#endif
399 cmdr = cmd->opcode;
400
401 if (mmc_resp_type(cmd) == MMC_RSP_NONE)
402 cmdr |= AT91_MCI_RSPTYP_NONE;
403 else {
404 /* if a response is expected then allow maximum response latancy */
405 cmdr |= AT91_MCI_MAXLAT;
406 /* set 136 bit response for R2, 48 bit response otherwise */
407 if (mmc_resp_type(cmd) == MMC_RSP_R2)
408 cmdr |= AT91_MCI_RSPTYP_136;
409 else
410 cmdr |= AT91_MCI_RSPTYP_48;
411 }
412
413 if (data) {
414 block_length = 1 << data->blksz_bits;
415 blocks = data->blocks;
416
417 /* always set data start - also set direction flag for read */
418 if (data->flags & MMC_DATA_READ)
419 cmdr |= (AT91_MCI_TRDIR | AT91_MCI_TRCMD_START);
420 else if (data->flags & MMC_DATA_WRITE)
421 cmdr |= AT91_MCI_TRCMD_START;
422
423 if (data->flags & MMC_DATA_STREAM)
424 cmdr |= AT91_MCI_TRTYP_STREAM;
425 if (data->flags & MMC_DATA_MULTI)
426 cmdr |= AT91_MCI_TRTYP_MULTIPLE;
427 }
428 else {
429 block_length = 0;
430 blocks = 0;
431 }
432
433 if (cmd->opcode == MMC_STOP_TRANSMISSION)
434 cmdr |= AT91_MCI_TRCMD_STOP;
435
436 if (host->bus_mode == MMC_BUSMODE_OPENDRAIN)
437 cmdr |= AT91_MCI_OPDCMD;
438
439 /*
440 * Set the arguments and send the command
441 */
442 DBG("Sending command %d as %08X, arg = %08X, blocks = %d, length = %d (MR = %08lX)\n",
443 cmd->opcode, cmdr, cmd->arg, blocks, block_length, at91_mci_read(AT91_MCI_MR));
444
445 if (!data) {
446 at91_mci_write(AT91_PDC_PTCR, AT91_PDC_TXTDIS | AT91_PDC_RXTDIS);
447 at91_mci_write(AT91_PDC_RPR, 0);
448 at91_mci_write(AT91_PDC_RCR, 0);
449 at91_mci_write(AT91_PDC_RNPR, 0);
450 at91_mci_write(AT91_PDC_RNCR, 0);
451 at91_mci_write(AT91_PDC_TPR, 0);
452 at91_mci_write(AT91_PDC_TCR, 0);
453 at91_mci_write(AT91_PDC_TNPR, 0);
454 at91_mci_write(AT91_PDC_TNCR, 0);
455
456 at91_mci_write(AT91_MCI_ARGR, cmd->arg);
457 at91_mci_write(AT91_MCI_CMDR, cmdr);
458 return AT91_MCI_CMDRDY;
459 }
460
461 mr = at91_mci_read(AT91_MCI_MR) & 0x7fff; /* zero block length and PDC mode */
462 at91_mci_write(AT91_MCI_MR, mr | (block_length << 16) | AT91_MCI_PDCMODE);
463
464 /*
465 * Disable the PDC controller
466 */
467 at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS);
468
469 if (cmdr & AT91_MCI_TRCMD_START) {
470 data->bytes_xfered = 0;
471 host->transfer_index = 0;
472 host->in_use_index = 0;
473 if (cmdr & AT91_MCI_TRDIR) {
474 /*
475 * Handle a read
476 */
477 host->buffer = NULL;
478 host->total_length = 0;
479
480 at91mci_pre_dma_read(host);
481 ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */;
482 }
483 else {
484 /*
485 * Handle a write
486 */
487 host->total_length = block_length * blocks;
488 host->buffer = dma_alloc_coherent(NULL,
489 host->total_length,
490 &host->physical_address, GFP_KERNEL);
491
492 at91mci_sg_to_dma(host, data);
493
494 DBG("Transmitting %d bytes\n", host->total_length);
495
496 at91_mci_write(AT91_PDC_TPR, host->physical_address);
497 at91_mci_write(AT91_PDC_TCR, host->total_length / 4);
498 ier = AT91_MCI_TXBUFE;
499 }
500 }
501
502 /*
503 * Send the command and then enable the PDC - not the other way round as
504 * the data sheet says
505 */
506
507 at91_mci_write(AT91_MCI_ARGR, cmd->arg);
508 at91_mci_write(AT91_MCI_CMDR, cmdr);
509
510 if (cmdr & AT91_MCI_TRCMD_START) {
511 if (cmdr & AT91_MCI_TRDIR)
512 at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTEN);
513 else
514 at91_mci_write(AT91_PDC_PTCR, AT91_PDC_TXTEN);
515 }
516 return ier;
517}
518
519/*
520 * Wait for a command to complete
521 */
522static void at91mci_process_command(struct at91mci_host *host, struct mmc_command *cmd)
523{
524 unsigned int ier;
525
526 ier = at91_mci_send_command(host, cmd);
527
528 DBG("setting ier to %08X\n", ier);
529
530 /* Stop on errors or the required value */
531 at91_mci_write(AT91_MCI_IER, 0xffff0000 | ier);
532}
533
534/*
535 * Process the next step in the request
536 */
537static void at91mci_process_next(struct at91mci_host *host)
538{
539 if (!(host->flags & FL_SENT_COMMAND)) {
540 host->flags |= FL_SENT_COMMAND;
541 at91mci_process_command(host, host->request->cmd);
542 }
543 else if ((!(host->flags & FL_SENT_STOP)) && host->request->stop) {
544 host->flags |= FL_SENT_STOP;
545 at91mci_process_command(host, host->request->stop);
546 }
547 else
548 mmc_request_done(host->mmc, host->request);
549}
550
551/*
552 * Handle a command that has been completed
553 */
554static void at91mci_completed_command(struct at91mci_host *host)
555{
556 struct mmc_command *cmd = host->cmd;
557 unsigned int status;
558
559 at91_mci_write(AT91_MCI_IDR, 0xffffffff);
560
561 cmd->resp[0] = at91_mci_read(AT91_MCI_RSPR(0));
562 cmd->resp[1] = at91_mci_read(AT91_MCI_RSPR(1));
563 cmd->resp[2] = at91_mci_read(AT91_MCI_RSPR(2));
564 cmd->resp[3] = at91_mci_read(AT91_MCI_RSPR(3));
565
566 if (host->buffer) {
567 dma_free_coherent(NULL, host->total_length, host->buffer, host->physical_address);
568 host->buffer = NULL;
569 }
570
571 status = at91_mci_read(AT91_MCI_SR);
572
573 DBG("Status = %08X [%08X %08X %08X %08X]\n",
574 status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
575
576 if (status & (AT91_MCI_RINDE | AT91_MCI_RDIRE | AT91_MCI_RCRCE |
577 AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE |
578 AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE)) {
579 if ((status & AT91_MCI_RCRCE) &&
580 ((cmd->opcode == MMC_SEND_OP_COND) || (cmd->opcode == SD_APP_OP_COND))) {
581 cmd->error = MMC_ERR_NONE;
582 }
583 else {
584 if (status & (AT91_MCI_RTOE | AT91_MCI_DTOE))
585 cmd->error = MMC_ERR_TIMEOUT;
586 else if (status & (AT91_MCI_RCRCE | AT91_MCI_DCRCE))
587 cmd->error = MMC_ERR_BADCRC;
588 else if (status & (AT91_MCI_OVRE | AT91_MCI_UNRE))
589 cmd->error = MMC_ERR_FIFO;
590 else
591 cmd->error = MMC_ERR_FAILED;
592
593 DBG("Error detected and set to %d (cmd = %d, retries = %d)\n",
594 cmd->error, cmd->opcode, cmd->retries);
595 }
596 }
597 else
598 cmd->error = MMC_ERR_NONE;
599
600 at91mci_process_next(host);
601}
602
603/*
604 * Handle an MMC request
605 */
606static void at91_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
607{
608 struct at91mci_host *host = mmc_priv(mmc);
609 host->request = mrq;
610 host->flags = 0;
611
612 at91mci_process_next(host);
613}
614
615/*
616 * Set the IOS
617 */
618static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
619{
620 int clkdiv;
621 struct at91mci_host *host = mmc_priv(mmc);
622 unsigned long at91_master_clock = clk_get_rate(mci_clk);
623
624 DBG("Clock %uHz, busmode %u, powermode %u, Vdd %u\n",
625 ios->clock, ios->bus_mode, ios->power_mode, ios->vdd);
626
627 if (host)
628 host->bus_mode = ios->bus_mode;
629 else
630 printk("MMC: No host for bus_mode\n");
631
632 if (ios->clock == 0) {
633 /* Disable the MCI controller */
634 at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIDIS);
635 clkdiv = 0;
636 }
637 else {
638 /* Enable the MCI controller */
639 at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIEN);
640
641 if ((at91_master_clock % (ios->clock * 2)) == 0)
642 clkdiv = ((at91_master_clock / ios->clock) / 2) - 1;
643 else
644 clkdiv = (at91_master_clock / ios->clock) / 2;
645
646 DBG("clkdiv = %d. mcck = %ld\n", clkdiv,
647 at91_master_clock / (2 * (clkdiv + 1)));
648 }
649 if (ios->bus_width == MMC_BUS_WIDTH_4 && host->board->wire4) {
650 DBG("MMC: Setting controller bus width to 4\n");
651 at91_mci_write(AT91_MCI_SDCR, at91_mci_read(AT91_MCI_SDCR) | AT91_MCI_SDCBUS);
652 }
653 else {
654 DBG("MMC: Setting controller bus width to 1\n");
655 at91_mci_write(AT91_MCI_SDCR, at91_mci_read(AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS);
656 }
657
658 /* Set the clock divider */
659 at91_mci_write(AT91_MCI_MR, (at91_mci_read(AT91_MCI_MR) & ~AT91_MCI_CLKDIV) | clkdiv);
660
661 /* maybe switch power to the card */
662 if (host && host->board->vcc_pin) {
663 switch (ios->power_mode) {
664 case MMC_POWER_OFF:
665 at91_set_gpio_output(host->board->vcc_pin, 0);
666 break;
667 case MMC_POWER_UP:
668 case MMC_POWER_ON:
669 at91_set_gpio_output(host->board->vcc_pin, 1);
670 break;
671 }
672 }
673}
674
675/*
676 * Handle an interrupt
677 */
678static irqreturn_t at91_mci_irq(int irq, void *devid, struct pt_regs *regs)
679{
680 struct at91mci_host *host = devid;
681 int completed = 0;
682
683 unsigned int int_status;
684
685 if (host == NULL)
686 return IRQ_HANDLED;
687
688 int_status = at91_mci_read(AT91_MCI_SR);
689 DBG("MCI irq: status = %08X, %08lX, %08lX\n", int_status, at91_mci_read(AT91_MCI_IMR),
690 int_status & at91_mci_read(AT91_MCI_IMR));
691
692 if ((int_status & at91_mci_read(AT91_MCI_IMR)) & 0xffff0000)
693 completed = 1;
694
695 int_status &= at91_mci_read(AT91_MCI_IMR);
696
697 if (int_status & AT91_MCI_UNRE)
698 DBG("MMC: Underrun error\n");
699 if (int_status & AT91_MCI_OVRE)
700 DBG("MMC: Overrun error\n");
701 if (int_status & AT91_MCI_DTOE)
702 DBG("MMC: Data timeout\n");
703 if (int_status & AT91_MCI_DCRCE)
704 DBG("MMC: CRC error in data\n");
705 if (int_status & AT91_MCI_RTOE)
706 DBG("MMC: Response timeout\n");
707 if (int_status & AT91_MCI_RENDE)
708 DBG("MMC: Response end bit error\n");
709 if (int_status & AT91_MCI_RCRCE)
710 DBG("MMC: Response CRC error\n");
711 if (int_status & AT91_MCI_RDIRE)
712 DBG("MMC: Response direction error\n");
713 if (int_status & AT91_MCI_RINDE)
714 DBG("MMC: Response index error\n");
715
716 /* Only continue processing if no errors */
717 if (!completed) {
718 if (int_status & AT91_MCI_TXBUFE) {
719 DBG("TX buffer empty\n");
720 at91_mci_handle_transmitted(host);
721 }
722
723 if (int_status & AT91_MCI_RXBUFF) {
724 DBG("RX buffer full\n");
725 at91_mci_write(AT91_MCI_IER, AT91_MCI_CMDRDY);
726 }
727
728 if (int_status & AT91_MCI_ENDTX) {
729 DBG("Transmit has ended\n");
730 }
731
732 if (int_status & AT91_MCI_ENDRX) {
733 DBG("Receive has ended\n");
734 at91mci_post_dma_read(host);
735 }
736
737 if (int_status & AT91_MCI_NOTBUSY) {
738 DBG("Card is ready\n");
739 at91_mci_write(AT91_MCI_IER, AT91_MCI_CMDRDY);
740 }
741
742 if (int_status & AT91_MCI_DTIP) {
743 DBG("Data transfer in progress\n");
744 }
745
746 if (int_status & AT91_MCI_BLKE) {
747 DBG("Block transfer has ended\n");
748 }
749
750 if (int_status & AT91_MCI_TXRDY) {
751 DBG("Ready to transmit\n");
752 }
753
754 if (int_status & AT91_MCI_RXRDY) {
755 DBG("Ready to receive\n");
756 }
757
758 if (int_status & AT91_MCI_CMDRDY) {
759 DBG("Command ready\n");
760 completed = 1;
761 }
762 }
763 at91_mci_write(AT91_MCI_IDR, int_status);
764
765 if (completed) {
766 DBG("Completed command\n");
767 at91_mci_write(AT91_MCI_IDR, 0xffffffff);
768 at91mci_completed_command(host);
769 }
770
771 return IRQ_HANDLED;
772}
773
774static irqreturn_t at91_mmc_det_irq(int irq, void *_host, struct pt_regs *regs)
775{
776 struct at91mci_host *host = _host;
777 int present = !at91_get_gpio_value(irq);
778
779 /*
780 * we expect this irq on both insert and remove,
781 * and use a short delay to debounce.
782 */
783 if (present != host->present) {
784 host->present = present;
785 DBG("%s: card %s\n", mmc_hostname(host->mmc),
786 present ? "insert" : "remove");
787 if (!present) {
788 DBG("****** Resetting SD-card bus width ******\n");
789 at91_mci_write(AT91_MCI_SDCR, 0);
790 }
791 mmc_detect_change(host->mmc, msecs_to_jiffies(100));
792 }
793 return IRQ_HANDLED;
794}
795
796int at91_mci_get_ro(struct mmc_host *mmc)
797{
798 int read_only = 0;
799 struct at91mci_host *host = mmc_priv(mmc);
800
801 if (host->board->wp_pin) {
802 read_only = at91_get_gpio_value(host->board->wp_pin);
803 printk(KERN_WARNING "%s: card is %s\n", mmc_hostname(mmc),
804 (read_only ? "read-only" : "read-write") );
805 }
806 else {
807 printk(KERN_WARNING "%s: host does not support reading read-only "
808 "switch. Assuming write-enable.\n", mmc_hostname(mmc));
809 }
810 return read_only;
811}
812
813static struct mmc_host_ops at91_mci_ops = {
814 .request = at91_mci_request,
815 .set_ios = at91_mci_set_ios,
816 .get_ro = at91_mci_get_ro,
817};
818
819/*
820 * Probe for the device
821 */
822static int at91_mci_probe(struct platform_device *pdev)
823{
824 struct mmc_host *mmc;
825 struct at91mci_host *host;
826 int ret;
827
828 DBG("Probe MCI devices\n");
829 at91_mci_disable();
830 at91_mci_enable();
831
832 mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev);
833 if (!mmc) {
834 DBG("Failed to allocate mmc host\n");
835 return -ENOMEM;
836 }
837
838 mmc->ops = &at91_mci_ops;
839 mmc->f_min = 375000;
840 mmc->f_max = 25000000;
841 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
842
843 host = mmc_priv(mmc);
844 host->mmc = mmc;
845 host->buffer = NULL;
846 host->bus_mode = 0;
847 host->board = pdev->dev.platform_data;
848 if (host->board->wire4) {
849#ifdef SUPPORT_4WIRE
850 mmc->caps |= MMC_CAP_4_BIT_DATA;
851#else
852 printk("MMC: 4 wire bus mode not supported by this driver - using 1 wire\n");
853#endif
854 }
855
856 /*
857 * Get Clock
858 */
859 mci_clk = clk_get(&pdev->dev, "mci_clk");
860 if (!mci_clk) {
861 printk(KERN_ERR "AT91 MMC: no clock defined.\n");
862 return -ENODEV;
863 }
864 clk_enable(mci_clk); /* Enable the peripheral clock */
865
866 /*
867 * Allocate the MCI interrupt
868 */
869 ret = request_irq(AT91_ID_MCI, at91_mci_irq, SA_SHIRQ, DRIVER_NAME, host);
870 if (ret) {
871 DBG("Failed to request MCI interrupt\n");
872 return ret;
873 }
874
875 platform_set_drvdata(pdev, mmc);
876
877 /*
878 * Add host to MMC layer
879 */
880 if (host->board->det_pin)
881 host->present = !at91_get_gpio_value(host->board->det_pin);
882 else
883 host->present = -1;
884
885 mmc_add_host(mmc);
886
887 /*
888 * monitor card insertion/removal if we can
889 */
890 if (host->board->det_pin) {
891 ret = request_irq(host->board->det_pin, at91_mmc_det_irq,
892 SA_SAMPLE_RANDOM, DRIVER_NAME, host);
893 if (ret)
894 DBG("couldn't allocate MMC detect irq\n");
895 }
896
897 DBG(KERN_INFO "Added MCI driver\n");
898
899 return 0;
900}
901
902/*
903 * Remove a device
904 */
905static int at91_mci_remove(struct platform_device *pdev)
906{
907 struct mmc_host *mmc = platform_get_drvdata(pdev);
908 struct at91mci_host *host;
909
910 if (!mmc)
911 return -1;
912
913 host = mmc_priv(mmc);
914
915 if (host->present != -1) {
916 free_irq(host->board->det_pin, host);
917 cancel_delayed_work(&host->mmc->detect);
918 }
919
920 mmc_remove_host(mmc);
921 at91_mci_disable();
922 free_irq(AT91_ID_MCI, host);
923 mmc_free_host(mmc);
924
925 clk_disable(mci_clk); /* Disable the peripheral clock */
926 clk_put(mci_clk);
927
928 platform_set_drvdata(pdev, NULL);
929
930 DBG("Removed\n");
931
932 return 0;
933}
934
935#ifdef CONFIG_PM
936static int at91_mci_suspend(struct platform_device *pdev, pm_message_t state)
937{
938 struct mmc_host *mmc = platform_get_drvdata(pdev);
939 int ret = 0;
940
941 if (mmc)
942 ret = mmc_suspend_host(mmc, state);
943
944 return ret;
945}
946
947static int at91_mci_resume(struct platform_device *pdev)
948{
949 struct mmc_host *mmc = platform_get_drvdata(pdev);
950 int ret = 0;
951
952 if (mmc)
953 ret = mmc_resume_host(mmc);
954
955 return ret;
956}
957#else
958#define at91_mci_suspend NULL
959#define at91_mci_resume NULL
960#endif
961
962static struct platform_driver at91_mci_driver = {
963 .probe = at91_mci_probe,
964 .remove = at91_mci_remove,
965 .suspend = at91_mci_suspend,
966 .resume = at91_mci_resume,
967 .driver = {
968 .name = DRIVER_NAME,
969 .owner = THIS_MODULE,
970 },
971};
972
973static int __init at91_mci_init(void)
974{
975 return platform_driver_register(&at91_mci_driver);
976}
977
978static void __exit at91_mci_exit(void)
979{
980 platform_driver_unregister(&at91_mci_driver);
981}
982
983module_init(at91_mci_init);
984module_exit(at91_mci_exit);
985
986MODULE_DESCRIPTION("AT91 Multimedia Card Interface driver");
987MODULE_AUTHOR("Nick Randell");
988MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/imxmmc.c b/drivers/mmc/imxmmc.c
new file mode 100644
index 000000000000..ffb7f55d3467
--- /dev/null
+++ b/drivers/mmc/imxmmc.c
@@ -0,0 +1,1096 @@
1/*
2 * linux/drivers/mmc/imxmmc.c - Motorola i.MX MMCI driver
3 *
4 * Copyright (C) 2004 Sascha Hauer, Pengutronix <sascha@saschahauer.de>
5 * Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com>
6 *
7 * derived from pxamci.c by Russell King
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * 2005-04-17 Pavel Pisa <pisa@cmp.felk.cvut.cz>
14 * Changed to conform redesigned i.MX scatter gather DMA interface
15 *
16 * 2005-11-04 Pavel Pisa <pisa@cmp.felk.cvut.cz>
17 * Updated for 2.6.14 kernel
18 *
19 * 2005-12-13 Jay Monkman <jtm@smoothsmoothie.com>
20 * Found and corrected problems in the write path
21 *
22 * 2005-12-30 Pavel Pisa <pisa@cmp.felk.cvut.cz>
23 * The event handling rewritten right way in softirq.
24 * Added many ugly hacks and delays to overcome SDHC
25 * deficiencies
26 *
27 */
28#include <linux/config.h>
29
30#ifdef CONFIG_MMC_DEBUG
31#define DEBUG
32#else
33#undef DEBUG
34#endif
35
36#include <linux/module.h>
37#include <linux/init.h>
38#include <linux/ioport.h>
39#include <linux/platform_device.h>
40#include <linux/interrupt.h>
41#include <linux/blkdev.h>
42#include <linux/dma-mapping.h>
43#include <linux/mmc/host.h>
44#include <linux/mmc/card.h>
45#include <linux/mmc/protocol.h>
46#include <linux/delay.h>
47
48#include <asm/dma.h>
49#include <asm/io.h>
50#include <asm/irq.h>
51#include <asm/sizes.h>
52#include <asm/arch/mmc.h>
53#include <asm/arch/imx-dma.h>
54
55#include "imxmmc.h"
56
57#define DRIVER_NAME "imx-mmc"
58
59#define IMXMCI_INT_MASK_DEFAULT (INT_MASK_BUF_READY | INT_MASK_DATA_TRAN | \
60 INT_MASK_WRITE_OP_DONE | INT_MASK_END_CMD_RES | \
61 INT_MASK_AUTO_CARD_DETECT | INT_MASK_DAT0_EN | INT_MASK_SDIO)
62
63struct imxmci_host {
64 struct mmc_host *mmc;
65 spinlock_t lock;
66 struct resource *res;
67 int irq;
68 imx_dmach_t dma;
69 unsigned int clkrt;
70 unsigned int cmdat;
71 volatile unsigned int imask;
72 unsigned int power_mode;
73 unsigned int present;
74 struct imxmmc_platform_data *pdata;
75
76 struct mmc_request *req;
77 struct mmc_command *cmd;
78 struct mmc_data *data;
79
80 struct timer_list timer;
81 struct tasklet_struct tasklet;
82 unsigned int status_reg;
83 unsigned long pending_events;
84 /* Next to fields are there for CPU driven transfers to overcome SDHC deficiencies */
85 u16 *data_ptr;
86 unsigned int data_cnt;
87 atomic_t stuck_timeout;
88
89 unsigned int dma_nents;
90 unsigned int dma_size;
91 unsigned int dma_dir;
92 int dma_allocated;
93
94 unsigned char actual_bus_width;
95};
96
97#define IMXMCI_PEND_IRQ_b 0
98#define IMXMCI_PEND_DMA_END_b 1
99#define IMXMCI_PEND_DMA_ERR_b 2
100#define IMXMCI_PEND_WAIT_RESP_b 3
101#define IMXMCI_PEND_DMA_DATA_b 4
102#define IMXMCI_PEND_CPU_DATA_b 5
103#define IMXMCI_PEND_CARD_XCHG_b 6
104#define IMXMCI_PEND_SET_INIT_b 7
105
106#define IMXMCI_PEND_IRQ_m (1 << IMXMCI_PEND_IRQ_b)
107#define IMXMCI_PEND_DMA_END_m (1 << IMXMCI_PEND_DMA_END_b)
108#define IMXMCI_PEND_DMA_ERR_m (1 << IMXMCI_PEND_DMA_ERR_b)
109#define IMXMCI_PEND_WAIT_RESP_m (1 << IMXMCI_PEND_WAIT_RESP_b)
110#define IMXMCI_PEND_DMA_DATA_m (1 << IMXMCI_PEND_DMA_DATA_b)
111#define IMXMCI_PEND_CPU_DATA_m (1 << IMXMCI_PEND_CPU_DATA_b)
112#define IMXMCI_PEND_CARD_XCHG_m (1 << IMXMCI_PEND_CARD_XCHG_b)
113#define IMXMCI_PEND_SET_INIT_m (1 << IMXMCI_PEND_SET_INIT_b)
114
115static void imxmci_stop_clock(struct imxmci_host *host)
116{
117 int i = 0;
118 MMC_STR_STP_CLK &= ~STR_STP_CLK_START_CLK;
119 while(i < 0x1000) {
120 if(!(i & 0x7f))
121 MMC_STR_STP_CLK |= STR_STP_CLK_STOP_CLK;
122
123 if(!(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN)) {
124 /* Check twice before cut */
125 if(!(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN))
126 return;
127 }
128
129 i++;
130 }
131 dev_dbg(mmc_dev(host->mmc), "imxmci_stop_clock blocked, no luck\n");
132}
133
134static void imxmci_start_clock(struct imxmci_host *host)
135{
136 int i = 0;
137 MMC_STR_STP_CLK &= ~STR_STP_CLK_STOP_CLK;
138 while(i < 0x1000) {
139 if(!(i & 0x7f))
140 MMC_STR_STP_CLK |= STR_STP_CLK_START_CLK;
141
142 if(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) {
143 /* Check twice before cut */
144 if(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN)
145 return;
146 }
147
148 i++;
149 }
150 dev_dbg(mmc_dev(host->mmc), "imxmci_start_clock blocked, no luck\n");
151}
152
153static void imxmci_softreset(void)
154{
155 /* reset sequence */
156 MMC_STR_STP_CLK = 0x8;
157 MMC_STR_STP_CLK = 0xD;
158 MMC_STR_STP_CLK = 0x5;
159 MMC_STR_STP_CLK = 0x5;
160 MMC_STR_STP_CLK = 0x5;
161 MMC_STR_STP_CLK = 0x5;
162 MMC_STR_STP_CLK = 0x5;
163 MMC_STR_STP_CLK = 0x5;
164 MMC_STR_STP_CLK = 0x5;
165 MMC_STR_STP_CLK = 0x5;
166
167 MMC_RES_TO = 0xff;
168 MMC_BLK_LEN = 512;
169 MMC_NOB = 1;
170}
171
172static int imxmci_busy_wait_for_status(struct imxmci_host *host,
173 unsigned int *pstat, unsigned int stat_mask,
174 int timeout, const char *where)
175{
176 int loops=0;
177 while(!(*pstat & stat_mask)) {
178 loops+=2;
179 if(loops >= timeout) {
180 dev_dbg(mmc_dev(host->mmc), "busy wait timeout in %s, STATUS = 0x%x (0x%x)\n",
181 where, *pstat, stat_mask);
182 return -1;
183 }
184 udelay(2);
185 *pstat |= MMC_STATUS;
186 }
187 if(!loops)
188 return 0;
189
190 dev_info(mmc_dev(host->mmc), "busy wait for %d usec in %s, STATUS = 0x%x (0x%x)\n",
191 loops, where, *pstat, stat_mask);
192 return loops;
193}
194
195static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data)
196{
197 unsigned int nob = data->blocks;
198 unsigned int blksz = 1 << data->blksz_bits;
199 unsigned int datasz = nob * blksz;
200 int i;
201
202 if (data->flags & MMC_DATA_STREAM)
203 nob = 0xffff;
204
205 host->data = data;
206 data->bytes_xfered = 0;
207
208 MMC_NOB = nob;
209 MMC_BLK_LEN = blksz;
210
211 /*
212 * DMA cannot be used for small block sizes, we have to use CPU driven transfers otherwise.
213 * We are in big troubles for non-512 byte transfers according to note in the paragraph
214 * 20.6.7 of User Manual anyway, but we need to be able to transfer SCR at least.
215 * The situation is even more complex in reality. The SDHC in not able to handle wll
216 * partial FIFO fills and reads. The length has to be rounded up to burst size multiple.
217 * This is required for SCR read at least.
218 */
219 if (datasz < 64) {
220 host->dma_size = datasz;
221 if (data->flags & MMC_DATA_READ) {
222 host->dma_dir = DMA_FROM_DEVICE;
223
224 /* Hack to enable read SCR */
225 if(datasz < 16) {
226 MMC_NOB = 1;
227 MMC_BLK_LEN = 16;
228 }
229 } else {
230 host->dma_dir = DMA_TO_DEVICE;
231 }
232
233 /* Convert back to virtual address */
234 host->data_ptr = (u16*)(page_address(data->sg->page) + data->sg->offset);
235 host->data_cnt = 0;
236
237 clear_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events);
238 set_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events);
239
240 return;
241 }
242
243 if (data->flags & MMC_DATA_READ) {
244 host->dma_dir = DMA_FROM_DEVICE;
245 host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
246 data->sg_len, host->dma_dir);
247
248 imx_dma_setup_sg(host->dma, data->sg, data->sg_len, datasz,
249 host->res->start + MMC_BUFFER_ACCESS_OFS, DMA_MODE_READ);
250
251 /*imx_dma_setup_mem2dev_ccr(host->dma, DMA_MODE_READ, IMX_DMA_WIDTH_16, CCR_REN);*/
252 CCR(host->dma) = CCR_DMOD_LINEAR | CCR_DSIZ_32 | CCR_SMOD_FIFO | CCR_SSIZ_16 | CCR_REN;
253 } else {
254 host->dma_dir = DMA_TO_DEVICE;
255
256 host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
257 data->sg_len, host->dma_dir);
258
259 imx_dma_setup_sg(host->dma, data->sg, data->sg_len, datasz,
260 host->res->start + MMC_BUFFER_ACCESS_OFS, DMA_MODE_WRITE);
261
262 /*imx_dma_setup_mem2dev_ccr(host->dma, DMA_MODE_WRITE, IMX_DMA_WIDTH_16, CCR_REN);*/
263 CCR(host->dma) = CCR_SMOD_LINEAR | CCR_SSIZ_32 | CCR_DMOD_FIFO | CCR_DSIZ_16 | CCR_REN;
264 }
265
266#if 1 /* This code is there only for consistency checking and can be disabled in future */
267 host->dma_size = 0;
268 for(i=0; i<host->dma_nents; i++)
269 host->dma_size+=data->sg[i].length;
270
271 if (datasz > host->dma_size) {
272 dev_err(mmc_dev(host->mmc), "imxmci_setup_data datasz 0x%x > 0x%x dm_size\n",
273 datasz, host->dma_size);
274 }
275#endif
276
277 host->dma_size = datasz;
278
279 wmb();
280
281 if(host->actual_bus_width == MMC_BUS_WIDTH_4)
282 BLR(host->dma) = 0; /* burst 64 byte read / 64 bytes write */
283 else
284 BLR(host->dma) = 16; /* burst 16 byte read / 16 bytes write */
285
286 RSSR(host->dma) = DMA_REQ_SDHC;
287
288 set_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events);
289 clear_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events);
290
291 /* start DMA engine for read, write is delayed after initial response */
292 if (host->dma_dir == DMA_FROM_DEVICE) {
293 imx_dma_enable(host->dma);
294 }
295}
296
297static void imxmci_start_cmd(struct imxmci_host *host, struct mmc_command *cmd, unsigned int cmdat)
298{
299 unsigned long flags;
300 u32 imask;
301
302 WARN_ON(host->cmd != NULL);
303 host->cmd = cmd;
304
305 if (cmd->flags & MMC_RSP_BUSY)
306 cmdat |= CMD_DAT_CONT_BUSY;
307
308 switch (mmc_resp_type(cmd)) {
309 case MMC_RSP_R1: /* short CRC, OPCODE */
310 case MMC_RSP_R1B:/* short CRC, OPCODE, BUSY */
311 cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R1;
312 break;
313 case MMC_RSP_R2: /* long 136 bit + CRC */
314 cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R2;
315 break;
316 case MMC_RSP_R3: /* short */
317 cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R3;
318 break;
319 case MMC_RSP_R6: /* short CRC */
320 cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R6;
321 break;
322 default:
323 break;
324 }
325
326 if ( test_and_clear_bit(IMXMCI_PEND_SET_INIT_b, &host->pending_events) )
327 cmdat |= CMD_DAT_CONT_INIT; /* This command needs init */
328
329 if ( host->actual_bus_width == MMC_BUS_WIDTH_4 )
330 cmdat |= CMD_DAT_CONT_BUS_WIDTH_4;
331
332 MMC_CMD = cmd->opcode;
333 MMC_ARGH = cmd->arg >> 16;
334 MMC_ARGL = cmd->arg & 0xffff;
335 MMC_CMD_DAT_CONT = cmdat;
336
337 atomic_set(&host->stuck_timeout, 0);
338 set_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events);
339
340
341 imask = IMXMCI_INT_MASK_DEFAULT;
342 imask &= ~INT_MASK_END_CMD_RES;
343 if ( cmdat & CMD_DAT_CONT_DATA_ENABLE ) {
344 /*imask &= ~INT_MASK_BUF_READY;*/
345 imask &= ~INT_MASK_DATA_TRAN;
346 if ( cmdat & CMD_DAT_CONT_WRITE )
347 imask &= ~INT_MASK_WRITE_OP_DONE;
348 if(test_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events))
349 imask &= ~INT_MASK_BUF_READY;
350 }
351
352 spin_lock_irqsave(&host->lock, flags);
353 host->imask = imask;
354 MMC_INT_MASK = host->imask;
355 spin_unlock_irqrestore(&host->lock, flags);
356
357 dev_dbg(mmc_dev(host->mmc), "CMD%02d (0x%02x) mask set to 0x%04x\n",
358 cmd->opcode, cmd->opcode, imask);
359
360 imxmci_start_clock(host);
361}
362
363static void imxmci_finish_request(struct imxmci_host *host, struct mmc_request *req)
364{
365 unsigned long flags;
366
367 spin_lock_irqsave(&host->lock, flags);
368
369 host->pending_events &= ~(IMXMCI_PEND_WAIT_RESP_m | IMXMCI_PEND_DMA_END_m |
370 IMXMCI_PEND_DMA_DATA_m | IMXMCI_PEND_CPU_DATA_m);
371
372 host->imask = IMXMCI_INT_MASK_DEFAULT;
373 MMC_INT_MASK = host->imask;
374
375 spin_unlock_irqrestore(&host->lock, flags);
376
377 host->req = NULL;
378 host->cmd = NULL;
379 host->data = NULL;
380 mmc_request_done(host->mmc, req);
381}
382
383static int imxmci_finish_data(struct imxmci_host *host, unsigned int stat)
384{
385 struct mmc_data *data = host->data;
386 int data_error;
387
388 if(test_and_clear_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)){
389 imx_dma_disable(host->dma);
390 dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_nents,
391 host->dma_dir);
392 }
393
394 if ( stat & STATUS_ERR_MASK ) {
395 dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n",stat);
396 if(stat & (STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR))
397 data->error = MMC_ERR_BADCRC;
398 else if(stat & STATUS_TIME_OUT_READ)
399 data->error = MMC_ERR_TIMEOUT;
400 else
401 data->error = MMC_ERR_FAILED;
402 } else {
403 data->bytes_xfered = host->dma_size;
404 }
405
406 data_error = data->error;
407
408 host->data = NULL;
409
410 return data_error;
411}
412
413static int imxmci_cmd_done(struct imxmci_host *host, unsigned int stat)
414{
415 struct mmc_command *cmd = host->cmd;
416 int i;
417 u32 a,b,c;
418 struct mmc_data *data = host->data;
419
420 if (!cmd)
421 return 0;
422
423 host->cmd = NULL;
424
425 if (stat & STATUS_TIME_OUT_RESP) {
426 dev_dbg(mmc_dev(host->mmc), "CMD TIMEOUT\n");
427 cmd->error = MMC_ERR_TIMEOUT;
428 } else if (stat & STATUS_RESP_CRC_ERR && cmd->flags & MMC_RSP_CRC) {
429 dev_dbg(mmc_dev(host->mmc), "cmd crc error\n");
430 cmd->error = MMC_ERR_BADCRC;
431 }
432
433 if(cmd->flags & MMC_RSP_PRESENT) {
434 if(cmd->flags & MMC_RSP_136) {
435 for (i = 0; i < 4; i++) {
436 u32 a = MMC_RES_FIFO & 0xffff;
437 u32 b = MMC_RES_FIFO & 0xffff;
438 cmd->resp[i] = a<<16 | b;
439 }
440 } else {
441 a = MMC_RES_FIFO & 0xffff;
442 b = MMC_RES_FIFO & 0xffff;
443 c = MMC_RES_FIFO & 0xffff;
444 cmd->resp[0] = a<<24 | b<<8 | c>>8;
445 }
446 }
447
448 dev_dbg(mmc_dev(host->mmc), "RESP 0x%08x, 0x%08x, 0x%08x, 0x%08x, error %d\n",
449 cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3], cmd->error);
450
451 if (data && (cmd->error == MMC_ERR_NONE) && !(stat & STATUS_ERR_MASK)) {
452 if (host->req->data->flags & MMC_DATA_WRITE) {
453
454 /* Wait for FIFO to be empty before starting DMA write */
455
456 stat = MMC_STATUS;
457 if(imxmci_busy_wait_for_status(host, &stat,
458 STATUS_APPL_BUFF_FE,
459 40, "imxmci_cmd_done DMA WR") < 0) {
460 cmd->error = MMC_ERR_FIFO;
461 imxmci_finish_data(host, stat);
462 if(host->req)
463 imxmci_finish_request(host, host->req);
464 dev_warn(mmc_dev(host->mmc), "STATUS = 0x%04x\n",
465 stat);
466 return 0;
467 }
468
469 if(test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)) {
470 imx_dma_enable(host->dma);
471 }
472 }
473 } else {
474 struct mmc_request *req;
475 imxmci_stop_clock(host);
476 req = host->req;
477
478 if(data)
479 imxmci_finish_data(host, stat);
480
481 if( req ) {
482 imxmci_finish_request(host, req);
483 } else {
484 dev_warn(mmc_dev(host->mmc), "imxmci_cmd_done: no request to finish\n");
485 }
486 }
487
488 return 1;
489}
490
491static int imxmci_data_done(struct imxmci_host *host, unsigned int stat)
492{
493 struct mmc_data *data = host->data;
494 int data_error;
495
496 if (!data)
497 return 0;
498
499 data_error = imxmci_finish_data(host, stat);
500
501 if (host->req->stop && (data_error == MMC_ERR_NONE)) {
502 imxmci_stop_clock(host);
503 imxmci_start_cmd(host, host->req->stop, 0);
504 } else {
505 struct mmc_request *req;
506 req = host->req;
507 if( req ) {
508 imxmci_finish_request(host, req);
509 } else {
510 dev_warn(mmc_dev(host->mmc), "imxmci_data_done: no request to finish\n");
511 }
512 }
513
514 return 1;
515}
516
517static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat)
518{
519 int i;
520 int burst_len;
521 int flush_len;
522 int trans_done = 0;
523 unsigned int stat = *pstat;
524
525 if(host->actual_bus_width == MMC_BUS_WIDTH_4)
526 burst_len = 16;
527 else
528 burst_len = 64;
529
530 /* This is unfortunately required */
531 dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data running STATUS = 0x%x\n",
532 stat);
533
534 if(host->dma_dir == DMA_FROM_DEVICE) {
535 imxmci_busy_wait_for_status(host, &stat,
536 STATUS_APPL_BUFF_FF | STATUS_DATA_TRANS_DONE,
537 20, "imxmci_cpu_driven_data read");
538
539 while((stat & (STATUS_APPL_BUFF_FF | STATUS_DATA_TRANS_DONE)) &&
540 (host->data_cnt < host->dma_size)) {
541 if(burst_len >= host->dma_size - host->data_cnt) {
542 flush_len = burst_len;
543 burst_len = host->dma_size - host->data_cnt;
544 flush_len -= burst_len;
545 host->data_cnt = host->dma_size;
546 trans_done = 1;
547 } else {
548 flush_len = 0;
549 host->data_cnt += burst_len;
550 }
551
552 for(i = burst_len; i>=2 ; i-=2) {
553 *(host->data_ptr++) = MMC_BUFFER_ACCESS;
554 udelay(20); /* required for clocks < 8MHz*/
555 }
556
557 if(i == 1)
558 *(u8*)(host->data_ptr) = MMC_BUFFER_ACCESS;
559
560 stat = MMC_STATUS;
561
562 /* Flush extra bytes from FIFO */
563 while(flush_len >= 2){
564 flush_len -= 2;
565 i = MMC_BUFFER_ACCESS;
566 stat = MMC_STATUS;
567 stat &= ~STATUS_CRC_READ_ERR; /* Stupid but required there */
568 }
569
570 dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data read burst %d STATUS = 0x%x\n",
571 burst_len, stat);
572 }
573 } else {
574 imxmci_busy_wait_for_status(host, &stat,
575 STATUS_APPL_BUFF_FE,
576 20, "imxmci_cpu_driven_data write");
577
578 while((stat & STATUS_APPL_BUFF_FE) &&
579 (host->data_cnt < host->dma_size)) {
580 if(burst_len >= host->dma_size - host->data_cnt) {
581 burst_len = host->dma_size - host->data_cnt;
582 host->data_cnt = host->dma_size;
583 trans_done = 1;
584 } else {
585 host->data_cnt += burst_len;
586 }
587
588 for(i = burst_len; i>0 ; i-=2)
589 MMC_BUFFER_ACCESS = *(host->data_ptr++);
590
591 stat = MMC_STATUS;
592
593 dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data write burst %d STATUS = 0x%x\n",
594 burst_len, stat);
595 }
596 }
597
598 *pstat = stat;
599
600 return trans_done;
601}
602
603static void imxmci_dma_irq(int dma, void *devid, struct pt_regs *regs)
604{
605 struct imxmci_host *host = devid;
606 uint32_t stat = MMC_STATUS;
607
608 atomic_set(&host->stuck_timeout, 0);
609 host->status_reg = stat;
610 set_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events);
611 tasklet_schedule(&host->tasklet);
612}
613
614static irqreturn_t imxmci_irq(int irq, void *devid, struct pt_regs *regs)
615{
616 struct imxmci_host *host = devid;
617 uint32_t stat = MMC_STATUS;
618 int handled = 1;
619
620 MMC_INT_MASK = host->imask | INT_MASK_SDIO | INT_MASK_AUTO_CARD_DETECT;
621
622 atomic_set(&host->stuck_timeout, 0);
623 host->status_reg = stat;
624 set_bit(IMXMCI_PEND_IRQ_b, &host->pending_events);
625 tasklet_schedule(&host->tasklet);
626
627 return IRQ_RETVAL(handled);;
628}
629
630static void imxmci_tasklet_fnc(unsigned long data)
631{
632 struct imxmci_host *host = (struct imxmci_host *)data;
633 u32 stat;
634 unsigned int data_dir_mask = 0; /* STATUS_WR_CRC_ERROR_CODE_MASK */
635 int timeout = 0;
636
637 if(atomic_read(&host->stuck_timeout) > 4) {
638 char *what;
639 timeout = 1;
640 stat = MMC_STATUS;
641 host->status_reg = stat;
642 if (test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events))
643 if (test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events))
644 what = "RESP+DMA";
645 else
646 what = "RESP";
647 else
648 if (test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events))
649 if(test_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events))
650 what = "DATA";
651 else
652 what = "DMA";
653 else
654 what = "???";
655
656 dev_err(mmc_dev(host->mmc), "%s TIMEOUT, hardware stucked STATUS = 0x%04x IMASK = 0x%04x\n",
657 what, stat, MMC_INT_MASK);
658 dev_err(mmc_dev(host->mmc), "CMD_DAT_CONT = 0x%04x, MMC_BLK_LEN = 0x%04x, MMC_NOB = 0x%04x, DMA_CCR = 0x%08x\n",
659 MMC_CMD_DAT_CONT, MMC_BLK_LEN, MMC_NOB, CCR(host->dma));
660 dev_err(mmc_dev(host->mmc), "CMD%d, bus %d-bit, dma_size = 0x%x\n",
661 host->cmd?host->cmd->opcode:0, 1<<host->actual_bus_width, host->dma_size);
662 }
663
664 if(!host->present || timeout)
665 host->status_reg = STATUS_TIME_OUT_RESP | STATUS_TIME_OUT_READ |
666 STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR;
667
668 if(test_bit(IMXMCI_PEND_IRQ_b, &host->pending_events) || timeout) {
669 clear_bit(IMXMCI_PEND_IRQ_b, &host->pending_events);
670
671 stat = MMC_STATUS;
672 /*
673 * This is not required in theory, but there is chance to miss some flag
674 * which clears automatically by mask write, FreeScale original code keeps
675 * stat from IRQ time so do I
676 */
677 stat |= host->status_reg;
678
679 if(test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) {
680 imxmci_busy_wait_for_status(host, &stat,
681 STATUS_END_CMD_RESP | STATUS_ERR_MASK,
682 20, "imxmci_tasklet_fnc resp (ERRATUM #4)");
683 }
684
685 if(stat & (STATUS_END_CMD_RESP | STATUS_ERR_MASK)) {
686 if(test_and_clear_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events))
687 imxmci_cmd_done(host, stat);
688 if(host->data && (stat & STATUS_ERR_MASK))
689 imxmci_data_done(host, stat);
690 }
691
692 if(test_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events)) {
693 stat |= MMC_STATUS;
694 if(imxmci_cpu_driven_data(host, &stat)){
695 if(test_and_clear_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events))
696 imxmci_cmd_done(host, stat);
697 atomic_clear_mask(IMXMCI_PEND_IRQ_m|IMXMCI_PEND_CPU_DATA_m,
698 &host->pending_events);
699 imxmci_data_done(host, stat);
700 }
701 }
702 }
703
704 if(test_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events) &&
705 !test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) {
706
707 stat = MMC_STATUS;
708 /* Same as above */
709 stat |= host->status_reg;
710
711 if(host->dma_dir == DMA_TO_DEVICE) {
712 data_dir_mask = STATUS_WRITE_OP_DONE;
713 } else {
714 data_dir_mask = STATUS_DATA_TRANS_DONE;
715 }
716
717 imxmci_busy_wait_for_status(host, &stat,
718 data_dir_mask,
719 50, "imxmci_tasklet_fnc data");
720
721 if(stat & data_dir_mask) {
722 clear_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events);
723 imxmci_data_done(host, stat);
724 }
725 }
726
727 if(test_and_clear_bit(IMXMCI_PEND_CARD_XCHG_b, &host->pending_events)) {
728
729 if(host->cmd)
730 imxmci_cmd_done(host, STATUS_TIME_OUT_RESP);
731
732 if(host->data)
733 imxmci_data_done(host, STATUS_TIME_OUT_READ |
734 STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR);
735
736 if(host->req)
737 imxmci_finish_request(host, host->req);
738
739 mmc_detect_change(host->mmc, msecs_to_jiffies(100));
740
741 }
742}
743
744static void imxmci_request(struct mmc_host *mmc, struct mmc_request *req)
745{
746 struct imxmci_host *host = mmc_priv(mmc);
747 unsigned int cmdat;
748
749 WARN_ON(host->req != NULL);
750
751 host->req = req;
752
753 cmdat = 0;
754
755 if (req->data) {
756 imxmci_setup_data(host, req->data);
757
758 cmdat |= CMD_DAT_CONT_DATA_ENABLE;
759
760 if (req->data->flags & MMC_DATA_WRITE)
761 cmdat |= CMD_DAT_CONT_WRITE;
762
763 if (req->data->flags & MMC_DATA_STREAM) {
764 cmdat |= CMD_DAT_CONT_STREAM_BLOCK;
765 }
766 }
767
768 imxmci_start_cmd(host, req->cmd, cmdat);
769}
770
771#define CLK_RATE 19200000
772
773static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
774{
775 struct imxmci_host *host = mmc_priv(mmc);
776 int prescaler;
777
778 dev_dbg(mmc_dev(host->mmc), "clock %u power %u vdd %u width %u\n",
779 ios->clock, ios->power_mode, ios->vdd,
780 (ios->bus_width==MMC_BUS_WIDTH_4)?4:1);
781
782 if( ios->bus_width==MMC_BUS_WIDTH_4 ) {
783 host->actual_bus_width = MMC_BUS_WIDTH_4;
784 imx_gpio_mode(PB11_PF_SD_DAT3);
785 }else{
786 host->actual_bus_width = MMC_BUS_WIDTH_1;
787 imx_gpio_mode(GPIO_PORTB | GPIO_IN | GPIO_PUEN | 11);
788 }
789
790 if ( host->power_mode != ios->power_mode ) {
791 switch (ios->power_mode) {
792 case MMC_POWER_OFF:
793 break;
794 case MMC_POWER_UP:
795 set_bit(IMXMCI_PEND_SET_INIT_b, &host->pending_events);
796 break;
797 case MMC_POWER_ON:
798 break;
799 }
800 host->power_mode = ios->power_mode;
801 }
802
803 if ( ios->clock ) {
804 unsigned int clk;
805
806 /* The prescaler is 5 for PERCLK2 equal to 96MHz
807 * then 96MHz / 5 = 19.2 MHz
808 */
809 clk=imx_get_perclk2();
810 prescaler=(clk+(CLK_RATE*7)/8)/CLK_RATE;
811 switch(prescaler) {
812 case 0:
813 case 1: prescaler = 0;
814 break;
815 case 2: prescaler = 1;
816 break;
817 case 3: prescaler = 2;
818 break;
819 case 4: prescaler = 4;
820 break;
821 default:
822 case 5: prescaler = 5;
823 break;
824 }
825
826 dev_dbg(mmc_dev(host->mmc), "PERCLK2 %d MHz -> prescaler %d\n",
827 clk, prescaler);
828
829 for(clk=0; clk<8; clk++) {
830 int x;
831 x = CLK_RATE / (1<<clk);
832 if( x <= ios->clock)
833 break;
834 }
835
836 MMC_STR_STP_CLK |= STR_STP_CLK_ENABLE; /* enable controller */
837
838 imxmci_stop_clock(host);
839 MMC_CLK_RATE = (prescaler<<3) | clk;
840 imxmci_start_clock(host);
841
842 dev_dbg(mmc_dev(host->mmc), "MMC_CLK_RATE: 0x%08x\n", MMC_CLK_RATE);
843 } else {
844 imxmci_stop_clock(host);
845 }
846}
847
848static struct mmc_host_ops imxmci_ops = {
849 .request = imxmci_request,
850 .set_ios = imxmci_set_ios,
851};
852
853static struct resource *platform_device_resource(struct platform_device *dev, unsigned int mask, int nr)
854{
855 int i;
856
857 for (i = 0; i < dev->num_resources; i++)
858 if (dev->resource[i].flags == mask && nr-- == 0)
859 return &dev->resource[i];
860 return NULL;
861}
862
863static int platform_device_irq(struct platform_device *dev, int nr)
864{
865 int i;
866
867 for (i = 0; i < dev->num_resources; i++)
868 if (dev->resource[i].flags == IORESOURCE_IRQ && nr-- == 0)
869 return dev->resource[i].start;
870 return NO_IRQ;
871}
872
873static void imxmci_check_status(unsigned long data)
874{
875 struct imxmci_host *host = (struct imxmci_host *)data;
876
877 if( host->pdata->card_present() != host->present ) {
878 host->present ^= 1;
879 dev_info(mmc_dev(host->mmc), "card %s\n",
880 host->present ? "inserted" : "removed");
881
882 set_bit(IMXMCI_PEND_CARD_XCHG_b, &host->pending_events);
883 tasklet_schedule(&host->tasklet);
884 }
885
886 if(test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events) ||
887 test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)) {
888 atomic_inc(&host->stuck_timeout);
889 if(atomic_read(&host->stuck_timeout) > 4)
890 tasklet_schedule(&host->tasklet);
891 } else {
892 atomic_set(&host->stuck_timeout, 0);
893
894 }
895
896 mod_timer(&host->timer, jiffies + (HZ>>1));
897}
898
899static int imxmci_probe(struct platform_device *pdev)
900{
901 struct mmc_host *mmc;
902 struct imxmci_host *host = NULL;
903 struct resource *r;
904 int ret = 0, irq;
905
906 printk(KERN_INFO "i.MX mmc driver\n");
907
908 r = platform_device_resource(pdev, IORESOURCE_MEM, 0);
909 irq = platform_device_irq(pdev, 0);
910 if (!r || irq == NO_IRQ)
911 return -ENXIO;
912
913 r = request_mem_region(r->start, 0x100, "IMXMCI");
914 if (!r)
915 return -EBUSY;
916
917 mmc = mmc_alloc_host(sizeof(struct imxmci_host), &pdev->dev);
918 if (!mmc) {
919 ret = -ENOMEM;
920 goto out;
921 }
922
923 mmc->ops = &imxmci_ops;
924 mmc->f_min = 150000;
925 mmc->f_max = CLK_RATE/2;
926 mmc->ocr_avail = MMC_VDD_32_33;
927 mmc->caps |= MMC_CAP_4_BIT_DATA;
928
929 /* MMC core transfer sizes tunable parameters */
930 mmc->max_hw_segs = 64;
931 mmc->max_phys_segs = 64;
932 mmc->max_sectors = 64; /* default 1 << (PAGE_CACHE_SHIFT - 9) */
933 mmc->max_seg_size = 64*512; /* default PAGE_CACHE_SIZE */
934
935 host = mmc_priv(mmc);
936 host->mmc = mmc;
937 host->dma_allocated = 0;
938 host->pdata = pdev->dev.platform_data;
939
940 spin_lock_init(&host->lock);
941 host->res = r;
942 host->irq = irq;
943
944 imx_gpio_mode(PB8_PF_SD_DAT0);
945 imx_gpio_mode(PB9_PF_SD_DAT1);
946 imx_gpio_mode(PB10_PF_SD_DAT2);
947 /* Configured as GPIO with pull-up to ensure right MCC card mode */
948 /* Switched to PB11_PF_SD_DAT3 if 4 bit bus is configured */
949 imx_gpio_mode(GPIO_PORTB | GPIO_IN | GPIO_PUEN | 11);
950 /* imx_gpio_mode(PB11_PF_SD_DAT3); */
951 imx_gpio_mode(PB12_PF_SD_CLK);
952 imx_gpio_mode(PB13_PF_SD_CMD);
953
954 imxmci_softreset();
955
956 if ( MMC_REV_NO != 0x390 ) {
957 dev_err(mmc_dev(host->mmc), "wrong rev.no. 0x%08x. aborting.\n",
958 MMC_REV_NO);
959 goto out;
960 }
961
962 MMC_READ_TO = 0x2db4; /* recommended in data sheet */
963
964 host->imask = IMXMCI_INT_MASK_DEFAULT;
965 MMC_INT_MASK = host->imask;
966
967
968 if(imx_dma_request_by_prio(&host->dma, DRIVER_NAME, DMA_PRIO_LOW)<0){
969 dev_err(mmc_dev(host->mmc), "imx_dma_request_by_prio failed\n");
970 ret = -EBUSY;
971 goto out;
972 }
973 host->dma_allocated=1;
974 imx_dma_setup_handlers(host->dma, imxmci_dma_irq, NULL, host);
975
976 tasklet_init(&host->tasklet, imxmci_tasklet_fnc, (unsigned long)host);
977 host->status_reg=0;
978 host->pending_events=0;
979
980 ret = request_irq(host->irq, imxmci_irq, 0, DRIVER_NAME, host);
981 if (ret)
982 goto out;
983
984 host->present = host->pdata->card_present();
985 init_timer(&host->timer);
986 host->timer.data = (unsigned long)host;
987 host->timer.function = imxmci_check_status;
988 add_timer(&host->timer);
989 mod_timer(&host->timer, jiffies + (HZ>>1));
990
991 platform_set_drvdata(pdev, mmc);
992
993 mmc_add_host(mmc);
994
995 return 0;
996
997out:
998 if (host) {
999 if(host->dma_allocated){
1000 imx_dma_free(host->dma);
1001 host->dma_allocated=0;
1002 }
1003 }
1004 if (mmc)
1005 mmc_free_host(mmc);
1006 release_resource(r);
1007 return ret;
1008}
1009
1010static int imxmci_remove(struct platform_device *pdev)
1011{
1012 struct mmc_host *mmc = platform_get_drvdata(pdev);
1013
1014 platform_set_drvdata(pdev, NULL);
1015
1016 if (mmc) {
1017 struct imxmci_host *host = mmc_priv(mmc);
1018
1019 tasklet_disable(&host->tasklet);
1020
1021 del_timer_sync(&host->timer);
1022 mmc_remove_host(mmc);
1023
1024 free_irq(host->irq, host);
1025 if(host->dma_allocated){
1026 imx_dma_free(host->dma);
1027 host->dma_allocated=0;
1028 }
1029
1030 tasklet_kill(&host->tasklet);
1031
1032 release_resource(host->res);
1033
1034 mmc_free_host(mmc);
1035 }
1036 return 0;
1037}
1038
1039#ifdef CONFIG_PM
1040static int imxmci_suspend(struct platform_device *dev, pm_message_t state)
1041{
1042 struct mmc_host *mmc = platform_get_drvdata(dev);
1043 int ret = 0;
1044
1045 if (mmc)
1046 ret = mmc_suspend_host(mmc, state);
1047
1048 return ret;
1049}
1050
1051static int imxmci_resume(struct platform_device *dev)
1052{
1053 struct mmc_host *mmc = platform_get_drvdata(dev);
1054 struct imxmci_host *host;
1055 int ret = 0;
1056
1057 if (mmc) {
1058 host = mmc_priv(mmc);
1059 if(host)
1060 set_bit(IMXMCI_PEND_SET_INIT_b, &host->pending_events);
1061 ret = mmc_resume_host(mmc);
1062 }
1063
1064 return ret;
1065}
1066#else
1067#define imxmci_suspend NULL
1068#define imxmci_resume NULL
1069#endif /* CONFIG_PM */
1070
1071static struct platform_driver imxmci_driver = {
1072 .probe = imxmci_probe,
1073 .remove = imxmci_remove,
1074 .suspend = imxmci_suspend,
1075 .resume = imxmci_resume,
1076 .driver = {
1077 .name = DRIVER_NAME,
1078 }
1079};
1080
1081static int __init imxmci_init(void)
1082{
1083 return platform_driver_register(&imxmci_driver);
1084}
1085
1086static void __exit imxmci_exit(void)
1087{
1088 platform_driver_unregister(&imxmci_driver);
1089}
1090
1091module_init(imxmci_init);
1092module_exit(imxmci_exit);
1093
1094MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver");
1095MODULE_AUTHOR("Sascha Hauer, Pengutronix");
1096MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/imxmmc.h b/drivers/mmc/imxmmc.h
new file mode 100644
index 000000000000..e5339e334dbb
--- /dev/null
+++ b/drivers/mmc/imxmmc.h
@@ -0,0 +1,67 @@
1
2# define __REG16(x) (*((volatile u16 *)IO_ADDRESS(x)))
3
4#define MMC_STR_STP_CLK __REG16(IMX_MMC_BASE + 0x00)
5#define MMC_STATUS __REG16(IMX_MMC_BASE + 0x04)
6#define MMC_CLK_RATE __REG16(IMX_MMC_BASE + 0x08)
7#define MMC_CMD_DAT_CONT __REG16(IMX_MMC_BASE + 0x0C)
8#define MMC_RES_TO __REG16(IMX_MMC_BASE + 0x10)
9#define MMC_READ_TO __REG16(IMX_MMC_BASE + 0x14)
10#define MMC_BLK_LEN __REG16(IMX_MMC_BASE + 0x18)
11#define MMC_NOB __REG16(IMX_MMC_BASE + 0x1C)
12#define MMC_REV_NO __REG16(IMX_MMC_BASE + 0x20)
13#define MMC_INT_MASK __REG16(IMX_MMC_BASE + 0x24)
14#define MMC_CMD __REG16(IMX_MMC_BASE + 0x28)
15#define MMC_ARGH __REG16(IMX_MMC_BASE + 0x2C)
16#define MMC_ARGL __REG16(IMX_MMC_BASE + 0x30)
17#define MMC_RES_FIFO __REG16(IMX_MMC_BASE + 0x34)
18#define MMC_BUFFER_ACCESS __REG16(IMX_MMC_BASE + 0x38)
19#define MMC_BUFFER_ACCESS_OFS 0x38
20
21
22#define STR_STP_CLK_ENDIAN (1<<5)
23#define STR_STP_CLK_RESET (1<<3)
24#define STR_STP_CLK_ENABLE (1<<2)
25#define STR_STP_CLK_START_CLK (1<<1)
26#define STR_STP_CLK_STOP_CLK (1<<0)
27#define STATUS_CARD_PRESENCE (1<<15)
28#define STATUS_SDIO_INT_ACTIVE (1<<14)
29#define STATUS_END_CMD_RESP (1<<13)
30#define STATUS_WRITE_OP_DONE (1<<12)
31#define STATUS_DATA_TRANS_DONE (1<<11)
32#define STATUS_WR_CRC_ERROR_CODE_MASK (3<<10)
33#define STATUS_CARD_BUS_CLK_RUN (1<<8)
34#define STATUS_APPL_BUFF_FF (1<<7)
35#define STATUS_APPL_BUFF_FE (1<<6)
36#define STATUS_RESP_CRC_ERR (1<<5)
37#define STATUS_CRC_READ_ERR (1<<3)
38#define STATUS_CRC_WRITE_ERR (1<<2)
39#define STATUS_TIME_OUT_RESP (1<<1)
40#define STATUS_TIME_OUT_READ (1<<0)
41#define STATUS_ERR_MASK 0x2f
42#define CLK_RATE_PRESCALER(x) ((x) & 0x7)
43#define CLK_RATE_CLK_RATE(x) (((x) & 0x7) << 3)
44#define CMD_DAT_CONT_CMD_RESP_LONG_OFF (1<<12)
45#define CMD_DAT_CONT_STOP_READWAIT (1<<11)
46#define CMD_DAT_CONT_START_READWAIT (1<<10)
47#define CMD_DAT_CONT_BUS_WIDTH_1 (0<<8)
48#define CMD_DAT_CONT_BUS_WIDTH_4 (2<<8)
49#define CMD_DAT_CONT_INIT (1<<7)
50#define CMD_DAT_CONT_BUSY (1<<6)
51#define CMD_DAT_CONT_STREAM_BLOCK (1<<5)
52#define CMD_DAT_CONT_WRITE (1<<4)
53#define CMD_DAT_CONT_DATA_ENABLE (1<<3)
54#define CMD_DAT_CONT_RESPONSE_FORMAT_R1 (1)
55#define CMD_DAT_CONT_RESPONSE_FORMAT_R2 (2)
56#define CMD_DAT_CONT_RESPONSE_FORMAT_R3 (3)
57#define CMD_DAT_CONT_RESPONSE_FORMAT_R4 (4)
58#define CMD_DAT_CONT_RESPONSE_FORMAT_R5 (5)
59#define CMD_DAT_CONT_RESPONSE_FORMAT_R6 (6)
60#define INT_MASK_AUTO_CARD_DETECT (1<<6)
61#define INT_MASK_DAT0_EN (1<<5)
62#define INT_MASK_SDIO (1<<4)
63#define INT_MASK_BUF_READY (1<<3)
64#define INT_MASK_END_CMD_RES (1<<2)
65#define INT_MASK_WRITE_OP_DONE (1<<1)
66#define INT_MASK_DATA_TRAN (1<<0)
67#define INT_ALL (0x7f)
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig
index 0f6bb2e625d8..a7ec5954caf5 100644
--- a/drivers/mtd/chips/Kconfig
+++ b/drivers/mtd/chips/Kconfig
@@ -200,27 +200,6 @@ config MTD_CFI_AMDSTD
200 provides support for one of those command sets, used on chips 200 provides support for one of those command sets, used on chips
201 including the AMD Am29LV320. 201 including the AMD Am29LV320.
202 202
203config MTD_CFI_AMDSTD_RETRY
204 int "Retry failed commands (erase/program)"
205 depends on MTD_CFI_AMDSTD
206 default "0"
207 help
208 Some chips, when attached to a shared bus, don't properly filter
209 bus traffic that is destined to other devices. This broken
210 behavior causes erase and program sequences to be aborted when
211 the sequences are mixed with traffic for other devices.
212
213 SST49LF040 (and related) chips are know to be broken.
214
215config MTD_CFI_AMDSTD_RETRY_MAX
216 int "Max retries of failed commands (erase/program)"
217 depends on MTD_CFI_AMDSTD_RETRY
218 default "0"
219 help
220 If you have an SST49LF040 (or related chip) then this value should
221 be set to at least 1. This can also be adjusted at driver load
222 time with the retry_cmd_max module parameter.
223
224config MTD_CFI_STAA 203config MTD_CFI_STAA
225 tristate "Support for ST (Advanced Architecture) flash chips" 204 tristate "Support for ST (Advanced Architecture) flash chips"
226 depends on MTD_GEN_PROBE 205 depends on MTD_GEN_PROBE
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index ce99845d8266..066e22b01a94 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -539,8 +539,7 @@ rx_status_loop:
539 unsigned buflen; 539 unsigned buflen;
540 540
541 skb = cp->rx_skb[rx_tail].skb; 541 skb = cp->rx_skb[rx_tail].skb;
542 if (!skb) 542 BUG_ON(!skb);
543 BUG();
544 543
545 desc = &cp->rx_ring[rx_tail]; 544 desc = &cp->rx_ring[rx_tail];
546 status = le32_to_cpu(desc->opts1); 545 status = le32_to_cpu(desc->opts1);
@@ -723,8 +722,7 @@ static void cp_tx (struct cp_private *cp)
723 break; 722 break;
724 723
725 skb = cp->tx_skb[tx_tail].skb; 724 skb = cp->tx_skb[tx_tail].skb;
726 if (!skb) 725 BUG_ON(!skb);
727 BUG();
728 726
729 pci_unmap_single(cp->pdev, cp->tx_skb[tx_tail].mapping, 727 pci_unmap_single(cp->pdev, cp->tx_skb[tx_tail].mapping,
730 cp->tx_skb[tx_tail].len, PCI_DMA_TODEVICE); 728 cp->tx_skb[tx_tail].len, PCI_DMA_TODEVICE);
@@ -1550,8 +1548,7 @@ static void cp_get_ethtool_stats (struct net_device *dev,
1550 tmp_stats[i++] = le16_to_cpu(nic_stats->tx_abort); 1548 tmp_stats[i++] = le16_to_cpu(nic_stats->tx_abort);
1551 tmp_stats[i++] = le16_to_cpu(nic_stats->tx_underrun); 1549 tmp_stats[i++] = le16_to_cpu(nic_stats->tx_underrun);
1552 tmp_stats[i++] = cp->cp_stats.rx_frags; 1550 tmp_stats[i++] = cp->cp_stats.rx_frags;
1553 if (i != CP_NUM_STATS) 1551 BUG_ON(i != CP_NUM_STATS);
1554 BUG();
1555 1552
1556 pci_free_consistent(cp->pdev, sizeof(*nic_stats), nic_stats, dma); 1553 pci_free_consistent(cp->pdev, sizeof(*nic_stats), nic_stats, dma);
1557} 1554}
@@ -1856,8 +1853,7 @@ static void cp_remove_one (struct pci_dev *pdev)
1856 struct net_device *dev = pci_get_drvdata(pdev); 1853 struct net_device *dev = pci_get_drvdata(pdev);
1857 struct cp_private *cp = netdev_priv(dev); 1854 struct cp_private *cp = netdev_priv(dev);
1858 1855
1859 if (!dev) 1856 BUG_ON(!dev);
1860 BUG();
1861 unregister_netdev(dev); 1857 unregister_netdev(dev);
1862 iounmap(cp->regs); 1858 iounmap(cp->regs);
1863 if (cp->wol_enabled) pci_set_power_state (pdev, PCI_D0); 1859 if (cp->wol_enabled) pci_set_power_state (pdev, PCI_D0);
diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
index 64e2caf3083d..fabc0607b0f1 100644
--- a/drivers/net/arcnet/arcnet.c
+++ b/drivers/net/arcnet/arcnet.c
@@ -765,8 +765,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
765 BUGMSG(D_DURING, "in arcnet_interrupt\n"); 765 BUGMSG(D_DURING, "in arcnet_interrupt\n");
766 766
767 lp = dev->priv; 767 lp = dev->priv;
768 if (!lp) 768 BUG_ON(!lp);
769 BUG();
770 769
771 spin_lock(&lp->lock); 770 spin_lock(&lp->lock);
772 771
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 15032f2c7817..c4e12b5cbb92 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -608,8 +608,7 @@ static void b44_tx(struct b44 *bp)
608 struct ring_info *rp = &bp->tx_buffers[cons]; 608 struct ring_info *rp = &bp->tx_buffers[cons];
609 struct sk_buff *skb = rp->skb; 609 struct sk_buff *skb = rp->skb;
610 610
611 if (unlikely(skb == NULL)) 611 BUG_ON(skb == NULL);
612 BUG();
613 612
614 pci_unmap_single(bp->pdev, 613 pci_unmap_single(bp->pdev,
615 pci_unmap_addr(rp, mapping), 614 pci_unmap_addr(rp, mapping),
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
index 30ff8ea1a402..4391bf4bf573 100644
--- a/drivers/net/chelsio/sge.c
+++ b/drivers/net/chelsio/sge.c
@@ -1093,8 +1093,7 @@ static int process_responses(struct adapter *adapter, int budget)
1093 if (likely(e->DataValid)) { 1093 if (likely(e->DataValid)) {
1094 struct freelQ *fl = &sge->freelQ[e->FreelistQid]; 1094 struct freelQ *fl = &sge->freelQ[e->FreelistQid];
1095 1095
1096 if (unlikely(!e->Sop || !e->Eop)) 1096 BUG_ON(!e->Sop || !e->Eop);
1097 BUG();
1098 if (unlikely(e->Offload)) 1097 if (unlikely(e->Offload))
1099 unexpected_offload(adapter, fl); 1098 unexpected_offload(adapter, fl);
1100 else 1099 else
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 49cd096a3c3d..add8dc4aa7b0 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -3308,8 +3308,7 @@ e1000_clean(struct net_device *poll_dev, int *budget)
3308 3308
3309 while (poll_dev != &adapter->polling_netdev[i]) { 3309 while (poll_dev != &adapter->polling_netdev[i]) {
3310 i++; 3310 i++;
3311 if (unlikely(i == adapter->num_rx_queues)) 3311 BUG_ON(i == adapter->num_rx_queues);
3312 BUG();
3313 } 3312 }
3314 3313
3315 if (likely(adapter->num_tx_queues == 1)) { 3314 if (likely(adapter->num_tx_queues == 1)) {
diff --git a/drivers/net/eql.c b/drivers/net/eql.c
index aa1569182fd6..815436c6170f 100644
--- a/drivers/net/eql.c
+++ b/drivers/net/eql.c
@@ -203,8 +203,7 @@ static int eql_open(struct net_device *dev)
203 printk(KERN_INFO "%s: remember to turn off Van-Jacobson compression on " 203 printk(KERN_INFO "%s: remember to turn off Van-Jacobson compression on "
204 "your slave devices.\n", dev->name); 204 "your slave devices.\n", dev->name);
205 205
206 if (!list_empty(&eql->queue.all_slaves)) 206 BUG_ON(!list_empty(&eql->queue.all_slaves));
207 BUG();
208 207
209 eql->min_slaves = 1; 208 eql->min_slaves = 1;
210 eql->max_slaves = EQL_DEFAULT_MAX_SLAVES; /* 4 usually... */ 209 eql->max_slaves = EQL_DEFAULT_MAX_SLAVES; /* 4 usually... */
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index 63d38fbbd04e..f530686bd09f 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -695,8 +695,7 @@ static int sa1100_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
695 /* 695 /*
696 * We must not be transmitting... 696 * We must not be transmitting...
697 */ 697 */
698 if (si->txskb) 698 BUG_ON(si->txskb);
699 BUG();
700 699
701 netif_stop_queue(dev); 700 netif_stop_queue(dev);
702 701
diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
index d11821dd86ed..ced9fdb8335c 100644
--- a/drivers/net/ne2k-pci.c
+++ b/drivers/net/ne2k-pci.c
@@ -645,9 +645,7 @@ static void __devexit ne2k_pci_remove_one (struct pci_dev *pdev)
645{ 645{
646 struct net_device *dev = pci_get_drvdata(pdev); 646 struct net_device *dev = pci_get_drvdata(pdev);
647 647
648 if (!dev) 648 BUG_ON(!dev);
649 BUG();
650
651 unregister_netdev(dev); 649 unregister_netdev(dev);
652 release_region(dev->base_addr, NE_IO_EXTENT); 650 release_region(dev->base_addr, NE_IO_EXTENT);
653 free_netdev(dev); 651 free_netdev(dev);
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index 8e9b1a537dee..706aed7d717f 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -568,8 +568,7 @@ static inline int ns83820_add_rx_skb(struct ns83820 *dev, struct sk_buff *skb)
568#endif 568#endif
569 569
570 sg = dev->rx_info.descs + (next_empty * DESC_SIZE); 570 sg = dev->rx_info.descs + (next_empty * DESC_SIZE);
571 if (unlikely(NULL != dev->rx_info.skbs[next_empty])) 571 BUG_ON(NULL != dev->rx_info.skbs[next_empty]);
572 BUG();
573 dev->rx_info.skbs[next_empty] = skb; 572 dev->rx_info.skbs[next_empty] = skb;
574 573
575 dev->rx_info.next_empty = (next_empty + 1) % NR_RX_DESC; 574 dev->rx_info.next_empty = (next_empty + 1) % NR_RX_DESC;
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index 35b18057fbdd..45ad036733e2 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -2122,8 +2122,7 @@ static void __devexit starfire_remove_one (struct pci_dev *pdev)
2122 struct net_device *dev = pci_get_drvdata(pdev); 2122 struct net_device *dev = pci_get_drvdata(pdev);
2123 struct netdev_private *np = netdev_priv(dev); 2123 struct netdev_private *np = netdev_priv(dev);
2124 2124
2125 if (!dev) 2125 BUG_ON(!dev);
2126 BUG();
2127 2126
2128 unregister_netdev(dev); 2127 unregister_netdev(dev);
2129 2128
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 770e6b6cec60..0b5358072172 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -2959,9 +2959,7 @@ static void tg3_tx(struct tg3 *tp)
2959 struct sk_buff *skb = ri->skb; 2959 struct sk_buff *skb = ri->skb;
2960 int i; 2960 int i;
2961 2961
2962 if (unlikely(skb == NULL)) 2962 BUG_ON(skb == NULL);
2963 BUG();
2964
2965 pci_unmap_single(tp->pdev, 2963 pci_unmap_single(tp->pdev,
2966 pci_unmap_addr(ri, mapping), 2964 pci_unmap_addr(ri, mapping),
2967 skb_headlen(skb), 2965 skb_headlen(skb),
@@ -2972,12 +2970,10 @@ static void tg3_tx(struct tg3 *tp)
2972 sw_idx = NEXT_TX(sw_idx); 2970 sw_idx = NEXT_TX(sw_idx);
2973 2971
2974 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 2972 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
2975 if (unlikely(sw_idx == hw_idx)) 2973 BUG_ON(sw_idx == hw_idx);
2976 BUG();
2977 2974
2978 ri = &tp->tx_buffers[sw_idx]; 2975 ri = &tp->tx_buffers[sw_idx];
2979 if (unlikely(ri->skb != NULL)) 2976 BUG_ON(ri->skb != NULL);
2980 BUG();
2981 2977
2982 pci_unmap_page(tp->pdev, 2978 pci_unmap_page(tp->pdev,
2983 pci_unmap_addr(ri, mapping), 2979 pci_unmap_addr(ri, mapping),
@@ -4928,9 +4924,8 @@ static int tg3_halt_cpu(struct tg3 *tp, u32 offset)
4928{ 4924{
4929 int i; 4925 int i;
4930 4926
4931 if (offset == TX_CPU_BASE && 4927 BUG_ON(offset == TX_CPU_BASE &&
4932 (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) 4928 (tp->tg3_flags2 & TG3_FLG2_5705_PLUS));
4933 BUG();
4934 4929
4935 if (offset == RX_CPU_BASE) { 4930 if (offset == RX_CPU_BASE) {
4936 for (i = 0; i < 10000; i++) { 4931 for (i = 0; i < 10000; i++) {
diff --git a/drivers/net/tokenring/abyss.c b/drivers/net/tokenring/abyss.c
index 9345e68c451e..649d8ea354f5 100644
--- a/drivers/net/tokenring/abyss.c
+++ b/drivers/net/tokenring/abyss.c
@@ -438,8 +438,7 @@ static void __devexit abyss_detach (struct pci_dev *pdev)
438{ 438{
439 struct net_device *dev = pci_get_drvdata(pdev); 439 struct net_device *dev = pci_get_drvdata(pdev);
440 440
441 if (!dev) 441 BUG_ON(!dev);
442 BUG();
443 unregister_netdev(dev); 442 unregister_netdev(dev);
444 release_region(dev->base_addr-0x10, ABYSS_IO_EXTENT); 443 release_region(dev->base_addr-0x10, ABYSS_IO_EXTENT);
445 free_irq(dev->irq, dev); 444 free_irq(dev->irq, dev);
diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c
index 3a25d191ea4a..19e6f4dfd69c 100644
--- a/drivers/net/tokenring/madgemc.c
+++ b/drivers/net/tokenring/madgemc.c
@@ -735,8 +735,7 @@ static int __devexit madgemc_remove(struct device *device)
735 struct net_local *tp; 735 struct net_local *tp;
736 struct card_info *card; 736 struct card_info *card;
737 737
738 if (!dev) 738 BUG_ON(!dev);
739 BUG();
740 739
741 tp = dev->priv; 740 tp = dev->priv;
742 card = tp->tmspriv; 741 card = tp->tmspriv;
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 9dce522526c5..bca89cff85a6 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -5573,8 +5573,7 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
5573 case IEEE80211_52GHZ_BAND: 5573 case IEEE80211_52GHZ_BAND:
5574 network->mode = IEEE_A; 5574 network->mode = IEEE_A;
5575 i = ieee80211_channel_to_index(priv->ieee, priv->channel); 5575 i = ieee80211_channel_to_index(priv->ieee, priv->channel);
5576 if (i == -1) 5576 BUG_ON(i == -1);
5577 BUG();
5578 if (geo->a[i].flags & IEEE80211_CH_PASSIVE_ONLY) { 5577 if (geo->a[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
5579 IPW_WARNING("Overriding invalid channel\n"); 5578 IPW_WARNING("Overriding invalid channel\n");
5580 priv->channel = geo->a[0].channel; 5579 priv->channel = geo->a[0].channel;
@@ -5587,8 +5586,7 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
5587 else 5586 else
5588 network->mode = IEEE_B; 5587 network->mode = IEEE_B;
5589 i = ieee80211_channel_to_index(priv->ieee, priv->channel); 5588 i = ieee80211_channel_to_index(priv->ieee, priv->channel);
5590 if (i == -1) 5589 BUG_ON(i == -1);
5591 BUG();
5592 if (geo->bg[i].flags & IEEE80211_CH_PASSIVE_ONLY) { 5590 if (geo->bg[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
5593 IPW_WARNING("Overriding invalid channel\n"); 5591 IPW_WARNING("Overriding invalid channel\n");
5594 priv->channel = geo->bg[0].channel; 5592 priv->channel = geo->bg[0].channel;
@@ -6715,8 +6713,7 @@ static int ipw_qos_association(struct ipw_priv *priv,
6715 6713
6716 switch (priv->ieee->iw_mode) { 6714 switch (priv->ieee->iw_mode) {
6717 case IW_MODE_ADHOC: 6715 case IW_MODE_ADHOC:
6718 if (!(network->capability & WLAN_CAPABILITY_IBSS)) 6716 BUG_ON(!(network->capability & WLAN_CAPABILITY_IBSS));
6719 BUG();
6720 6717
6721 qos_data = &ibss_data; 6718 qos_data = &ibss_data;
6722 break; 6719 break;
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
index 75d56bfef0ee..fd0f43b7db5b 100644
--- a/drivers/net/yellowfin.c
+++ b/drivers/net/yellowfin.c
@@ -1441,8 +1441,7 @@ static void __devexit yellowfin_remove_one (struct pci_dev *pdev)
1441 struct net_device *dev = pci_get_drvdata(pdev); 1441 struct net_device *dev = pci_get_drvdata(pdev);
1442 struct yellowfin_private *np; 1442 struct yellowfin_private *np;
1443 1443
1444 if (!dev) 1444 BUG_ON(!dev);
1445 BUG();
1446 np = netdev_priv(dev); 1445 np = netdev_priv(dev);
1447 1446
1448 pci_free_consistent(pdev, STATUS_TOTAL_SIZE, np->tx_status, 1447 pci_free_consistent(pdev, STATUS_TOTAL_SIZE, np->tx_status,
diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c
index 8fd71ab02ef0..b842377cb0c6 100644
--- a/drivers/s390/block/dasd_erp.c
+++ b/drivers/s390/block/dasd_erp.c
@@ -32,9 +32,8 @@ dasd_alloc_erp_request(char *magic, int cplength, int datasize,
32 int size; 32 int size;
33 33
34 /* Sanity checks */ 34 /* Sanity checks */
35 if ( magic == NULL || datasize > PAGE_SIZE || 35 BUG_ON( magic == NULL || datasize > PAGE_SIZE ||
36 (cplength*sizeof(struct ccw1)) > PAGE_SIZE) 36 (cplength*sizeof(struct ccw1)) > PAGE_SIZE);
37 BUG();
38 37
39 size = (sizeof(struct dasd_ccw_req) + 7L) & -8L; 38 size = (sizeof(struct dasd_ccw_req) + 7L) & -8L;
40 if (cplength > 0) 39 if (cplength > 0)
@@ -125,8 +124,7 @@ dasd_default_erp_postaction(struct dasd_ccw_req * cqr)
125 struct dasd_device *device; 124 struct dasd_device *device;
126 int success; 125 int success;
127 126
128 if (cqr->refers == NULL || cqr->function == NULL) 127 BUG_ON(cqr->refers == NULL || cqr->function == NULL);
129 BUG();
130 128
131 device = cqr->device; 129 device = cqr->device;
132 success = cqr->status == DASD_CQR_DONE; 130 success = cqr->status == DASD_CQR_DONE;
diff --git a/drivers/s390/char/sclp_rw.c b/drivers/s390/char/sclp_rw.c
index ac10dfb20a62..91e93c78f57a 100644
--- a/drivers/s390/char/sclp_rw.c
+++ b/drivers/s390/char/sclp_rw.c
@@ -24,7 +24,7 @@
24 24
25/* 25/*
26 * The room for the SCCB (only for writing) is not equal to a pages size 26 * The room for the SCCB (only for writing) is not equal to a pages size
27 * (as it is specified as the maximum size in the the SCLP ducumentation) 27 * (as it is specified as the maximum size in the the SCLP documentation)
28 * because of the additional data structure described above. 28 * because of the additional data structure described above.
29 */ 29 */
30#define MAX_SCCB_ROOM (PAGE_SIZE - sizeof(struct sclp_buffer)) 30#define MAX_SCCB_ROOM (PAGE_SIZE - sizeof(struct sclp_buffer))
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c
index 5ced2725d6c7..5c65cf3e5cc0 100644
--- a/drivers/s390/char/tape_block.c
+++ b/drivers/s390/char/tape_block.c
@@ -198,9 +198,7 @@ tapeblock_request_fn(request_queue_t *queue)
198 198
199 device = (struct tape_device *) queue->queuedata; 199 device = (struct tape_device *) queue->queuedata;
200 DBF_LH(6, "tapeblock_request_fn(device=%p)\n", device); 200 DBF_LH(6, "tapeblock_request_fn(device=%p)\n", device);
201 if (device == NULL) 201 BUG_ON(device == NULL);
202 BUG();
203
204 tapeblock_trigger_requeue(device); 202 tapeblock_trigger_requeue(device);
205} 203}
206 204
@@ -307,8 +305,7 @@ tapeblock_revalidate_disk(struct gendisk *disk)
307 int rc; 305 int rc;
308 306
309 device = (struct tape_device *) disk->private_data; 307 device = (struct tape_device *) disk->private_data;
310 if (!device) 308 BUG_ON(!device);
311 BUG();
312 309
313 if (!device->blk_data.medium_changed) 310 if (!device->blk_data.medium_changed)
314 return 0; 311 return 0;
@@ -440,11 +437,9 @@ tapeblock_ioctl(
440 437
441 rc = 0; 438 rc = 0;
442 disk = inode->i_bdev->bd_disk; 439 disk = inode->i_bdev->bd_disk;
443 if (!disk) 440 BUG_ON(!disk);
444 BUG();
445 device = disk->private_data; 441 device = disk->private_data;
446 if (!device) 442 BUG_ON(!device);
447 BUG();
448 minor = iminor(inode); 443 minor = iminor(inode);
449 444
450 DBF_LH(6, "tapeblock_ioctl(0x%0x)\n", command); 445 DBF_LH(6, "tapeblock_ioctl(0x%0x)\n", command);
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index edcf05d5d568..5d6b7a57b02f 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -675,9 +675,8 @@ lcs_ready_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer)
675 int index, rc; 675 int index, rc;
676 676
677 LCS_DBF_TEXT(5, trace, "rdybuff"); 677 LCS_DBF_TEXT(5, trace, "rdybuff");
678 if (buffer->state != BUF_STATE_LOCKED && 678 BUG_ON(buffer->state != BUF_STATE_LOCKED &&
679 buffer->state != BUF_STATE_PROCESSED) 679 buffer->state != BUF_STATE_PROCESSED);
680 BUG();
681 spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); 680 spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
682 buffer->state = BUF_STATE_READY; 681 buffer->state = BUF_STATE_READY;
683 index = buffer - channel->iob; 682 index = buffer - channel->iob;
@@ -701,8 +700,7 @@ __lcs_processed_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer)
701 int index, prev, next; 700 int index, prev, next;
702 701
703 LCS_DBF_TEXT(5, trace, "prcsbuff"); 702 LCS_DBF_TEXT(5, trace, "prcsbuff");
704 if (buffer->state != BUF_STATE_READY) 703 BUG_ON(buffer->state != BUF_STATE_READY);
705 BUG();
706 buffer->state = BUF_STATE_PROCESSED; 704 buffer->state = BUF_STATE_PROCESSED;
707 index = buffer - channel->iob; 705 index = buffer - channel->iob;
708 prev = (index - 1) & (LCS_NUM_BUFFS - 1); 706 prev = (index - 1) & (LCS_NUM_BUFFS - 1);
@@ -734,9 +732,8 @@ lcs_release_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer)
734 unsigned long flags; 732 unsigned long flags;
735 733
736 LCS_DBF_TEXT(5, trace, "relbuff"); 734 LCS_DBF_TEXT(5, trace, "relbuff");
737 if (buffer->state != BUF_STATE_LOCKED && 735 BUG_ON(buffer->state != BUF_STATE_LOCKED &&
738 buffer->state != BUF_STATE_PROCESSED) 736 buffer->state != BUF_STATE_PROCESSED);
739 BUG();
740 spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); 737 spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
741 buffer->state = BUF_STATE_EMPTY; 738 buffer->state = BUF_STATE_EMPTY;
742 spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); 739 spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
diff --git a/drivers/scsi/aic7xxx/Kconfig.aic7xxx b/drivers/scsi/aic7xxx/Kconfig.aic7xxx
index 6c2c395554ff..5517da5855f0 100644
--- a/drivers/scsi/aic7xxx/Kconfig.aic7xxx
+++ b/drivers/scsi/aic7xxx/Kconfig.aic7xxx
@@ -86,7 +86,7 @@ config AIC7XXX_DEBUG_MASK
86 default "0" 86 default "0"
87 help 87 help
88 Bit mask of debug options that is only valid if the 88 Bit mask of debug options that is only valid if the
89 CONFIG_AIC7XXX_DEBUG_ENBLE option is enabled. The bits in this mask 89 CONFIG_AIC7XXX_DEBUG_ENABLE option is enabled. The bits in this mask
90 are defined in the drivers/scsi/aic7xxx/aic7xxx.h - search for the 90 are defined in the drivers/scsi/aic7xxx/aic7xxx.h - search for the
91 variable ahc_debug in that file to find them. 91 variable ahc_debug in that file to find them.
92 92
diff --git a/drivers/serial/jsm/jsm.h b/drivers/serial/jsm/jsm.h
index dfc1e86d3aa1..043f50b1d10c 100644
--- a/drivers/serial/jsm/jsm.h
+++ b/drivers/serial/jsm/jsm.h
@@ -20,7 +20,7 @@
20 * 20 *
21 * Contact Information: 21 * Contact Information:
22 * Scott H Kilau <Scott_Kilau@digi.com> 22 * Scott H Kilau <Scott_Kilau@digi.com>
23 * Wendy Xiong <wendyx@us.ltcfwd.linux.ibm.com> 23 * Wendy Xiong <wendyx@us.ibm.com>
24 * 24 *
25 ***********************************************************************/ 25 ***********************************************************************/
26 26
diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c
index b1b66e71d281..b3e1f71be4da 100644
--- a/drivers/serial/jsm/jsm_driver.c
+++ b/drivers/serial/jsm/jsm_driver.c
@@ -20,7 +20,7 @@
20 * 20 *
21 * Contact Information: 21 * Contact Information:
22 * Scott H Kilau <Scott_Kilau@digi.com> 22 * Scott H Kilau <Scott_Kilau@digi.com>
23 * Wendy Xiong <wendyx@us.ltcfwd.linux.ibm.com> 23 * Wendy Xiong <wendyx@us.ibm.com>
24 * 24 *
25 * 25 *
26 ***********************************************************************/ 26 ***********************************************************************/
diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c
index 87e4e2cf8ce7..a5fc589d6ef5 100644
--- a/drivers/serial/jsm/jsm_neo.c
+++ b/drivers/serial/jsm/jsm_neo.c
@@ -20,7 +20,7 @@
20 * 20 *
21 * Contact Information: 21 * Contact Information:
22 * Scott H Kilau <Scott_Kilau@digi.com> 22 * Scott H Kilau <Scott_Kilau@digi.com>
23 * Wendy Xiong <wendyx@us.ltcfwd.linux.ibm.com> 23 * Wendy Xiong <wendyx@us.ibm.com>
24 * 24 *
25 ***********************************************************************/ 25 ***********************************************************************/
26#include <linux/delay.h> /* For udelay */ 26#include <linux/delay.h> /* For udelay */
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 910a8ed74b5d..b05d1b218776 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -929,8 +929,7 @@ do_holes:
929 block_in_page += this_chunk_blocks; 929 block_in_page += this_chunk_blocks;
930 dio->blocks_available -= this_chunk_blocks; 930 dio->blocks_available -= this_chunk_blocks;
931next_block: 931next_block:
932 if (dio->block_in_file > dio->final_block_in_request) 932 BUG_ON(dio->block_in_file > dio->final_block_in_request);
933 BUG();
934 if (dio->block_in_file == dio->final_block_in_request) 933 if (dio->block_in_file == dio->final_block_in_request)
935 break; 934 break;
936 } 935 }
diff --git a/fs/dquot.c b/fs/dquot.c
index 6b3886920939..81d87a413c68 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -590,8 +590,7 @@ we_slept:
590 atomic_dec(&dquot->dq_count); 590 atomic_dec(&dquot->dq_count);
591#ifdef __DQUOT_PARANOIA 591#ifdef __DQUOT_PARANOIA
592 /* sanity check */ 592 /* sanity check */
593 if (!list_empty(&dquot->dq_free)) 593 BUG_ON(!list_empty(&dquot->dq_free));
594 BUG();
595#endif 594#endif
596 put_dquot_last(dquot); 595 put_dquot_last(dquot);
597 spin_unlock(&dq_list_lock); 596 spin_unlock(&dq_list_lock);
@@ -666,8 +665,7 @@ we_slept:
666 return NODQUOT; 665 return NODQUOT;
667 } 666 }
668#ifdef __DQUOT_PARANOIA 667#ifdef __DQUOT_PARANOIA
669 if (!dquot->dq_sb) /* Has somebody invalidated entry under us? */ 668 BUG_ON(!dquot->dq_sb); /* Has somebody invalidated entry under us? */
670 BUG();
671#endif 669#endif
672 670
673 return dquot; 671 return dquot;
diff --git a/fs/exec.c b/fs/exec.c
index 950ebd43cdc3..0291a68a3626 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -561,7 +561,7 @@ static int exec_mmap(struct mm_struct *mm)
561 arch_pick_mmap_layout(mm); 561 arch_pick_mmap_layout(mm);
562 if (old_mm) { 562 if (old_mm) {
563 up_read(&old_mm->mmap_sem); 563 up_read(&old_mm->mmap_sem);
564 if (active_mm != old_mm) BUG(); 564 BUG_ON(active_mm != old_mm);
565 mmput(old_mm); 565 mmput(old_mm);
566 return 0; 566 return 0;
567 } 567 }
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 2a2479196f96..d35cbc6bc112 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -453,8 +453,7 @@ static void send_sigio_to_task(struct task_struct *p,
453 /* Make sure we are called with one of the POLL_* 453 /* Make sure we are called with one of the POLL_*
454 reasons, otherwise we could leak kernel stack into 454 reasons, otherwise we could leak kernel stack into
455 userspace. */ 455 userspace. */
456 if ((reason & __SI_MASK) != __SI_POLL) 456 BUG_ON((reason & __SI_MASK) != __SI_POLL);
457 BUG();
458 if (reason - POLL_IN >= NSIGPOLL) 457 if (reason - POLL_IN >= NSIGPOLL)
459 si.si_band = ~0L; 458 si.si_band = ~0L;
460 else 459 else
diff --git a/fs/freevxfs/vxfs_olt.c b/fs/freevxfs/vxfs_olt.c
index 76a0708ae978..049500847903 100644
--- a/fs/freevxfs/vxfs_olt.c
+++ b/fs/freevxfs/vxfs_olt.c
@@ -42,24 +42,21 @@
42static inline void 42static inline void
43vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp) 43vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp)
44{ 44{
45 if (infp->vsi_fshino) 45 BUG_ON(infp->vsi_fshino);
46 BUG();
47 infp->vsi_fshino = fshp->olt_fsino[0]; 46 infp->vsi_fshino = fshp->olt_fsino[0];
48} 47}
49 48
50static inline void 49static inline void
51vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp) 50vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp)
52{ 51{
53 if (infp->vsi_iext) 52 BUG_ON(infp->vsi_iext);
54 BUG();
55 infp->vsi_iext = ilistp->olt_iext[0]; 53 infp->vsi_iext = ilistp->olt_iext[0];
56} 54}
57 55
58static inline u_long 56static inline u_long
59vxfs_oblock(struct super_block *sbp, daddr_t block, u_long bsize) 57vxfs_oblock(struct super_block *sbp, daddr_t block, u_long bsize)
60{ 58{
61 if (sbp->s_blocksize % bsize) 59 BUG_ON(sbp->s_blocksize % bsize);
62 BUG();
63 return (block * (sbp->s_blocksize / bsize)); 60 return (block * (sbp->s_blocksize / bsize));
64} 61}
65 62
diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c
index 8f07e8fbd03d..746abc9ecf70 100644
--- a/fs/hfsplus/bnode.c
+++ b/fs/hfsplus/bnode.c
@@ -466,8 +466,7 @@ void hfs_bnode_unhash(struct hfs_bnode *node)
466 for (p = &node->tree->node_hash[hfs_bnode_hash(node->this)]; 466 for (p = &node->tree->node_hash[hfs_bnode_hash(node->this)];
467 *p && *p != node; p = &(*p)->next_hash) 467 *p && *p != node; p = &(*p)->next_hash)
468 ; 468 ;
469 if (!*p) 469 BUG_ON(!*p);
470 BUG();
471 *p = node->next_hash; 470 *p = node->next_hash;
472 node->tree->node_hash_cnt--; 471 node->tree->node_hash_cnt--;
473} 472}
@@ -622,8 +621,7 @@ void hfs_bnode_put(struct hfs_bnode *node)
622 621
623 dprint(DBG_BNODE_REFS, "put_node(%d:%d): %d\n", 622 dprint(DBG_BNODE_REFS, "put_node(%d:%d): %d\n",
624 node->tree->cnid, node->this, atomic_read(&node->refcnt)); 623 node->tree->cnid, node->this, atomic_read(&node->refcnt));
625 if (!atomic_read(&node->refcnt)) 624 BUG_ON(!atomic_read(&node->refcnt));
626 BUG();
627 if (!atomic_dec_and_lock(&node->refcnt, &tree->hash_lock)) 625 if (!atomic_dec_and_lock(&node->refcnt, &tree->hash_lock))
628 return; 626 return;
629 for (i = 0; i < tree->pages_per_bnode; i++) { 627 for (i = 0; i < tree->pages_per_bnode; i++) {
diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c
index a67edfa34e9e..effa8991999c 100644
--- a/fs/hfsplus/btree.c
+++ b/fs/hfsplus/btree.c
@@ -269,8 +269,7 @@ void hfs_bmap_free(struct hfs_bnode *node)
269 u8 *data, byte, m; 269 u8 *data, byte, m;
270 270
271 dprint(DBG_BNODE_MOD, "btree_free_node: %u\n", node->this); 271 dprint(DBG_BNODE_MOD, "btree_free_node: %u\n", node->this);
272 if (!node->this) 272 BUG_ON(!node->this);
273 BUG();
274 tree = node->tree; 273 tree = node->tree;
275 nidx = node->this; 274 nidx = node->this;
276 node = hfs_bnode_find(tree, 0); 275 node = hfs_bnode_find(tree, 0);
diff --git a/fs/inode.c b/fs/inode.c
index 32b7c3375021..3a2446a27d2c 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -172,8 +172,7 @@ static struct inode *alloc_inode(struct super_block *sb)
172 172
173void destroy_inode(struct inode *inode) 173void destroy_inode(struct inode *inode)
174{ 174{
175 if (inode_has_buffers(inode)) 175 BUG_ON(inode_has_buffers(inode));
176 BUG();
177 security_inode_free(inode); 176 security_inode_free(inode);
178 if (inode->i_sb->s_op->destroy_inode) 177 if (inode->i_sb->s_op->destroy_inode)
179 inode->i_sb->s_op->destroy_inode(inode); 178 inode->i_sb->s_op->destroy_inode(inode);
@@ -249,12 +248,9 @@ void clear_inode(struct inode *inode)
249 might_sleep(); 248 might_sleep();
250 invalidate_inode_buffers(inode); 249 invalidate_inode_buffers(inode);
251 250
252 if (inode->i_data.nrpages) 251 BUG_ON(inode->i_data.nrpages);
253 BUG(); 252 BUG_ON(!(inode->i_state & I_FREEING));
254 if (!(inode->i_state & I_FREEING)) 253 BUG_ON(inode->i_state & I_CLEAR);
255 BUG();
256 if (inode->i_state & I_CLEAR)
257 BUG();
258 wait_on_inode(inode); 254 wait_on_inode(inode);
259 DQUOT_DROP(inode); 255 DQUOT_DROP(inode);
260 if (inode->i_sb && inode->i_sb->s_op->clear_inode) 256 if (inode->i_sb && inode->i_sb->s_op->clear_inode)
@@ -1054,8 +1050,7 @@ void generic_delete_inode(struct inode *inode)
1054 hlist_del_init(&inode->i_hash); 1050 hlist_del_init(&inode->i_hash);
1055 spin_unlock(&inode_lock); 1051 spin_unlock(&inode_lock);
1056 wake_up_inode(inode); 1052 wake_up_inode(inode);
1057 if (inode->i_state != I_CLEAR) 1053 BUG_ON(inode->i_state != I_CLEAR);
1058 BUG();
1059 destroy_inode(inode); 1054 destroy_inode(inode);
1060} 1055}
1061 1056
diff --git a/fs/jffs2/background.c b/fs/jffs2/background.c
index 7b77a9541125..ff2a872e80e7 100644
--- a/fs/jffs2/background.c
+++ b/fs/jffs2/background.c
@@ -35,8 +35,7 @@ int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c)
35 pid_t pid; 35 pid_t pid;
36 int ret = 0; 36 int ret = 0;
37 37
38 if (c->gc_task) 38 BUG_ON(c->gc_task);
39 BUG();
40 39
41 init_completion(&c->gc_thread_start); 40 init_completion(&c->gc_thread_start);
42 init_completion(&c->gc_thread_exit); 41 init_completion(&c->gc_thread_exit);
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c
index c56bd99a9701..ed9a24d19d7d 100644
--- a/fs/smbfs/file.c
+++ b/fs/smbfs/file.c
@@ -178,11 +178,9 @@ smb_writepage(struct page *page, struct writeback_control *wbc)
178 unsigned offset = PAGE_CACHE_SIZE; 178 unsigned offset = PAGE_CACHE_SIZE;
179 int err; 179 int err;
180 180
181 if (!mapping) 181 BUG_ON(!mapping);
182 BUG();
183 inode = mapping->host; 182 inode = mapping->host;
184 if (!inode) 183 BUG_ON(!inode);
185 BUG();
186 184
187 end_index = inode->i_size >> PAGE_CACHE_SHIFT; 185 end_index = inode->i_size >> PAGE_CACHE_SHIFT;
188 186
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index f26880a4785e..6cfdc9a87772 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -50,7 +50,7 @@ static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent * parent_sd,
50 return sd; 50 return sd;
51} 51}
52 52
53/** 53/*
54 * 54 *
55 * Return -EEXIST if there is already a sysfs element with the same name for 55 * Return -EEXIST if there is already a sysfs element with the same name for
56 * the same parent. 56 * the same parent.
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 830f76fa098c..f1cb1ddde511 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -183,7 +183,7 @@ fill_write_buffer(struct sysfs_buffer * buffer, const char __user * buf, size_t
183 return -ENOMEM; 183 return -ENOMEM;
184 184
185 if (count >= PAGE_SIZE) 185 if (count >= PAGE_SIZE)
186 count = PAGE_SIZE; 186 count = PAGE_SIZE - 1;
187 error = copy_from_user(buffer->page,buf,count); 187 error = copy_from_user(buffer->page,buf,count);
188 buffer->needs_read_fill = 1; 188 buffer->needs_read_fill = 1;
189 return error ? -EFAULT : count; 189 return error ? -EFAULT : count;
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 4c29ac41ac3e..f0b347bd12ca 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -175,8 +175,7 @@ const unsigned char * sysfs_get_name(struct sysfs_dirent *sd)
175 struct bin_attribute * bin_attr; 175 struct bin_attribute * bin_attr;
176 struct sysfs_symlink * sl; 176 struct sysfs_symlink * sl;
177 177
178 if (!sd || !sd->s_element) 178 BUG_ON(!sd || !sd->s_element);
179 BUG();
180 179
181 switch (sd->s_type) { 180 switch (sd->s_type) {
182 case SYSFS_DIR: 181 case SYSFS_DIR:
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c
index 8c66e9270dd6..d7074341ee87 100644
--- a/fs/sysv/dir.c
+++ b/fs/sysv/dir.c
@@ -253,8 +253,7 @@ int sysv_delete_entry(struct sysv_dir_entry *de, struct page *page)
253 253
254 lock_page(page); 254 lock_page(page);
255 err = mapping->a_ops->prepare_write(NULL, page, from, to); 255 err = mapping->a_ops->prepare_write(NULL, page, from, to);
256 if (err) 256 BUG_ON(err);
257 BUG();
258 de->inode = 0; 257 de->inode = 0;
259 err = dir_commit_chunk(page, from, to); 258 err = dir_commit_chunk(page, from, to);
260 dir_put_page(page); 259 dir_put_page(page);
@@ -353,8 +352,7 @@ void sysv_set_link(struct sysv_dir_entry *de, struct page *page,
353 352
354 lock_page(page); 353 lock_page(page);
355 err = page->mapping->a_ops->prepare_write(NULL, page, from, to); 354 err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
356 if (err) 355 BUG_ON(err);
357 BUG();
358 de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); 356 de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino);
359 err = dir_commit_chunk(page, from, to); 357 err = dir_commit_chunk(page, from, to);
360 dir_put_page(page); 358 dir_put_page(page);
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 81e0e8459af1..2983afd5e7fd 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -312,12 +312,10 @@ static int udf_get_block(struct inode *inode, sector_t block, struct buffer_head
312 err = 0; 312 err = 0;
313 313
314 bh = inode_getblk(inode, block, &err, &phys, &new); 314 bh = inode_getblk(inode, block, &err, &phys, &new);
315 if (bh) 315 BUG_ON(bh);
316 BUG();
317 if (err) 316 if (err)
318 goto abort; 317 goto abort;
319 if (!phys) 318 BUG_ON(!phys);
320 BUG();
321 319
322 if (new) 320 if (new)
323 set_buffer_new(bh_result); 321 set_buffer_new(bh_result);
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 85997b1205f5..ae4c4754ed31 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -69,7 +69,6 @@ __xfs_file_read(
69 return rval; 69 return rval;
70} 70}
71 71
72
73STATIC ssize_t 72STATIC ssize_t
74xfs_file_aio_read( 73xfs_file_aio_read(
75 struct kiocb *iocb, 74 struct kiocb *iocb,
@@ -90,7 +89,6 @@ xfs_file_aio_read_invis(
90 return __xfs_file_read(iocb, buf, IO_ISAIO|IO_INVIS, count, pos); 89 return __xfs_file_read(iocb, buf, IO_ISAIO|IO_INVIS, count, pos);
91} 90}
92 91
93
94STATIC inline ssize_t 92STATIC inline ssize_t
95__xfs_file_write( 93__xfs_file_write(
96 struct kiocb *iocb, 94 struct kiocb *iocb,
@@ -113,7 +111,6 @@ __xfs_file_write(
113 return rval; 111 return rval;
114} 112}
115 113
116
117STATIC ssize_t 114STATIC ssize_t
118xfs_file_aio_write( 115xfs_file_aio_write(
119 struct kiocb *iocb, 116 struct kiocb *iocb,
@@ -134,7 +131,6 @@ xfs_file_aio_write_invis(
134 return __xfs_file_write(iocb, buf, IO_ISAIO|IO_INVIS, count, pos); 131 return __xfs_file_write(iocb, buf, IO_ISAIO|IO_INVIS, count, pos);
135} 132}
136 133
137
138STATIC inline ssize_t 134STATIC inline ssize_t
139__xfs_file_readv( 135__xfs_file_readv(
140 struct file *file, 136 struct file *file,
@@ -179,7 +175,6 @@ xfs_file_readv_invis(
179 return __xfs_file_readv(file, iov, IO_INVIS, nr_segs, ppos); 175 return __xfs_file_readv(file, iov, IO_INVIS, nr_segs, ppos);
180} 176}
181 177
182
183STATIC inline ssize_t 178STATIC inline ssize_t
184__xfs_file_writev( 179__xfs_file_writev(
185 struct file *file, 180 struct file *file,
@@ -204,7 +199,6 @@ __xfs_file_writev(
204 return rval; 199 return rval;
205} 200}
206 201
207
208STATIC ssize_t 202STATIC ssize_t
209xfs_file_writev( 203xfs_file_writev(
210 struct file *file, 204 struct file *file,
@@ -228,7 +222,7 @@ xfs_file_writev_invis(
228STATIC ssize_t 222STATIC ssize_t
229xfs_file_sendfile( 223xfs_file_sendfile(
230 struct file *filp, 224 struct file *filp,
231 loff_t *ppos, 225 loff_t *pos,
232 size_t count, 226 size_t count,
233 read_actor_t actor, 227 read_actor_t actor,
234 void *target) 228 void *target)
@@ -236,10 +230,80 @@ xfs_file_sendfile(
236 vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode); 230 vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode);
237 ssize_t rval; 231 ssize_t rval;
238 232
239 VOP_SENDFILE(vp, filp, ppos, 0, count, actor, target, NULL, rval); 233 VOP_SENDFILE(vp, filp, pos, 0, count, actor, target, NULL, rval);
240 return rval; 234 return rval;
241} 235}
242 236
237STATIC ssize_t
238xfs_file_sendfile_invis(
239 struct file *filp,
240 loff_t *pos,
241 size_t count,
242 read_actor_t actor,
243 void *target)
244{
245 vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode);
246 ssize_t rval;
247
248 VOP_SENDFILE(vp, filp, pos, IO_INVIS, count, actor, target, NULL, rval);
249 return rval;
250}
251
252STATIC ssize_t
253xfs_file_splice_read(
254 struct file *infilp,
255 struct inode *pipe,
256 size_t len,
257 unsigned int flags)
258{
259 vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode);
260 ssize_t rval;
261
262 VOP_SPLICE_READ(vp, infilp, pipe, len, flags, 0, NULL, rval);
263 return rval;
264}
265
266STATIC ssize_t
267xfs_file_splice_read_invis(
268 struct file *infilp,
269 struct inode *pipe,
270 size_t len,
271 unsigned int flags)
272{
273 vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode);
274 ssize_t rval;
275
276 VOP_SPLICE_READ(vp, infilp, pipe, len, flags, IO_INVIS, NULL, rval);
277 return rval;
278}
279
280STATIC ssize_t
281xfs_file_splice_write(
282 struct inode *pipe,
283 struct file *outfilp,
284 size_t len,
285 unsigned int flags)
286{
287 vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode);
288 ssize_t rval;
289
290 VOP_SPLICE_WRITE(vp, pipe, outfilp, len, flags, 0, NULL, rval);
291 return rval;
292}
293
294STATIC ssize_t
295xfs_file_splice_write_invis(
296 struct inode *pipe,
297 struct file *outfilp,
298 size_t len,
299 unsigned int flags)
300{
301 vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode);
302 ssize_t rval;
303
304 VOP_SPLICE_WRITE(vp, pipe, outfilp, len, flags, IO_INVIS, NULL, rval);
305 return rval;
306}
243 307
244STATIC int 308STATIC int
245xfs_file_open( 309xfs_file_open(
@@ -251,13 +315,10 @@ xfs_file_open(
251 315
252 if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS) 316 if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
253 return -EFBIG; 317 return -EFBIG;
254
255 ASSERT(vp);
256 VOP_OPEN(vp, NULL, error); 318 VOP_OPEN(vp, NULL, error);
257 return -error; 319 return -error;
258} 320}
259 321
260
261STATIC int 322STATIC int
262xfs_file_release( 323xfs_file_release(
263 struct inode *inode, 324 struct inode *inode,
@@ -271,7 +332,6 @@ xfs_file_release(
271 return -error; 332 return -error;
272} 333}
273 334
274
275STATIC int 335STATIC int
276xfs_file_fsync( 336xfs_file_fsync(
277 struct file *filp, 337 struct file *filp,
@@ -285,21 +345,11 @@ xfs_file_fsync(
285 345
286 if (datasync) 346 if (datasync)
287 flags |= FSYNC_DATA; 347 flags |= FSYNC_DATA;
288
289 ASSERT(vp);
290 VOP_FSYNC(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1, error); 348 VOP_FSYNC(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1, error);
291 return -error; 349 return -error;
292} 350}
293 351
294/*
295 * xfs_file_readdir maps to VOP_READDIR().
296 * We need to build a uio, cred, ...
297 */
298
299#define nextdp(dp) ((struct xfs_dirent *)((char *)(dp) + (dp)->d_reclen))
300
301#ifdef CONFIG_XFS_DMAPI 352#ifdef CONFIG_XFS_DMAPI
302
303STATIC struct page * 353STATIC struct page *
304xfs_vm_nopage( 354xfs_vm_nopage(
305 struct vm_area_struct *area, 355 struct vm_area_struct *area,
@@ -319,10 +369,8 @@ xfs_vm_nopage(
319 369
320 return filemap_nopage(area, address, type); 370 return filemap_nopage(area, address, type);
321} 371}
322
323#endif /* CONFIG_XFS_DMAPI */ 372#endif /* CONFIG_XFS_DMAPI */
324 373
325
326STATIC int 374STATIC int
327xfs_file_readdir( 375xfs_file_readdir(
328 struct file *filp, 376 struct file *filp,
@@ -330,7 +378,7 @@ xfs_file_readdir(
330 filldir_t filldir) 378 filldir_t filldir)
331{ 379{
332 int error = 0; 380 int error = 0;
333 vnode_t *vp; 381 vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode);
334 uio_t uio; 382 uio_t uio;
335 iovec_t iov; 383 iovec_t iov;
336 int eof = 0; 384 int eof = 0;
@@ -340,9 +388,6 @@ xfs_file_readdir(
340 xfs_off_t start_offset, curr_offset; 388 xfs_off_t start_offset, curr_offset;
341 xfs_dirent_t *dbp = NULL; 389 xfs_dirent_t *dbp = NULL;
342 390
343 vp = vn_from_inode(filp->f_dentry->d_inode);
344 ASSERT(vp);
345
346 /* Try fairly hard to get memory */ 391 /* Try fairly hard to get memory */
347 do { 392 do {
348 if ((read_buf = (caddr_t)kmalloc(rlen, GFP_KERNEL))) 393 if ((read_buf = (caddr_t)kmalloc(rlen, GFP_KERNEL)))
@@ -387,7 +432,7 @@ xfs_file_readdir(
387 } 432 }
388 size -= dbp->d_reclen; 433 size -= dbp->d_reclen;
389 curr_offset = (loff_t)dbp->d_off /* & 0x7fffffff */; 434 curr_offset = (loff_t)dbp->d_off /* & 0x7fffffff */;
390 dbp = nextdp(dbp); 435 dbp = (xfs_dirent_t *)((char *)dbp + dbp->d_reclen);
391 } 436 }
392 } 437 }
393done: 438done:
@@ -402,7 +447,6 @@ done:
402 return -error; 447 return -error;
403} 448}
404 449
405
406STATIC int 450STATIC int
407xfs_file_mmap( 451xfs_file_mmap(
408 struct file *filp, 452 struct file *filp,
@@ -457,11 +501,10 @@ xfs_file_ioctl_invis(
457 unsigned int cmd, 501 unsigned int cmd,
458 unsigned long arg) 502 unsigned long arg)
459{ 503{
460 int error;
461 struct inode *inode = filp->f_dentry->d_inode; 504 struct inode *inode = filp->f_dentry->d_inode;
462 vnode_t *vp = vn_from_inode(inode); 505 vnode_t *vp = vn_from_inode(inode);
506 int error;
463 507
464 ASSERT(vp);
465 VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, (void __user *)arg, error); 508 VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, (void __user *)arg, error);
466 VMODIFY(vp); 509 VMODIFY(vp);
467 510
@@ -537,6 +580,8 @@ const struct file_operations xfs_file_operations = {
537 .aio_read = xfs_file_aio_read, 580 .aio_read = xfs_file_aio_read,
538 .aio_write = xfs_file_aio_write, 581 .aio_write = xfs_file_aio_write,
539 .sendfile = xfs_file_sendfile, 582 .sendfile = xfs_file_sendfile,
583 .splice_read = xfs_file_splice_read,
584 .splice_write = xfs_file_splice_write,
540 .unlocked_ioctl = xfs_file_ioctl, 585 .unlocked_ioctl = xfs_file_ioctl,
541#ifdef CONFIG_COMPAT 586#ifdef CONFIG_COMPAT
542 .compat_ioctl = xfs_file_compat_ioctl, 587 .compat_ioctl = xfs_file_compat_ioctl,
@@ -558,7 +603,9 @@ const struct file_operations xfs_invis_file_operations = {
558 .writev = xfs_file_writev_invis, 603 .writev = xfs_file_writev_invis,
559 .aio_read = xfs_file_aio_read_invis, 604 .aio_read = xfs_file_aio_read_invis,
560 .aio_write = xfs_file_aio_write_invis, 605 .aio_write = xfs_file_aio_write_invis,
561 .sendfile = xfs_file_sendfile, 606 .sendfile = xfs_file_sendfile_invis,
607 .splice_read = xfs_file_splice_read_invis,
608 .splice_write = xfs_file_splice_write_invis,
562 .unlocked_ioctl = xfs_file_ioctl_invis, 609 .unlocked_ioctl = xfs_file_ioctl_invis,
563#ifdef CONFIG_COMPAT 610#ifdef CONFIG_COMPAT
564 .compat_ioctl = xfs_file_compat_invis_ioctl, 611 .compat_ioctl = xfs_file_compat_invis_ioctl,
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index 1fe09f2d6519..e9fe43d74768 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -103,6 +103,7 @@
103 */ 103 */
104#undef HAVE_REFCACHE /* reference cache not needed for NFS in 2.6 */ 104#undef HAVE_REFCACHE /* reference cache not needed for NFS in 2.6 */
105#define HAVE_SENDFILE /* sendfile(2) exists in 2.6, but not in 2.4 */ 105#define HAVE_SENDFILE /* sendfile(2) exists in 2.6, but not in 2.4 */
106#define HAVE_SPLICE /* a splice(2) exists in 2.6, but not in 2.4 */
106#ifdef CONFIG_SMP 107#ifdef CONFIG_SMP
107#define HAVE_PERCPU_SB /* per cpu superblock counters are a 2.6 feature */ 108#define HAVE_PERCPU_SB /* per cpu superblock counters are a 2.6 feature */
108#else 109#else
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 84ddf1893894..90cd314acbaa 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -301,36 +301,23 @@ xfs_sendfile(
301 void *target, 301 void *target,
302 cred_t *credp) 302 cred_t *credp)
303{ 303{
304 xfs_inode_t *ip = XFS_BHVTOI(bdp);
305 xfs_mount_t *mp = ip->i_mount;
304 ssize_t ret; 306 ssize_t ret;
305 xfs_fsize_t n;
306 xfs_inode_t *ip;
307 xfs_mount_t *mp;
308 vnode_t *vp;
309
310 ip = XFS_BHVTOI(bdp);
311 vp = BHV_TO_VNODE(bdp);
312 mp = ip->i_mount;
313 307
314 XFS_STATS_INC(xs_read_calls); 308 XFS_STATS_INC(xs_read_calls);
315 309 if (XFS_FORCED_SHUTDOWN(mp))
316 n = XFS_MAXIOFFSET(mp) - *offset;
317 if ((n <= 0) || (count == 0))
318 return 0;
319
320 if (n < count)
321 count = n;
322
323 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
324 return -EIO; 310 return -EIO;
325 311
326 xfs_ilock(ip, XFS_IOLOCK_SHARED); 312 xfs_ilock(ip, XFS_IOLOCK_SHARED);
327 313
328 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) && 314 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
329 (!(ioflags & IO_INVIS))) { 315 (!(ioflags & IO_INVIS))) {
330 vrwlock_t locktype = VRWLOCK_READ; 316 vrwlock_t locktype = VRWLOCK_READ;
331 int error; 317 int error;
332 318
333 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), *offset, count, 319 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
320 *offset, count,
334 FILP_DELAY_FLAG(filp), &locktype); 321 FILP_DELAY_FLAG(filp), &locktype);
335 if (error) { 322 if (error) {
336 xfs_iunlock(ip, XFS_IOLOCK_SHARED); 323 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
@@ -340,12 +327,96 @@ xfs_sendfile(
340 xfs_rw_enter_trace(XFS_SENDFILE_ENTER, &ip->i_iocore, 327 xfs_rw_enter_trace(XFS_SENDFILE_ENTER, &ip->i_iocore,
341 (void *)(unsigned long)target, count, *offset, ioflags); 328 (void *)(unsigned long)target, count, *offset, ioflags);
342 ret = generic_file_sendfile(filp, offset, count, actor, target); 329 ret = generic_file_sendfile(filp, offset, count, actor, target);
330 if (ret > 0)
331 XFS_STATS_ADD(xs_read_bytes, ret);
343 332
344 xfs_iunlock(ip, XFS_IOLOCK_SHARED); 333 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
334 return ret;
335}
345 336
337ssize_t
338xfs_splice_read(
339 bhv_desc_t *bdp,
340 struct file *infilp,
341 struct inode *pipe,
342 size_t count,
343 int flags,
344 int ioflags,
345 cred_t *credp)
346{
347 xfs_inode_t *ip = XFS_BHVTOI(bdp);
348 xfs_mount_t *mp = ip->i_mount;
349 ssize_t ret;
350
351 XFS_STATS_INC(xs_read_calls);
352 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
353 return -EIO;
354
355 xfs_ilock(ip, XFS_IOLOCK_SHARED);
356
357 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
358 (!(ioflags & IO_INVIS))) {
359 vrwlock_t locktype = VRWLOCK_READ;
360 int error;
361
362 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
363 infilp->f_pos, count,
364 FILP_DELAY_FLAG(infilp), &locktype);
365 if (error) {
366 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
367 return -error;
368 }
369 }
370 xfs_rw_enter_trace(XFS_SPLICE_READ_ENTER, &ip->i_iocore,
371 pipe, count, infilp->f_pos, ioflags);
372 ret = generic_file_splice_read(infilp, pipe, count, flags);
346 if (ret > 0) 373 if (ret > 0)
347 XFS_STATS_ADD(xs_read_bytes, ret); 374 XFS_STATS_ADD(xs_read_bytes, ret);
348 375
376 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
377 return ret;
378}
379
380ssize_t
381xfs_splice_write(
382 bhv_desc_t *bdp,
383 struct inode *pipe,
384 struct file *outfilp,
385 size_t count,
386 int flags,
387 int ioflags,
388 cred_t *credp)
389{
390 xfs_inode_t *ip = XFS_BHVTOI(bdp);
391 xfs_mount_t *mp = ip->i_mount;
392 ssize_t ret;
393
394 XFS_STATS_INC(xs_write_calls);
395 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
396 return -EIO;
397
398 xfs_ilock(ip, XFS_IOLOCK_EXCL);
399
400 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_WRITE) &&
401 (!(ioflags & IO_INVIS))) {
402 vrwlock_t locktype = VRWLOCK_WRITE;
403 int error;
404
405 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, BHV_TO_VNODE(bdp),
406 outfilp->f_pos, count,
407 FILP_DELAY_FLAG(outfilp), &locktype);
408 if (error) {
409 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
410 return -error;
411 }
412 }
413 xfs_rw_enter_trace(XFS_SPLICE_WRITE_ENTER, &ip->i_iocore,
414 pipe, count, outfilp->f_pos, ioflags);
415 ret = generic_file_splice_write(pipe, outfilp, count, flags);
416 if (ret > 0)
417 XFS_STATS_ADD(xs_write_bytes, ret);
418
419 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
349 return ret; 420 return ret;
350} 421}
351 422
@@ -363,7 +434,7 @@ xfs_zero_last_block(
363 xfs_fsize_t end_size) 434 xfs_fsize_t end_size)
364{ 435{
365 xfs_fileoff_t last_fsb; 436 xfs_fileoff_t last_fsb;
366 xfs_mount_t *mp; 437 xfs_mount_t *mp = io->io_mount;
367 int nimaps; 438 int nimaps;
368 int zero_offset; 439 int zero_offset;
369 int zero_len; 440 int zero_len;
@@ -373,8 +444,6 @@ xfs_zero_last_block(
373 444
374 ASSERT(ismrlocked(io->io_lock, MR_UPDATE) != 0); 445 ASSERT(ismrlocked(io->io_lock, MR_UPDATE) != 0);
375 446
376 mp = io->io_mount;
377
378 zero_offset = XFS_B_FSB_OFFSET(mp, isize); 447 zero_offset = XFS_B_FSB_OFFSET(mp, isize);
379 if (zero_offset == 0) { 448 if (zero_offset == 0) {
380 /* 449 /*
@@ -405,10 +474,9 @@ xfs_zero_last_block(
405 * don't deadlock when the buffer cache calls back to us. 474 * don't deadlock when the buffer cache calls back to us.
406 */ 475 */
407 XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL| XFS_EXTSIZE_RD); 476 XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL| XFS_EXTSIZE_RD);
408 loff = XFS_FSB_TO_B(mp, last_fsb);
409 477
478 loff = XFS_FSB_TO_B(mp, last_fsb);
410 zero_len = mp->m_sb.sb_blocksize - zero_offset; 479 zero_len = mp->m_sb.sb_blocksize - zero_offset;
411
412 error = xfs_iozero(ip, loff + zero_offset, zero_len, end_size); 480 error = xfs_iozero(ip, loff + zero_offset, zero_len, end_size);
413 481
414 XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); 482 XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD);
@@ -441,7 +509,7 @@ xfs_zero_eof(
441 xfs_fileoff_t zero_count_fsb; 509 xfs_fileoff_t zero_count_fsb;
442 xfs_fileoff_t last_fsb; 510 xfs_fileoff_t last_fsb;
443 xfs_extlen_t buf_len_fsb; 511 xfs_extlen_t buf_len_fsb;
444 xfs_mount_t *mp; 512 xfs_mount_t *mp = io->io_mount;
445 int nimaps; 513 int nimaps;
446 int error = 0; 514 int error = 0;
447 xfs_bmbt_irec_t imap; 515 xfs_bmbt_irec_t imap;
@@ -450,8 +518,6 @@ xfs_zero_eof(
450 ASSERT(ismrlocked(io->io_iolock, MR_UPDATE)); 518 ASSERT(ismrlocked(io->io_iolock, MR_UPDATE));
451 ASSERT(offset > isize); 519 ASSERT(offset > isize);
452 520
453 mp = io->io_mount;
454
455 /* 521 /*
456 * First handle zeroing the block on which isize resides. 522 * First handle zeroing the block on which isize resides.
457 * We only zero a part of that block so it is handled specially. 523 * We only zero a part of that block so it is handled specially.
diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h
index 38864a88d42d..eaa5659713fb 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.h
+++ b/fs/xfs/linux-2.6/xfs_lrw.h
@@ -60,6 +60,8 @@ struct xfs_iomap;
60#define XFS_IOMAP_ALLOC_ENTER 25 60#define XFS_IOMAP_ALLOC_ENTER 25
61#define XFS_IOMAP_ALLOC_MAP 26 61#define XFS_IOMAP_ALLOC_MAP 26
62#define XFS_IOMAP_UNWRITTEN 27 62#define XFS_IOMAP_UNWRITTEN 27
63#define XFS_SPLICE_READ_ENTER 28
64#define XFS_SPLICE_WRITE_ENTER 29
63extern void xfs_rw_enter_trace(int, struct xfs_iocore *, 65extern void xfs_rw_enter_trace(int, struct xfs_iocore *,
64 void *, size_t, loff_t, int); 66 void *, size_t, loff_t, int);
65extern void xfs_inval_cached_trace(struct xfs_iocore *, 67extern void xfs_inval_cached_trace(struct xfs_iocore *,
@@ -78,6 +80,7 @@ extern int xfs_bmap(struct bhv_desc *, xfs_off_t, ssize_t, int,
78 struct xfs_iomap *, int *); 80 struct xfs_iomap *, int *);
79extern int xfsbdstrat(struct xfs_mount *, struct xfs_buf *); 81extern int xfsbdstrat(struct xfs_mount *, struct xfs_buf *);
80extern int xfs_bdstrat_cb(struct xfs_buf *); 82extern int xfs_bdstrat_cb(struct xfs_buf *);
83extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
81 84
82extern int xfs_zero_eof(struct vnode *, struct xfs_iocore *, xfs_off_t, 85extern int xfs_zero_eof(struct vnode *, struct xfs_iocore *, xfs_off_t,
83 xfs_fsize_t, xfs_fsize_t); 86 xfs_fsize_t, xfs_fsize_t);
@@ -90,7 +93,11 @@ extern ssize_t xfs_write(struct bhv_desc *, struct kiocb *,
90extern ssize_t xfs_sendfile(struct bhv_desc *, struct file *, 93extern ssize_t xfs_sendfile(struct bhv_desc *, struct file *,
91 loff_t *, int, size_t, read_actor_t, 94 loff_t *, int, size_t, read_actor_t,
92 void *, struct cred *); 95 void *, struct cred *);
93 96extern ssize_t xfs_splice_read(struct bhv_desc *, struct file *,
94extern int xfs_dev_is_read_only(struct xfs_mount *, char *); 97 struct inode *, size_t, int, int,
98 struct cred *);
99extern ssize_t xfs_splice_write(struct bhv_desc *, struct inode *,
100 struct file *, size_t, int, int,
101 struct cred *);
95 102
96#endif /* __XFS_LRW_H__ */ 103#endif /* __XFS_LRW_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 1884300417e3..68f4793e8a11 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -67,7 +67,8 @@ mempool_t *xfs_ioend_pool;
67 67
68STATIC struct xfs_mount_args * 68STATIC struct xfs_mount_args *
69xfs_args_allocate( 69xfs_args_allocate(
70 struct super_block *sb) 70 struct super_block *sb,
71 int silent)
71{ 72{
72 struct xfs_mount_args *args; 73 struct xfs_mount_args *args;
73 74
@@ -80,8 +81,8 @@ xfs_args_allocate(
80 args->flags |= XFSMNT_DIRSYNC; 81 args->flags |= XFSMNT_DIRSYNC;
81 if (sb->s_flags & MS_SYNCHRONOUS) 82 if (sb->s_flags & MS_SYNCHRONOUS)
82 args->flags |= XFSMNT_WSYNC; 83 args->flags |= XFSMNT_WSYNC;
83 84 if (silent)
84 /* Default to 32 bit inodes on Linux all the time */ 85 args->flags |= XFSMNT_QUIET;
85 args->flags |= XFSMNT_32BITINODES; 86 args->flags |= XFSMNT_32BITINODES;
86 87
87 return args; 88 return args;
@@ -719,7 +720,7 @@ xfs_fs_remount(
719 char *options) 720 char *options)
720{ 721{
721 vfs_t *vfsp = vfs_from_sb(sb); 722 vfs_t *vfsp = vfs_from_sb(sb);
722 struct xfs_mount_args *args = xfs_args_allocate(sb); 723 struct xfs_mount_args *args = xfs_args_allocate(sb, 0);
723 int error; 724 int error;
724 725
725 VFS_PARSEARGS(vfsp, options, args, 1, error); 726 VFS_PARSEARGS(vfsp, options, args, 1, error);
@@ -825,7 +826,7 @@ xfs_fs_fill_super(
825{ 826{
826 vnode_t *rootvp; 827 vnode_t *rootvp;
827 struct vfs *vfsp = vfs_allocate(sb); 828 struct vfs *vfsp = vfs_allocate(sb);
828 struct xfs_mount_args *args = xfs_args_allocate(sb); 829 struct xfs_mount_args *args = xfs_args_allocate(sb, silent);
829 struct kstatfs statvfs; 830 struct kstatfs statvfs;
830 int error, error2; 831 int error, error2;
831 832
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index 06f5845e9568..6f1c79a28f8b 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -173,6 +173,12 @@ typedef ssize_t (*vop_write_t)(bhv_desc_t *, struct kiocb *,
173typedef ssize_t (*vop_sendfile_t)(bhv_desc_t *, struct file *, 173typedef ssize_t (*vop_sendfile_t)(bhv_desc_t *, struct file *,
174 loff_t *, int, size_t, read_actor_t, 174 loff_t *, int, size_t, read_actor_t,
175 void *, struct cred *); 175 void *, struct cred *);
176typedef ssize_t (*vop_splice_read_t)(bhv_desc_t *, struct file *,
177 struct inode *, size_t, int, int,
178 struct cred *);
179typedef ssize_t (*vop_splice_write_t)(bhv_desc_t *, struct inode *,
180 struct file *, size_t, int, int,
181 struct cred *);
176typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *, 182typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *,
177 int, unsigned int, void __user *); 183 int, unsigned int, void __user *);
178typedef int (*vop_getattr_t)(bhv_desc_t *, struct vattr *, int, 184typedef int (*vop_getattr_t)(bhv_desc_t *, struct vattr *, int,
@@ -231,6 +237,8 @@ typedef struct vnodeops {
231 vop_read_t vop_read; 237 vop_read_t vop_read;
232 vop_write_t vop_write; 238 vop_write_t vop_write;
233 vop_sendfile_t vop_sendfile; 239 vop_sendfile_t vop_sendfile;
240 vop_splice_read_t vop_splice_read;
241 vop_splice_write_t vop_splice_write;
234 vop_ioctl_t vop_ioctl; 242 vop_ioctl_t vop_ioctl;
235 vop_getattr_t vop_getattr; 243 vop_getattr_t vop_getattr;
236 vop_setattr_t vop_setattr; 244 vop_setattr_t vop_setattr;
@@ -276,6 +284,10 @@ typedef struct vnodeops {
276 rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr) 284 rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr)
277#define VOP_SENDFILE(vp,f,off,ioflags,cnt,act,targ,cr,rv) \ 285#define VOP_SENDFILE(vp,f,off,ioflags,cnt,act,targ,cr,rv) \
278 rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,off,ioflags,cnt,act,targ,cr) 286 rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,off,ioflags,cnt,act,targ,cr)
287#define VOP_SPLICE_READ(vp,f,pipe,cnt,fl,iofl,cr,rv) \
288 rv = _VOP_(vop_splice_read, vp)((vp)->v_fbhv,f,pipe,cnt,fl,iofl,cr)
289#define VOP_SPLICE_WRITE(vp,f,pipe,cnt,fl,iofl,cr,rv) \
290 rv = _VOP_(vop_splice_write, vp)((vp)->v_fbhv,f,pipe,cnt,fl,iofl,cr)
279#define VOP_BMAP(vp,of,sz,rw,b,n,rv) \ 291#define VOP_BMAP(vp,of,sz,rw,b,n,rv) \
280 rv = _VOP_(vop_bmap, vp)((vp)->v_fbhv,of,sz,rw,b,n) 292 rv = _VOP_(vop_bmap, vp)((vp)->v_fbhv,of,sz,rw,b,n)
281#define VOP_OPEN(vp, cr, rv) \ 293#define VOP_OPEN(vp, cr, rv) \
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 73c1e5e80c07..7fb5eca9bd50 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -2624,7 +2624,7 @@ xfs_qm_vop_chown_reserve(
2624{ 2624{
2625 int error; 2625 int error;
2626 xfs_mount_t *mp; 2626 xfs_mount_t *mp;
2627 uint delblks, blkflags; 2627 uint delblks, blkflags, prjflags = 0;
2628 xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq; 2628 xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq;
2629 2629
2630 ASSERT(XFS_ISLOCKED_INODE(ip)); 2630 ASSERT(XFS_ISLOCKED_INODE(ip));
@@ -2650,10 +2650,13 @@ xfs_qm_vop_chown_reserve(
2650 } 2650 }
2651 } 2651 }
2652 if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) { 2652 if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) {
2653 if ((XFS_IS_GQUOTA_ON(ip->i_mount) && 2653 if (XFS_IS_PQUOTA_ON(ip->i_mount) &&
2654 ip->i_d.di_gid != be32_to_cpu(gdqp->q_core.d_id)) || 2654 ip->i_d.di_projid != be32_to_cpu(gdqp->q_core.d_id))
2655 (XFS_IS_PQUOTA_ON(ip->i_mount) && 2655 prjflags = XFS_QMOPT_ENOSPC;
2656 ip->i_d.di_projid != be32_to_cpu(gdqp->q_core.d_id))) { 2656
2657 if (prjflags ||
2658 (XFS_IS_GQUOTA_ON(ip->i_mount) &&
2659 ip->i_d.di_gid != be32_to_cpu(gdqp->q_core.d_id))) {
2657 delblksgdq = gdqp; 2660 delblksgdq = gdqp;
2658 if (delblks) { 2661 if (delblks) {
2659 ASSERT(ip->i_gdquot); 2662 ASSERT(ip->i_gdquot);
@@ -2664,7 +2667,7 @@ xfs_qm_vop_chown_reserve(
2664 2667
2665 if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount, 2668 if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount,
2666 delblksudq, delblksgdq, ip->i_d.di_nblocks, 1, 2669 delblksudq, delblksgdq, ip->i_d.di_nblocks, 1,
2667 flags | blkflags))) 2670 flags | blkflags | prjflags)))
2668 return (error); 2671 return (error);
2669 2672
2670 /* 2673 /*
@@ -2681,7 +2684,7 @@ xfs_qm_vop_chown_reserve(
2681 ASSERT(unresudq || unresgdq); 2684 ASSERT(unresudq || unresgdq);
2682 if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, 2685 if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
2683 delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0, 2686 delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0,
2684 flags | blkflags))) 2687 flags | blkflags | prjflags)))
2685 return (error); 2688 return (error);
2686 xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, 2689 xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
2687 unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0, 2690 unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0,
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c
index d8e131ec0aa8..9168918db252 100644
--- a/fs/xfs/quota/xfs_trans_dquot.c
+++ b/fs/xfs/quota/xfs_trans_dquot.c
@@ -595,12 +595,19 @@ xfs_trans_unreserve_and_mod_dquots(
595 } 595 }
596} 596}
597 597
598STATIC int
599xfs_quota_error(uint flags)
600{
601 if (flags & XFS_QMOPT_ENOSPC)
602 return ENOSPC;
603 return EDQUOT;
604}
605
598/* 606/*
599 * This reserves disk blocks and inodes against a dquot. 607 * This reserves disk blocks and inodes against a dquot.
600 * Flags indicate if the dquot is to be locked here and also 608 * Flags indicate if the dquot is to be locked here and also
601 * if the blk reservation is for RT or regular blocks. 609 * if the blk reservation is for RT or regular blocks.
602 * Sending in XFS_QMOPT_FORCE_RES flag skips the quota check. 610 * Sending in XFS_QMOPT_FORCE_RES flag skips the quota check.
603 * Returns EDQUOT if quota is exceeded.
604 */ 611 */
605STATIC int 612STATIC int
606xfs_trans_dqresv( 613xfs_trans_dqresv(
@@ -666,19 +673,15 @@ xfs_trans_dqresv(
666 */ 673 */
667 if (hardlimit > 0ULL && 674 if (hardlimit > 0ULL &&
668 (hardlimit <= nblks + *resbcountp)) { 675 (hardlimit <= nblks + *resbcountp)) {
669 error = EDQUOT; 676 error = xfs_quota_error(flags);
670 goto error_return; 677 goto error_return;
671 } 678 }
672 679
673 if (softlimit > 0ULL && 680 if (softlimit > 0ULL &&
674 (softlimit <= nblks + *resbcountp)) { 681 (softlimit <= nblks + *resbcountp)) {
675 /*
676 * If timer or warnings has expired,
677 * return EDQUOT
678 */
679 if ((timer != 0 && get_seconds() > timer) || 682 if ((timer != 0 && get_seconds() > timer) ||
680 (warns != 0 && warns >= warnlimit)) { 683 (warns != 0 && warns >= warnlimit)) {
681 error = EDQUOT; 684 error = xfs_quota_error(flags);
682 goto error_return; 685 goto error_return;
683 } 686 }
684 } 687 }
@@ -695,16 +698,12 @@ xfs_trans_dqresv(
695 if (!softlimit) 698 if (!softlimit)
696 softlimit = q->qi_isoftlimit; 699 softlimit = q->qi_isoftlimit;
697 if (hardlimit > 0ULL && count >= hardlimit) { 700 if (hardlimit > 0ULL && count >= hardlimit) {
698 error = EDQUOT; 701 error = xfs_quota_error(flags);
699 goto error_return; 702 goto error_return;
700 } else if (softlimit > 0ULL && count >= softlimit) { 703 } else if (softlimit > 0ULL && count >= softlimit) {
701 /*
702 * If timer or warnings has expired,
703 * return EDQUOT
704 */
705 if ((timer != 0 && get_seconds() > timer) || 704 if ((timer != 0 && get_seconds() > timer) ||
706 (warns != 0 && warns >= warnlimit)) { 705 (warns != 0 && warns >= warnlimit)) {
707 error = EDQUOT; 706 error = xfs_quota_error(flags);
708 goto error_return; 707 goto error_return;
709 } 708 }
710 } 709 }
@@ -751,13 +750,14 @@ error_return:
751 750
752 751
753/* 752/*
754 * Given a dquot(s), make disk block and/or inode reservations against them. 753 * Given dquot(s), make disk block and/or inode reservations against them.
755 * The fact that this does the reservation against both the usr and 754 * The fact that this does the reservation against both the usr and
756 * grp quotas is important, because this follows a both-or-nothing 755 * grp/prj quotas is important, because this follows a both-or-nothing
757 * approach. 756 * approach.
758 * 757 *
759 * flags = XFS_QMOPT_DQLOCK indicate if dquot(s) need to be locked. 758 * flags = XFS_QMOPT_DQLOCK indicate if dquot(s) need to be locked.
760 * XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown. 759 * XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
760 * XFS_QMOPT_ENOSPC returns ENOSPC not EDQUOT. Used by pquota.
761 * XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks 761 * XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks
762 * XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks 762 * XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks
763 * dquots are unlocked on return, if they were not locked by caller. 763 * dquots are unlocked on return, if they were not locked by caller.
@@ -772,25 +772,27 @@ xfs_trans_reserve_quota_bydquots(
772 long ninos, 772 long ninos,
773 uint flags) 773 uint flags)
774{ 774{
775 int resvd; 775 int resvd = 0, error;
776 776
777 if (! XFS_IS_QUOTA_ON(mp)) 777 if (!XFS_IS_QUOTA_ON(mp))
778 return (0); 778 return 0;
779 779
780 if (tp && tp->t_dqinfo == NULL) 780 if (tp && tp->t_dqinfo == NULL)
781 xfs_trans_alloc_dqinfo(tp); 781 xfs_trans_alloc_dqinfo(tp);
782 782
783 ASSERT(flags & XFS_QMOPT_RESBLK_MASK); 783 ASSERT(flags & XFS_QMOPT_RESBLK_MASK);
784 resvd = 0;
785 784
786 if (udqp) { 785 if (udqp) {
787 if (xfs_trans_dqresv(tp, mp, udqp, nblks, ninos, flags)) 786 error = xfs_trans_dqresv(tp, mp, udqp, nblks, ninos,
788 return (EDQUOT); 787 (flags & ~XFS_QMOPT_ENOSPC));
788 if (error)
789 return error;
789 resvd = 1; 790 resvd = 1;
790 } 791 }
791 792
792 if (gdqp) { 793 if (gdqp) {
793 if (xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags)) { 794 error = xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags);
795 if (error) {
794 /* 796 /*
795 * can't do it, so backout previous reservation 797 * can't do it, so backout previous reservation
796 */ 798 */
@@ -799,14 +801,14 @@ xfs_trans_reserve_quota_bydquots(
799 xfs_trans_dqresv(tp, mp, udqp, 801 xfs_trans_dqresv(tp, mp, udqp,
800 -nblks, -ninos, flags); 802 -nblks, -ninos, flags);
801 } 803 }
802 return (EDQUOT); 804 return error;
803 } 805 }
804 } 806 }
805 807
806 /* 808 /*
807 * Didn't change anything critical, so, no need to log 809 * Didn't change anything critical, so, no need to log
808 */ 810 */
809 return (0); 811 return 0;
810} 812}
811 813
812 814
@@ -814,8 +816,6 @@ xfs_trans_reserve_quota_bydquots(
814 * Lock the dquot and change the reservation if we can. 816 * Lock the dquot and change the reservation if we can.
815 * This doesn't change the actual usage, just the reservation. 817 * This doesn't change the actual usage, just the reservation.
816 * The inode sent in is locked. 818 * The inode sent in is locked.
817 *
818 * Returns 0 on success, EDQUOT or other errors otherwise
819 */ 819 */
820STATIC int 820STATIC int
821xfs_trans_reserve_quota_nblks( 821xfs_trans_reserve_quota_nblks(
@@ -824,20 +824,24 @@ xfs_trans_reserve_quota_nblks(
824 xfs_inode_t *ip, 824 xfs_inode_t *ip,
825 long nblks, 825 long nblks,
826 long ninos, 826 long ninos,
827 uint type) 827 uint flags)
828{ 828{
829 int error; 829 int error;
830 830
831 if (!XFS_IS_QUOTA_ON(mp)) 831 if (!XFS_IS_QUOTA_ON(mp))
832 return (0); 832 return 0;
833 if (XFS_IS_PQUOTA_ON(mp))
834 flags |= XFS_QMOPT_ENOSPC;
833 835
834 ASSERT(ip->i_ino != mp->m_sb.sb_uquotino); 836 ASSERT(ip->i_ino != mp->m_sb.sb_uquotino);
835 ASSERT(ip->i_ino != mp->m_sb.sb_gquotino); 837 ASSERT(ip->i_ino != mp->m_sb.sb_gquotino);
836 838
837 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); 839 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
838 ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount)); 840 ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount));
839 ASSERT((type & ~XFS_QMOPT_FORCE_RES) == XFS_TRANS_DQ_RES_RTBLKS || 841 ASSERT((flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) ==
840 (type & ~XFS_QMOPT_FORCE_RES) == XFS_TRANS_DQ_RES_BLKS); 842 XFS_TRANS_DQ_RES_RTBLKS ||
843 (flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) ==
844 XFS_TRANS_DQ_RES_BLKS);
841 845
842 /* 846 /*
843 * Reserve nblks against these dquots, with trans as the mediator. 847 * Reserve nblks against these dquots, with trans as the mediator.
@@ -845,8 +849,8 @@ xfs_trans_reserve_quota_nblks(
845 error = xfs_trans_reserve_quota_bydquots(tp, mp, 849 error = xfs_trans_reserve_quota_bydquots(tp, mp,
846 ip->i_udquot, ip->i_gdquot, 850 ip->i_udquot, ip->i_gdquot,
847 nblks, ninos, 851 nblks, ninos,
848 type); 852 flags);
849 return (error); 853 return error;
850} 854}
851 855
852/* 856/*
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index d384e489705f..26939d364bc4 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -4719,18 +4719,17 @@ xfs_bmapi(
4719 /* 4719 /*
4720 * Make a transaction-less quota reservation for 4720 * Make a transaction-less quota reservation for
4721 * delayed allocation blocks. This number gets 4721 * delayed allocation blocks. This number gets
4722 * adjusted later. 4722 * adjusted later. We return if we haven't
4723 * We return EDQUOT if we haven't allocated 4723 * allocated blocks already inside this loop.
4724 * blks already inside this loop;
4725 */ 4724 */
4726 if (XFS_TRANS_RESERVE_QUOTA_NBLKS( 4725 if ((error = XFS_TRANS_RESERVE_QUOTA_NBLKS(
4727 mp, NULL, ip, (long)alen, 0, 4726 mp, NULL, ip, (long)alen, 0,
4728 rt ? XFS_QMOPT_RES_RTBLKS : 4727 rt ? XFS_QMOPT_RES_RTBLKS :
4729 XFS_QMOPT_RES_REGBLKS)) { 4728 XFS_QMOPT_RES_REGBLKS))) {
4730 if (n == 0) { 4729 if (n == 0) {
4731 *nmap = 0; 4730 *nmap = 0;
4732 ASSERT(cur == NULL); 4731 ASSERT(cur == NULL);
4733 return XFS_ERROR(EDQUOT); 4732 return error;
4734 } 4733 }
4735 break; 4734 break;
4736 } 4735 }
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index f83399c89ce3..8e0d73d9ccc4 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -353,10 +353,11 @@ xfs_check_nostate_extents(
353 xfs_extnum_t num); 353 xfs_extnum_t num);
354 354
355/* 355/*
356 * Call xfs_bmap_do_search_extents() to search for the extent 356 * Search the extent records for the entry containing block bno.
357 * record containing block bno. If in multi-level in-core extent 357 * If bno lies in a hole, point to the next entry. If bno lies
358 * allocation mode, find and extract the target extent buffer, 358 * past eof, *eofp will be set, and *prevp will contain the last
359 * otherwise just use the direct extent list. 359 * entry (null if none). Else, *lastxp will be set to the index
360 * of the found entry; *gotp will contain the entry.
360 */ 361 */
361xfs_bmbt_rec_t * 362xfs_bmbt_rec_t *
362xfs_bmap_search_multi_extents(struct xfs_ifork *, xfs_fileoff_t, int *, 363xfs_bmap_search_multi_extents(struct xfs_ifork *, xfs_fileoff_t, int *,
diff --git a/fs/xfs/xfs_clnt.h b/fs/xfs/xfs_clnt.h
index 022fff62085b..5b7eb81453be 100644
--- a/fs/xfs/xfs_clnt.h
+++ b/fs/xfs/xfs_clnt.h
@@ -68,6 +68,7 @@ struct xfs_mount_args {
68 * enforcement */ 68 * enforcement */
69#define XFSMNT_PQUOTAENF 0x00000040 /* IRIX project quota limit 69#define XFSMNT_PQUOTAENF 0x00000040 /* IRIX project quota limit
70 * enforcement */ 70 * enforcement */
71#define XFSMNT_QUIET 0x00000080 /* don't report mount errors */
71#define XFSMNT_NOALIGN 0x00000200 /* don't allocate at 72#define XFSMNT_NOALIGN 0x00000200 /* don't allocate at
72 * stripe boundaries*/ 73 * stripe boundaries*/
73#define XFSMNT_RETERR 0x00000400 /* return error to user */ 74#define XFSMNT_RETERR 0x00000400 /* return error to user */
diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h
index 26b8e709a569..bc43163456ef 100644
--- a/fs/xfs/xfs_error.h
+++ b/fs/xfs/xfs_error.h
@@ -186,4 +186,7 @@ extern void xfs_fs_cmn_err(int level, struct xfs_mount *mp, char *fmt, ...);
186#define xfs_fs_repair_cmn_err(level, mp, fmt, args...) \ 186#define xfs_fs_repair_cmn_err(level, mp, fmt, args...) \
187 xfs_fs_cmn_err(level, mp, fmt " Unmount and run xfs_repair.", ## args) 187 xfs_fs_cmn_err(level, mp, fmt " Unmount and run xfs_repair.", ## args)
188 188
189#define xfs_fs_mount_cmn_err(f, fmt, args...) \
190 ((f & XFS_MFSI_QUIET)? cmn_err(CE_WARN, "XFS: " fmt, ## args) : (void)0)
191
189#endif /* __XFS_ERROR_H__ */ 192#endif /* __XFS_ERROR_H__ */
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 72e7e78bfff8..049fabb7f7e0 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -213,7 +213,8 @@ xfs_mount_free(
213STATIC int 213STATIC int
214xfs_mount_validate_sb( 214xfs_mount_validate_sb(
215 xfs_mount_t *mp, 215 xfs_mount_t *mp,
216 xfs_sb_t *sbp) 216 xfs_sb_t *sbp,
217 int flags)
217{ 218{
218 /* 219 /*
219 * If the log device and data device have the 220 * If the log device and data device have the
@@ -223,33 +224,29 @@ xfs_mount_validate_sb(
223 * a volume filesystem in a non-volume manner. 224 * a volume filesystem in a non-volume manner.
224 */ 225 */
225 if (sbp->sb_magicnum != XFS_SB_MAGIC) { 226 if (sbp->sb_magicnum != XFS_SB_MAGIC) {
226 cmn_err(CE_WARN, "XFS: bad magic number"); 227 xfs_fs_mount_cmn_err(flags, "bad magic number");
227 return XFS_ERROR(EWRONGFS); 228 return XFS_ERROR(EWRONGFS);
228 } 229 }
229 230
230 if (!XFS_SB_GOOD_VERSION(sbp)) { 231 if (!XFS_SB_GOOD_VERSION(sbp)) {
231 cmn_err(CE_WARN, "XFS: bad version"); 232 xfs_fs_mount_cmn_err(flags, "bad version");
232 return XFS_ERROR(EWRONGFS); 233 return XFS_ERROR(EWRONGFS);
233 } 234 }
234 235
235 if (unlikely( 236 if (unlikely(
236 sbp->sb_logstart == 0 && mp->m_logdev_targp == mp->m_ddev_targp)) { 237 sbp->sb_logstart == 0 && mp->m_logdev_targp == mp->m_ddev_targp)) {
237 cmn_err(CE_WARN, 238 xfs_fs_mount_cmn_err(flags,
238 "XFS: filesystem is marked as having an external log; " 239 "filesystem is marked as having an external log; "
239 "specify logdev on the\nmount command line."); 240 "specify logdev on the\nmount command line.");
240 XFS_CORRUPTION_ERROR("xfs_mount_validate_sb(1)", 241 return XFS_ERROR(EINVAL);
241 XFS_ERRLEVEL_HIGH, mp, sbp);
242 return XFS_ERROR(EFSCORRUPTED);
243 } 242 }
244 243
245 if (unlikely( 244 if (unlikely(
246 sbp->sb_logstart != 0 && mp->m_logdev_targp != mp->m_ddev_targp)) { 245 sbp->sb_logstart != 0 && mp->m_logdev_targp != mp->m_ddev_targp)) {
247 cmn_err(CE_WARN, 246 xfs_fs_mount_cmn_err(flags,
248 "XFS: filesystem is marked as having an internal log; " 247 "filesystem is marked as having an internal log; "
249 "don't specify logdev on\nthe mount command line."); 248 "do not specify logdev on\nthe mount command line.");
250 XFS_CORRUPTION_ERROR("xfs_mount_validate_sb(2)", 249 return XFS_ERROR(EINVAL);
251 XFS_ERRLEVEL_HIGH, mp, sbp);
252 return XFS_ERROR(EFSCORRUPTED);
253 } 250 }
254 251
255 /* 252 /*
@@ -274,9 +271,7 @@ xfs_mount_validate_sb(
274 (sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE) || 271 (sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE) ||
275 (sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE) || 272 (sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE) ||
276 (sbp->sb_imax_pct > 100 || sbp->sb_imax_pct < 1))) { 273 (sbp->sb_imax_pct > 100 || sbp->sb_imax_pct < 1))) {
277 cmn_err(CE_WARN, "XFS: SB sanity check 1 failed"); 274 xfs_fs_mount_cmn_err(flags, "SB sanity check 1 failed");
278 XFS_CORRUPTION_ERROR("xfs_mount_validate_sb(3)",
279 XFS_ERRLEVEL_LOW, mp, sbp);
280 return XFS_ERROR(EFSCORRUPTED); 275 return XFS_ERROR(EFSCORRUPTED);
281 } 276 }
282 277
@@ -289,9 +284,7 @@ xfs_mount_validate_sb(
289 (xfs_drfsbno_t)sbp->sb_agcount * sbp->sb_agblocks || 284 (xfs_drfsbno_t)sbp->sb_agcount * sbp->sb_agblocks ||
290 sbp->sb_dblocks < (xfs_drfsbno_t)(sbp->sb_agcount - 1) * 285 sbp->sb_dblocks < (xfs_drfsbno_t)(sbp->sb_agcount - 1) *
291 sbp->sb_agblocks + XFS_MIN_AG_BLOCKS)) { 286 sbp->sb_agblocks + XFS_MIN_AG_BLOCKS)) {
292 cmn_err(CE_WARN, "XFS: SB sanity check 2 failed"); 287 xfs_fs_mount_cmn_err(flags, "SB sanity check 2 failed");
293 XFS_ERROR_REPORT("xfs_mount_validate_sb(4)",
294 XFS_ERRLEVEL_LOW, mp);
295 return XFS_ERROR(EFSCORRUPTED); 288 return XFS_ERROR(EFSCORRUPTED);
296 } 289 }
297 290
@@ -307,15 +300,13 @@ xfs_mount_validate_sb(
307 (sbp->sb_dblocks << (sbp->sb_blocklog - BBSHIFT)) > UINT_MAX || 300 (sbp->sb_dblocks << (sbp->sb_blocklog - BBSHIFT)) > UINT_MAX ||
308 (sbp->sb_rblocks << (sbp->sb_blocklog - BBSHIFT)) > UINT_MAX)) { 301 (sbp->sb_rblocks << (sbp->sb_blocklog - BBSHIFT)) > UINT_MAX)) {
309#endif 302#endif
310 cmn_err(CE_WARN, 303 xfs_fs_mount_cmn_err(flags,
311 "XFS: File system is too large to be mounted on this system."); 304 "file system too large to be mounted on this system.");
312 return XFS_ERROR(E2BIG); 305 return XFS_ERROR(E2BIG);
313 } 306 }
314 307
315 if (unlikely(sbp->sb_inprogress)) { 308 if (unlikely(sbp->sb_inprogress)) {
316 cmn_err(CE_WARN, "XFS: file system busy"); 309 xfs_fs_mount_cmn_err(flags, "file system busy");
317 XFS_ERROR_REPORT("xfs_mount_validate_sb(5)",
318 XFS_ERRLEVEL_LOW, mp);
319 return XFS_ERROR(EFSCORRUPTED); 310 return XFS_ERROR(EFSCORRUPTED);
320 } 311 }
321 312
@@ -323,8 +314,8 @@ xfs_mount_validate_sb(
323 * Version 1 directory format has never worked on Linux. 314 * Version 1 directory format has never worked on Linux.
324 */ 315 */
325 if (unlikely(!XFS_SB_VERSION_HASDIRV2(sbp))) { 316 if (unlikely(!XFS_SB_VERSION_HASDIRV2(sbp))) {
326 cmn_err(CE_WARN, 317 xfs_fs_mount_cmn_err(flags,
327 "XFS: Attempted to mount file system using version 1 directory format"); 318 "file system using version 1 directory format");
328 return XFS_ERROR(ENOSYS); 319 return XFS_ERROR(ENOSYS);
329 } 320 }
330 321
@@ -332,11 +323,11 @@ xfs_mount_validate_sb(
332 * Until this is fixed only page-sized or smaller data blocks work. 323 * Until this is fixed only page-sized or smaller data blocks work.
333 */ 324 */
334 if (unlikely(sbp->sb_blocksize > PAGE_SIZE)) { 325 if (unlikely(sbp->sb_blocksize > PAGE_SIZE)) {
335 cmn_err(CE_WARN, 326 xfs_fs_mount_cmn_err(flags,
336 "XFS: Attempted to mount file system with blocksize %d bytes", 327 "file system with blocksize %d bytes",
337 sbp->sb_blocksize); 328 sbp->sb_blocksize);
338 cmn_err(CE_WARN, 329 xfs_fs_mount_cmn_err(flags,
339 "XFS: Only page-sized (%ld) or less blocksizes currently work.", 330 "only pagesize (%ld) or less will currently work.",
340 PAGE_SIZE); 331 PAGE_SIZE);
341 return XFS_ERROR(ENOSYS); 332 return XFS_ERROR(ENOSYS);
342 } 333 }
@@ -484,7 +475,7 @@ xfs_xlatesb(
484 * Does the initial read of the superblock. 475 * Does the initial read of the superblock.
485 */ 476 */
486int 477int
487xfs_readsb(xfs_mount_t *mp) 478xfs_readsb(xfs_mount_t *mp, int flags)
488{ 479{
489 unsigned int sector_size; 480 unsigned int sector_size;
490 unsigned int extra_flags; 481 unsigned int extra_flags;
@@ -506,7 +497,7 @@ xfs_readsb(xfs_mount_t *mp)
506 bp = xfs_buf_read_flags(mp->m_ddev_targp, XFS_SB_DADDR, 497 bp = xfs_buf_read_flags(mp->m_ddev_targp, XFS_SB_DADDR,
507 BTOBB(sector_size), extra_flags); 498 BTOBB(sector_size), extra_flags);
508 if (!bp || XFS_BUF_ISERROR(bp)) { 499 if (!bp || XFS_BUF_ISERROR(bp)) {
509 cmn_err(CE_WARN, "XFS: SB read failed"); 500 xfs_fs_mount_cmn_err(flags, "SB read failed");
510 error = bp ? XFS_BUF_GETERROR(bp) : ENOMEM; 501 error = bp ? XFS_BUF_GETERROR(bp) : ENOMEM;
511 goto fail; 502 goto fail;
512 } 503 }
@@ -520,9 +511,9 @@ xfs_readsb(xfs_mount_t *mp)
520 sbp = XFS_BUF_TO_SBP(bp); 511 sbp = XFS_BUF_TO_SBP(bp);
521 xfs_xlatesb(XFS_BUF_PTR(bp), &(mp->m_sb), 1, XFS_SB_ALL_BITS); 512 xfs_xlatesb(XFS_BUF_PTR(bp), &(mp->m_sb), 1, XFS_SB_ALL_BITS);
522 513
523 error = xfs_mount_validate_sb(mp, &(mp->m_sb)); 514 error = xfs_mount_validate_sb(mp, &(mp->m_sb), flags);
524 if (error) { 515 if (error) {
525 cmn_err(CE_WARN, "XFS: SB validate failed"); 516 xfs_fs_mount_cmn_err(flags, "SB validate failed");
526 goto fail; 517 goto fail;
527 } 518 }
528 519
@@ -530,8 +521,8 @@ xfs_readsb(xfs_mount_t *mp)
530 * We must be able to do sector-sized and sector-aligned IO. 521 * We must be able to do sector-sized and sector-aligned IO.
531 */ 522 */
532 if (sector_size > mp->m_sb.sb_sectsize) { 523 if (sector_size > mp->m_sb.sb_sectsize) {
533 cmn_err(CE_WARN, 524 xfs_fs_mount_cmn_err(flags,
534 "XFS: device supports only %u byte sectors (not %u)", 525 "device supports only %u byte sectors (not %u)",
535 sector_size, mp->m_sb.sb_sectsize); 526 sector_size, mp->m_sb.sb_sectsize);
536 error = ENOSYS; 527 error = ENOSYS;
537 goto fail; 528 goto fail;
@@ -548,7 +539,7 @@ xfs_readsb(xfs_mount_t *mp)
548 bp = xfs_buf_read_flags(mp->m_ddev_targp, XFS_SB_DADDR, 539 bp = xfs_buf_read_flags(mp->m_ddev_targp, XFS_SB_DADDR,
549 BTOBB(sector_size), extra_flags); 540 BTOBB(sector_size), extra_flags);
550 if (!bp || XFS_BUF_ISERROR(bp)) { 541 if (!bp || XFS_BUF_ISERROR(bp)) {
551 cmn_err(CE_WARN, "XFS: SB re-read failed"); 542 xfs_fs_mount_cmn_err(flags, "SB re-read failed");
552 error = bp ? XFS_BUF_GETERROR(bp) : ENOMEM; 543 error = bp ? XFS_BUF_GETERROR(bp) : ENOMEM;
553 goto fail; 544 goto fail;
554 } 545 }
@@ -678,7 +669,7 @@ xfs_mountfs(
678 int error = 0; 669 int error = 0;
679 670
680 if (mp->m_sb_bp == NULL) { 671 if (mp->m_sb_bp == NULL) {
681 if ((error = xfs_readsb(mp))) { 672 if ((error = xfs_readsb(mp, mfsi_flags))) {
682 return error; 673 return error;
683 } 674 }
684 } 675 }
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 66cbee79864e..668ad23fd37c 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -510,9 +510,12 @@ xfs_preferred_iosize(xfs_mount_t *mp)
510 */ 510 */
511#define XFS_MFSI_SECOND 0x01 /* Secondary mount -- skip stuff */ 511#define XFS_MFSI_SECOND 0x01 /* Secondary mount -- skip stuff */
512#define XFS_MFSI_CLIENT 0x02 /* Is a client -- skip lots of stuff */ 512#define XFS_MFSI_CLIENT 0x02 /* Is a client -- skip lots of stuff */
513/* XFS_MFSI_RRINODES */
513#define XFS_MFSI_NOUNLINK 0x08 /* Skip unlinked inode processing in */ 514#define XFS_MFSI_NOUNLINK 0x08 /* Skip unlinked inode processing in */
514 /* log recovery */ 515 /* log recovery */
515#define XFS_MFSI_NO_QUOTACHECK 0x10 /* Skip quotacheck processing */ 516#define XFS_MFSI_NO_QUOTACHECK 0x10 /* Skip quotacheck processing */
517/* XFS_MFSI_CONVERT_SUNIT */
518#define XFS_MFSI_QUIET 0x40 /* Be silent if mount errors found */
516 519
517/* 520/*
518 * Macros for getting from mount to vfs and back. 521 * Macros for getting from mount to vfs and back.
@@ -581,7 +584,7 @@ extern int xfs_mod_incore_sb_unlocked(xfs_mount_t *, xfs_sb_field_t,
581extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *, 584extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *,
582 uint, int); 585 uint, int);
583extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); 586extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int);
584extern int xfs_readsb(xfs_mount_t *mp); 587extern int xfs_readsb(xfs_mount_t *, int);
585extern void xfs_freesb(xfs_mount_t *); 588extern void xfs_freesb(xfs_mount_t *);
586extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int); 589extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int);
587extern int xfs_syncsub(xfs_mount_t *, int, int, int *); 590extern int xfs_syncsub(xfs_mount_t *, int, int, int *);
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index 4f6a034de7f7..7fbef974bce6 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -196,10 +196,11 @@ typedef struct xfs_qoff_logformat {
196#define XFS_QMOPT_QUOTAOFF 0x0000080 /* quotas are being turned off */ 196#define XFS_QMOPT_QUOTAOFF 0x0000080 /* quotas are being turned off */
197#define XFS_QMOPT_UMOUNTING 0x0000100 /* filesys is being unmounted */ 197#define XFS_QMOPT_UMOUNTING 0x0000100 /* filesys is being unmounted */
198#define XFS_QMOPT_DOLOG 0x0000200 /* log buf changes (in quotacheck) */ 198#define XFS_QMOPT_DOLOG 0x0000200 /* log buf changes (in quotacheck) */
199#define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if necessary */ 199#define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if needed */
200#define XFS_QMOPT_ILOCKED 0x0000800 /* inode is already locked (excl) */ 200#define XFS_QMOPT_ILOCKED 0x0000800 /* inode is already locked (excl) */
201#define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot, if damaged. */ 201#define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot if damaged */
202#define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */ 202#define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */
203#define XFS_QMOPT_ENOSPC 0x0004000 /* enospc instead of edquot (prj) */
203 204
204/* 205/*
205 * flags to xfs_trans_mod_dquot to indicate which field needs to be 206 * flags to xfs_trans_mod_dquot to indicate which field needs to be
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index 504d2a80747a..f0e09ca14139 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -442,6 +442,9 @@ xfs_mount(
442 p = vfs_bhv_lookup(vfsp, VFS_POSITION_IO); 442 p = vfs_bhv_lookup(vfsp, VFS_POSITION_IO);
443 mp->m_io_ops = p ? *(xfs_ioops_t *) vfs_bhv_custom(p) : xfs_iocore_xfs; 443 mp->m_io_ops = p ? *(xfs_ioops_t *) vfs_bhv_custom(p) : xfs_iocore_xfs;
444 444
445 if (args->flags & XFSMNT_QUIET)
446 flags |= XFS_MFSI_QUIET;
447
445 /* 448 /*
446 * Open real time and log devices - order is important. 449 * Open real time and log devices - order is important.
447 */ 450 */
@@ -492,7 +495,7 @@ xfs_mount(
492 error = xfs_start_flags(vfsp, args, mp); 495 error = xfs_start_flags(vfsp, args, mp);
493 if (error) 496 if (error)
494 goto error1; 497 goto error1;
495 error = xfs_readsb(mp); 498 error = xfs_readsb(mp, flags);
496 if (error) 499 if (error)
497 goto error1; 500 goto error1;
498 error = xfs_finish_flags(vfsp, args, mp); 501 error = xfs_finish_flags(vfsp, args, mp);
@@ -1697,8 +1700,9 @@ xfs_parseargs(
1697 int dsunit, dswidth, vol_dsunit, vol_dswidth; 1700 int dsunit, dswidth, vol_dsunit, vol_dswidth;
1698 int iosize; 1701 int iosize;
1699 1702
1700 args->flags2 |= XFSMNT2_COMPAT_IOSIZE;
1701 args->flags |= XFSMNT_IDELETE; 1703 args->flags |= XFSMNT_IDELETE;
1704 args->flags |= XFSMNT_BARRIER;
1705 args->flags2 |= XFSMNT2_COMPAT_IOSIZE;
1702 1706
1703 if (!options) 1707 if (!options)
1704 goto done; 1708 goto done;
@@ -1947,8 +1951,6 @@ xfs_showargs(
1947 seq_printf(m, "," MNTOPT_IKEEP); 1951 seq_printf(m, "," MNTOPT_IKEEP);
1948 if (!(mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE)) 1952 if (!(mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE))
1949 seq_printf(m, "," MNTOPT_LARGEIO); 1953 seq_printf(m, "," MNTOPT_LARGEIO);
1950 if (mp->m_flags & XFS_MOUNT_BARRIER)
1951 seq_printf(m, "," MNTOPT_BARRIER);
1952 1954
1953 if (!(vfsp->vfs_flag & VFS_32BITINODES)) 1955 if (!(vfsp->vfs_flag & VFS_32BITINODES))
1954 seq_printf(m, "," MNTOPT_64BITINODE); 1956 seq_printf(m, "," MNTOPT_64BITINODE);
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index de49601919c1..fa71b305ba5c 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -4649,6 +4649,10 @@ vnodeops_t xfs_vnodeops = {
4649#ifdef HAVE_SENDFILE 4649#ifdef HAVE_SENDFILE
4650 .vop_sendfile = xfs_sendfile, 4650 .vop_sendfile = xfs_sendfile,
4651#endif 4651#endif
4652#ifdef HAVE_SPLICE
4653 .vop_splice_read = xfs_splice_read,
4654 .vop_splice_write = xfs_splice_write,
4655#endif
4652 .vop_write = xfs_write, 4656 .vop_write = xfs_write,
4653 .vop_ioctl = xfs_ioctl, 4657 .vop_ioctl = xfs_ioctl,
4654 .vop_getattr = xfs_getattr, 4658 .vop_getattr = xfs_getattr,
diff --git a/include/asm-arm/arch-at91rm9200/at91rm9200_mci.h b/include/asm-arm/arch-at91rm9200/at91rm9200_mci.h
new file mode 100644
index 000000000000..f28636d61e39
--- /dev/null
+++ b/include/asm-arm/arch-at91rm9200/at91rm9200_mci.h
@@ -0,0 +1,104 @@
1/*
2 * include/asm-arm/arch-at91rm9200/at91rm9200_mci.h
3 *
4 * Copyright (C) 2005 Ivan Kokshaysky
5 * Copyright (C) SAN People
6 *
7 * MultiMedia Card Interface (MCI) registers.
8 * Based on AT91RM9200 datasheet revision E.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 */
15
16#ifndef AT91RM9200_MCI_H
17#define AT91RM9200_MCI_H
18
19#define AT91_MCI_CR 0x00 /* Control Register */
20#define AT91_MCI_MCIEN (1 << 0) /* Multi-Media Interface Enable */
21#define AT91_MCI_MCIDIS (1 << 1) /* Multi-Media Interface Disable */
22#define AT91_MCI_PWSEN (1 << 2) /* Power Save Mode Enable */
23#define AT91_MCI_PWSDIS (1 << 3) /* Power Save Mode Disable */
24#define AT91_MCI_SWRST (1 << 7) /* Software Reset */
25
26#define AT91_MCI_MR 0x04 /* Mode Register */
27#define AT91_MCI_CLKDIV (0xff << 0) /* Clock Divider */
28#define AT91_MCI_PWSDIV (3 << 8) /* Power Saving Divider */
29#define AT91_MCI_PDCPADV (1 << 14) /* PDC Padding Value */
30#define AT91_MCI_PDCMODE (1 << 15) /* PDC-orientated Mode */
31#define AT91_MCI_BLKLEN (0xfff << 18) /* Data Block Length */
32
33#define AT91_MCI_DTOR 0x08 /* Data Timeout Register */
34#define AT91_MCI_DTOCYC (0xf << 0) /* Data Timeout Cycle Number */
35#define AT91_MCI_DTOMUL (7 << 4) /* Data Timeout Multiplier */
36#define AT91_MCI_DTOMUL_1 (0 << 4)
37#define AT91_MCI_DTOMUL_16 (1 << 4)
38#define AT91_MCI_DTOMUL_128 (2 << 4)
39#define AT91_MCI_DTOMUL_256 (3 << 4)
40#define AT91_MCI_DTOMUL_1K (4 << 4)
41#define AT91_MCI_DTOMUL_4K (5 << 4)
42#define AT91_MCI_DTOMUL_64K (6 << 4)
43#define AT91_MCI_DTOMUL_1M (7 << 4)
44
45#define AT91_MCI_SDCR 0x0c /* SD Card Register */
46#define AT91_MCI_SDCSEL (0xf << 0) /* SD Card Selector */
47#define AT91_MCI_SDCBUS (1 << 7) /* 1-bit or 4-bit bus */
48
49#define AT91_MCI_ARGR 0x10 /* Argument Register */
50
51#define AT91_MCI_CMDR 0x14 /* Command Register */
52#define AT91_MCI_CMDNB (0x3f << 0) /* Command Number */
53#define AT91_MCI_RSPTYP (3 << 6) /* Response Type */
54#define AT91_MCI_RSPTYP_NONE (0 << 6)
55#define AT91_MCI_RSPTYP_48 (1 << 6)
56#define AT91_MCI_RSPTYP_136 (2 << 6)
57#define AT91_MCI_SPCMD (7 << 8) /* Special Command */
58#define AT91_MCI_SPCMD_NONE (0 << 8)
59#define AT91_MCI_SPCMD_INIT (1 << 8)
60#define AT91_MCI_SPCMD_SYNC (2 << 8)
61#define AT91_MCI_SPCMD_ICMD (4 << 8)
62#define AT91_MCI_SPCMD_IRESP (5 << 8)
63#define AT91_MCI_OPDCMD (1 << 11) /* Open Drain Command */
64#define AT91_MCI_MAXLAT (1 << 12) /* Max Latency for Command to Response */
65#define AT91_MCI_TRCMD (3 << 16) /* Transfer Command */
66#define AT91_MCI_TRCMD_NONE (0 << 16)
67#define AT91_MCI_TRCMD_START (1 << 16)
68#define AT91_MCI_TRCMD_STOP (2 << 16)
69#define AT91_MCI_TRDIR (1 << 18) /* Transfer Direction */
70#define AT91_MCI_TRTYP (3 << 19) /* Transfer Type */
71#define AT91_MCI_TRTYP_BLOCK (0 << 19)
72#define AT91_MCI_TRTYP_MULTIPLE (1 << 19)
73#define AT91_MCI_TRTYP_STREAM (2 << 19)
74
75#define AT91_MCI_RSPR(n) (0x20 + ((n) * 4)) /* Response Registers 0-3 */
76#define AT91_MCR_RDR 0x30 /* Receive Data Register */
77#define AT91_MCR_TDR 0x34 /* Transmit Data Register */
78
79#define AT91_MCI_SR 0x40 /* Status Register */
80#define AT91_MCI_CMDRDY (1 << 0) /* Command Ready */
81#define AT91_MCI_RXRDY (1 << 1) /* Receiver Ready */
82#define AT91_MCI_TXRDY (1 << 2) /* Transmit Ready */
83#define AT91_MCI_BLKE (1 << 3) /* Data Block Ended */
84#define AT91_MCI_DTIP (1 << 4) /* Data Transfer in Progress */
85#define AT91_MCI_NOTBUSY (1 << 5) /* Data Not Busy */
86#define AT91_MCI_ENDRX (1 << 6) /* End of RX Buffer */
87#define AT91_MCI_ENDTX (1 << 7) /* End fo TX Buffer */
88#define AT91_MCI_RXBUFF (1 << 14) /* RX Buffer Full */
89#define AT91_MCI_TXBUFE (1 << 15) /* TX Buffer Empty */
90#define AT91_MCI_RINDE (1 << 16) /* Response Index Error */
91#define AT91_MCI_RDIRE (1 << 17) /* Response Direction Error */
92#define AT91_MCI_RCRCE (1 << 18) /* Response CRC Error */
93#define AT91_MCI_RENDE (1 << 19) /* Response End Bit Error */
94#define AT91_MCI_RTOE (1 << 20) /* Reponse Time-out Error */
95#define AT91_MCI_DCRCE (1 << 21) /* Data CRC Error */
96#define AT91_MCI_DTOE (1 << 22) /* Data Time-out Error */
97#define AT91_MCI_OVRE (1 << 30) /* Overrun */
98#define AT91_MCI_UNRE (1 << 31) /* Underrun */
99
100#define AT91_MCI_IER 0x44 /* Interrupt Enable Register */
101#define AT91_MCI_IDR 0x48 /* Interrupt Disable Register */
102#define AT91_MCI_IMR 0x4c /* Interrupt Mask Register */
103
104#endif
diff --git a/include/asm-arm/arch-at91rm9200/board.h b/include/asm-arm/arch-at91rm9200/board.h
index 2e7d1139a799..4fdef13d01d4 100644
--- a/include/asm-arm/arch-at91rm9200/board.h
+++ b/include/asm-arm/arch-at91rm9200/board.h
@@ -38,6 +38,8 @@ extern unsigned long at91_master_clock;
38extern int at91_serial_map[AT91_NR_UART]; 38extern int at91_serial_map[AT91_NR_UART];
39extern int at91_console_port; 39extern int at91_console_port;
40 40
41#include <linux/mtd/partitions.h>
42
41 /* USB Device */ 43 /* USB Device */
42struct at91_udc_data { 44struct at91_udc_data {
43 u8 vbus_pin; /* high == host powering us */ 45 u8 vbus_pin; /* high == host powering us */
@@ -77,4 +79,26 @@ struct at91_usbh_data {
77}; 79};
78extern void __init at91_add_device_usbh(struct at91_usbh_data *data); 80extern void __init at91_add_device_usbh(struct at91_usbh_data *data);
79 81
82 /* NAND / SmartMedia */
83struct at91_nand_data {
84 u8 enable_pin; /* chip enable */
85 u8 det_pin; /* card detect */
86 u8 rdy_pin; /* ready/busy */
87 u8 ale; /* address line number connected to ALE */
88 u8 cle; /* address line number connected to CLE */
89 struct mtd_partition* (*partition_info)(int, int*);
90};
91extern void __init at91_add_device_nand(struct at91_nand_data *data);
92
93 /* I2C*/
94void __init at91_add_device_i2c(void);
95
96 /* RTC */
97void __init at91_add_device_rtc(void);
98
99 /* LEDs */
100extern u8 at91_leds_cpu;
101extern u8 at91_leds_timer;
102extern void __init at91_init_leds(u8 cpu_led, u8 timer_led);
103
80#endif 104#endif
diff --git a/include/asm-arm/arch-ep93xx/ts72xx.h b/include/asm-arm/arch-ep93xx/ts72xx.h
index 412215e77f44..a94f63ff0535 100644
--- a/include/asm-arm/arch-ep93xx/ts72xx.h
+++ b/include/asm-arm/arch-ep93xx/ts72xx.h
@@ -12,6 +12,8 @@
12 * febfc000 [67]0000000 4K NAND data register 12 * febfc000 [67]0000000 4K NAND data register
13 * febfb000 [67]0400000 4K NAND control register 13 * febfb000 [67]0400000 4K NAND control register
14 * febfa000 [67]0800000 4K NAND busy register 14 * febfa000 [67]0800000 4K NAND busy register
15 * febf9000 10800000 4K TS-5620 RTC index register
16 * febf8000 11700000 4K TS-5620 RTC data register
15 */ 17 */
16 18
17#define TS72XX_MODEL_PHYS_BASE 0x22000000 19#define TS72XX_MODEL_PHYS_BASE 0x22000000
@@ -58,6 +60,15 @@
58#define TS72XX_NAND_BUSY_SIZE 0x00001000 60#define TS72XX_NAND_BUSY_SIZE 0x00001000
59 61
60 62
63#define TS72XX_RTC_INDEX_VIRT_BASE 0xfebf9000
64#define TS72XX_RTC_INDEX_PHYS_BASE 0x10800000
65#define TS72XX_RTC_INDEX_SIZE 0x00001000
66
67#define TS72XX_RTC_DATA_VIRT_BASE 0xfebf8000
68#define TS72XX_RTC_DATA_PHYS_BASE 0x11700000
69#define TS72XX_RTC_DATA_SIZE 0x00001000
70
71
61#ifndef __ASSEMBLY__ 72#ifndef __ASSEMBLY__
62#include <asm/io.h> 73#include <asm/io.h>
63 74
diff --git a/include/asm-arm/arch-imx/dma.h b/include/asm-arm/arch-imx/dma.h
index b45fa367d71e..621ff2c730f2 100644
--- a/include/asm-arm/arch-imx/dma.h
+++ b/include/asm-arm/arch-imx/dma.h
@@ -17,27 +17,16 @@
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20
20#ifndef __ASM_ARCH_DMA_H 21#ifndef __ASM_ARCH_DMA_H
21#define __ASM_ARCH_DMA_H 22#define __ASM_ARCH_DMA_H
22 23
23/*
24 * DMA registration
25 */
26
27typedef enum { 24typedef enum {
28 DMA_PRIO_HIGH = 0, 25 DMA_PRIO_HIGH = 0,
29 DMA_PRIO_MEDIUM = 3, 26 DMA_PRIO_MEDIUM = 1,
30 DMA_PRIO_LOW = 6 27 DMA_PRIO_LOW = 2
31} imx_dma_prio; 28} imx_dma_prio;
32 29
33int imx_request_dma(char *name, imx_dma_prio prio,
34 void (*irq_handler) (int, void *, struct pt_regs *),
35 void (*err_handler) (int, void *, struct pt_regs *),
36 void *data);
37
38void imx_free_dma(int dma_ch);
39
40
41#define DMA_REQ_UART3_T 2 30#define DMA_REQ_UART3_T 2
42#define DMA_REQ_UART3_R 3 31#define DMA_REQ_UART3_R 3
43#define DMA_REQ_SSI2_T 4 32#define DMA_REQ_SSI2_T 4
diff --git a/include/asm-arm/arch-imx/imx-dma.h b/include/asm-arm/arch-imx/imx-dma.h
new file mode 100644
index 000000000000..f2063c1d610d
--- /dev/null
+++ b/include/asm-arm/arch-imx/imx-dma.h
@@ -0,0 +1,90 @@
1/*
2 * linux/include/asm-arm/imxads/dma.h
3 *
4 * Copyright (C) 1997,1998 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <asm/dma.h>
22
23#ifndef __ASM_ARCH_IMX_DMA_H
24#define __ASM_ARCH_IMX_DMA_H
25
26#define IMX_DMA_CHANNELS 11
27
28/*
29 * struct imx_dma_channel - i.MX specific DMA extension
30 * @name: name specified by DMA client
31 * @irq_handler: client callback for end of transfer
32 * @err_handler: client callback for error condition
33 * @data: clients context data for callbacks
34 * @dma_mode: direction of the transfer %DMA_MODE_READ or %DMA_MODE_WRITE
35 * @sg: pointer to the actual read/written chunk for scatter-gather emulation
36 * @sgbc: counter of processed bytes in the actual read/written chunk
37 * @resbytes: total residual number of bytes to transfer
38 * (it can be lower or same as sum of SG mapped chunk sizes)
39 * @sgcount: number of chunks to be read/written
40 *
41 * Structure is used for IMX DMA processing. It would be probably good
42 * @struct dma_struct in the future for external interfacing and use
43 * @struct imx_dma_channel only as extension to it.
44 */
45
46struct imx_dma_channel {
47 const char *name;
48 void (*irq_handler) (int, void *, struct pt_regs *);
49 void (*err_handler) (int, void *, struct pt_regs *);
50 void *data;
51 dmamode_t dma_mode;
52 struct scatterlist *sg;
53 unsigned int sgbc;
54 unsigned int sgcount;
55 unsigned int resbytes;
56 int dma_num;
57};
58
59extern struct imx_dma_channel imx_dma_channels[IMX_DMA_CHANNELS];
60
61
62/* The type to distinguish channel numbers parameter from ordinal int type */
63typedef int imx_dmach_t;
64
65int
66imx_dma_setup_single(imx_dmach_t dma_ch, dma_addr_t dma_address,
67 unsigned int dma_length, unsigned int dev_addr, dmamode_t dmamode);
68
69int
70imx_dma_setup_sg(imx_dmach_t dma_ch,
71 struct scatterlist *sg, unsigned int sgcount, unsigned int dma_length,
72 unsigned int dev_addr, dmamode_t dmamode);
73
74int
75imx_dma_setup_handlers(imx_dmach_t dma_ch,
76 void (*irq_handler) (int, void *, struct pt_regs *),
77 void (*err_handler) (int, void *, struct pt_regs *), void *data);
78
79void imx_dma_enable(imx_dmach_t dma_ch);
80
81void imx_dma_disable(imx_dmach_t dma_ch);
82
83int imx_dma_request(imx_dmach_t dma_ch, const char *name);
84
85void imx_dma_free(imx_dmach_t dma_ch);
86
87int imx_dma_request_by_prio(imx_dmach_t *pdma_ch, const char *name, imx_dma_prio prio);
88
89
90#endif /* _ASM_ARCH_IMX_DMA_H */
diff --git a/include/asm-arm/arch-imx/mmc.h b/include/asm-arm/arch-imx/mmc.h
new file mode 100644
index 000000000000..1937151665c7
--- /dev/null
+++ b/include/asm-arm/arch-imx/mmc.h
@@ -0,0 +1,12 @@
1#ifndef ASMARM_ARCH_MMC_H
2#define ASMARM_ARCH_MMC_H
3
4#include <linux/mmc/protocol.h>
5
6struct imxmmc_platform_data {
7 int (*card_present)(void);
8};
9
10extern void imx_set_mmc_info(struct imxmmc_platform_data *info);
11
12#endif
diff --git a/include/asm-arm/arch-ixp23xx/memory.h b/include/asm-arm/arch-ixp23xx/memory.h
index bebcf0aa0d72..6e19f46d54d1 100644
--- a/include/asm-arm/arch-ixp23xx/memory.h
+++ b/include/asm-arm/arch-ixp23xx/memory.h
@@ -28,6 +28,7 @@
28 * to an address that the kernel can use. 28 * to an address that the kernel can use.
29 */ 29 */
30#ifndef __ASSEMBLY__ 30#ifndef __ASSEMBLY__
31#include <asm/mach-types.h>
31 32
32#define __virt_to_bus(v) \ 33#define __virt_to_bus(v) \
33 ({ unsigned int ret; \ 34 ({ unsigned int ret; \
@@ -40,6 +41,22 @@
40 data = *((volatile int *)IXP23XX_PCI_SDRAM_BAR); \ 41 data = *((volatile int *)IXP23XX_PCI_SDRAM_BAR); \
41 __phys_to_virt((((b - (data & 0xfffffff0)) + 0x00000000))); }) 42 __phys_to_virt((((b - (data & 0xfffffff0)) + 0x00000000))); })
42 43
44/*
45 * Coherency support. Only supported on A2 CPUs or on A1
46 * systems that have the cache coherency workaround.
47 */
48static inline int __ixp23xx_arch_is_coherent(void)
49{
50 extern unsigned int processor_id;
51
52 if (((processor_id & 15) >= 2) || machine_is_roadrunner())
53 return 1;
54
55 return 0;
56}
57
58#define arch_is_coherent() __ixp23xx_arch_is_coherent()
59
43#endif 60#endif
44 61
45 62
diff --git a/include/asm-arm/arch-ixp23xx/platform.h b/include/asm-arm/arch-ixp23xx/platform.h
index f85b4685a491..e4d99060a049 100644
--- a/include/asm-arm/arch-ixp23xx/platform.h
+++ b/include/asm-arm/arch-ixp23xx/platform.h
@@ -22,6 +22,7 @@ void ixp23xx_sys_init(void);
22int ixp23xx_pci_setup(int, struct pci_sys_data *); 22int ixp23xx_pci_setup(int, struct pci_sys_data *);
23void ixp23xx_pci_preinit(void); 23void ixp23xx_pci_preinit(void);
24struct pci_bus *ixp23xx_pci_scan_bus(int, struct pci_sys_data*); 24struct pci_bus *ixp23xx_pci_scan_bus(int, struct pci_sys_data*);
25void ixp23xx_pci_slave_init(void);
25 26
26extern struct sys_timer ixp23xx_timer; 27extern struct sys_timer ixp23xx_timer;
27 28
diff --git a/include/asm-arm/arch-omap/aic23.h b/include/asm-arm/arch-omap/aic23.h
index 590bac25b7c4..6513065941d0 100644
--- a/include/asm-arm/arch-omap/aic23.h
+++ b/include/asm-arm/arch-omap/aic23.h
@@ -57,6 +57,7 @@
57#define LHV_MIN 0x0000 57#define LHV_MIN 0x0000
58 58
59// Analog audio path control register 59// Analog audio path control register
60#define STA_REG(x) ((x)<<6)
60#define STE_ENABLED 0x0020 61#define STE_ENABLED 0x0020
61#define DAC_SELECTED 0x0010 62#define DAC_SELECTED 0x0010
62#define BYPASS_ON 0x0008 63#define BYPASS_ON 0x0008
@@ -109,4 +110,7 @@
109#define TLV320AIC23ID1 (0x1a) // cs low 110#define TLV320AIC23ID1 (0x1a) // cs low
110#define TLV320AIC23ID2 (0x1b) // cs high 111#define TLV320AIC23ID2 (0x1b) // cs high
111 112
113void tlv320aic23_power_up(void);
114void tlv320aic23_power_down(void);
115
112#endif /* __ASM_ARCH_AIC23_H */ 116#endif /* __ASM_ARCH_AIC23_H */
diff --git a/include/asm-arm/arch-omap/board-ams-delta.h b/include/asm-arm/arch-omap/board-ams-delta.h
new file mode 100644
index 000000000000..0070f6d3b75c
--- /dev/null
+++ b/include/asm-arm/arch-omap/board-ams-delta.h
@@ -0,0 +1,65 @@
1/*
2 * linux/include/asm-arm/arch-omap/board-ams-delta.h
3 *
4 * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
14 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
15 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
17 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
18 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
20 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21 *
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26#ifndef __ASM_ARCH_OMAP_AMS_DELTA_H
27#define __ASM_ARCH_OMAP_AMS_DELTA_H
28
29#if defined (CONFIG_MACH_AMS_DELTA)
30
31#define AMS_DELTA_LATCH1_PHYS 0x01000000
32#define AMS_DELTA_LATCH1_VIRT 0xEA000000
33#define AMS_DELTA_MODEM_PHYS 0x04000000
34#define AMS_DELTA_MODEM_VIRT 0xEB000000
35#define AMS_DELTA_LATCH2_PHYS 0x08000000
36#define AMS_DELTA_LATCH2_VIRT 0xEC000000
37
38#define AMS_DELTA_LATCH1_LED_CAMERA 0x01
39#define AMS_DELTA_LATCH1_LED_ADVERT 0x02
40#define AMS_DELTA_LATCH1_LED_EMAIL 0x04
41#define AMS_DELTA_LATCH1_LED_HANDSFREE 0x08
42#define AMS_DELTA_LATCH1_LED_VOICEMAIL 0x10
43#define AMS_DELTA_LATCH1_LED_VOICE 0x20
44
45#define AMS_DELTA_LATCH2_LCD_VBLEN 0x0001
46#define AMS_DELTA_LATCH2_LCD_NDISP 0x0002
47#define AMS_DELTA_LATCH2_NAND_NCE 0x0004
48#define AMS_DELTA_LATCH2_NAND_NRE 0x0008
49#define AMS_DELTA_LATCH2_NAND_NWP 0x0010
50#define AMS_DELTA_LATCH2_NAND_NWE 0x0020
51#define AMS_DELTA_LATCH2_NAND_ALE 0x0040
52#define AMS_DELTA_LATCH2_NAND_CLE 0x0080
53#define AMS_DELTA_LATCH2_MODEM_NRESET 0x1000
54#define AMS_DELTA_LATCH2_MODEM_CODEC 0x2000
55
56#define AMS_DELTA_GPIO_PIN_NAND_RB 12
57
58#ifndef __ASSEMBLY__
59void ams_delta_latch1_write(u8 mask, u8 value);
60void ams_delta_latch2_write(u16 mask, u16 value);
61#endif
62
63#endif /* CONFIG_MACH_AMS_DELTA */
64
65#endif /* __ASM_ARCH_OMAP_AMS_DELTA_H */
diff --git a/include/asm-arm/arch-omap/board-apollon.h b/include/asm-arm/arch-omap/board-apollon.h
new file mode 100644
index 000000000000..de0c5b792c58
--- /dev/null
+++ b/include/asm-arm/arch-omap/board-apollon.h
@@ -0,0 +1,45 @@
1/*
2 * linux/include/asm-arm/arch-omap/board-apollon.h
3 *
4 * Hardware definitions for Samsung OMAP24XX Apollon board.
5 *
6 * Initial creation by Kyungmin Park <kyungmin.park@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
14 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
16 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
19 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29#ifndef __ASM_ARCH_OMAP_APOLLON_H
30#define __ASM_ARCH_OMAP_APOLLON_H
31
32/* Placeholder for APOLLON specific defines */
33/* GPMC CS0 */
34#define APOLLON_CS0_BASE 0x00000000
35/* GPMC CS1 */
36#define APOLLON_CS1_BASE 0x08000000
37#define APOLLON_ETHR_START (APOLLON_CS1_BASE + 0x300)
38#define APOLLON_ETHR_GPIO_IRQ 74
39/* GPMC CS2 - reserved for OneNAND */
40#define APOLLON_CS2_BASE 0x10000000
41/* GPMC CS3 - reserved for NOR or NAND */
42#define APOLLON_CS3_BASE 0x18000000
43
44#endif /* __ASM_ARCH_OMAP_APOLLON_H */
45
diff --git a/include/asm-arm/arch-omap/board-h2.h b/include/asm-arm/arch-omap/board-h2.h
index 39ca5a31aeea..b2888ef9e9b4 100644
--- a/include/asm-arm/arch-omap/board-h2.h
+++ b/include/asm-arm/arch-omap/board-h2.h
@@ -34,9 +34,5 @@
34/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */ 34/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
35#define OMAP1610_ETHR_START 0x04000300 35#define OMAP1610_ETHR_START 0x04000300
36 36
37/* Samsung NAND flash at CS2B or CS3(NAND Boot) */
38#define OMAP_NAND_FLASH_START1 0x0A000000 /* CS2B */
39#define OMAP_NAND_FLASH_START2 0x0C000000 /* CS3 */
40
41#endif /* __ASM_ARCH_OMAP_H2_H */ 37#endif /* __ASM_ARCH_OMAP_H2_H */
42 38
diff --git a/include/asm-arm/arch-omap/board-h3.h b/include/asm-arm/arch-omap/board-h3.h
index 1b12c1dcc2fa..761ea0a17897 100644
--- a/include/asm-arm/arch-omap/board-h3.h
+++ b/include/asm-arm/arch-omap/board-h3.h
@@ -30,10 +30,6 @@
30/* In OMAP1710 H3 the Ethernet is directly connected to CS1 */ 30/* In OMAP1710 H3 the Ethernet is directly connected to CS1 */
31#define OMAP1710_ETHR_START 0x04000300 31#define OMAP1710_ETHR_START 0x04000300
32 32
33/* Samsung NAND flash at CS2B or CS3(NAND Boot) */
34#define OMAP_NAND_FLASH_START1 0x0A000000 /* CS2B */
35#define OMAP_NAND_FLASH_START2 0x0C000000 /* CS3 */
36
37#define MAXIRQNUM (IH_BOARD_BASE) 33#define MAXIRQNUM (IH_BOARD_BASE)
38#define MAXFIQNUM MAXIRQNUM 34#define MAXFIQNUM MAXIRQNUM
39#define MAXSWINUM MAXIRQNUM 35#define MAXSWINUM MAXIRQNUM
diff --git a/include/asm-arm/arch-omap/board-h4.h b/include/asm-arm/arch-omap/board-h4.h
index 33ea29a41654..7ef664bc9e33 100644
--- a/include/asm-arm/arch-omap/board-h4.h
+++ b/include/asm-arm/arch-omap/board-h4.h
@@ -33,12 +33,6 @@
33/* GPMC CS1 */ 33/* GPMC CS1 */
34#define OMAP24XX_ETHR_START 0x08000300 34#define OMAP24XX_ETHR_START 0x08000300
35#define OMAP24XX_ETHR_GPIO_IRQ 92 35#define OMAP24XX_ETHR_GPIO_IRQ 92
36 36#define H4_CS0_BASE 0x04000000
37#define H4_CS0_BASE 0x04000000
38
39#define H4_CS0_BASE 0x04000000
40
41#define H4_CS0_BASE 0x04000000
42
43#endif /* __ASM_ARCH_OMAP_H4_H */ 37#endif /* __ASM_ARCH_OMAP_H4_H */
44 38
diff --git a/include/asm-arm/arch-omap/board-netstar.h b/include/asm-arm/arch-omap/board-netstar.h
deleted file mode 100644
index 77cc0fb54d54..000000000000
--- a/include/asm-arm/arch-omap/board-netstar.h
+++ /dev/null
@@ -1,19 +0,0 @@
1/*
2 * Copyright (C) 2004 2N Telekomunikace, Ladislav Michl <michl@2n.cz>
3 *
4 * Hardware definitions for OMAP5910 based NetStar board.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __ASM_ARCH_NETSTAR_H
12#define __ASM_ARCH_NETSTAR_H
13
14#include <asm/arch/tc.h>
15
16#define OMAP_NAND_FLASH_START1 OMAP_CS1_PHYS + (1 << 23)
17#define OMAP_NAND_FLASH_START2 OMAP_CS1_PHYS + (2 << 23)
18
19#endif /* __ASM_ARCH_NETSTAR_H */
diff --git a/include/asm-arm/arch-omap/board-nokia.h b/include/asm-arm/arch-omap/board-nokia.h
new file mode 100644
index 000000000000..72deea203493
--- /dev/null
+++ b/include/asm-arm/arch-omap/board-nokia.h
@@ -0,0 +1,54 @@
1/*
2 * linux/include/asm-arm/arch-omap/board-nokia.h
3 *
4 * Information structures for Nokia-specific board config data
5 *
6 * Copyright (C) 2005 Nokia Corporation
7 */
8
9#ifndef _OMAP_BOARD_NOKIA_H
10#define _OMAP_BOARD_NOKIA_H
11
12#include <linux/types.h>
13
14#define OMAP_TAG_NOKIA_BT 0x4e01
15#define OMAP_TAG_WLAN_CX3110X 0x4e02
16#define OMAP_TAG_CBUS 0x4e03
17#define OMAP_TAG_EM_ASIC_BB5 0x4e04
18
19
20#define BT_CHIP_CSR 1
21#define BT_CHIP_TI 2
22
23#define BT_SYSCLK_12 1
24#define BT_SYSCLK_38_4 2
25
26struct omap_bluetooth_config {
27 u8 chip_type;
28 u8 bt_wakeup_gpio;
29 u8 host_wakeup_gpio;
30 u8 reset_gpio;
31 u8 bt_uart;
32 u8 bd_addr[6];
33 u8 bt_sysclk;
34};
35
36struct omap_wlan_cx3110x_config {
37 u8 chip_type;
38 s16 power_gpio;
39 s16 irq_gpio;
40 s16 spi_cs_gpio;
41};
42
43struct omap_cbus_config {
44 s16 clk_gpio;
45 s16 dat_gpio;
46 s16 sel_gpio;
47};
48
49struct omap_em_asic_bb5_config {
50 s16 retu_irq_gpio;
51 s16 tahvo_irq_gpio;
52};
53
54#endif
diff --git a/include/asm-arm/arch-omap/board-perseus2.h b/include/asm-arm/arch-omap/board-perseus2.h
index 691e52a52b43..eb74420cb439 100644
--- a/include/asm-arm/arch-omap/board-perseus2.h
+++ b/include/asm-arm/arch-omap/board-perseus2.h
@@ -42,8 +42,4 @@
42 42
43#define NR_IRQS (MAXIRQNUM + 1) 43#define NR_IRQS (MAXIRQNUM + 1)
44 44
45/* Samsung NAND flash at CS2B or CS3(NAND Boot) */
46#define OMAP_NAND_FLASH_START1 0x0A000000 /* CS2B */
47#define OMAP_NAND_FLASH_START2 0x0C000000 /* CS3 */
48
49#endif 45#endif
diff --git a/include/asm-arm/arch-omap/board.h b/include/asm-arm/arch-omap/board.h
index a0040cd86639..6d6240a4681c 100644
--- a/include/asm-arm/arch-omap/board.h
+++ b/include/asm-arm/arch-omap/board.h
@@ -21,9 +21,12 @@
21#define OMAP_TAG_LCD 0x4f05 21#define OMAP_TAG_LCD 0x4f05
22#define OMAP_TAG_GPIO_SWITCH 0x4f06 22#define OMAP_TAG_GPIO_SWITCH 0x4f06
23#define OMAP_TAG_UART 0x4f07 23#define OMAP_TAG_UART 0x4f07
24#define OMAP_TAG_FBMEM 0x4f08
25#define OMAP_TAG_STI_CONSOLE 0x4f09
24 26
25#define OMAP_TAG_BOOT_REASON 0x4f80 27#define OMAP_TAG_BOOT_REASON 0x4f80
26#define OMAP_TAG_FLASH_PART 0x4f81 28#define OMAP_TAG_FLASH_PART 0x4f81
29#define OMAP_TAG_VERSION_STR 0x4f82
27 30
28struct omap_clock_config { 31struct omap_clock_config {
29 /* 0 for 12 MHz, 1 for 13 MHz and 2 for 19.2 MHz */ 32 /* 0 for 12 MHz, 1 for 13 MHz and 2 for 19.2 MHz */
@@ -54,6 +57,11 @@ struct omap_serial_console_config {
54 u32 console_speed; 57 u32 console_speed;
55}; 58};
56 59
60struct omap_sti_console_config {
61 unsigned enable:1;
62 u8 channel;
63};
64
57struct omap_usb_config { 65struct omap_usb_config {
58 /* Configure drivers according to the connectors on your board: 66 /* Configure drivers according to the connectors on your board:
59 * - "A" connector (rectagular) 67 * - "A" connector (rectagular)
@@ -87,6 +95,13 @@ struct omap_lcd_config {
87 char ctrl_name[16]; 95 char ctrl_name[16];
88}; 96};
89 97
98struct omap_fbmem_config {
99 u32 fb_sram_start;
100 u32 fb_sram_size;
101 u32 fb_sdram_start;
102 u32 fb_sdram_size;
103};
104
90/* Cover: 105/* Cover:
91 * high -> closed 106 * high -> closed
92 * low -> open 107 * low -> open
@@ -106,6 +121,12 @@ struct omap_gpio_switch_config {
106 int key_code:24; /* Linux key code */ 121 int key_code:24; /* Linux key code */
107}; 122};
108 123
124struct omap_uart_config {
125 /* Bit field of UARTs present; bit 0 --> UART1 */
126 unsigned int enabled_uarts;
127};
128
129
109struct omap_flash_part_config { 130struct omap_flash_part_config {
110 char part_table[0]; 131 char part_table[0];
111}; 132};
@@ -114,11 +135,14 @@ struct omap_boot_reason_config {
114 char reason_str[12]; 135 char reason_str[12];
115}; 136};
116 137
117struct omap_uart_config { 138struct omap_version_config {
118 /* Bit field of UARTs present; bit 0 --> UART1 */ 139 char component[12];
119 unsigned int enabled_uarts; 140 char version[12];
120}; 141};
121 142
143
144#include <asm-arm/arch-omap/board-nokia.h>
145
122struct omap_board_config_entry { 146struct omap_board_config_entry {
123 u16 tag; 147 u16 tag;
124 u16 len; 148 u16 len;
diff --git a/include/asm-arm/arch-omap/clock.h b/include/asm-arm/arch-omap/clock.h
index 46a0402696de..3c4eb9fbe48a 100644
--- a/include/asm-arm/arch-omap/clock.h
+++ b/include/asm-arm/arch-omap/clock.h
@@ -19,6 +19,7 @@ struct clk {
19 struct list_head node; 19 struct list_head node;
20 struct module *owner; 20 struct module *owner;
21 const char *name; 21 const char *name;
22 int id;
22 struct clk *parent; 23 struct clk *parent;
23 unsigned long rate; 24 unsigned long rate;
24 __u32 flags; 25 __u32 flags;
@@ -57,6 +58,7 @@ extern void propagate_rate(struct clk *clk);
57extern void followparent_recalc(struct clk * clk); 58extern void followparent_recalc(struct clk * clk);
58extern void clk_allow_idle(struct clk *clk); 59extern void clk_allow_idle(struct clk *clk);
59extern void clk_deny_idle(struct clk *clk); 60extern void clk_deny_idle(struct clk *clk);
61extern int clk_get_usecount(struct clk *clk);
60 62
61/* Clock flags */ 63/* Clock flags */
62#define RATE_CKCTL (1 << 0) /* Main fixed ratio clocks */ 64#define RATE_CKCTL (1 << 0) /* Main fixed ratio clocks */
@@ -80,10 +82,11 @@ extern void clk_deny_idle(struct clk *clk);
80#define CM_PLL_SEL1 (1 << 18) 82#define CM_PLL_SEL1 (1 << 18)
81#define CM_PLL_SEL2 (1 << 19) 83#define CM_PLL_SEL2 (1 << 19)
82#define CM_SYSCLKOUT_SEL1 (1 << 20) 84#define CM_SYSCLKOUT_SEL1 (1 << 20)
83#define CLOCK_IN_OMAP730 (1 << 21) 85#define CLOCK_IN_OMAP310 (1 << 21)
84#define CLOCK_IN_OMAP1510 (1 << 22) 86#define CLOCK_IN_OMAP730 (1 << 22)
85#define CLOCK_IN_OMAP16XX (1 << 23) 87#define CLOCK_IN_OMAP1510 (1 << 23)
86#define CLOCK_IN_OMAP242X (1 << 24) 88#define CLOCK_IN_OMAP16XX (1 << 24)
87#define CLOCK_IN_OMAP243X (1 << 25) 89#define CLOCK_IN_OMAP242X (1 << 25)
90#define CLOCK_IN_OMAP243X (1 << 26)
88 91
89#endif 92#endif
diff --git a/include/asm-arm/arch-omap/dma.h b/include/asm-arm/arch-omap/dma.h
index d4e73efcb816..ca1202312a45 100644
--- a/include/asm-arm/arch-omap/dma.h
+++ b/include/asm-arm/arch-omap/dma.h
@@ -404,6 +404,7 @@ extern void omap_free_lcd_dma(void);
404extern void omap_setup_lcd_dma(void); 404extern void omap_setup_lcd_dma(void);
405extern void omap_enable_lcd_dma(void); 405extern void omap_enable_lcd_dma(void);
406extern void omap_stop_lcd_dma(void); 406extern void omap_stop_lcd_dma(void);
407extern int omap_lcd_dma_ext_running(void);
407extern void omap_set_lcd_dma_ext_controller(int external); 408extern void omap_set_lcd_dma_ext_controller(int external);
408extern void omap_set_lcd_dma_single_transfer(int single); 409extern void omap_set_lcd_dma_single_transfer(int single);
409extern void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres, 410extern void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
diff --git a/include/asm-arm/arch-omap/dmtimer.h b/include/asm-arm/arch-omap/dmtimer.h
index 11772c792f3e..e6522e6a3834 100644
--- a/include/asm-arm/arch-omap/dmtimer.h
+++ b/include/asm-arm/arch-omap/dmtimer.h
@@ -88,5 +88,6 @@ unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer);
88void omap_dm_timer_reset_counter(struct omap_dm_timer *timer); 88void omap_dm_timer_reset_counter(struct omap_dm_timer *timer);
89 89
90int omap_dm_timers_active(void); 90int omap_dm_timers_active(void);
91u32 omap_dm_timer_modify_idlect_mask(u32 inputmask);
91 92
92#endif /* __ASM_ARCH_TIMER_H */ 93#endif /* __ASM_ARCH_TIMER_H */
diff --git a/include/asm-arm/arch-omap/dsp.h b/include/asm-arm/arch-omap/dsp.h
index 57bf4f39ca58..06dad83dd41f 100644
--- a/include/asm-arm/arch-omap/dsp.h
+++ b/include/asm-arm/arch-omap/dsp.h
@@ -181,10 +181,16 @@ struct omap_dsp_varinfo {
181#define OMAP_DSP_MBCMD_PM_ENABLE 0x01 181#define OMAP_DSP_MBCMD_PM_ENABLE 0x01
182 182
183#define OMAP_DSP_MBCMD_KFUNC_FBCTL 0x00 183#define OMAP_DSP_MBCMD_KFUNC_FBCTL 0x00
184#define OMAP_DSP_MBCMD_KFUNC_AUDIO_PWR 0x01
184 185
186#define OMAP_DSP_MBCMD_FBCTL_UPD 0x0000
185#define OMAP_DSP_MBCMD_FBCTL_ENABLE 0x0002 187#define OMAP_DSP_MBCMD_FBCTL_ENABLE 0x0002
186#define OMAP_DSP_MBCMD_FBCTL_DISABLE 0x0003 188#define OMAP_DSP_MBCMD_FBCTL_DISABLE 0x0003
187 189
190#define OMAP_DSP_MBCMD_AUDIO_PWR_UP 0x0000
191#define OMAP_DSP_MBCMD_AUDIO_PWR_DOWN1 0x0001
192#define OMAP_DSP_MBCMD_AUDIO_PWR_DOWN2 0x0002
193
188#define OMAP_DSP_MBCMD_TDEL_SAFE 0x0000 194#define OMAP_DSP_MBCMD_TDEL_SAFE 0x0000
189#define OMAP_DSP_MBCMD_TDEL_KILL 0x0001 195#define OMAP_DSP_MBCMD_TDEL_KILL 0x0001
190 196
diff --git a/include/asm-arm/arch-omap/dsp_common.h b/include/asm-arm/arch-omap/dsp_common.h
index 4fcce6944056..16a459dfa714 100644
--- a/include/asm-arm/arch-omap/dsp_common.h
+++ b/include/asm-arm/arch-omap/dsp_common.h
@@ -27,11 +27,12 @@
27#ifndef ASM_ARCH_DSP_COMMON_H 27#ifndef ASM_ARCH_DSP_COMMON_H
28#define ASM_ARCH_DSP_COMMON_H 28#define ASM_ARCH_DSP_COMMON_H
29 29
30void omap_dsp_pm_suspend(void); 30extern void omap_dsp_request_mpui(void);
31void omap_dsp_pm_resume(void); 31extern void omap_dsp_release_mpui(void);
32void omap_dsp_request_mpui(void); 32extern int omap_dsp_request_mem(void);
33void omap_dsp_release_mpui(void); 33extern int omap_dsp_release_mem(void);
34int omap_dsp_request_mem(void); 34
35int omap_dsp_release_mem(void); 35extern void (*omap_dsp_audio_pwr_up_request)(int stage);
36extern void (*omap_dsp_audio_pwr_down_request)(int stage);
36 37
37#endif /* ASM_ARCH_DSP_COMMON_H */ 38#endif /* ASM_ARCH_DSP_COMMON_H */
diff --git a/include/asm-arm/arch-omap/gpioexpander.h b/include/asm-arm/arch-omap/gpioexpander.h
new file mode 100644
index 000000000000..7a43b0a912e4
--- /dev/null
+++ b/include/asm-arm/arch-omap/gpioexpander.h
@@ -0,0 +1,24 @@
1/*
2 * linux/include/asm-arm/arch-omap/gpioexpander.h
3 *
4 *
5 * Copyright (C) 2004 Texas Instruments, Inc.
6 *
7 * This package is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
12 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
13 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
14 */
15
16#ifndef __ASM_ARCH_OMAP_GPIOEXPANDER_H
17#define __ASM_ARCH_OMAP_GPIOEXPANDER_H
18
19/* Function Prototypes for GPIO Expander functions */
20
21int read_gpio_expa(u8 *, int);
22int write_gpio_expa(u8 , int);
23
24#endif /* __ASM_ARCH_OMAP_GPIOEXPANDER_H */
diff --git a/include/asm-arm/arch-omap/hardware.h b/include/asm-arm/arch-omap/hardware.h
index 5406b875c422..7909b729826c 100644
--- a/include/asm-arm/arch-omap/hardware.h
+++ b/include/asm-arm/arch-omap/hardware.h
@@ -306,6 +306,10 @@
306#include "board-h4.h" 306#include "board-h4.h"
307#endif 307#endif
308 308
309#ifdef CONFIG_MACH_OMAP_APOLLON
310#include "board-apollon.h"
311#endif
312
309#ifdef CONFIG_MACH_OMAP_OSK 313#ifdef CONFIG_MACH_OMAP_OSK
310#include "board-osk.h" 314#include "board-osk.h"
311#endif 315#endif
@@ -314,10 +318,6 @@
314#include "board-voiceblue.h" 318#include "board-voiceblue.h"
315#endif 319#endif
316 320
317#ifdef CONFIG_MACH_NETSTAR
318#include "board-netstar.h"
319#endif
320
321#endif /* !__ASSEMBLER__ */ 321#endif /* !__ASSEMBLER__ */
322 322
323#endif /* __ASM_ARCH_OMAP_HARDWARE_H */ 323#endif /* __ASM_ARCH_OMAP_HARDWARE_H */
diff --git a/include/asm-arm/arch-omap/irda.h b/include/asm-arm/arch-omap/irda.h
new file mode 100644
index 000000000000..805ae3575e44
--- /dev/null
+++ b/include/asm-arm/arch-omap/irda.h
@@ -0,0 +1,36 @@
1/*
2 * linux/include/asm-arm/arch-omap/irda.h
3 *
4 * Copyright (C) 2005-2006 Komal Shah <komal_shah802003@yahoo.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#ifndef ASMARM_ARCH_IRDA_H
11#define ASMARM_ARCH_IRDA_H
12
13/* board specific transceiver capabilities */
14
15#define IR_SEL 1 /* Selects IrDA */
16#define IR_SIRMODE 2
17#define IR_FIRMODE 4
18#define IR_MIRMODE 8
19
20struct omap_irda_config {
21 int transceiver_cap;
22 int (*transceiver_mode)(struct device *dev, int mode);
23 int (*select_irda)(struct device *dev, int state);
24 /* Very specific to the needs of some platforms (h3,h4)
25 * having calls which can sleep in irda_set_speed.
26 */
27 struct work_struct gpio_expa;
28 int rx_channel;
29 int tx_channel;
30 unsigned long dest_start;
31 unsigned long src_start;
32 int tx_trigger;
33 int rx_trigger;
34};
35
36#endif
diff --git a/include/asm-arm/arch-omap/irqs.h b/include/asm-arm/arch-omap/irqs.h
index 4ffce1d77759..42098d99f302 100644
--- a/include/asm-arm/arch-omap/irqs.h
+++ b/include/asm-arm/arch-omap/irqs.h
@@ -242,6 +242,11 @@
242#define INT_24XX_GPIO_BANK2 30 242#define INT_24XX_GPIO_BANK2 30
243#define INT_24XX_GPIO_BANK3 31 243#define INT_24XX_GPIO_BANK3 31
244#define INT_24XX_GPIO_BANK4 32 244#define INT_24XX_GPIO_BANK4 32
245#define INT_24XX_MCBSP1_IRQ_TX 59
246#define INT_24XX_MCBSP1_IRQ_RX 60
247#define INT_24XX_MCBSP2_IRQ_TX 62
248#define INT_24XX_MCBSP2_IRQ_RX 63
249#define INT_24XX_UART3_IRQ 74
245 250
246/* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730) and 251/* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730) and
247 * 16 MPUIO lines */ 252 * 16 MPUIO lines */
diff --git a/include/asm-arm/arch-omap/keypad.h b/include/asm-arm/arch-omap/keypad.h
new file mode 100644
index 000000000000..8a023a984acb
--- /dev/null
+++ b/include/asm-arm/arch-omap/keypad.h
@@ -0,0 +1,36 @@
1/*
2 * linux/include/asm-arm/arch-omap/keypad.h
3 *
4 * Copyright (C) 2006 Komal Shah <komal_shah802003@yahoo.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#ifndef ASMARM_ARCH_KEYPAD_H
11#define ASMARM_ARCH_KEYPAD_H
12
13struct omap_kp_platform_data {
14 int rows;
15 int cols;
16 int *keymap;
17 unsigned int rep:1;
18 /* specific to OMAP242x*/
19 unsigned int *row_gpios;
20 unsigned int *col_gpios;
21};
22
23/* Group (0..3) -- when multiple keys are pressed, only the
24 * keys pressed in the same group are considered as pressed. This is
25 * in order to workaround certain crappy HW designs that produce ghost
26 * keypresses. */
27#define GROUP_0 (0 << 16)
28#define GROUP_1 (1 << 16)
29#define GROUP_2 (2 << 16)
30#define GROUP_3 (3 << 16)
31#define GROUP_MASK GROUP_3
32
33#define KEY(col, row, val) (((col) << 28) | ((row) << 24) | (val))
34
35#endif
36
diff --git a/include/asm-arm/arch-omap/lcd_lph8923.h b/include/asm-arm/arch-omap/lcd_lph8923.h
new file mode 100644
index 000000000000..004e67e22ca7
--- /dev/null
+++ b/include/asm-arm/arch-omap/lcd_lph8923.h
@@ -0,0 +1,14 @@
1#ifndef __LCD_LPH8923_H
2#define __LCD_LPH8923_H
3
4enum lcd_lph8923_test_num {
5 LCD_LPH8923_TEST_RGB_LINES,
6};
7
8enum lcd_lph8923_test_result {
9 LCD_LPH8923_TEST_SUCCESS,
10 LCD_LPH8923_TEST_INVALID,
11 LCD_LPH8923_TEST_FAILED,
12};
13
14#endif
diff --git a/include/asm-arm/arch-omap/mcbsp.h b/include/asm-arm/arch-omap/mcbsp.h
index e79d98ab2ab6..ed0dde4f7219 100644
--- a/include/asm-arm/arch-omap/mcbsp.h
+++ b/include/asm-arm/arch-omap/mcbsp.h
@@ -37,6 +37,11 @@
37#define OMAP1610_MCBSP2_BASE 0xfffb1000 37#define OMAP1610_MCBSP2_BASE 0xfffb1000
38#define OMAP1610_MCBSP3_BASE 0xe1017000 38#define OMAP1610_MCBSP3_BASE 0xe1017000
39 39
40#define OMAP24XX_MCBSP1_BASE 0x48074000
41#define OMAP24XX_MCBSP2_BASE 0x48076000
42
43#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730)
44
40#define OMAP_MCBSP_REG_DRR2 0x00 45#define OMAP_MCBSP_REG_DRR2 0x00
41#define OMAP_MCBSP_REG_DRR1 0x02 46#define OMAP_MCBSP_REG_DRR1 0x02
42#define OMAP_MCBSP_REG_DXR2 0x04 47#define OMAP_MCBSP_REG_DXR2 0x04
@@ -71,9 +76,62 @@
71 76
72#define OMAP_MAX_MCBSP_COUNT 3 77#define OMAP_MAX_MCBSP_COUNT 3
73 78
79#define AUDIO_MCBSP_DATAWRITE (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1)
80#define AUDIO_MCBSP_DATAREAD (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1)
81
82#define AUDIO_MCBSP OMAP_MCBSP1
83#define AUDIO_DMA_TX OMAP_DMA_MCBSP1_TX
84#define AUDIO_DMA_RX OMAP_DMA_MCBSP1_RX
85
86#elif defined(CONFIG_ARCH_OMAP24XX)
87
88#define OMAP_MCBSP_REG_DRR2 0x00
89#define OMAP_MCBSP_REG_DRR1 0x04
90#define OMAP_MCBSP_REG_DXR2 0x08
91#define OMAP_MCBSP_REG_DXR1 0x0C
92#define OMAP_MCBSP_REG_SPCR2 0x10
93#define OMAP_MCBSP_REG_SPCR1 0x14
94#define OMAP_MCBSP_REG_RCR2 0x18
95#define OMAP_MCBSP_REG_RCR1 0x1C
96#define OMAP_MCBSP_REG_XCR2 0x20
97#define OMAP_MCBSP_REG_XCR1 0x24
98#define OMAP_MCBSP_REG_SRGR2 0x28
99#define OMAP_MCBSP_REG_SRGR1 0x2C
100#define OMAP_MCBSP_REG_MCR2 0x30
101#define OMAP_MCBSP_REG_MCR1 0x34
102#define OMAP_MCBSP_REG_RCERA 0x38
103#define OMAP_MCBSP_REG_RCERB 0x3C
104#define OMAP_MCBSP_REG_XCERA 0x40
105#define OMAP_MCBSP_REG_XCERB 0x44
106#define OMAP_MCBSP_REG_PCR0 0x48
107#define OMAP_MCBSP_REG_RCERC 0x4C
108#define OMAP_MCBSP_REG_RCERD 0x50
109#define OMAP_MCBSP_REG_XCERC 0x54
110#define OMAP_MCBSP_REG_XCERD 0x58
111#define OMAP_MCBSP_REG_RCERE 0x5C
112#define OMAP_MCBSP_REG_RCERF 0x60
113#define OMAP_MCBSP_REG_XCERE 0x64
114#define OMAP_MCBSP_REG_XCERF 0x68
115#define OMAP_MCBSP_REG_RCERG 0x6C
116#define OMAP_MCBSP_REG_RCERH 0x70
117#define OMAP_MCBSP_REG_XCERG 0x74
118#define OMAP_MCBSP_REG_XCERH 0x78
119
120#define OMAP_MAX_MCBSP_COUNT 2
121
122#define AUDIO_MCBSP_DATAWRITE (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR1)
123#define AUDIO_MCBSP_DATAREAD (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1)
124
125#define AUDIO_MCBSP OMAP_MCBSP2
126#define AUDIO_DMA_TX OMAP24XX_DMA_MCBSP2_TX
127#define AUDIO_DMA_RX OMAP24XX_DMA_MCBSP2_RX
128
129#endif
130
74#define OMAP_MCBSP_READ(base, reg) __raw_readw((base) + OMAP_MCBSP_REG_##reg) 131#define OMAP_MCBSP_READ(base, reg) __raw_readw((base) + OMAP_MCBSP_REG_##reg)
75#define OMAP_MCBSP_WRITE(base, reg, val) __raw_writew((val), (base) + OMAP_MCBSP_REG_##reg) 132#define OMAP_MCBSP_WRITE(base, reg, val) __raw_writew((val), (base) + OMAP_MCBSP_REG_##reg)
76 133
134
77/************************** McBSP SPCR1 bit definitions ***********************/ 135/************************** McBSP SPCR1 bit definitions ***********************/
78#define RRST 0x0001 136#define RRST 0x0001
79#define RRDY 0x0002 137#define RRDY 0x0002
@@ -195,6 +253,10 @@ typedef enum {
195 OMAP_MCBSP3, 253 OMAP_MCBSP3,
196} omap_mcbsp_id; 254} omap_mcbsp_id;
197 255
256typedef int __bitwise omap_mcbsp_io_type_t;
257#define OMAP_MCBSP_IRQ_IO ((__force omap_mcbsp_io_type_t) 1)
258#define OMAP_MCBSP_POLL_IO ((__force omap_mcbsp_io_type_t) 2)
259
198typedef enum { 260typedef enum {
199 OMAP_MCBSP_WORD_8 = 0, 261 OMAP_MCBSP_WORD_8 = 0,
200 OMAP_MCBSP_WORD_12, 262 OMAP_MCBSP_WORD_12,
@@ -246,6 +308,9 @@ u32 omap_mcbsp_recv_word(unsigned int id);
246 308
247int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length); 309int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length);
248int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length); 310int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length);
311int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word);
312int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word);
313
249 314
250/* SPI specific API */ 315/* SPI specific API */
251void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg); 316void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg);
diff --git a/include/asm-arm/arch-omap/mcspi.h b/include/asm-arm/arch-omap/mcspi.h
new file mode 100644
index 000000000000..9e7f40a88e1b
--- /dev/null
+++ b/include/asm-arm/arch-omap/mcspi.h
@@ -0,0 +1,16 @@
1#ifndef _OMAP2_MCSPI_H
2#define _OMAP2_MCSPI_H
3
4struct omap2_mcspi_platform_config {
5 unsigned long base;
6 unsigned short num_cs;
7};
8
9struct omap2_mcspi_device_config {
10 unsigned turbo_mode:1;
11
12 /* Do we want one channel enabled at the same time? */
13 unsigned single_channel:1;
14};
15
16#endif
diff --git a/include/asm-arm/arch-omap/menelaus.h b/include/asm-arm/arch-omap/menelaus.h
index 46be8b8d6346..88cd4c87f0de 100644
--- a/include/asm-arm/arch-omap/menelaus.h
+++ b/include/asm-arm/arch-omap/menelaus.h
@@ -7,7 +7,7 @@
7#ifndef __ASM_ARCH_MENELAUS_H 7#ifndef __ASM_ARCH_MENELAUS_H
8#define __ASM_ARCH_MENELAUS_H 8#define __ASM_ARCH_MENELAUS_H
9 9
10extern void menelaus_mmc_register(void (*callback)(u8 card_mask), 10extern void menelaus_mmc_register(void (*callback)(unsigned long data, u8 card_mask),
11 unsigned long data); 11 unsigned long data);
12extern void menelaus_mmc_remove(void); 12extern void menelaus_mmc_remove(void);
13extern void menelaus_mmc_opendrain(int enable); 13extern void menelaus_mmc_opendrain(int enable);
diff --git a/include/asm-arm/arch-omap/mux.h b/include/asm-arm/arch-omap/mux.h
index 13415a9aab06..0dc24d4ba59c 100644
--- a/include/asm-arm/arch-omap/mux.h
+++ b/include/asm-arm/arch-omap/mux.h
@@ -112,14 +112,13 @@
112 * as mux config 112 * as mux config
113 */ 113 */
114#define MUX_CFG_730(desc, mux_reg, mode_offset, mode, \ 114#define MUX_CFG_730(desc, mux_reg, mode_offset, mode, \
115 pull_reg, pull_bit, pull_status, \ 115 pull_bit, pull_status, debug_status)\
116 pu_pd_reg, pu_pd_status, debug_status)\
117{ \ 116{ \
118 .name = desc, \ 117 .name = desc, \
119 .debug = debug_status, \ 118 .debug = debug_status, \
120 MUX_REG_730(mux_reg, mode_offset, mode) \ 119 MUX_REG_730(mux_reg, mode_offset, mode) \
121 PULL_REG_730(mux_reg, pull_bit, pull_status) \ 120 PULL_REG_730(mux_reg, pull_bit, pull_status) \
122 PU_PD_REG(pu_pd_reg, pu_pd_status) \ 121 PU_PD_REG(NA, 0) \
123}, 122},
124 123
125#define MUX_CFG_24XX(desc, reg_offset, mode, \ 124#define MUX_CFG_24XX(desc, reg_offset, mode, \
@@ -172,6 +171,11 @@ enum omap730_index {
172 E4_730_KBC2, 171 E4_730_KBC2,
173 F4_730_KBC3, 172 F4_730_KBC3,
174 E3_730_KBC4, 173 E3_730_KBC4,
174
175 /* USB */
176 AA17_730_USB_DM,
177 W16_730_USB_PU_EN,
178 W17_730_USB_VBUSI,
175}; 179};
176 180
177enum omap1xxx_index { 181enum omap1xxx_index {
@@ -403,9 +407,53 @@ enum omap24xx_index {
403 /* 24xx Menelaus interrupt */ 407 /* 24xx Menelaus interrupt */
404 W19_24XX_SYS_NIRQ, 408 W19_24XX_SYS_NIRQ,
405 409
410 /* 24xx clock */
411 W14_24XX_SYS_CLKOUT,
412
413 /* 242X McBSP */
414 Y15_24XX_MCBSP2_CLKX,
415 R14_24XX_MCBSP2_FSX,
416 W15_24XX_MCBSP2_DR,
417 V15_24XX_MCBSP2_DX,
418
406 /* 24xx GPIO */ 419 /* 24xx GPIO */
420 M21_242X_GPIO11,
421 AA10_242X_GPIO13,
422 AA6_242X_GPIO14,
423 AA4_242X_GPIO15,
424 Y11_242X_GPIO16,
425 AA12_242X_GPIO17,
426 AA8_242X_GPIO58,
407 Y20_24XX_GPIO60, 427 Y20_24XX_GPIO60,
428 W4__24XX_GPIO74,
408 M15_24XX_GPIO92, 429 M15_24XX_GPIO92,
430 V14_24XX_GPIO117,
431
432 P20_24XX_TSC_IRQ,
433
434 /* UART3 */
435 K15_24XX_UART3_TX,
436 K14_24XX_UART3_RX,
437
438 /* Keypad GPIO*/
439 T19_24XX_KBR0,
440 R19_24XX_KBR1,
441 V18_24XX_KBR2,
442 M21_24XX_KBR3,
443 E5__24XX_KBR4,
444 M18_24XX_KBR5,
445 R20_24XX_KBC0,
446 M14_24XX_KBC1,
447 H19_24XX_KBC2,
448 V17_24XX_KBC3,
449 P21_24XX_KBC4,
450 L14_24XX_KBC5,
451 N19_24XX_KBC6,
452
453 /* 24xx Menelaus Keypad GPIO */
454 B3__24XX_KBR5,
455 AA4_24XX_KBC2,
456 B13_24XX_KBC6,
409}; 457};
410 458
411#ifdef CONFIG_OMAP_MUX 459#ifdef CONFIG_OMAP_MUX
diff --git a/include/asm-arm/arch-omap/omap-alsa.h b/include/asm-arm/arch-omap/omap-alsa.h
new file mode 100644
index 000000000000..df4695474e3d
--- /dev/null
+++ b/include/asm-arm/arch-omap/omap-alsa.h
@@ -0,0 +1,124 @@
1/*
2 * linux/include/asm-arm/arch-omap/omap-alsa.h
3 *
4 * Alsa Driver for AIC23 and TSC2101 codecs on OMAP platform boards.
5 *
6 * Copyright (C) 2006 Mika Laitio <lamikr@cc.jyu.fi>
7 *
8 * Copyright (C) 2005 Instituto Nokia de Tecnologia - INdT - Manaus Brazil
9 * Written by Daniel Petrini, David Cohen, Anderson Briglia
10 * {daniel.petrini, david.cohen, anderson.briglia}@indt.org.br
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
20 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * You should have received a copy of the GNU General Public License along
29 * with this program; if not, write to the Free Software Foundation, Inc.,
30 * 675 Mass Ave, Cambridge, MA 02139, USA.
31 *
32 * History
33 * -------
34 *
35 * 2005/07/25 INdT-10LE Kernel Team - Alsa driver for omap osk,
36 * original version based in sa1100 driver
37 * and omap oss driver.
38 */
39
40#ifndef __OMAP_ALSA_H
41#define __OMAP_ALSA_H
42
43#include <sound/driver.h>
44#include <asm/arch/dma.h>
45#include <sound/core.h>
46#include <sound/pcm.h>
47#include <asm/arch/mcbsp.h>
48#include <linux/platform_device.h>
49
50#define DMA_BUF_SIZE (1024 * 8)
51
52/*
53 * Buffer management for alsa and dma
54 */
55struct audio_stream {
56 char *id; /* identification string */
57 int stream_id; /* numeric identification */
58 int dma_dev; /* dma number of that device */
59 int *lch; /* Chain of channels this stream is linked to */
60 char started; /* to store if the chain was started or not */
61 int dma_q_head; /* DMA Channel Q Head */
62 int dma_q_tail; /* DMA Channel Q Tail */
63 char dma_q_count; /* DMA Channel Q Count */
64 int active:1; /* we are using this stream for transfer now */
65 int period; /* current transfer period */
66 int periods; /* current count of periods registerd in the DMA engine */
67 spinlock_t dma_lock; /* for locking in DMA operations */
68 snd_pcm_substream_t *stream; /* the pcm stream */
69 unsigned linked:1; /* dma channels linked */
70 int offset; /* store start position of the last period in the alsa buffer */
71 int (*hw_start)(void); /* interface to start HW interface, e.g. McBSP */
72 int (*hw_stop)(void); /* interface to stop HW interface, e.g. McBSP */
73};
74
75/*
76 * Alsa card structure for aic23
77 */
78struct snd_card_omap_codec {
79 snd_card_t *card;
80 snd_pcm_t *pcm;
81 long samplerate;
82 struct audio_stream s[2]; /* playback & capture */
83};
84
85/* Codec specific information and function pointers.
86 * Codec (omap-alsa-aic23.c and omap-alsa-tsc2101.c)
87 * are responsible for defining the function pointers.
88 */
89struct omap_alsa_codec_config {
90 char *name;
91 struct omap_mcbsp_reg_cfg *mcbsp_regs_alsa;
92 snd_pcm_hw_constraint_list_t *hw_constraints_rates;
93 snd_pcm_hardware_t *snd_omap_alsa_playback;
94 snd_pcm_hardware_t *snd_omap_alsa_capture;
95 void (*codec_configure_dev)(void);
96 void (*codec_set_samplerate)(long);
97 void (*codec_clock_setup)(void);
98 int (*codec_clock_on)(void);
99 int (*codec_clock_off)(void);
100 int (*get_default_samplerate)(void);
101};
102
103/*********** Mixer function prototypes *************************/
104int snd_omap_mixer(struct snd_card_omap_codec *);
105void snd_omap_init_mixer(void);
106
107#ifdef CONFIG_PM
108void snd_omap_suspend_mixer(void);
109void snd_omap_resume_mixer(void);
110#endif
111
112int snd_omap_alsa_post_probe(struct platform_device *pdev, struct omap_alsa_codec_config *config);
113int snd_omap_alsa_remove(struct platform_device *pdev);
114#ifdef CONFIG_PM
115int snd_omap_alsa_suspend(struct platform_device *pdev, pm_message_t state);
116int snd_omap_alsa_resume(struct platform_device *pdev);
117#else
118#define snd_omap_alsa_suspend NULL
119#define snd_omap_alsa_resume NULL
120#endif
121
122void callback_omap_alsa_sound_dma(void *);
123
124#endif
diff --git a/include/asm-arm/arch-omap/omapfb.h b/include/asm-arm/arch-omap/omapfb.h
index 4ba2622cc142..fccdb3db025f 100644
--- a/include/asm-arm/arch-omap/omapfb.h
+++ b/include/asm-arm/arch-omap/omapfb.h
@@ -34,9 +34,10 @@
34#define OMAPFB_MIRROR OMAP_IOW(31, int) 34#define OMAPFB_MIRROR OMAP_IOW(31, int)
35#define OMAPFB_SYNC_GFX OMAP_IO(37) 35#define OMAPFB_SYNC_GFX OMAP_IO(37)
36#define OMAPFB_VSYNC OMAP_IO(38) 36#define OMAPFB_VSYNC OMAP_IO(38)
37#define OMAPFB_SET_UPDATE_MODE OMAP_IOW(40, enum omapfb_update_mode) 37#define OMAPFB_SET_UPDATE_MODE OMAP_IOW(40, int)
38#define OMAPFB_UPDATE_WINDOW_OLD OMAP_IOW(41, struct omapfb_update_window_old)
38#define OMAPFB_GET_CAPS OMAP_IOR(42, unsigned long) 39#define OMAPFB_GET_CAPS OMAP_IOR(42, unsigned long)
39#define OMAPFB_GET_UPDATE_MODE OMAP_IOW(43, enum omapfb_update_mode) 40#define OMAPFB_GET_UPDATE_MODE OMAP_IOW(43, int)
40#define OMAPFB_LCD_TEST OMAP_IOW(45, int) 41#define OMAPFB_LCD_TEST OMAP_IOW(45, int)
41#define OMAPFB_CTRL_TEST OMAP_IOW(46, int) 42#define OMAPFB_CTRL_TEST OMAP_IOW(46, int)
42#define OMAPFB_UPDATE_WINDOW OMAP_IOW(47, struct omapfb_update_window) 43#define OMAPFB_UPDATE_WINDOW OMAP_IOW(47, struct omapfb_update_window)
@@ -66,9 +67,14 @@ enum omapfb_color_format {
66}; 67};
67 68
68struct omapfb_update_window { 69struct omapfb_update_window {
69 u32 x, y; 70 __u32 x, y;
70 u32 width, height; 71 __u32 width, height;
71 u32 format; 72 __u32 format;
73};
74
75struct omapfb_update_window_old {
76 __u32 x, y;
77 __u32 width, height;
72}; 78};
73 79
74enum omapfb_plane { 80enum omapfb_plane {
@@ -83,17 +89,17 @@ enum omapfb_channel_out {
83}; 89};
84 90
85struct omapfb_setup_plane { 91struct omapfb_setup_plane {
86 u8 plane; 92 __u8 plane;
87 u8 channel_out; 93 __u8 channel_out;
88 u32 offset; 94 __u32 offset;
89 u32 pos_x, pos_y; 95 __u32 pos_x, pos_y;
90 u32 width, height; 96 __u32 width, height;
91 u32 color_mode; 97 __u32 color_mode;
92}; 98};
93 99
94struct omapfb_enable_plane { 100struct omapfb_enable_plane {
95 u8 plane; 101 __u8 plane;
96 u8 enable; 102 __u8 enable;
97}; 103};
98 104
99enum omapfb_color_key_type { 105enum omapfb_color_key_type {
@@ -103,10 +109,10 @@ enum omapfb_color_key_type {
103}; 109};
104 110
105struct omapfb_color_key { 111struct omapfb_color_key {
106 u8 channel_out; 112 __u8 channel_out;
107 u32 background; 113 __u32 background;
108 u32 trans_key; 114 __u32 trans_key;
109 u8 key_type; 115 __u8 key_type;
110}; 116};
111 117
112enum omapfb_update_mode { 118enum omapfb_update_mode {
@@ -120,6 +126,9 @@ enum omapfb_update_mode {
120#include <linux/completion.h> 126#include <linux/completion.h>
121#include <linux/interrupt.h> 127#include <linux/interrupt.h>
122#include <linux/fb.h> 128#include <linux/fb.h>
129#include <linux/mutex.h>
130
131#include <asm/arch/board.h>
123 132
124#define OMAP_LCDC_INV_VSYNC 0x0001 133#define OMAP_LCDC_INV_VSYNC 0x0001
125#define OMAP_LCDC_INV_HSYNC 0x0002 134#define OMAP_LCDC_INV_HSYNC 0x0002
@@ -184,19 +193,38 @@ struct extif_timings {
184 int re_cycle_time; 193 int re_cycle_time;
185 int cs_pulse_width; 194 int cs_pulse_width;
186 int access_time; 195 int access_time;
196
197 int clk_div;
198
199 u32 tim[5]; /* set by extif->convert_timings */
200
201 int converted;
187}; 202};
188 203
189struct lcd_ctrl_extif { 204struct lcd_ctrl_extif {
190 int (*init) (void); 205 int (*init) (void);
191 void (*cleanup) (void); 206 void (*cleanup) (void);
207 void (*get_clk_info) (u32 *clk_period, u32 *max_clk_div);
208 int (*convert_timings) (struct extif_timings *timings);
192 void (*set_timings) (const struct extif_timings *timings); 209 void (*set_timings) (const struct extif_timings *timings);
193 void (*write_command) (u32 cmd); 210 void (*set_bits_per_cycle)(int bpc);
194 u32 (*read_data) (void); 211 void (*write_command) (const void *buf, unsigned int len);
195 void (*write_data) (u32 data); 212 void (*read_data) (void *buf, unsigned int len);
213 void (*write_data) (const void *buf, unsigned int len);
196 void (*transfer_area) (int width, int height, 214 void (*transfer_area) (int width, int height,
197 void (callback)(void * data), void *data); 215 void (callback)(void * data), void *data);
216 unsigned long max_transmit_size;
198}; 217};
199 218
219struct omapfb_notifier_block {
220 struct notifier_block nb;
221 void *data;
222};
223
224typedef int (*omapfb_notifier_callback_t)(struct omapfb_notifier_block *,
225 unsigned long event,
226 struct omapfb_device *fbdev);
227
200struct lcd_ctrl { 228struct lcd_ctrl {
201 const char *name; 229 const char *name;
202 void *data; 230 void *data;
@@ -204,9 +232,11 @@ struct lcd_ctrl {
204 int (*init) (struct omapfb_device *fbdev, 232 int (*init) (struct omapfb_device *fbdev,
205 int ext_mode, int req_vram_size); 233 int ext_mode, int req_vram_size);
206 void (*cleanup) (void); 234 void (*cleanup) (void);
235 void (*bind_client) (struct omapfb_notifier_block *nb);
207 void (*get_vram_layout)(unsigned long *size, 236 void (*get_vram_layout)(unsigned long *size,
208 void **virt_base, 237 void **virt_base,
209 dma_addr_t *phys_base); 238 dma_addr_t *phys_base);
239 int (*mmap) (struct vm_area_struct *vma);
210 unsigned long (*get_caps) (void); 240 unsigned long (*get_caps) (void);
211 int (*set_update_mode)(enum omapfb_update_mode mode); 241 int (*set_update_mode)(enum omapfb_update_mode mode);
212 enum omapfb_update_mode (*get_update_mode)(void); 242 enum omapfb_update_mode (*get_update_mode)(void);
@@ -240,7 +270,7 @@ struct omapfb_device {
240 int state; 270 int state;
241 int ext_lcdc; /* Using external 271 int ext_lcdc; /* Using external
242 LCD controller */ 272 LCD controller */
243 struct semaphore rqueue_sema; 273 struct mutex rqueue_mutex;
244 274
245 void *vram_virt_base; 275 void *vram_virt_base;
246 dma_addr_t vram_phys_base; 276 dma_addr_t vram_phys_base;
@@ -261,12 +291,13 @@ struct omapfb_device {
261 struct device *dev; 291 struct device *dev;
262}; 292};
263 293
264extern struct lcd_panel h3_panel; 294struct omapfb_platform_data {
265extern struct lcd_panel h2_panel; 295 struct omap_lcd_config lcd;
266extern struct lcd_panel p2_panel; 296 struct omap_fbmem_config fbmem;
267extern struct lcd_panel osk_panel; 297};
268extern struct lcd_panel innovator1610_panel; 298
269extern struct lcd_panel innovator1510_panel; 299#define OMAPFB_EVENT_READY 1
300#define OMAPFB_EVENT_DISABLED 2
270 301
271#ifdef CONFIG_ARCH_OMAP1 302#ifdef CONFIG_ARCH_OMAP1
272extern struct lcd_ctrl omap1_lcd_ctrl; 303extern struct lcd_ctrl omap1_lcd_ctrl;
@@ -274,7 +305,20 @@ extern struct lcd_ctrl omap1_lcd_ctrl;
274extern struct lcd_ctrl omap2_disp_ctrl; 305extern struct lcd_ctrl omap2_disp_ctrl;
275#endif 306#endif
276 307
308extern void omapfb_register_panel(struct lcd_panel *panel);
277extern void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval); 309extern void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval);
310extern void omapfb_notify_clients(struct omapfb_device *fbdev,
311 unsigned long event);
312extern int omapfb_register_client(struct omapfb_notifier_block *nb,
313 omapfb_notifier_callback_t callback,
314 void *callback_data);
315extern int omapfb_unregister_client(struct omapfb_notifier_block *nb);
316extern int omapfb_update_window_async(struct omapfb_update_window *win,
317 void (*callback)(void *),
318 void *callback_data);
319
320/* in arch/arm/plat-omap/devices.c */
321extern void omapfb_reserve_mem(void);
278 322
279#endif /* __KERNEL__ */ 323#endif /* __KERNEL__ */
280 324
diff --git a/include/asm-arm/arch-omap/param.h b/include/asm-arm/arch-omap/param.h
new file mode 100644
index 000000000000..face9ad41e97
--- /dev/null
+++ b/include/asm-arm/arch-omap/param.h
@@ -0,0 +1,8 @@
1/*
2 * linux/include/asm-arm/arch-omap/param.h
3 *
4 */
5
6#ifdef CONFIG_OMAP_32K_TIMER_HZ
7#define HZ CONFIG_OMAP_32K_TIMER_HZ
8#endif
diff --git a/include/asm-arm/arch-omap/pm.h b/include/asm-arm/arch-omap/pm.h
index 7c790425e363..05b003f3a94c 100644
--- a/include/asm-arm/arch-omap/pm.h
+++ b/include/asm-arm/arch-omap/pm.h
@@ -49,7 +49,7 @@
49 49
50/* 50/*
51 * ---------------------------------------------------------------------------- 51 * ----------------------------------------------------------------------------
52 * Powermanagement bitmasks 52 * Power management bitmasks
53 * ---------------------------------------------------------------------------- 53 * ----------------------------------------------------------------------------
54 */ 54 */
55#define IDLE_WAIT_CYCLES 0x00000fff 55#define IDLE_WAIT_CYCLES 0x00000fff
@@ -112,32 +112,59 @@
112#endif 112#endif
113 113
114#ifndef __ASSEMBLER__ 114#ifndef __ASSEMBLER__
115
116#include <linux/clk.h>
117
118extern void prevent_idle_sleep(void);
119extern void allow_idle_sleep(void);
120
121/**
122 * clk_deny_idle - Prevents the clock from being idled during MPU idle
123 * @clk: clock signal handle
124 */
125void clk_deny_idle(struct clk *clk);
126
127/**
128 * clk_allow_idle - Counters previous clk_deny_idle
129 * @clk: clock signal handle
130 */
131void clk_deny_idle(struct clk *clk);
132
115extern void omap_pm_idle(void); 133extern void omap_pm_idle(void);
116extern void omap_pm_suspend(void); 134extern void omap_pm_suspend(void);
117extern void omap730_cpu_suspend(unsigned short, unsigned short); 135extern void omap730_cpu_suspend(unsigned short, unsigned short);
118extern void omap1510_cpu_suspend(unsigned short, unsigned short); 136extern void omap1510_cpu_suspend(unsigned short, unsigned short);
119extern void omap1610_cpu_suspend(unsigned short, unsigned short); 137extern void omap1610_cpu_suspend(unsigned short, unsigned short);
138extern void omap24xx_cpu_suspend(u32 dll_ctrl, u32 cpu_revision);
120extern void omap730_idle_loop_suspend(void); 139extern void omap730_idle_loop_suspend(void);
121extern void omap1510_idle_loop_suspend(void); 140extern void omap1510_idle_loop_suspend(void);
122extern void omap1610_idle_loop_suspend(void); 141extern void omap1610_idle_loop_suspend(void);
142extern void omap24xx_idle_loop_suspend(void);
143
144extern unsigned int omap730_cpu_suspend_sz;
145extern unsigned int omap1510_cpu_suspend_sz;
146extern unsigned int omap1610_cpu_suspend_sz;
147extern unsigned int omap24xx_cpu_suspend_sz;
148extern unsigned int omap730_idle_loop_suspend_sz;
149extern unsigned int omap1510_idle_loop_suspend_sz;
150extern unsigned int omap1610_idle_loop_suspend_sz;
151extern unsigned int omap24xx_idle_loop_suspend_sz;
123 152
124#ifdef CONFIG_OMAP_SERIAL_WAKE 153#ifdef CONFIG_OMAP_SERIAL_WAKE
125extern void omap_serial_wake_trigger(int enable); 154extern void omap_serial_wake_trigger(int enable);
126#else 155#else
156#define omap_serial_wakeup_init() {}
127#define omap_serial_wake_trigger(x) {} 157#define omap_serial_wake_trigger(x) {}
128#endif /* CONFIG_OMAP_SERIAL_WAKE */ 158#endif /* CONFIG_OMAP_SERIAL_WAKE */
129 159
130extern unsigned int omap730_cpu_suspend_sz;
131extern unsigned int omap730_idle_loop_suspend_sz;
132extern unsigned int omap1510_cpu_suspend_sz;
133extern unsigned int omap1510_idle_loop_suspend_sz;
134extern unsigned int omap1610_cpu_suspend_sz;
135extern unsigned int omap1610_idle_loop_suspend_sz;
136
137#define ARM_SAVE(x) arm_sleep_save[ARM_SLEEP_SAVE_##x] = omap_readl(x) 160#define ARM_SAVE(x) arm_sleep_save[ARM_SLEEP_SAVE_##x] = omap_readl(x)
138#define ARM_RESTORE(x) omap_writel((arm_sleep_save[ARM_SLEEP_SAVE_##x]), (x)) 161#define ARM_RESTORE(x) omap_writel((arm_sleep_save[ARM_SLEEP_SAVE_##x]), (x))
139#define ARM_SHOW(x) arm_sleep_save[ARM_SLEEP_SAVE_##x] 162#define ARM_SHOW(x) arm_sleep_save[ARM_SLEEP_SAVE_##x]
140 163
164#define DSP_SAVE(x) dsp_sleep_save[DSP_SLEEP_SAVE_##x] = __raw_readw(x)
165#define DSP_RESTORE(x) __raw_writew((dsp_sleep_save[DSP_SLEEP_SAVE_##x]), (x))
166#define DSP_SHOW(x) dsp_sleep_save[DSP_SLEEP_SAVE_##x]
167
141#define ULPD_SAVE(x) ulpd_sleep_save[ULPD_SLEEP_SAVE_##x] = omap_readw(x) 168#define ULPD_SAVE(x) ulpd_sleep_save[ULPD_SLEEP_SAVE_##x] = omap_readw(x)
142#define ULPD_RESTORE(x) omap_writew((ulpd_sleep_save[ULPD_SLEEP_SAVE_##x]), (x)) 169#define ULPD_RESTORE(x) omap_writew((ulpd_sleep_save[ULPD_SLEEP_SAVE_##x]), (x))
143#define ULPD_SHOW(x) ulpd_sleep_save[ULPD_SLEEP_SAVE_##x] 170#define ULPD_SHOW(x) ulpd_sleep_save[ULPD_SLEEP_SAVE_##x]
@@ -154,6 +181,10 @@ extern unsigned int omap1610_idle_loop_suspend_sz;
154#define MPUI1610_RESTORE(x) omap_writel((mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_##x]), (x)) 181#define MPUI1610_RESTORE(x) omap_writel((mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_##x]), (x))
155#define MPUI1610_SHOW(x) mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_##x] 182#define MPUI1610_SHOW(x) mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_##x]
156 183
184#define OMAP24XX_SAVE(x) omap24xx_sleep_save[OMAP24XX_SLEEP_SAVE_##x] = x
185#define OMAP24XX_RESTORE(x) x = omap24xx_sleep_save[OMAP24XX_SLEEP_SAVE_##x]
186#define OMAP24XX_SHOW(x) omap24xx_sleep_save[OMAP24XX_SLEEP_SAVE_##x]
187
157/* 188/*
158 * List of global OMAP registers to preserve. 189 * List of global OMAP registers to preserve.
159 * More ones like CP and general purpose register values are preserved 190 * More ones like CP and general purpose register values are preserved
@@ -176,6 +207,15 @@ enum arm_save_state {
176 ARM_SLEEP_SAVE_SIZE 207 ARM_SLEEP_SAVE_SIZE
177}; 208};
178 209
210enum dsp_save_state {
211 DSP_SLEEP_SAVE_START = 0,
212 /*
213 * DSP registers 16 bits
214 */
215 DSP_SLEEP_SAVE_DSP_IDLECT2,
216 DSP_SLEEP_SAVE_SIZE
217};
218
179enum ulpd_save_state { 219enum ulpd_save_state {
180 ULPD_SLEEP_SAVE_START = 0, 220 ULPD_SLEEP_SAVE_START = 0,
181 /* 221 /*
@@ -254,5 +294,30 @@ enum mpui1610_save_state {
254#endif 294#endif
255}; 295};
256 296
297enum omap24xx_save_state {
298 OMAP24XX_SLEEP_SAVE_START = 0,
299 OMAP24XX_SLEEP_SAVE_INTC_MIR0,
300 OMAP24XX_SLEEP_SAVE_INTC_MIR1,
301 OMAP24XX_SLEEP_SAVE_INTC_MIR2,
302 OMAP24XX_SLEEP_SAVE_CM_FCLKEN1_CORE,
303 OMAP24XX_SLEEP_SAVE_CM_FCLKEN2_CORE,
304 OMAP24XX_SLEEP_SAVE_CM_ICLKEN1_CORE,
305 OMAP24XX_SLEEP_SAVE_CM_ICLKEN2_CORE,
306 OMAP24XX_SLEEP_SAVE_CM_ICLKEN4_CORE,
307 OMAP24XX_SLEEP_SAVE_GPIO1_IRQENABLE1,
308 OMAP24XX_SLEEP_SAVE_GPIO2_IRQENABLE1,
309 OMAP24XX_SLEEP_SAVE_GPIO3_IRQENABLE1,
310 OMAP24XX_SLEEP_SAVE_GPIO4_IRQENABLE1,
311 OMAP24XX_SLEEP_SAVE_GPIO3_OE,
312 OMAP24XX_SLEEP_SAVE_GPIO4_OE,
313 OMAP24XX_SLEEP_SAVE_GPIO3_RISINGDETECT,
314 OMAP24XX_SLEEP_SAVE_GPIO3_FALLINGDETECT,
315 OMAP24XX_SLEEP_SAVE_CONTROL_PADCONF_SPI1_NCS2,
316 OMAP24XX_SLEEP_SAVE_CONTROL_PADCONF_MCBSP1_DX,
317 OMAP24XX_SLEEP_SAVE_CONTROL_PADCONF_SSI1_FLAG_TX,
318 OMAP24XX_SLEEP_SAVE_CONTROL_PADCONF_SYS_NIRQW0,
319 OMAP24XX_SLEEP_SAVE_SIZE
320};
321
257#endif /* ASSEMBLER */ 322#endif /* ASSEMBLER */
258#endif /* __ASM_ARCH_OMAP_PM_H */ 323#endif /* __ASM_ARCH_OMAP_PM_H */
diff --git a/include/asm-arm/arch-omap/prcm.h b/include/asm-arm/arch-omap/prcm.h
index 7b48a5cbb15f..7bcaf94bde9f 100644
--- a/include/asm-arm/arch-omap/prcm.h
+++ b/include/asm-arm/arch-omap/prcm.h
@@ -1,5 +1,7 @@
1/* 1/*
2 * prcm.h - Access definations for use in OMAP24XX clock and power management 2 * linux/include/asm-arm/arch-omap/prcm.h
3 *
4 * Access definations for use in OMAP24XX clock and power management
3 * 5 *
4 * Copyright (C) 2005 Texas Instruments, Inc. 6 * Copyright (C) 2005 Texas Instruments, Inc.
5 * 7 *
@@ -21,405 +23,7 @@
21#ifndef __ASM_ARM_ARCH_DPM_PRCM_H 23#ifndef __ASM_ARM_ARCH_DPM_PRCM_H
22#define __ASM_ARM_ARCH_DPM_PRCM_H 24#define __ASM_ARM_ARCH_DPM_PRCM_H
23 25
24/* SET_PERFORMANCE_LEVEL PARAMETERS */ 26u32 omap_prcm_get_reset_sources(void);
25#define PRCM_HALF_SPEED 1
26#define PRCM_FULL_SPEED 2
27
28#ifndef __ASSEMBLER__
29
30#define PRCM_REG32(offset) __REG32(OMAP24XX_PRCM_BASE + (offset))
31
32#define PRCM_REVISION PRCM_REG32(0x000)
33#define PRCM_SYSCONFIG PRCM_REG32(0x010)
34#define PRCM_IRQSTATUS_MPU PRCM_REG32(0x018)
35#define PRCM_IRQENABLE_MPU PRCM_REG32(0x01C)
36#define PRCM_VOLTCTRL PRCM_REG32(0x050)
37#define PRCM_VOLTST PRCM_REG32(0x054)
38#define PRCM_CLKSRC_CTRL PRCM_REG32(0x060)
39#define PRCM_CLKOUT_CTRL PRCM_REG32(0x070)
40#define PRCM_CLKEMUL_CTRL PRCM_REG32(0x078)
41#define PRCM_CLKCFG_CTRL PRCM_REG32(0x080)
42#define PRCM_CLKCFG_STATUS PRCM_REG32(0x084)
43#define PRCM_VOLTSETUP PRCM_REG32(0x090)
44#define PRCM_CLKSSETUP PRCM_REG32(0x094)
45#define PRCM_POLCTRL PRCM_REG32(0x098)
46
47/* GENERAL PURPOSE */
48#define GENERAL_PURPOSE1 PRCM_REG32(0x0B0)
49#define GENERAL_PURPOSE2 PRCM_REG32(0x0B4)
50#define GENERAL_PURPOSE3 PRCM_REG32(0x0B8)
51#define GENERAL_PURPOSE4 PRCM_REG32(0x0BC)
52#define GENERAL_PURPOSE5 PRCM_REG32(0x0C0)
53#define GENERAL_PURPOSE6 PRCM_REG32(0x0C4)
54#define GENERAL_PURPOSE7 PRCM_REG32(0x0C8)
55#define GENERAL_PURPOSE8 PRCM_REG32(0x0CC)
56#define GENERAL_PURPOSE9 PRCM_REG32(0x0D0)
57#define GENERAL_PURPOSE10 PRCM_REG32(0x0D4)
58#define GENERAL_PURPOSE11 PRCM_REG32(0x0D8)
59#define GENERAL_PURPOSE12 PRCM_REG32(0x0DC)
60#define GENERAL_PURPOSE13 PRCM_REG32(0x0E0)
61#define GENERAL_PURPOSE14 PRCM_REG32(0x0E4)
62#define GENERAL_PURPOSE15 PRCM_REG32(0x0E8)
63#define GENERAL_PURPOSE16 PRCM_REG32(0x0EC)
64#define GENERAL_PURPOSE17 PRCM_REG32(0x0F0)
65#define GENERAL_PURPOSE18 PRCM_REG32(0x0F4)
66#define GENERAL_PURPOSE19 PRCM_REG32(0x0F8)
67#define GENERAL_PURPOSE20 PRCM_REG32(0x0FC)
68
69/* MPU */
70#define CM_CLKSEL_MPU PRCM_REG32(0x140)
71#define CM_CLKSTCTRL_MPU PRCM_REG32(0x148)
72#define RM_RSTST_MPU PRCM_REG32(0x158)
73#define PM_WKDEP_MPU PRCM_REG32(0x1C8)
74#define PM_EVGENCTRL_MPU PRCM_REG32(0x1D4)
75#define PM_EVEGENONTIM_MPU PRCM_REG32(0x1D8)
76#define PM_EVEGENOFFTIM_MPU PRCM_REG32(0x1DC)
77#define PM_PWSTCTRL_MPU PRCM_REG32(0x1E0)
78#define PM_PWSTST_MPU PRCM_REG32(0x1E4)
79
80/* CORE */
81#define CM_FCLKEN1_CORE PRCM_REG32(0x200)
82#define CM_FCLKEN2_CORE PRCM_REG32(0x204)
83#define CM_FCLKEN3_CORE PRCM_REG32(0x208)
84#define CM_ICLKEN1_CORE PRCM_REG32(0x210)
85#define CM_ICLKEN2_CORE PRCM_REG32(0x214)
86#define CM_ICLKEN3_CORE PRCM_REG32(0x218)
87#define CM_ICLKEN4_CORE PRCM_REG32(0x21C)
88#define CM_IDLEST1_CORE PRCM_REG32(0x220)
89#define CM_IDLEST2_CORE PRCM_REG32(0x224)
90#define CM_IDLEST3_CORE PRCM_REG32(0x228)
91#define CM_IDLEST4_CORE PRCM_REG32(0x22C)
92#define CM_AUTOIDLE1_CORE PRCM_REG32(0x230)
93#define CM_AUTOIDLE2_CORE PRCM_REG32(0x234)
94#define CM_AUTOIDLE3_CORE PRCM_REG32(0x238)
95#define CM_AUTOIDLE4_CORE PRCM_REG32(0x23C)
96#define CM_CLKSEL1_CORE PRCM_REG32(0x240)
97#define CM_CLKSEL2_CORE PRCM_REG32(0x244)
98#define CM_CLKSTCTRL_CORE PRCM_REG32(0x248)
99#define PM_WKEN1_CORE PRCM_REG32(0x2A0)
100#define PM_WKEN2_CORE PRCM_REG32(0x2A4)
101#define PM_WKST1_CORE PRCM_REG32(0x2B0)
102#define PM_WKST2_CORE PRCM_REG32(0x2B4)
103#define PM_WKDEP_CORE PRCM_REG32(0x2C8)
104#define PM_PWSTCTRL_CORE PRCM_REG32(0x2E0)
105#define PM_PWSTST_CORE PRCM_REG32(0x2E4)
106
107/* GFX */
108#define CM_FCLKEN_GFX PRCM_REG32(0x300)
109#define CM_ICLKEN_GFX PRCM_REG32(0x310)
110#define CM_IDLEST_GFX PRCM_REG32(0x320)
111#define CM_CLKSEL_GFX PRCM_REG32(0x340)
112#define CM_CLKSTCTRL_GFX PRCM_REG32(0x348)
113#define RM_RSTCTRL_GFX PRCM_REG32(0x350)
114#define RM_RSTST_GFX PRCM_REG32(0x358)
115#define PM_WKDEP_GFX PRCM_REG32(0x3C8)
116#define PM_PWSTCTRL_GFX PRCM_REG32(0x3E0)
117#define PM_PWSTST_GFX PRCM_REG32(0x3E4)
118
119/* WAKE-UP */
120#define CM_FCLKEN_WKUP PRCM_REG32(0x400)
121#define CM_ICLKEN_WKUP PRCM_REG32(0x410)
122#define CM_IDLEST_WKUP PRCM_REG32(0x420)
123#define CM_AUTOIDLE_WKUP PRCM_REG32(0x430)
124#define CM_CLKSEL_WKUP PRCM_REG32(0x440)
125#define RM_RSTCTRL_WKUP PRCM_REG32(0x450)
126#define RM_RSTTIME_WKUP PRCM_REG32(0x454)
127#define RM_RSTST_WKUP PRCM_REG32(0x458)
128#define PM_WKEN_WKUP PRCM_REG32(0x4A0)
129#define PM_WKST_WKUP PRCM_REG32(0x4B0)
130
131/* CLOCKS */
132#define CM_CLKEN_PLL PRCM_REG32(0x500)
133#define CM_IDLEST_CKGEN PRCM_REG32(0x520)
134#define CM_AUTOIDLE_PLL PRCM_REG32(0x530)
135#define CM_CLKSEL1_PLL PRCM_REG32(0x540)
136#define CM_CLKSEL2_PLL PRCM_REG32(0x544)
137
138/* DSP */
139#define CM_FCLKEN_DSP PRCM_REG32(0x800)
140#define CM_ICLKEN_DSP PRCM_REG32(0x810)
141#define CM_IDLEST_DSP PRCM_REG32(0x820)
142#define CM_AUTOIDLE_DSP PRCM_REG32(0x830)
143#define CM_CLKSEL_DSP PRCM_REG32(0x840)
144#define CM_CLKSTCTRL_DSP PRCM_REG32(0x848)
145#define RM_RSTCTRL_DSP PRCM_REG32(0x850)
146#define RM_RSTST_DSP PRCM_REG32(0x858)
147#define PM_WKEN_DSP PRCM_REG32(0x8A0)
148#define PM_WKDEP_DSP PRCM_REG32(0x8C8)
149#define PM_PWSTCTRL_DSP PRCM_REG32(0x8E0)
150#define PM_PWSTST_DSP PRCM_REG32(0x8E4)
151#define PRCM_IRQSTATUS_DSP PRCM_REG32(0x8F0)
152#define PRCM_IRQENABLE_DSP PRCM_REG32(0x8F4)
153
154/* IVA */
155#define PRCM_IRQSTATUS_IVA PRCM_REG32(0x8F8)
156#define PRCM_IRQENABLE_IVA PRCM_REG32(0x8FC)
157
158/* Modem on 2430 */
159#define CM_FCLKEN_MDM PRCM_REG32(0xC00)
160#define CM_ICLKEN_MDM PRCM_REG32(0xC10)
161#define CM_IDLEST_MDM PRCM_REG32(0xC20)
162#define CM_CLKSEL_MDM PRCM_REG32(0xC40)
163
164/* FIXME: Move to header for 2430 */
165#define DISP_BASE (OMAP24XX_L4_IO_BASE+0x50000)
166#define DISP_REG32(offset) __REG32(DISP_BASE + (offset))
167
168#define OMAP24XX_GPMC_BASE (L3_24XX_BASE + 0xa000)
169#define GPMC_BASE (OMAP24XX_GPMC_BASE)
170#define GPMC_REG32(offset) __REG32(GPMC_BASE + (offset))
171
172#define GPT1_BASE (OMAP24XX_GPT1)
173#define GPT1_REG32(offset) __REG32(GPT1_BASE + (offset))
174
175/* Misc sysconfig */
176#define DISPC_SYSCONFIG DISP_REG32(0x410)
177#define SPI_BASE (OMAP24XX_L4_IO_BASE+0x98000)
178#define MCSPI1_SYSCONFIG __REG32(SPI_BASE + 0x10)
179#define MCSPI2_SYSCONFIG __REG32(SPI_BASE+0x2000 + 0x10)
180
181//#define DSP_MMU_SYSCONFIG 0x5A000010
182#define CAMERA_MMU_SYSCONFIG __REG32(DISP_BASE+0x2C10)
183//#define IVA_MMU_SYSCONFIG 0x5D000010
184//#define DSP_DMA_SYSCONFIG 0x00FCC02C
185#define CAMERA_DMA_SYSCONFIG __REG32(DISP_BASE+0x282C)
186#define SYSTEM_DMA_SYSCONFIG __REG32(DISP_BASE+0x602C)
187#define GPMC_SYSCONFIG GPMC_REG32(0x010)
188#define MAILBOXES_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x94010)
189#define UART1_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6A054)
190#define UART2_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6C054)
191#define UART3_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6E054)
192//#define IVA_SYSCONFIG 0x5C060010
193#define SDRC_SYSCONFIG __REG32(OMAP24XX_SDRC_BASE+0x10)
194#define SMS_SYSCONFIG __REG32(OMAP24XX_SMS_BASE+0x10)
195#define SSI_SYSCONFIG __REG32(DISP_BASE+0x8010)
196//#define VLYNQ_SYSCONFIG 0x67FFFE10
197
198/* rkw - good cannidates for PM_ to start what nm was trying */
199#define OMAP24XX_GPT2 (OMAP24XX_L4_IO_BASE+0x2A000)
200#define OMAP24XX_GPT3 (OMAP24XX_L4_IO_BASE+0x78000)
201#define OMAP24XX_GPT4 (OMAP24XX_L4_IO_BASE+0x7A000)
202#define OMAP24XX_GPT5 (OMAP24XX_L4_IO_BASE+0x7C000)
203#define OMAP24XX_GPT6 (OMAP24XX_L4_IO_BASE+0x7E000)
204#define OMAP24XX_GPT7 (OMAP24XX_L4_IO_BASE+0x80000)
205#define OMAP24XX_GPT8 (OMAP24XX_L4_IO_BASE+0x82000)
206#define OMAP24XX_GPT9 (OMAP24XX_L4_IO_BASE+0x84000)
207#define OMAP24XX_GPT10 (OMAP24XX_L4_IO_BASE+0x86000)
208#define OMAP24XX_GPT11 (OMAP24XX_L4_IO_BASE+0x88000)
209#define OMAP24XX_GPT12 (OMAP24XX_L4_IO_BASE+0x8A000)
210
211#define GPTIMER1_SYSCONFIG GPT1_REG32(0x010)
212#define GPTIMER2_SYSCONFIG __REG32(OMAP24XX_GPT2 + 0x10)
213#define GPTIMER3_SYSCONFIG __REG32(OMAP24XX_GPT3 + 0x10)
214#define GPTIMER4_SYSCONFIG __REG32(OMAP24XX_GPT4 + 0x10)
215#define GPTIMER5_SYSCONFIG __REG32(OMAP24XX_GPT5 + 0x10)
216#define GPTIMER6_SYSCONFIG __REG32(OMAP24XX_GPT6 + 0x10)
217#define GPTIMER7_SYSCONFIG __REG32(OMAP24XX_GPT7 + 0x10)
218#define GPTIMER8_SYSCONFIG __REG32(OMAP24XX_GPT8 + 0x10)
219#define GPTIMER9_SYSCONFIG __REG32(OMAP24XX_GPT9 + 0x10)
220#define GPTIMER10_SYSCONFIG __REG32(OMAP24XX_GPT10 + 0x10)
221#define GPTIMER11_SYSCONFIG __REG32(OMAP24XX_GPT11 + 0x10)
222#define GPTIMER12_SYSCONFIG __REG32(OMAP24XX_GPT12 + 0x10)
223
224#define GPIOX_BASE(X) (OMAP24XX_GPIO_BASE+(0x2000*((X)-1)))
225
226#define GPIO1_SYSCONFIG __REG32((GPIOX_BASE(1)+0x10))
227#define GPIO2_SYSCONFIG __REG32((GPIOX_BASE(2)+0x10))
228#define GPIO3_SYSCONFIG __REG32((GPIOX_BASE(3)+0x10))
229#define GPIO4_SYSCONFIG __REG32((GPIOX_BASE(4)+0x10))
230
231/* GP TIMER 1 */
232#define GPTIMER1_TISTAT GPT1_REG32(0x014)
233#define GPTIMER1_TISR GPT1_REG32(0x018)
234#define GPTIMER1_TIER GPT1_REG32(0x01C)
235#define GPTIMER1_TWER GPT1_REG32(0x020)
236#define GPTIMER1_TCLR GPT1_REG32(0x024)
237#define GPTIMER1_TCRR GPT1_REG32(0x028)
238#define GPTIMER1_TLDR GPT1_REG32(0x02C)
239#define GPTIMER1_TTGR GPT1_REG32(0x030)
240#define GPTIMER1_TWPS GPT1_REG32(0x034)
241#define GPTIMER1_TMAR GPT1_REG32(0x038)
242#define GPTIMER1_TCAR1 GPT1_REG32(0x03C)
243#define GPTIMER1_TSICR GPT1_REG32(0x040)
244#define GPTIMER1_TCAR2 GPT1_REG32(0x044)
245
246/* rkw -- base fix up please... */
247#define GPTIMER3_TISR __REG32(OMAP24XX_L4_IO_BASE+0x78018)
248
249/* SDRC */
250#define SDRC_DLLA_CTRL __REG32(OMAP24XX_SDRC_BASE+0x060)
251#define SDRC_DLLA_STATUS __REG32(OMAP24XX_SDRC_BASE+0x064)
252#define SDRC_DLLB_CTRL __REG32(OMAP24XX_SDRC_BASE+0x068)
253#define SDRC_DLLB_STATUS __REG32(OMAP24XX_SDRC_BASE+0x06C)
254#define SDRC_POWER __REG32(OMAP24XX_SDRC_BASE+0x070)
255#define SDRC_MR_0 __REG32(OMAP24XX_SDRC_BASE+0x084)
256
257/* GPIO 1 */
258#define GPIO1_BASE GPIOX_BASE(1)
259#define GPIO1_REG32(offset) __REG32(GPIO1_BASE + (offset))
260#define GPIO1_IRQENABLE1 GPIO1_REG32(0x01C)
261#define GPIO1_IRQSTATUS1 GPIO1_REG32(0x018)
262#define GPIO1_IRQENABLE2 GPIO1_REG32(0x02C)
263#define GPIO1_IRQSTATUS2 GPIO1_REG32(0x028)
264#define GPIO1_WAKEUPENABLE GPIO1_REG32(0x020)
265#define GPIO1_RISINGDETECT GPIO1_REG32(0x048)
266#define GPIO1_DATAIN GPIO1_REG32(0x038)
267#define GPIO1_OE GPIO1_REG32(0x034)
268#define GPIO1_DATAOUT GPIO1_REG32(0x03C)
269
270/* GPIO2 */
271#define GPIO2_BASE GPIOX_BASE(2)
272#define GPIO2_REG32(offset) __REG32(GPIO2_BASE + (offset))
273#define GPIO2_IRQENABLE1 GPIO2_REG32(0x01C)
274#define GPIO2_IRQSTATUS1 GPIO2_REG32(0x018)
275#define GPIO2_IRQENABLE2 GPIO2_REG32(0x02C)
276#define GPIO2_IRQSTATUS2 GPIO2_REG32(0x028)
277#define GPIO2_WAKEUPENABLE GPIO2_REG32(0x020)
278#define GPIO2_RISINGDETECT GPIO2_REG32(0x048)
279#define GPIO2_DATAIN GPIO2_REG32(0x038)
280#define GPIO2_OE GPIO2_REG32(0x034)
281#define GPIO2_DATAOUT GPIO2_REG32(0x03C)
282
283/* GPIO 3 */
284#define GPIO3_BASE GPIOX_BASE(3)
285#define GPIO3_REG32(offset) __REG32(GPIO3_BASE + (offset))
286#define GPIO3_IRQENABLE1 GPIO3_REG32(0x01C)
287#define GPIO3_IRQSTATUS1 GPIO3_REG32(0x018)
288#define GPIO3_IRQENABLE2 GPIO3_REG32(0x02C)
289#define GPIO3_IRQSTATUS2 GPIO3_REG32(0x028)
290#define GPIO3_WAKEUPENABLE GPIO3_REG32(0x020)
291#define GPIO3_RISINGDETECT GPIO3_REG32(0x048)
292#define GPIO3_FALLINGDETECT GPIO3_REG32(0x04C)
293#define GPIO3_DATAIN GPIO3_REG32(0x038)
294#define GPIO3_OE GPIO3_REG32(0x034)
295#define GPIO3_DATAOUT GPIO3_REG32(0x03C)
296#define GPIO3_DEBOUNCENABLE GPIO3_REG32(0x050)
297#define GPIO3_DEBOUNCINGTIME GPIO3_REG32(0x054)
298
299/* GPIO 4 */
300#define GPIO4_BASE GPIOX_BASE(4)
301#define GPIO4_REG32(offset) __REG32(GPIO4_BASE + (offset))
302#define GPIO4_IRQENABLE1 GPIO4_REG32(0x01C)
303#define GPIO4_IRQSTATUS1 GPIO4_REG32(0x018)
304#define GPIO4_IRQENABLE2 GPIO4_REG32(0x02C)
305#define GPIO4_IRQSTATUS2 GPIO4_REG32(0x028)
306#define GPIO4_WAKEUPENABLE GPIO4_REG32(0x020)
307#define GPIO4_RISINGDETECT GPIO4_REG32(0x048)
308#define GPIO4_FALLINGDETECT GPIO4_REG32(0x04C)
309#define GPIO4_DATAIN GPIO4_REG32(0x038)
310#define GPIO4_OE GPIO4_REG32(0x034)
311#define GPIO4_DATAOUT GPIO4_REG32(0x03C)
312#define GPIO4_DEBOUNCENABLE GPIO4_REG32(0x050)
313#define GPIO4_DEBOUNCINGTIME GPIO4_REG32(0x054)
314
315
316/* IO CONFIG */
317#define CONTROL_BASE (OMAP24XX_CTRL_BASE)
318#define CONTROL_REG32(offset) __REG32(CONTROL_BASE + (offset))
319
320#define CONTROL_PADCONF_SPI1_NCS2 CONTROL_REG32(0x104)
321#define CONTROL_PADCONF_SYS_XTALOUT CONTROL_REG32(0x134)
322#define CONTROL_PADCONF_UART1_RX CONTROL_REG32(0x0C8)
323#define CONTROL_PADCONF_MCBSP1_DX CONTROL_REG32(0x10C)
324#define CONTROL_PADCONF_GPMC_NCS4 CONTROL_REG32(0x090)
325#define CONTROL_PADCONF_DSS_D5 CONTROL_REG32(0x0B8)
326#define CONTROL_PADCONF_DSS_D9 CONTROL_REG32(0x0BC)
327#define CONTROL_PADCONF_DSS_D13 CONTROL_REG32(0x0C0)
328#define CONTROL_PADCONF_DSS_VSYNC CONTROL_REG32(0x0CC)
329
330/* CONTROL */
331#define CONTROL_DEVCONF CONTROL_REG32(0x274)
332
333/* INTERRUPT CONTROLLER */
334#define INTC_BASE (OMAP24XX_L4_IO_BASE+0xfe000)
335#define INTC_REG32(offset) __REG32(INTC_BASE + (offset))
336
337#define INTC1_U_BASE INTC_REG32(0x000)
338#define INTC_MIR0 INTC_REG32(0x084)
339#define INTC_MIR_SET0 INTC_REG32(0x08C)
340#define INTC_MIR_CLEAR0 INTC_REG32(0x088)
341#define INTC_ISR_CLEAR0 INTC_REG32(0x094)
342#define INTC_MIR1 INTC_REG32(0x0A4)
343#define INTC_MIR_SET1 INTC_REG32(0x0AC)
344#define INTC_MIR_CLEAR1 INTC_REG32(0x0A8)
345#define INTC_ISR_CLEAR1 INTC_REG32(0x0B4)
346#define INTC_MIR2 INTC_REG32(0x0C4)
347#define INTC_MIR_SET2 INTC_REG32(0x0CC)
348#define INTC_MIR_CLEAR2 INTC_REG32(0x0C8)
349#define INTC_ISR_CLEAR2 INTC_REG32(0x0D4)
350#define INTC_SIR_IRQ INTC_REG32(0x040)
351#define INTC_CONTROL INTC_REG32(0x048)
352#define INTC_ILR11 INTC_REG32(0x12C)
353#define INTC_ILR32 INTC_REG32(0x180)
354#define INTC_ILR37 INTC_REG32(0x194)
355#define INTC_SYSCONFIG INTC_REG32(0x010)
356
357/* RAM FIREWALL */
358#define RAMFW_BASE (0x68005000)
359#define RAMFW_REG32(offset) __REG32(RAMFW_BASE + (offset))
360
361#define RAMFW_REQINFOPERM0 RAMFW_REG32(0x048)
362#define RAMFW_READPERM0 RAMFW_REG32(0x050)
363#define RAMFW_WRITEPERM0 RAMFW_REG32(0x058)
364
365/* GPMC CS1 FPGA ON USER INTERFACE MODULE */
366//#define DEBUG_BOARD_LED_REGISTER 0x04000014
367
368/* GPMC CS0 */
369#define GPMC_CONFIG1_0 GPMC_REG32(0x060)
370#define GPMC_CONFIG2_0 GPMC_REG32(0x064)
371#define GPMC_CONFIG3_0 GPMC_REG32(0x068)
372#define GPMC_CONFIG4_0 GPMC_REG32(0x06C)
373#define GPMC_CONFIG5_0 GPMC_REG32(0x070)
374#define GPMC_CONFIG6_0 GPMC_REG32(0x074)
375#define GPMC_CONFIG7_0 GPMC_REG32(0x078)
376
377/* GPMC CS1 */
378#define GPMC_CONFIG1_1 GPMC_REG32(0x090)
379#define GPMC_CONFIG2_1 GPMC_REG32(0x094)
380#define GPMC_CONFIG3_1 GPMC_REG32(0x098)
381#define GPMC_CONFIG4_1 GPMC_REG32(0x09C)
382#define GPMC_CONFIG5_1 GPMC_REG32(0x0a0)
383#define GPMC_CONFIG6_1 GPMC_REG32(0x0a4)
384#define GPMC_CONFIG7_1 GPMC_REG32(0x0a8)
385
386/* DSS */
387#define DSS_CONTROL DISP_REG32(0x040)
388#define DISPC_CONTROL DISP_REG32(0x440)
389#define DISPC_SYSSTATUS DISP_REG32(0x414)
390#define DISPC_IRQSTATUS DISP_REG32(0x418)
391#define DISPC_IRQENABLE DISP_REG32(0x41C)
392#define DISPC_CONFIG DISP_REG32(0x444)
393#define DISPC_DEFAULT_COLOR0 DISP_REG32(0x44C)
394#define DISPC_DEFAULT_COLOR1 DISP_REG32(0x450)
395#define DISPC_TRANS_COLOR0 DISP_REG32(0x454)
396#define DISPC_TRANS_COLOR1 DISP_REG32(0x458)
397#define DISPC_LINE_NUMBER DISP_REG32(0x460)
398#define DISPC_TIMING_H DISP_REG32(0x464)
399#define DISPC_TIMING_V DISP_REG32(0x468)
400#define DISPC_POL_FREQ DISP_REG32(0x46C)
401#define DISPC_DIVISOR DISP_REG32(0x470)
402#define DISPC_SIZE_DIG DISP_REG32(0x478)
403#define DISPC_SIZE_LCD DISP_REG32(0x47C)
404#define DISPC_GFX_BA0 DISP_REG32(0x480)
405#define DISPC_GFX_BA1 DISP_REG32(0x484)
406#define DISPC_GFX_POSITION DISP_REG32(0x488)
407#define DISPC_GFX_SIZE DISP_REG32(0x48C)
408#define DISPC_GFX_ATTRIBUTES DISP_REG32(0x4A0)
409#define DISPC_GFX_FIFO_THRESHOLD DISP_REG32(0x4A4)
410#define DISPC_GFX_ROW_INC DISP_REG32(0x4AC)
411#define DISPC_GFX_PIXEL_INC DISP_REG32(0x4B0)
412#define DISPC_GFX_WINDOW_SKIP DISP_REG32(0x4B4)
413#define DISPC_GFX_TABLE_BA DISP_REG32(0x4B8)
414#define DISPC_DATA_CYCLE1 DISP_REG32(0x5D4)
415#define DISPC_DATA_CYCLE2 DISP_REG32(0x5D8)
416#define DISPC_DATA_CYCLE3 DISP_REG32(0x5DC)
417
418/* Wake up define for board */
419#define GPIO97 (1 << 1)
420#define GPIO88 (1 << 24)
421
422#endif /* __ASSEMBLER__ */
423 27
424#endif 28#endif
425 29
diff --git a/include/asm-arm/arch-omap/sram.h b/include/asm-arm/arch-omap/sram.h
index e72ccbf0fe06..6fc0dd57b7c3 100644
--- a/include/asm-arm/arch-omap/sram.h
+++ b/include/asm-arm/arch-omap/sram.h
@@ -20,6 +20,8 @@ extern void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
20 u32 mem_type); 20 u32 mem_type);
21extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass); 21extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
22 22
23extern unsigned long omap_fb_sram_start;
24extern unsigned long omap_fb_sram_size;
23 25
24/* Do not use these */ 26/* Do not use these */
25extern void sram_reprogram_clock(u32 ckctl, u32 dpllctl); 27extern void sram_reprogram_clock(u32 ckctl, u32 dpllctl);
diff --git a/include/asm-arm/arch-omap/system.h b/include/asm-arm/arch-omap/system.h
index 6724a81bd10b..67970d1a2020 100644
--- a/include/asm-arm/arch-omap/system.h
+++ b/include/asm-arm/arch-omap/system.h
@@ -9,12 +9,13 @@
9 9
10#include <asm/mach-types.h> 10#include <asm/mach-types.h>
11#include <asm/hardware.h> 11#include <asm/hardware.h>
12#include <asm/arch/prcm.h>
13 12
14#ifndef CONFIG_MACH_VOICEBLUE 13#ifndef CONFIG_MACH_VOICEBLUE
15#define voiceblue_reset() do {} while (0) 14#define voiceblue_reset() do {} while (0)
16#endif 15#endif
17 16
17extern void omap_prcm_arch_reset(char mode);
18
18static inline void arch_idle(void) 19static inline void arch_idle(void)
19{ 20{
20 cpu_do_idle(); 21 cpu_do_idle();
@@ -38,24 +39,12 @@ static inline void omap1_arch_reset(char mode)
38 omap_writew(1, ARM_RSTCT1); 39 omap_writew(1, ARM_RSTCT1);
39} 40}
40 41
41static inline void omap2_arch_reset(char mode)
42{
43 u32 rate;
44 struct clk *vclk, *sclk;
45
46 vclk = clk_get(NULL, "virt_prcm_set");
47 sclk = clk_get(NULL, "sys_ck");
48 rate = clk_get_rate(sclk);
49 clk_set_rate(vclk, rate); /* go to bypass for OMAP limitation */
50 RM_RSTCTRL_WKUP |= 2;
51}
52
53static inline void arch_reset(char mode) 42static inline void arch_reset(char mode)
54{ 43{
55 if (!cpu_is_omap24xx()) 44 if (!cpu_is_omap24xx())
56 omap1_arch_reset(mode); 45 omap1_arch_reset(mode);
57 else 46 else
58 omap2_arch_reset(mode); 47 omap_prcm_arch_reset(mode);
59} 48}
60 49
61#endif 50#endif
diff --git a/include/asm-arm/arch-s3c2410/entry-macro.S b/include/asm-arm/arch-s3c2410/entry-macro.S
index cc06b1bd37b2..894c35cf3b1e 100644
--- a/include/asm-arm/arch-s3c2410/entry-macro.S
+++ b/include/asm-arm/arch-s3c2410/entry-macro.S
@@ -6,116 +6,83 @@
6 * This file is licensed under the terms of the GNU General Public 6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any 7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied. 8 * warranty of any kind, whether express or implied.
9*/
10
11/* We have a problem that the INTOFFSET register does not always
12 * show one interrupt. Occasionally we get two interrupts through
13 * the prioritiser, and this causes the INTOFFSET register to show
14 * what looks like the logical-or of the two interrupt numbers.
15 *
16 * Thanks to Klaus, Shannon, et al for helping to debug this problem
17*/
18
19#define INTPND (0x10)
20#define INTOFFSET (0x14)
21#define EXTINTPEND (0xa8)
22#define EXTINTMASK (0xa4)
9 23
10 * Modifications:
11 * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
12 */
13#include <asm/hardware.h> 24#include <asm/hardware.h>
14#include <asm/arch/irqs.h> 25#include <asm/arch/irqs.h>
15 26
16
17 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp 27 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
18 28
19 mov \tmp, #S3C24XX_VA_IRQ 29 mov \base, #S3C24XX_VA_IRQ
20 ldr \irqnr, [ \tmp, #0x14 ] @ get irq no 30
2130000: 31 ldr \irqstat, [ \base, #INTPND]
22 teq \irqnr, #4 32 bics \irqnr, \irqstat, #3<<4 @@ only an GPIO IRQ
23 teqne \irqnr, #5 33 beq 2000f
24 beq 1002f @ external irq reg 34
25 35 @@ try the interrupt offset register, since it is there
26 @ debug check to see if interrupt reported is the same 36
27 @ as the offset.... 37 ldr \irqnr, [ \base, #INTOFFSET ]
28 38 mov \tmp, #1
29 teq \irqnr, #0 39 tst \irqstat, \tmp, lsl \irqnr
30 beq 20002f 40 addne \irqnr, \irqnr, #IRQ_EINT0
31 ldr \irqstat, [ \tmp, #0x10 ] @ INTPND 41 bne 1001f
32 mov \irqstat, \irqstat, lsr \irqnr 42
33 tst \irqstat, #1 43 @@ the number specified is not a valid irq, so try
34 bne 20002f 44 @@ and work it out for ourselves
35 45
36 /* debug/warning if we get an invalud response from the 46 mov \irqnr, #IRQ_EINT0 @@ start here
37 * INTOFFSET register */ 47 b 3000f
38#if 1 48
39 stmfd r13!, { r0 - r4 , r8-r12, r14 } 492000:
40 ldr r1, [ \tmp, #0x14 ] @ INTOFFSET 50 @@ load the GPIO interrupt register, and check it
41 ldr r2, [ \tmp, #0x10 ] @ INTPND 51
42 ldr r3, [ \tmp, #0x00 ] @ SRCPND 52 add \tmp, \base, #S3C24XX_VA_GPIO - S3C24XX_VA_IRQ
43 adr r0, 20003f 53 ldr \irqstat, [ \tmp, # EXTINTPEND ]
44 bl printk 54 ldr \irqnr, [ \tmp, # EXTINTMASK ]
45 b 20004f 55 bics \irqstat, \irqstat, \irqnr
46 56 beq 1001f
4720003: 57
48 .ascii "<7>irq: err - bad offset %d, intpnd=%08x, srcpnd=%08x\n" 58 mov \irqnr, #(IRQ_EINT4 - 4)
49 .byte 0 59
50 .align 4 60 @@ work out which irq (if any) we got
5120004: 613000:
52 mov r1, #1 62 movs \tmp, \irqstat, lsl#16
53 mov \tmp, #S3C24XX_VA_IRQ 63 addeq \irqnr, \irqnr, #16
54 ldmfd r13!, { r0 - r4 , r8-r12, r14 } 64 moveq \irqstat, \irqstat, lsr#16
55#endif 65 tst \irqstat, #0xff
56 66 addeq \irqnr, \irqnr, #8
57 @ try working out interrupt number for ourselves 67 moveq \irqstat, \irqstat, lsr#8
58 mov \irqnr, #0 68 tst \irqstat, #0xf
59 ldr \irqstat, [ \tmp, #0x10 ] @ INTPND 69 addeq \irqnr, \irqnr, #4
6010021: 70 moveq \irqstat, \irqstat, lsr#4
61 movs \irqstat, \irqstat, lsr#1 71 tst \irqstat, #0x3
62 bcs 30000b @ try and re-start the proccess 72 addeq \irqnr, \irqnr, #2
63 add \irqnr, \irqnr, #1 73 moveq \irqstat, \irqstat, lsr#2
64 cmp \irqnr, #32 74 tst \irqstat, #0x1
65 ble 10021b 75 addeq \irqnr, \irqnr, #1
66 76
67 @ found no interrupt, set Z flag and leave 77 @@ we have the value
68 movs \irqnr, #0 78 movs \irqnr, \irqnr
69 b 1001f 79
70
7120005:
7220002: @ exit
73 @ we base the s3c2410x interrupts at 16 and above to allow
74 @ isa peripherals to have their standard interrupts, also
75 @ ensure that Z flag is un-set on exit
76
77 @ note, we cannot be sure if we get IRQ_EINT0 (0) that
78 @ there is simply no interrupt pending, so in all other
79 @ cases we jump to say we have found something, otherwise
80 @ we check to see if the interrupt really is assrted
81 adds \irqnr, \irqnr, #IRQ_EINT0
82 teq \irqnr, #IRQ_EINT0
83 bne 1001f @ exit
84 ldr \irqstat, [ \tmp, #0x10 ] @ INTPND
85 teq \irqstat, #0
86 moveq \irqnr, #0
87 b 1001f
88
89 @ we get here from no main or external interrupts pending
901002:
91 add \tmp, \tmp, #S3C24XX_VA_GPIO - S3C24XX_VA_IRQ
92 ldr \irqstat, [ \tmp, # 0xa8 ] @ EXTINTPEND
93 ldr \irqnr, [ \tmp, # 0xa4 ] @ EXTINTMASK
94
95 bic \irqstat, \irqstat, \irqnr @ clear masked irqs
96
97 mov \irqnr, #IRQ_EINT4 @ start extint nos
98 mov \irqstat, \irqstat, lsr#4 @ ignore bottom 4 bits
9910021:
100 movs \irqstat, \irqstat, lsr#1
101 bcs 1004f
102 add \irqnr, \irqnr, #1
103 cmp \irqnr, #IRQ_EINT23
104 ble 10021b
105
106 @ found no interrupt, set Z flag and leave
107 movs \irqnr, #0
108
1091004: @ ensure Z flag clear in case our MOVS shifted out the last bit
110 teq \irqnr, #0
1111001: 801001:
112 @ exit irq routine 81 @@ exit here, Z flag unset if IRQ
113 .endm
114 82
83 .endm
115 84
116 /* currently don't need an disable_fiq macro */ 85 /* currently don't need an disable_fiq macro */
117 86
118 .macro disable_fiq 87 .macro disable_fiq
119 .endm 88 .endm
120
121
diff --git a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h
index e3e8541ee63b..63ca7412a462 100644
--- a/include/asm-arm/dma-mapping.h
+++ b/include/asm-arm/dma-mapping.h
@@ -47,7 +47,7 @@ static inline int dma_get_cache_alignment(void)
47 47
48static inline int dma_is_consistent(dma_addr_t handle) 48static inline int dma_is_consistent(dma_addr_t handle)
49{ 49{
50 return 0; 50 return !!arch_is_coherent();
51} 51}
52 52
53/* 53/*
@@ -145,7 +145,9 @@ static inline dma_addr_t
145dma_map_single(struct device *dev, void *cpu_addr, size_t size, 145dma_map_single(struct device *dev, void *cpu_addr, size_t size,
146 enum dma_data_direction dir) 146 enum dma_data_direction dir)
147{ 147{
148 consistent_sync(cpu_addr, size, dir); 148 if (!arch_is_coherent())
149 consistent_sync(cpu_addr, size, dir);
150
149 return virt_to_dma(dev, (unsigned long)cpu_addr); 151 return virt_to_dma(dev, (unsigned long)cpu_addr);
150} 152}
151#else 153#else
@@ -255,7 +257,9 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
255 257
256 sg->dma_address = page_to_dma(dev, sg->page) + sg->offset; 258 sg->dma_address = page_to_dma(dev, sg->page) + sg->offset;
257 virt = page_address(sg->page) + sg->offset; 259 virt = page_address(sg->page) + sg->offset;
258 consistent_sync(virt, sg->length, dir); 260
261 if (!arch_is_coherent())
262 consistent_sync(virt, sg->length, dir);
259 } 263 }
260 264
261 return nents; 265 return nents;
@@ -310,14 +314,16 @@ static inline void
310dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, size_t size, 314dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, size_t size,
311 enum dma_data_direction dir) 315 enum dma_data_direction dir)
312{ 316{
313 consistent_sync((void *)dma_to_virt(dev, handle), size, dir); 317 if (!arch_is_coherent())
318 consistent_sync((void *)dma_to_virt(dev, handle), size, dir);
314} 319}
315 320
316static inline void 321static inline void
317dma_sync_single_for_device(struct device *dev, dma_addr_t handle, size_t size, 322dma_sync_single_for_device(struct device *dev, dma_addr_t handle, size_t size,
318 enum dma_data_direction dir) 323 enum dma_data_direction dir)
319{ 324{
320 consistent_sync((void *)dma_to_virt(dev, handle), size, dir); 325 if (!arch_is_coherent())
326 consistent_sync((void *)dma_to_virt(dev, handle), size, dir);
321} 327}
322#else 328#else
323extern void dma_sync_single_for_cpu(struct device*, dma_addr_t, size_t, enum dma_data_direction); 329extern void dma_sync_single_for_cpu(struct device*, dma_addr_t, size_t, enum dma_data_direction);
@@ -347,7 +353,8 @@ dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
347 353
348 for (i = 0; i < nents; i++, sg++) { 354 for (i = 0; i < nents; i++, sg++) {
349 char *virt = page_address(sg->page) + sg->offset; 355 char *virt = page_address(sg->page) + sg->offset;
350 consistent_sync(virt, sg->length, dir); 356 if (!arch_is_coherent())
357 consistent_sync(virt, sg->length, dir);
351 } 358 }
352} 359}
353 360
@@ -359,7 +366,8 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
359 366
360 for (i = 0; i < nents; i++, sg++) { 367 for (i = 0; i < nents; i++, sg++) {
361 char *virt = page_address(sg->page) + sg->offset; 368 char *virt = page_address(sg->page) + sg->offset;
362 consistent_sync(virt, sg->length, dir); 369 if (!arch_is_coherent())
370 consistent_sync(virt, sg->length, dir);
363 } 371 }
364} 372}
365#else 373#else
diff --git a/include/asm-arm/memory.h b/include/asm-arm/memory.h
index afa5c3ea077c..2b3cf69b3ed9 100644
--- a/include/asm-arm/memory.h
+++ b/include/asm-arm/memory.h
@@ -234,6 +234,14 @@ static inline __deprecated void *bus_to_virt(unsigned long x)
234#define virt_to_dma(dev, addr) (__arch_virt_to_dma(dev, addr)) 234#define virt_to_dma(dev, addr) (__arch_virt_to_dma(dev, addr))
235#endif 235#endif
236 236
237/*
238 * Optional coherency support. Currently used only by selected
239 * Intel XSC3-based systems.
240 */
241#ifndef arch_is_coherent
242#define arch_is_coherent() 0
243#endif
244
237#endif 245#endif
238 246
239#include <asm-generic/memory_model.h> 247#include <asm-generic/memory_model.h>
diff --git a/include/asm-arm/pgtable-hwdef.h b/include/asm-arm/pgtable-hwdef.h
index 1d033495cc75..1bc1f997bda2 100644
--- a/include/asm-arm/pgtable-hwdef.h
+++ b/include/asm-arm/pgtable-hwdef.h
@@ -73,6 +73,7 @@
73#define PTE_EXT_AP_URW_SRW (PTE_EXT_AP1|PTE_EXT_AP0) 73#define PTE_EXT_AP_URW_SRW (PTE_EXT_AP1|PTE_EXT_AP0)
74#define PTE_EXT_TEX(x) ((x) << 6) /* v5 */ 74#define PTE_EXT_TEX(x) ((x) << 6) /* v5 */
75#define PTE_EXT_APX (1 << 9) /* v6 */ 75#define PTE_EXT_APX (1 << 9) /* v6 */
76#define PTE_EXT_COHERENT (1 << 9) /* XScale3 */
76#define PTE_EXT_SHARED (1 << 10) /* v6 */ 77#define PTE_EXT_SHARED (1 << 10) /* v6 */
77#define PTE_EXT_NG (1 << 11) /* v6 */ 78#define PTE_EXT_NG (1 << 11) /* v6 */
78 79
diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h
index e595ae24efe2..e85c08d78dda 100644
--- a/include/asm-arm/pgtable.h
+++ b/include/asm-arm/pgtable.h
@@ -156,6 +156,7 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
156#define L_PTE_WRITE (1 << 5) 156#define L_PTE_WRITE (1 << 5)
157#define L_PTE_EXEC (1 << 6) 157#define L_PTE_EXEC (1 << 6)
158#define L_PTE_DIRTY (1 << 7) 158#define L_PTE_DIRTY (1 << 7)
159#define L_PTE_COHERENT (1 << 9) /* I/O coherent (xsc3) */
159#define L_PTE_SHARED (1 << 10) /* shared between CPUs (v6) */ 160#define L_PTE_SHARED (1 << 10) /* shared between CPUs (v6) */
160#define L_PTE_ASID (1 << 11) /* non-global (use ASID, v6) */ 161#define L_PTE_ASID (1 << 11) /* non-global (use ASID, v6) */
161 162
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 4ed7e602d703..1e9ebaba07b7 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -864,7 +864,7 @@ struct super_block {
864 */ 864 */
865 struct mutex s_vfs_rename_mutex; /* Kludge */ 865 struct mutex s_vfs_rename_mutex; /* Kludge */
866 866
867 /* Granuality of c/m/atime in ns. 867 /* Granularity of c/m/atime in ns.
868 Cannot be worse than a second */ 868 Cannot be worse than a second */
869 u32 s_time_gran; 869 u32 s_time_gran;
870}; 870};
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index b20939287613..306acf1dc6d5 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -80,7 +80,7 @@ struct hrtimer_sleeper {
80 * @first: pointer to the timer node which expires first 80 * @first: pointer to the timer node which expires first
81 * @resolution: the resolution of the clock, in nanoseconds 81 * @resolution: the resolution of the clock, in nanoseconds
82 * @get_time: function to retrieve the current time of the clock 82 * @get_time: function to retrieve the current time of the clock
83 * @get_sofirq_time: function to retrieve the current time from the softirq 83 * @get_softirq_time: function to retrieve the current time from the softirq
84 * @curr_timer: the timer which is executing a callback right now 84 * @curr_timer: the timer which is executing a callback right now
85 * @softirq_time: the time when running the hrtimer queue in the softirq 85 * @softirq_time: the time when running the hrtimer queue in the softirq
86 */ 86 */
diff --git a/include/sound/core.h b/include/sound/core.h
index 7f32c12b4a0a..d1d043f6cb80 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -170,7 +170,7 @@ static inline void snd_power_change_state(struct snd_card *card, unsigned int st
170} 170}
171 171
172/* init.c */ 172/* init.c */
173int snd_power_wait(struct snd_card *card, unsigned int power_state, struct file *file); 173int snd_power_wait(struct snd_card *card, unsigned int power_state);
174 174
175#else /* ! CONFIG_PM */ 175#else /* ! CONFIG_PM */
176 176
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 15b885660bf0..66b1f08b42b9 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -369,6 +369,7 @@ struct snd_pcm_substream {
369 /* -- assigned files -- */ 369 /* -- assigned files -- */
370 struct snd_pcm_file *file; 370 struct snd_pcm_file *file;
371 struct file *ffile; 371 struct file *ffile;
372 void (*pcm_release)(struct snd_pcm_substream *);
372#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) 373#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
373 /* -- OSS things -- */ 374 /* -- OSS things -- */
374 struct snd_pcm_oss_substream oss; 375 struct snd_pcm_oss_substream oss;
@@ -381,13 +382,10 @@ struct snd_pcm_substream {
381 struct snd_info_entry *proc_prealloc_entry; 382 struct snd_info_entry *proc_prealloc_entry;
382 /* misc flags */ 383 /* misc flags */
383 unsigned int no_mmap_ctrl: 1; 384 unsigned int no_mmap_ctrl: 1;
385 unsigned int hw_opened: 1;
384}; 386};
385 387
386#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
387#define SUBSTREAM_BUSY(substream) ((substream)->file != NULL || ((substream)->oss.file != NULL))
388#else
389#define SUBSTREAM_BUSY(substream) ((substream)->file != NULL) 388#define SUBSTREAM_BUSY(substream) ((substream)->file != NULL)
390#endif
391 389
392 390
393struct snd_pcm_str { 391struct snd_pcm_str {
@@ -460,7 +458,6 @@ int snd_pcm_info_user(struct snd_pcm_substream *substream,
460 struct snd_pcm_info __user *info); 458 struct snd_pcm_info __user *info);
461int snd_pcm_status(struct snd_pcm_substream *substream, 459int snd_pcm_status(struct snd_pcm_substream *substream,
462 struct snd_pcm_status *status); 460 struct snd_pcm_status *status);
463int snd_pcm_prepare(struct snd_pcm_substream *substream);
464int snd_pcm_start(struct snd_pcm_substream *substream); 461int snd_pcm_start(struct snd_pcm_substream *substream);
465int snd_pcm_stop(struct snd_pcm_substream *substream, int status); 462int snd_pcm_stop(struct snd_pcm_substream *substream, int status);
466int snd_pcm_drain_done(struct snd_pcm_substream *substream); 463int snd_pcm_drain_done(struct snd_pcm_substream *substream);
@@ -468,11 +465,13 @@ int snd_pcm_drain_done(struct snd_pcm_substream *substream);
468int snd_pcm_suspend(struct snd_pcm_substream *substream); 465int snd_pcm_suspend(struct snd_pcm_substream *substream);
469int snd_pcm_suspend_all(struct snd_pcm *pcm); 466int snd_pcm_suspend_all(struct snd_pcm *pcm);
470#endif 467#endif
471int snd_pcm_kernel_playback_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg);
472int snd_pcm_kernel_capture_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg);
473int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg); 468int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg);
474int snd_pcm_open_substream(struct snd_pcm *pcm, int stream, struct snd_pcm_substream **rsubstream); 469int snd_pcm_open_substream(struct snd_pcm *pcm, int stream, struct file *file,
470 struct snd_pcm_substream **rsubstream);
475void snd_pcm_release_substream(struct snd_pcm_substream *substream); 471void snd_pcm_release_substream(struct snd_pcm_substream *substream);
472int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, struct file *file,
473 struct snd_pcm_substream **rsubstream);
474void snd_pcm_detach_substream(struct snd_pcm_substream *substream);
476void snd_pcm_vma_notify_data(void *client, void *data); 475void snd_pcm_vma_notify_data(void *client, void *data);
477int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file, struct vm_area_struct *area); 476int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file, struct vm_area_struct *area);
478 477
diff --git a/include/sound/pcm_oss.h b/include/sound/pcm_oss.h
index bff0778e1969..39df2baca18a 100644
--- a/include/sound/pcm_oss.h
+++ b/include/sound/pcm_oss.h
@@ -69,8 +69,7 @@ struct snd_pcm_oss_file {
69 69
70struct snd_pcm_oss_substream { 70struct snd_pcm_oss_substream {
71 unsigned oss: 1; /* oss mode */ 71 unsigned oss: 1; /* oss mode */
72 struct snd_pcm_oss_setup *setup; /* active setup */ 72 struct snd_pcm_oss_setup setup; /* active setup */
73 struct snd_pcm_oss_file *file;
74}; 73};
75 74
76struct snd_pcm_oss_stream { 75struct snd_pcm_oss_stream {
diff --git a/ipc/shm.c b/ipc/shm.c
index f806a2e314e0..6b0c9af5bbf7 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -91,8 +91,8 @@ static inline int shm_addid(struct shmid_kernel *shp)
91static inline void shm_inc (int id) { 91static inline void shm_inc (int id) {
92 struct shmid_kernel *shp; 92 struct shmid_kernel *shp;
93 93
94 if(!(shp = shm_lock(id))) 94 shp = shm_lock(id);
95 BUG(); 95 BUG_ON(!shp);
96 shp->shm_atim = get_seconds(); 96 shp->shm_atim = get_seconds();
97 shp->shm_lprid = current->tgid; 97 shp->shm_lprid = current->tgid;
98 shp->shm_nattch++; 98 shp->shm_nattch++;
@@ -142,8 +142,8 @@ static void shm_close (struct vm_area_struct *shmd)
142 142
143 mutex_lock(&shm_ids.mutex); 143 mutex_lock(&shm_ids.mutex);
144 /* remove from the list of attaches of the shm segment */ 144 /* remove from the list of attaches of the shm segment */
145 if(!(shp = shm_lock(id))) 145 shp = shm_lock(id);
146 BUG(); 146 BUG_ON(!shp);
147 shp->shm_lprid = current->tgid; 147 shp->shm_lprid = current->tgid;
148 shp->shm_dtim = get_seconds(); 148 shp->shm_dtim = get_seconds();
149 shp->shm_nattch--; 149 shp->shm_nattch--;
@@ -283,8 +283,7 @@ asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
283 err = -EEXIST; 283 err = -EEXIST;
284 } else { 284 } else {
285 shp = shm_lock(id); 285 shp = shm_lock(id);
286 if(shp==NULL) 286 BUG_ON(shp==NULL);
287 BUG();
288 if (shp->shm_segsz < size) 287 if (shp->shm_segsz < size)
289 err = -EINVAL; 288 err = -EINVAL;
290 else if (ipcperms(&shp->shm_perm, shmflg)) 289 else if (ipcperms(&shp->shm_perm, shmflg))
@@ -774,8 +773,8 @@ invalid:
774 up_write(&current->mm->mmap_sem); 773 up_write(&current->mm->mmap_sem);
775 774
776 mutex_lock(&shm_ids.mutex); 775 mutex_lock(&shm_ids.mutex);
777 if(!(shp = shm_lock(shmid))) 776 shp = shm_lock(shmid);
778 BUG(); 777 BUG_ON(!shp);
779 shp->shm_nattch--; 778 shp->shm_nattch--;
780 if(shp->shm_nattch == 0 && 779 if(shp->shm_nattch == 0 &&
781 shp->shm_perm.mode & SHM_DEST) 780 shp->shm_perm.mode & SHM_DEST)
diff --git a/ipc/util.c b/ipc/util.c
index 23151ef32590..5e785a29e1e6 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -266,8 +266,7 @@ struct kern_ipc_perm* ipc_rmid(struct ipc_ids* ids, int id)
266{ 266{
267 struct kern_ipc_perm* p; 267 struct kern_ipc_perm* p;
268 int lid = id % SEQ_MULTIPLIER; 268 int lid = id % SEQ_MULTIPLIER;
269 if(lid >= ids->entries->size) 269 BUG_ON(lid >= ids->entries->size);
270 BUG();
271 270
272 /* 271 /*
273 * do not need a rcu_dereference()() here to force ordering 272 * do not need a rcu_dereference()() here to force ordering
@@ -275,8 +274,7 @@ struct kern_ipc_perm* ipc_rmid(struct ipc_ids* ids, int id)
275 */ 274 */
276 p = ids->entries->p[lid]; 275 p = ids->entries->p[lid];
277 ids->entries->p[lid] = NULL; 276 ids->entries->p[lid] = NULL;
278 if(p==NULL) 277 BUG_ON(p==NULL);
279 BUG();
280 ids->in_use--; 278 ids->in_use--;
281 279
282 if (lid == ids->max_id) { 280 if (lid == ids->max_id) {
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 9fd8d4f03595..ce0dfb8f4a4e 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -41,7 +41,7 @@ config SOFTWARE_SUSPEND
41 depends on PM && SWAP && (X86 && (!SMP || SUSPEND_SMP)) || ((FRV || PPC32) && !SMP) 41 depends on PM && SWAP && (X86 && (!SMP || SUSPEND_SMP)) || ((FRV || PPC32) && !SMP)
42 ---help--- 42 ---help---
43 Enable the possibility of suspending the machine. 43 Enable the possibility of suspending the machine.
44 It doesn't need APM. 44 It doesn't need ACPI or APM.
45 You may suspend your machine by 'swsusp' or 'shutdown -z <time>' 45 You may suspend your machine by 'swsusp' or 'shutdown -z <time>'
46 (patch for sysvinit needed). 46 (patch for sysvinit needed).
47 47
diff --git a/kernel/printk.c b/kernel/printk.c
index 8cc19431e74b..c056f3324432 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -360,8 +360,7 @@ static void call_console_drivers(unsigned long start, unsigned long end)
360 unsigned long cur_index, start_print; 360 unsigned long cur_index, start_print;
361 static int msg_level = -1; 361 static int msg_level = -1;
362 362
363 if (((long)(start - end)) > 0) 363 BUG_ON(((long)(start - end)) > 0);
364 BUG();
365 364
366 cur_index = start; 365 cur_index = start;
367 start_print = start; 366 start_print = start;
@@ -708,8 +707,7 @@ int __init add_preferred_console(char *name, int idx, char *options)
708 */ 707 */
709void acquire_console_sem(void) 708void acquire_console_sem(void)
710{ 709{
711 if (in_interrupt()) 710 BUG_ON(in_interrupt());
712 BUG();
713 down(&console_sem); 711 down(&console_sem);
714 console_locked = 1; 712 console_locked = 1;
715 console_may_schedule = 1; 713 console_may_schedule = 1;
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 86a7f6c60cb2..0eeb7e66722c 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -30,8 +30,7 @@
30 */ 30 */
31void __ptrace_link(task_t *child, task_t *new_parent) 31void __ptrace_link(task_t *child, task_t *new_parent)
32{ 32{
33 if (!list_empty(&child->ptrace_list)) 33 BUG_ON(!list_empty(&child->ptrace_list));
34 BUG();
35 if (child->parent == new_parent) 34 if (child->parent == new_parent)
36 return; 35 return;
37 list_add(&child->ptrace_list, &child->parent->ptrace_children); 36 list_add(&child->ptrace_list, &child->parent->ptrace_children);
diff --git a/kernel/signal.c b/kernel/signal.c
index 92025b108791..5ccaac505e8d 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -769,8 +769,7 @@ specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
769{ 769{
770 int ret = 0; 770 int ret = 0;
771 771
772 if (!irqs_disabled()) 772 BUG_ON(!irqs_disabled());
773 BUG();
774 assert_spin_locked(&t->sighand->siglock); 773 assert_spin_locked(&t->sighand->siglock);
775 774
776 /* Short-circuit ignored signals. */ 775 /* Short-circuit ignored signals. */
@@ -1384,8 +1383,7 @@ send_group_sigqueue(int sig, struct sigqueue *q, struct task_struct *p)
1384 * the overrun count. Other uses should not try to 1383 * the overrun count. Other uses should not try to
1385 * send the signal multiple times. 1384 * send the signal multiple times.
1386 */ 1385 */
1387 if (q->info.si_code != SI_TIMER) 1386 BUG_ON(q->info.si_code != SI_TIMER);
1388 BUG();
1389 q->info.si_overrun++; 1387 q->info.si_overrun++;
1390 goto out; 1388 goto out;
1391 } 1389 }
diff --git a/kernel/time.c b/kernel/time.c
index ff8e7019c4c4..b00ddc71cedb 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -410,7 +410,7 @@ EXPORT_SYMBOL(current_kernel_time);
410 * current_fs_time - Return FS time 410 * current_fs_time - Return FS time
411 * @sb: Superblock. 411 * @sb: Superblock.
412 * 412 *
413 * Return the current time truncated to the time granuality supported by 413 * Return the current time truncated to the time granularity supported by
414 * the fs. 414 * the fs.
415 */ 415 */
416struct timespec current_fs_time(struct super_block *sb) 416struct timespec current_fs_time(struct super_block *sb)
@@ -421,11 +421,11 @@ struct timespec current_fs_time(struct super_block *sb)
421EXPORT_SYMBOL(current_fs_time); 421EXPORT_SYMBOL(current_fs_time);
422 422
423/** 423/**
424 * timespec_trunc - Truncate timespec to a granuality 424 * timespec_trunc - Truncate timespec to a granularity
425 * @t: Timespec 425 * @t: Timespec
426 * @gran: Granuality in ns. 426 * @gran: Granularity in ns.
427 * 427 *
428 * Truncate a timespec to a granuality. gran must be smaller than a second. 428 * Truncate a timespec to a granularity. gran must be smaller than a second.
429 * Always rounds down. 429 * Always rounds down.
430 * 430 *
431 * This function should be only used for timestamps returned by 431 * This function should be only used for timestamps returned by
diff --git a/kernel/timer.c b/kernel/timer.c
index 6b812c04737b..c3a874f1393c 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -1479,8 +1479,7 @@ register_time_interpolator(struct time_interpolator *ti)
1479 unsigned long flags; 1479 unsigned long flags;
1480 1480
1481 /* Sanity check */ 1481 /* Sanity check */
1482 if (ti->frequency == 0 || ti->mask == 0) 1482 BUG_ON(ti->frequency == 0 || ti->mask == 0);
1483 BUG();
1484 1483
1485 ti->nsec_per_cyc = ((u64)NSEC_PER_SEC << ti->shift) / ti->frequency; 1484 ti->nsec_per_cyc = ((u64)NSEC_PER_SEC << ti->shift) / ti->frequency;
1486 spin_lock(&time_interpolator_lock); 1485 spin_lock(&time_interpolator_lock);
diff --git a/mm/highmem.c b/mm/highmem.c
index 55885f64af40..9b274fdf9d08 100644
--- a/mm/highmem.c
+++ b/mm/highmem.c
@@ -74,8 +74,7 @@ static void flush_all_zero_pkmaps(void)
74 pkmap_count[i] = 0; 74 pkmap_count[i] = 0;
75 75
76 /* sanity check */ 76 /* sanity check */
77 if (pte_none(pkmap_page_table[i])) 77 BUG_ON(pte_none(pkmap_page_table[i]));
78 BUG();
79 78
80 /* 79 /*
81 * Don't need an atomic fetch-and-clear op here; 80 * Don't need an atomic fetch-and-clear op here;
@@ -158,8 +157,7 @@ void fastcall *kmap_high(struct page *page)
158 if (!vaddr) 157 if (!vaddr)
159 vaddr = map_new_virtual(page); 158 vaddr = map_new_virtual(page);
160 pkmap_count[PKMAP_NR(vaddr)]++; 159 pkmap_count[PKMAP_NR(vaddr)]++;
161 if (pkmap_count[PKMAP_NR(vaddr)] < 2) 160 BUG_ON(pkmap_count[PKMAP_NR(vaddr)] < 2);
162 BUG();
163 spin_unlock(&kmap_lock); 161 spin_unlock(&kmap_lock);
164 return (void*) vaddr; 162 return (void*) vaddr;
165} 163}
@@ -174,8 +172,7 @@ void fastcall kunmap_high(struct page *page)
174 172
175 spin_lock(&kmap_lock); 173 spin_lock(&kmap_lock);
176 vaddr = (unsigned long)page_address(page); 174 vaddr = (unsigned long)page_address(page);
177 if (!vaddr) 175 BUG_ON(!vaddr);
178 BUG();
179 nr = PKMAP_NR(vaddr); 176 nr = PKMAP_NR(vaddr);
180 177
181 /* 178 /*
@@ -220,8 +217,7 @@ static __init int init_emergency_pool(void)
220 return 0; 217 return 0;
221 218
222 page_pool = mempool_create_page_pool(POOL_SIZE, 0); 219 page_pool = mempool_create_page_pool(POOL_SIZE, 0);
223 if (!page_pool) 220 BUG_ON(!page_pool);
224 BUG();
225 printk("highmem bounce pool size: %d pages\n", POOL_SIZE); 221 printk("highmem bounce pool size: %d pages\n", POOL_SIZE);
226 222
227 return 0; 223 return 0;
@@ -264,8 +260,7 @@ int init_emergency_isa_pool(void)
264 260
265 isa_page_pool = mempool_create(ISA_POOL_SIZE, mempool_alloc_pages_isa, 261 isa_page_pool = mempool_create(ISA_POOL_SIZE, mempool_alloc_pages_isa,
266 mempool_free_pages, (void *) 0); 262 mempool_free_pages, (void *) 0);
267 if (!isa_page_pool) 263 BUG_ON(!isa_page_pool);
268 BUG();
269 264
270 printk("isa bounce pool size: %d pages\n", ISA_POOL_SIZE); 265 printk("isa bounce pool size: %d pages\n", ISA_POOL_SIZE);
271 return 0; 266 return 0;
diff --git a/mm/mmap.c b/mm/mmap.c
index 4f5b5709136a..e780d19aa214 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -294,8 +294,7 @@ void validate_mm(struct mm_struct *mm)
294 i = browse_rb(&mm->mm_rb); 294 i = browse_rb(&mm->mm_rb);
295 if (i != mm->map_count) 295 if (i != mm->map_count)
296 printk("map_count %d rb %d\n", mm->map_count, i), bug = 1; 296 printk("map_count %d rb %d\n", mm->map_count, i), bug = 1;
297 if (bug) 297 BUG_ON(bug);
298 BUG();
299} 298}
300#else 299#else
301#define validate_mm(mm) do { } while (0) 300#define validate_mm(mm) do { } while (0)
@@ -432,8 +431,7 @@ __insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
432 struct rb_node ** rb_link, * rb_parent; 431 struct rb_node ** rb_link, * rb_parent;
433 432
434 __vma = find_vma_prepare(mm, vma->vm_start,&prev, &rb_link, &rb_parent); 433 __vma = find_vma_prepare(mm, vma->vm_start,&prev, &rb_link, &rb_parent);
435 if (__vma && __vma->vm_start < vma->vm_end) 434 BUG_ON(__vma && __vma->vm_start < vma->vm_end);
436 BUG();
437 __vma_link(mm, vma, prev, rb_link, rb_parent); 435 __vma_link(mm, vma, prev, rb_link, rb_parent);
438 mm->map_count++; 436 mm->map_count++;
439} 437}
@@ -813,8 +811,7 @@ try_prev:
813 * (e.g. stash info in next's anon_vma_node when assigning 811 * (e.g. stash info in next's anon_vma_node when assigning
814 * an anon_vma, or when trying vma_merge). Another time. 812 * an anon_vma, or when trying vma_merge). Another time.
815 */ 813 */
816 if (find_vma_prev(vma->vm_mm, vma->vm_start, &near) != vma) 814 BUG_ON(find_vma_prev(vma->vm_mm, vma->vm_start, &near) != vma);
817 BUG();
818 if (!near) 815 if (!near)
819 goto none; 816 goto none;
820 817
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 893d7677579e..6dcce3a4bbdc 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -258,7 +258,7 @@ static void balance_dirty_pages(struct address_space *mapping)
258/** 258/**
259 * balance_dirty_pages_ratelimited_nr - balance dirty memory state 259 * balance_dirty_pages_ratelimited_nr - balance dirty memory state
260 * @mapping: address_space which was dirtied 260 * @mapping: address_space which was dirtied
261 * @nr_pages: number of pages which the caller has just dirtied 261 * @nr_pages_dirtied: number of pages which the caller has just dirtied
262 * 262 *
263 * Processes which are dirtying memory should call in here once for each page 263 * Processes which are dirtying memory should call in here once for each page
264 * which was newly dirtied. The function will periodically check the system's 264 * which was newly dirtied. The function will periodically check the system's
diff --git a/mm/slab.c b/mm/slab.c
index 4cbf8bb13557..f055c1420216 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1297,8 +1297,7 @@ void __init kmem_cache_init(void)
1297 if (cache_cache.num) 1297 if (cache_cache.num)
1298 break; 1298 break;
1299 } 1299 }
1300 if (!cache_cache.num) 1300 BUG_ON(!cache_cache.num);
1301 BUG();
1302 cache_cache.gfporder = order; 1301 cache_cache.gfporder = order;
1303 cache_cache.colour = left_over / cache_cache.colour_off; 1302 cache_cache.colour = left_over / cache_cache.colour_off;
1304 cache_cache.slab_size = ALIGN(cache_cache.num * sizeof(kmem_bufctl_t) + 1303 cache_cache.slab_size = ALIGN(cache_cache.num * sizeof(kmem_bufctl_t) +
@@ -1974,8 +1973,7 @@ kmem_cache_create (const char *name, size_t size, size_t align,
1974 * Always checks flags, a caller might be expecting debug support which 1973 * Always checks flags, a caller might be expecting debug support which
1975 * isn't available. 1974 * isn't available.
1976 */ 1975 */
1977 if (flags & ~CREATE_MASK) 1976 BUG_ON(flags & ~CREATE_MASK);
1978 BUG();
1979 1977
1980 /* 1978 /*
1981 * Check that size is in terms of words. This is needed to avoid 1979 * Check that size is in terms of words. This is needed to avoid
@@ -2206,8 +2204,7 @@ static int __node_shrink(struct kmem_cache *cachep, int node)
2206 2204
2207 slabp = list_entry(l3->slabs_free.prev, struct slab, list); 2205 slabp = list_entry(l3->slabs_free.prev, struct slab, list);
2208#if DEBUG 2206#if DEBUG
2209 if (slabp->inuse) 2207 BUG_ON(slabp->inuse);
2210 BUG();
2211#endif 2208#endif
2212 list_del(&slabp->list); 2209 list_del(&slabp->list);
2213 2210
@@ -2248,8 +2245,7 @@ static int __cache_shrink(struct kmem_cache *cachep)
2248 */ 2245 */
2249int kmem_cache_shrink(struct kmem_cache *cachep) 2246int kmem_cache_shrink(struct kmem_cache *cachep)
2250{ 2247{
2251 if (!cachep || in_interrupt()) 2248 BUG_ON(!cachep || in_interrupt());
2252 BUG();
2253 2249
2254 return __cache_shrink(cachep); 2250 return __cache_shrink(cachep);
2255} 2251}
@@ -2277,8 +2273,7 @@ int kmem_cache_destroy(struct kmem_cache *cachep)
2277 int i; 2273 int i;
2278 struct kmem_list3 *l3; 2274 struct kmem_list3 *l3;
2279 2275
2280 if (!cachep || in_interrupt()) 2276 BUG_ON(!cachep || in_interrupt());
2281 BUG();
2282 2277
2283 /* Don't let CPUs to come and go */ 2278 /* Don't let CPUs to come and go */
2284 lock_cpu_hotplug(); 2279 lock_cpu_hotplug();
@@ -2477,8 +2472,7 @@ static int cache_grow(struct kmem_cache *cachep, gfp_t flags, int nodeid)
2477 * Be lazy and only check for valid flags here, keeping it out of the 2472 * Be lazy and only check for valid flags here, keeping it out of the
2478 * critical path in kmem_cache_alloc(). 2473 * critical path in kmem_cache_alloc().
2479 */ 2474 */
2480 if (flags & ~(SLAB_DMA | SLAB_LEVEL_MASK | SLAB_NO_GROW)) 2475 BUG_ON(flags & ~(SLAB_DMA | SLAB_LEVEL_MASK | SLAB_NO_GROW));
2481 BUG();
2482 if (flags & SLAB_NO_GROW) 2476 if (flags & SLAB_NO_GROW)
2483 return 0; 2477 return 0;
2484 2478
diff --git a/mm/swap_state.c b/mm/swap_state.c
index d7af296833fc..e0e1583f32c2 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -148,8 +148,7 @@ int add_to_swap(struct page * page, gfp_t gfp_mask)
148 swp_entry_t entry; 148 swp_entry_t entry;
149 int err; 149 int err;
150 150
151 if (!PageLocked(page)) 151 BUG_ON(!PageLocked(page));
152 BUG();
153 152
154 for (;;) { 153 for (;;) {
155 entry = get_swap_page(); 154 entry = get_swap_page();
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 729eb3eec75f..c0504f1e34eb 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -321,8 +321,7 @@ void __vunmap(void *addr, int deallocate_pages)
321 int i; 321 int i;
322 322
323 for (i = 0; i < area->nr_pages; i++) { 323 for (i = 0; i < area->nr_pages; i++) {
324 if (unlikely(!area->pages[i])) 324 BUG_ON(!area->pages[i]);
325 BUG();
326 __free_page(area->pages[i]); 325 __free_page(area->pages[i]);
327 } 326 }
328 327
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index 9dd121bb5638..8efc1b12f3a8 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -92,8 +92,9 @@ config SND_SEQUENCER_OSS
92 92
93 Many programs still use the OSS API, so say Y. 93 Many programs still use the OSS API, so say Y.
94 94
95 To compile this driver as a module, choose M here: the module 95 If you choose M in "Sequencer support" (SND_SEQUENCER),
96 will be called snd-seq-oss. 96 this will be compiled as a module. The module will be called
97 snd-seq-oss.
97 98
98config SND_RTCTIMER 99config SND_RTCTIMER
99 tristate "RTC Timer support" 100 tristate "RTC Timer support"
diff --git a/sound/core/control.c b/sound/core/control.c
index 574745314e70..22565c9b9603 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -664,7 +664,7 @@ static int snd_ctl_elem_info_user(struct snd_ctl_file *ctl,
664 if (copy_from_user(&info, _info, sizeof(info))) 664 if (copy_from_user(&info, _info, sizeof(info)))
665 return -EFAULT; 665 return -EFAULT;
666 snd_power_lock(ctl->card); 666 snd_power_lock(ctl->card);
667 result = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0, NULL); 667 result = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0);
668 if (result >= 0) 668 if (result >= 0)
669 result = snd_ctl_elem_info(ctl, &info); 669 result = snd_ctl_elem_info(ctl, &info);
670 snd_power_unlock(ctl->card); 670 snd_power_unlock(ctl->card);
@@ -718,7 +718,7 @@ static int snd_ctl_elem_read_user(struct snd_card *card,
718 return -EFAULT; 718 return -EFAULT;
719 } 719 }
720 snd_power_lock(card); 720 snd_power_lock(card);
721 result = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL); 721 result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
722 if (result >= 0) 722 if (result >= 0)
723 result = snd_ctl_elem_read(card, control); 723 result = snd_ctl_elem_read(card, control);
724 snd_power_unlock(card); 724 snd_power_unlock(card);
@@ -783,7 +783,7 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
783 } 783 }
784 card = file->card; 784 card = file->card;
785 snd_power_lock(card); 785 snd_power_lock(card);
786 result = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL); 786 result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
787 if (result >= 0) 787 if (result >= 0)
788 result = snd_ctl_elem_write(card, file, control); 788 result = snd_ctl_elem_write(card, file, control);
789 snd_power_unlock(card); 789 snd_power_unlock(card);
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
index 84fef5084e17..3c0161bb5ba4 100644
--- a/sound/core/control_compat.c
+++ b/sound/core/control_compat.c
@@ -109,7 +109,7 @@ static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl,
109 goto error; 109 goto error;
110 110
111 snd_power_lock(ctl->card); 111 snd_power_lock(ctl->card);
112 err = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0, NULL); 112 err = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0);
113 if (err >= 0) 113 if (err >= 0)
114 err = snd_ctl_elem_info(ctl, data); 114 err = snd_ctl_elem_info(ctl, data);
115 snd_power_unlock(ctl->card); 115 snd_power_unlock(ctl->card);
@@ -294,7 +294,7 @@ static int snd_ctl_elem_read_user_compat(struct snd_card *card,
294 goto error; 294 goto error;
295 295
296 snd_power_lock(card); 296 snd_power_lock(card);
297 err = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL); 297 err = snd_power_wait(card, SNDRV_CTL_POWER_D0);
298 if (err >= 0) 298 if (err >= 0)
299 err = snd_ctl_elem_read(card, data); 299 err = snd_ctl_elem_read(card, data);
300 snd_power_unlock(card); 300 snd_power_unlock(card);
@@ -320,7 +320,7 @@ static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
320 goto error; 320 goto error;
321 321
322 snd_power_lock(card); 322 snd_power_lock(card);
323 err = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL); 323 err = snd_power_wait(card, SNDRV_CTL_POWER_D0);
324 if (err >= 0) 324 if (err >= 0)
325 err = snd_ctl_elem_write(card, file, data); 325 err = snd_ctl_elem_write(card, file, data);
326 snd_power_unlock(card); 326 snd_power_unlock(card);
diff --git a/sound/core/init.c b/sound/core/init.c
index 5bb8a8b23d51..39ed2e5bb0af 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -722,13 +722,12 @@ int snd_card_file_remove(struct snd_card *card, struct file *file)
722 * snd_power_wait - wait until the power-state is changed. 722 * snd_power_wait - wait until the power-state is changed.
723 * @card: soundcard structure 723 * @card: soundcard structure
724 * @power_state: expected power state 724 * @power_state: expected power state
725 * @file: file structure for the O_NONBLOCK check (optional)
726 * 725 *
727 * Waits until the power-state is changed. 726 * Waits until the power-state is changed.
728 * 727 *
729 * Note: the power lock must be active before call. 728 * Note: the power lock must be active before call.
730 */ 729 */
731int snd_power_wait(struct snd_card *card, unsigned int power_state, struct file *file) 730int snd_power_wait(struct snd_card *card, unsigned int power_state)
732{ 731{
733 wait_queue_t wait; 732 wait_queue_t wait;
734 int result = 0; 733 int result = 0;
@@ -745,12 +744,6 @@ int snd_power_wait(struct snd_card *card, unsigned int power_state, struct file
745 } 744 }
746 if (snd_power_get_state(card) == power_state) 745 if (snd_power_get_state(card) == power_state)
747 break; 746 break;
748#if 0 /* block all devices */
749 if (file && (file->f_flags & O_NONBLOCK)) {
750 result = -EAGAIN;
751 break;
752 }
753#endif
754 set_current_state(TASK_UNINTERRUPTIBLE); 747 set_current_state(TASK_UNINTERRUPTIBLE);
755 snd_power_unlock(card); 748 snd_power_unlock(card);
756 schedule_timeout(30 * HZ); 749 schedule_timeout(30 * HZ);
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index f8302b703a30..91114c7aeff5 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -208,9 +208,8 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream,
208 oss_buffer_size = runtime->oss.mmap_bytes; 208 oss_buffer_size = runtime->oss.mmap_bytes;
209 } 209 }
210 210
211 if (substream->oss.setup && 211 if (substream->oss.setup.period_size > 16)
212 substream->oss.setup->period_size > 16) 212 oss_period_size = substream->oss.setup.period_size;
213 oss_period_size = substream->oss.setup->period_size;
214 else if (runtime->oss.fragshift) { 213 else if (runtime->oss.fragshift) {
215 oss_period_size = 1 << runtime->oss.fragshift; 214 oss_period_size = 1 << runtime->oss.fragshift;
216 if (oss_period_size > oss_buffer_size / 2) 215 if (oss_period_size > oss_buffer_size / 2)
@@ -252,10 +251,8 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream,
252 251
253 oss_periods = oss_buffer_size / oss_period_size; 252 oss_periods = oss_buffer_size / oss_period_size;
254 253
255 if (substream->oss.setup) { 254 if (substream->oss.setup.periods > 1)
256 if (substream->oss.setup->periods > 1) 255 oss_periods = substream->oss.setup.periods;
257 oss_periods = substream->oss.setup->periods;
258 }
259 256
260 s = snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_PERIODS, NULL); 257 s = snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_PERIODS, NULL);
261 if (runtime->oss.maxfrags && s > runtime->oss.maxfrags) 258 if (runtime->oss.maxfrags && s > runtime->oss.maxfrags)
@@ -341,12 +338,10 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
341 goto failure; 338 goto failure;
342 } 339 }
343 340
344 if (atomic_read(&runtime->mmap_count)) { 341 if (atomic_read(&runtime->mmap_count))
345 direct = 1; 342 direct = 1;
346 } else { 343 else
347 struct snd_pcm_oss_setup *setup = substream->oss.setup; 344 direct = substream->oss.setup.direct;
348 direct = (setup != NULL && setup->direct);
349 }
350 345
351 _snd_pcm_hw_params_any(sparams); 346 _snd_pcm_hw_params_any(sparams);
352 _snd_pcm_hw_param_setinteger(sparams, SNDRV_PCM_HW_PARAM_PERIODS); 347 _snd_pcm_hw_param_setinteger(sparams, SNDRV_PCM_HW_PARAM_PERIODS);
@@ -482,7 +477,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
482 1 : runtime->period_size; 477 1 : runtime->period_size;
483 sw_params->xfer_align = 1; 478 sw_params->xfer_align = 1;
484 if (atomic_read(&runtime->mmap_count) || 479 if (atomic_read(&runtime->mmap_count) ||
485 (substream->oss.setup && substream->oss.setup->nosilence)) { 480 substream->oss.setup.nosilence) {
486 sw_params->silence_threshold = 0; 481 sw_params->silence_threshold = 0;
487 sw_params->silence_size = 0; 482 sw_params->silence_size = 0;
488 } else { 483 } else {
@@ -843,7 +838,7 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha
843 buf += tmp; 838 buf += tmp;
844 bytes -= tmp; 839 bytes -= tmp;
845 xfer += tmp; 840 xfer += tmp;
846 if ((substream->oss.setup != NULL && substream->oss.setup->partialfrag) || 841 if (substream->oss.setup.partialfrag ||
847 runtime->oss.buffer_used == runtime->oss.period_bytes) { 842 runtime->oss.buffer_used == runtime->oss.period_bytes) {
848 tmp = snd_pcm_oss_write2(substream, runtime->oss.buffer + runtime->oss.period_ptr, 843 tmp = snd_pcm_oss_write2(substream, runtime->oss.buffer + runtime->oss.period_ptr,
849 runtime->oss.buffer_used - runtime->oss.period_ptr, 1); 844 runtime->oss.buffer_used - runtime->oss.period_ptr, 1);
@@ -959,12 +954,12 @@ static int snd_pcm_oss_reset(struct snd_pcm_oss_file *pcm_oss_file)
959 954
960 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; 955 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
961 if (substream != NULL) { 956 if (substream != NULL) {
962 snd_pcm_kernel_playback_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); 957 snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
963 substream->runtime->oss.prepare = 1; 958 substream->runtime->oss.prepare = 1;
964 } 959 }
965 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE]; 960 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
966 if (substream != NULL) { 961 if (substream != NULL) {
967 snd_pcm_kernel_capture_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); 962 snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
968 substream->runtime->oss.prepare = 1; 963 substream->runtime->oss.prepare = 1;
969 } 964 }
970 return 0; 965 return 0;
@@ -979,7 +974,7 @@ static int snd_pcm_oss_post(struct snd_pcm_oss_file *pcm_oss_file)
979 if (substream != NULL) { 974 if (substream != NULL) {
980 if ((err = snd_pcm_oss_make_ready(substream)) < 0) 975 if ((err = snd_pcm_oss_make_ready(substream)) < 0)
981 return err; 976 return err;
982 snd_pcm_kernel_playback_ioctl(substream, SNDRV_PCM_IOCTL_START, NULL); 977 snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_START, NULL);
983 } 978 }
984 /* note: all errors from the start action are ignored */ 979 /* note: all errors from the start action are ignored */
985 /* OSS apps do not know, how to handle them */ 980 /* OSS apps do not know, how to handle them */
@@ -1108,7 +1103,7 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
1108 __direct: 1103 __direct:
1109 saved_f_flags = substream->ffile->f_flags; 1104 saved_f_flags = substream->ffile->f_flags;
1110 substream->ffile->f_flags &= ~O_NONBLOCK; 1105 substream->ffile->f_flags &= ~O_NONBLOCK;
1111 err = snd_pcm_kernel_playback_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL); 1106 err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL);
1112 substream->ffile->f_flags = saved_f_flags; 1107 substream->ffile->f_flags = saved_f_flags;
1113 if (err < 0) 1108 if (err < 0)
1114 return err; 1109 return err;
@@ -1120,7 +1115,7 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
1120 if ((err = snd_pcm_oss_make_ready(substream)) < 0) 1115 if ((err = snd_pcm_oss_make_ready(substream)) < 0)
1121 return err; 1116 return err;
1122 runtime = substream->runtime; 1117 runtime = substream->runtime;
1123 err = snd_pcm_kernel_capture_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); 1118 err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
1124 if (err < 0) 1119 if (err < 0)
1125 return err; 1120 return err;
1126 runtime->oss.buffer_used = 0; 1121 runtime->oss.buffer_used = 0;
@@ -1214,12 +1209,10 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
1214 1209
1215 if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0) 1210 if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
1216 return err; 1211 return err;
1217 if (atomic_read(&substream->runtime->mmap_count)) { 1212 if (atomic_read(&substream->runtime->mmap_count))
1218 direct = 1; 1213 direct = 1;
1219 } else { 1214 else
1220 struct snd_pcm_oss_setup *setup = substream->oss.setup; 1215 direct = substream->oss.setup.direct;
1221 direct = (setup != NULL && setup->direct);
1222 }
1223 if (!direct) 1216 if (!direct)
1224 return AFMT_MU_LAW | AFMT_U8 | 1217 return AFMT_MU_LAW | AFMT_U8 |
1225 AFMT_S16_LE | AFMT_S16_BE | 1218 AFMT_S16_LE | AFMT_S16_BE |
@@ -1437,7 +1430,7 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr
1437 cmd = SNDRV_PCM_IOCTL_DROP; 1430 cmd = SNDRV_PCM_IOCTL_DROP;
1438 runtime->oss.prepare = 1; 1431 runtime->oss.prepare = 1;
1439 } 1432 }
1440 err = snd_pcm_kernel_playback_ioctl(psubstream, cmd, NULL); 1433 err = snd_pcm_kernel_ioctl(psubstream, cmd, NULL);
1441 if (err < 0) 1434 if (err < 0)
1442 return err; 1435 return err;
1443 } 1436 }
@@ -1458,7 +1451,7 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr
1458 cmd = SNDRV_PCM_IOCTL_DROP; 1451 cmd = SNDRV_PCM_IOCTL_DROP;
1459 runtime->oss.prepare = 1; 1452 runtime->oss.prepare = 1;
1460 } 1453 }
1461 err = snd_pcm_kernel_capture_ioctl(csubstream, cmd, NULL); 1454 err = snd_pcm_kernel_ioctl(csubstream, cmd, NULL);
1462 if (err < 0) 1455 if (err < 0)
1463 return err; 1456 return err;
1464 } 1457 }
@@ -1495,7 +1488,7 @@ static int snd_pcm_oss_get_odelay(struct snd_pcm_oss_file *pcm_oss_file)
1495 runtime = substream->runtime; 1488 runtime = substream->runtime;
1496 if (runtime->oss.params || runtime->oss.prepare) 1489 if (runtime->oss.params || runtime->oss.prepare)
1497 return 0; 1490 return 0;
1498 err = snd_pcm_kernel_playback_ioctl(substream, SNDRV_PCM_IOCTL_DELAY, &delay); 1491 err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DELAY, &delay);
1499 if (err == -EPIPE) 1492 if (err == -EPIPE)
1500 delay = 0; /* hack for broken OSS applications */ 1493 delay = 0; /* hack for broken OSS applications */
1501 else if (err < 0) 1494 else if (err < 0)
@@ -1555,8 +1548,7 @@ static int snd_pcm_oss_get_ptr(struct snd_pcm_oss_file *pcm_oss_file, int stream
1555 } else { 1548 } else {
1556 delay = snd_pcm_oss_bytes(substream, delay); 1549 delay = snd_pcm_oss_bytes(substream, delay);
1557 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 1550 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
1558 struct snd_pcm_oss_setup *setup = substream->oss.setup; 1551 if (substream->oss.setup.buggyptr)
1559 if (setup && setup->buggyptr)
1560 info.blocks = (runtime->oss.buffer_bytes - delay - fixup) / runtime->oss.period_bytes; 1552 info.blocks = (runtime->oss.buffer_bytes - delay - fixup) / runtime->oss.period_bytes;
1561 else 1553 else
1562 info.blocks = (delay + fixup) / runtime->oss.period_bytes; 1554 info.blocks = (delay + fixup) / runtime->oss.period_bytes;
@@ -1638,37 +1630,46 @@ static int snd_pcm_oss_get_mapbuf(struct snd_pcm_oss_file *pcm_oss_file, int str
1638 return -EINVAL; 1630 return -EINVAL;
1639} 1631}
1640 1632
1641static struct snd_pcm_oss_setup *snd_pcm_oss_look_for_setup(struct snd_pcm *pcm, int stream, const char *task_name) 1633static const char *strip_task_path(const char *path)
1642{ 1634{
1643 const char *ptr, *ptrl; 1635 const char *ptr, *ptrl = NULL;
1644 struct snd_pcm_oss_setup *setup; 1636 for (ptr = path; *ptr; ptr++) {
1645
1646 mutex_lock(&pcm->streams[stream].oss.setup_mutex);
1647 for (setup = pcm->streams[stream].oss.setup_list; setup; setup = setup->next) {
1648 if (!strcmp(setup->task_name, task_name)) {
1649 mutex_unlock(&pcm->streams[stream].oss.setup_mutex);
1650 return setup;
1651 }
1652 }
1653 ptr = ptrl = task_name;
1654 while (*ptr) {
1655 if (*ptr == '/') 1637 if (*ptr == '/')
1656 ptrl = ptr + 1; 1638 ptrl = ptr + 1;
1657 ptr++;
1658 } 1639 }
1659 if (ptrl == task_name) { 1640 return ptrl;
1660 goto __not_found; 1641}
1661 return NULL; 1642
1662 } 1643static void snd_pcm_oss_look_for_setup(struct snd_pcm *pcm, int stream,
1663 for (setup = pcm->streams[stream].oss.setup_list; setup; setup = setup->next) { 1644 const char *task_name,
1664 if (!strcmp(setup->task_name, ptrl)) { 1645 struct snd_pcm_oss_setup *rsetup)
1665 mutex_unlock(&pcm->streams[stream].oss.setup_mutex); 1646{
1666 return setup; 1647 struct snd_pcm_oss_setup *setup;
1648
1649 mutex_lock(&pcm->streams[stream].oss.setup_mutex);
1650 do {
1651 for (setup = pcm->streams[stream].oss.setup_list; setup;
1652 setup = setup->next) {
1653 if (!strcmp(setup->task_name, task_name))
1654 goto out;
1667 } 1655 }
1668 } 1656 } while ((task_name = strip_task_path(task_name)) != NULL);
1669 __not_found: 1657 out:
1658 if (setup)
1659 *rsetup = *setup;
1670 mutex_unlock(&pcm->streams[stream].oss.setup_mutex); 1660 mutex_unlock(&pcm->streams[stream].oss.setup_mutex);
1671 return NULL; 1661}
1662
1663static void snd_pcm_oss_release_substream(struct snd_pcm_substream *substream)
1664{
1665 struct snd_pcm_runtime *runtime;
1666 runtime = substream->runtime;
1667 vfree(runtime->oss.buffer);
1668 runtime->oss.buffer = NULL;
1669#ifdef CONFIG_SND_PCM_OSS_PLUGINS
1670 snd_pcm_oss_plugin_clear(substream);
1671#endif
1672 substream->oss.oss = 0;
1672} 1673}
1673 1674
1674static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream, 1675static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream,
@@ -1678,7 +1679,11 @@ static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream,
1678 struct snd_pcm_runtime *runtime; 1679 struct snd_pcm_runtime *runtime;
1679 1680
1680 substream->oss.oss = 1; 1681 substream->oss.oss = 1;
1681 substream->oss.setup = setup; 1682 substream->oss.setup = *setup;
1683 if (setup->nonblock)
1684 substream->ffile->f_flags |= O_NONBLOCK;
1685 else
1686 substream->ffile->f_flags &= ~O_NONBLOCK;
1682 runtime = substream->runtime; 1687 runtime = substream->runtime;
1683 runtime->oss.params = 1; 1688 runtime->oss.params = 1;
1684 runtime->oss.trigger = 1; 1689 runtime->oss.trigger = 1;
@@ -1697,18 +1702,7 @@ static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream,
1697 runtime->oss.fragshift = 0; 1702 runtime->oss.fragshift = 0;
1698 runtime->oss.maxfrags = 0; 1703 runtime->oss.maxfrags = 0;
1699 runtime->oss.subdivision = 0; 1704 runtime->oss.subdivision = 0;
1700} 1705 substream->pcm_release = snd_pcm_oss_release_substream;
1701
1702static void snd_pcm_oss_release_substream(struct snd_pcm_substream *substream)
1703{
1704 struct snd_pcm_runtime *runtime;
1705 runtime = substream->runtime;
1706 vfree(runtime->oss.buffer);
1707#ifdef CONFIG_SND_PCM_OSS_PLUGINS
1708 snd_pcm_oss_plugin_clear(substream);
1709#endif
1710 substream->oss.file = NULL;
1711 substream->oss.oss = 0;
1712} 1706}
1713 1707
1714static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file) 1708static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file)
@@ -1717,23 +1711,8 @@ static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file)
1717 snd_assert(pcm_oss_file != NULL, return -ENXIO); 1711 snd_assert(pcm_oss_file != NULL, return -ENXIO);
1718 for (cidx = 0; cidx < 2; ++cidx) { 1712 for (cidx = 0; cidx < 2; ++cidx) {
1719 struct snd_pcm_substream *substream = pcm_oss_file->streams[cidx]; 1713 struct snd_pcm_substream *substream = pcm_oss_file->streams[cidx];
1720 struct snd_pcm_runtime *runtime; 1714 if (substream)
1721 if (substream == NULL) 1715 snd_pcm_release_substream(substream);
1722 continue;
1723 runtime = substream->runtime;
1724
1725 snd_pcm_stream_lock_irq(substream);
1726 if (snd_pcm_running(substream))
1727 snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
1728 snd_pcm_stream_unlock_irq(substream);
1729 if (substream->ffile != NULL) {
1730 if (substream->ops->hw_free != NULL)
1731 substream->ops->hw_free(substream);
1732 substream->ops->close(substream);
1733 substream->ffile = NULL;
1734 }
1735 snd_pcm_oss_release_substream(substream);
1736 snd_pcm_release_substream(substream);
1737 } 1716 }
1738 kfree(pcm_oss_file); 1717 kfree(pcm_oss_file);
1739 return 0; 1718 return 0;
@@ -1743,12 +1722,11 @@ static int snd_pcm_oss_open_file(struct file *file,
1743 struct snd_pcm *pcm, 1722 struct snd_pcm *pcm,
1744 struct snd_pcm_oss_file **rpcm_oss_file, 1723 struct snd_pcm_oss_file **rpcm_oss_file,
1745 int minor, 1724 int minor,
1746 struct snd_pcm_oss_setup *psetup, 1725 struct snd_pcm_oss_setup *setup)
1747 struct snd_pcm_oss_setup *csetup)
1748{ 1726{
1749 int err = 0; 1727 int idx, err;
1750 struct snd_pcm_oss_file *pcm_oss_file; 1728 struct snd_pcm_oss_file *pcm_oss_file;
1751 struct snd_pcm_substream *psubstream = NULL, *csubstream = NULL; 1729 struct snd_pcm_substream *substream;
1752 unsigned int f_mode = file->f_mode; 1730 unsigned int f_mode = file->f_mode;
1753 1731
1754 snd_assert(rpcm_oss_file != NULL, return -EINVAL); 1732 snd_assert(rpcm_oss_file != NULL, return -EINVAL);
@@ -1761,73 +1739,31 @@ static int snd_pcm_oss_open_file(struct file *file,
1761 if ((f_mode & (FMODE_WRITE|FMODE_READ)) == (FMODE_WRITE|FMODE_READ) && 1739 if ((f_mode & (FMODE_WRITE|FMODE_READ)) == (FMODE_WRITE|FMODE_READ) &&
1762 (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX)) 1740 (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX))
1763 f_mode = FMODE_WRITE; 1741 f_mode = FMODE_WRITE;
1764 if ((f_mode & FMODE_WRITE) && !(psetup && psetup->disable)) { 1742
1765 if ((err = snd_pcm_open_substream(pcm, SNDRV_PCM_STREAM_PLAYBACK, 1743 for (idx = 0; idx < 2; idx++) {
1766 &psubstream)) < 0) { 1744 if (setup[idx].disable)
1745 continue;
1746 if (idx == SNDRV_PCM_STREAM_PLAYBACK) {
1747 if (! (f_mode & FMODE_WRITE))
1748 continue;
1749 } else {
1750 if (! (f_mode & FMODE_READ))
1751 continue;
1752 }
1753 err = snd_pcm_open_substream(pcm, idx, file, &substream);
1754 if (err < 0) {
1767 snd_pcm_oss_release_file(pcm_oss_file); 1755 snd_pcm_oss_release_file(pcm_oss_file);
1768 return err; 1756 return err;
1769 } 1757 }
1770 pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK] = psubstream; 1758
1771 } 1759 pcm_oss_file->streams[idx] = substream;
1772 if ((f_mode & FMODE_READ) && !(csetup && csetup->disable)) { 1760 snd_pcm_oss_init_substream(substream, &setup[idx], minor);
1773 if ((err = snd_pcm_open_substream(pcm, SNDRV_PCM_STREAM_CAPTURE,
1774 &csubstream)) < 0) {
1775 if (!(f_mode & FMODE_WRITE) || err != -ENODEV) {
1776 snd_pcm_oss_release_file(pcm_oss_file);
1777 return err;
1778 } else {
1779 csubstream = NULL;
1780 }
1781 }
1782 pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE] = csubstream;
1783 } 1761 }
1784 1762
1785 if (psubstream == NULL && csubstream == NULL) { 1763 if (! pcm_oss_file->streams[0] && pcm_oss_file->streams[1]) {
1786 snd_pcm_oss_release_file(pcm_oss_file); 1764 snd_pcm_oss_release_file(pcm_oss_file);
1787 return -EINVAL; 1765 return -EINVAL;
1788 } 1766 }
1789 if (psubstream != NULL) {
1790 psubstream->oss.file = pcm_oss_file;
1791 err = snd_pcm_hw_constraints_init(psubstream);
1792 if (err < 0) {
1793 snd_printd("snd_pcm_hw_constraint_init failed\n");
1794 snd_pcm_oss_release_file(pcm_oss_file);
1795 return err;
1796 }
1797 if ((err = psubstream->ops->open(psubstream)) < 0) {
1798 snd_pcm_oss_release_file(pcm_oss_file);
1799 return err;
1800 }
1801 psubstream->ffile = file;
1802 err = snd_pcm_hw_constraints_complete(psubstream);
1803 if (err < 0) {
1804 snd_printd("snd_pcm_hw_constraint_complete failed\n");
1805 snd_pcm_oss_release_file(pcm_oss_file);
1806 return err;
1807 }
1808 snd_pcm_oss_init_substream(psubstream, psetup, minor);
1809 }
1810 if (csubstream != NULL) {
1811 csubstream->oss.file = pcm_oss_file;
1812 err = snd_pcm_hw_constraints_init(csubstream);
1813 if (err < 0) {
1814 snd_printd("snd_pcm_hw_constraint_init failed\n");
1815 snd_pcm_oss_release_file(pcm_oss_file);
1816 return err;
1817 }
1818 if ((err = csubstream->ops->open(csubstream)) < 0) {
1819 snd_pcm_oss_release_file(pcm_oss_file);
1820 return err;
1821 }
1822 csubstream->ffile = file;
1823 err = snd_pcm_hw_constraints_complete(csubstream);
1824 if (err < 0) {
1825 snd_printd("snd_pcm_hw_constraint_complete failed\n");
1826 snd_pcm_oss_release_file(pcm_oss_file);
1827 return err;
1828 }
1829 snd_pcm_oss_init_substream(csubstream, csetup, minor);
1830 }
1831 1767
1832 file->private_data = pcm_oss_file; 1768 file->private_data = pcm_oss_file;
1833 *rpcm_oss_file = pcm_oss_file; 1769 *rpcm_oss_file = pcm_oss_file;
@@ -1852,7 +1788,7 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
1852 char task_name[32]; 1788 char task_name[32];
1853 struct snd_pcm *pcm; 1789 struct snd_pcm *pcm;
1854 struct snd_pcm_oss_file *pcm_oss_file; 1790 struct snd_pcm_oss_file *pcm_oss_file;
1855 struct snd_pcm_oss_setup *psetup = NULL, *csetup = NULL; 1791 struct snd_pcm_oss_setup setup[2];
1856 int nonblock; 1792 int nonblock;
1857 wait_queue_t wait; 1793 wait_queue_t wait;
1858 1794
@@ -1873,23 +1809,15 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
1873 err = -EFAULT; 1809 err = -EFAULT;
1874 goto __error; 1810 goto __error;
1875 } 1811 }
1812 memset(setup, 0, sizeof(*setup));
1876 if (file->f_mode & FMODE_WRITE) 1813 if (file->f_mode & FMODE_WRITE)
1877 psetup = snd_pcm_oss_look_for_setup(pcm, SNDRV_PCM_STREAM_PLAYBACK, task_name); 1814 snd_pcm_oss_look_for_setup(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1815 task_name, &setup[0]);
1878 if (file->f_mode & FMODE_READ) 1816 if (file->f_mode & FMODE_READ)
1879 csetup = snd_pcm_oss_look_for_setup(pcm, SNDRV_PCM_STREAM_CAPTURE, task_name); 1817 snd_pcm_oss_look_for_setup(pcm, SNDRV_PCM_STREAM_CAPTURE,
1818 task_name, &setup[1]);
1880 1819
1881 nonblock = !!(file->f_flags & O_NONBLOCK); 1820 nonblock = !!(file->f_flags & O_NONBLOCK);
1882 if (psetup && !psetup->disable) {
1883 if (psetup->nonblock)
1884 nonblock = 1;
1885 else if (psetup->block)
1886 nonblock = 0;
1887 } else if (csetup && !csetup->disable) {
1888 if (csetup->nonblock)
1889 nonblock = 1;
1890 else if (csetup->block)
1891 nonblock = 0;
1892 }
1893 if (!nonblock) 1821 if (!nonblock)
1894 nonblock = nonblock_open; 1822 nonblock = nonblock_open;
1895 1823
@@ -1898,7 +1826,7 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
1898 mutex_lock(&pcm->open_mutex); 1826 mutex_lock(&pcm->open_mutex);
1899 while (1) { 1827 while (1) {
1900 err = snd_pcm_oss_open_file(file, pcm, &pcm_oss_file, 1828 err = snd_pcm_oss_open_file(file, pcm, &pcm_oss_file,
1901 iminor(inode), psetup, csetup); 1829 iminor(inode), setup);
1902 if (err >= 0) 1830 if (err >= 0)
1903 break; 1831 break;
1904 if (err == -EAGAIN) { 1832 if (err == -EAGAIN) {
@@ -2312,13 +2240,8 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry,
2312 2240
2313static void snd_pcm_oss_proc_free_setup_list(struct snd_pcm_str * pstr) 2241static void snd_pcm_oss_proc_free_setup_list(struct snd_pcm_str * pstr)
2314{ 2242{
2315 unsigned int idx;
2316 struct snd_pcm_substream *substream;
2317 struct snd_pcm_oss_setup *setup, *setupn; 2243 struct snd_pcm_oss_setup *setup, *setupn;
2318 2244
2319 for (idx = 0, substream = pstr->substream;
2320 idx < pstr->substream_count; idx++, substream = substream->next)
2321 substream->oss.setup = NULL;
2322 for (setup = pstr->oss.setup_list, pstr->oss.setup_list = NULL; 2245 for (setup = pstr->oss.setup_list, pstr->oss.setup_list = NULL;
2323 setup; setup = setupn) { 2246 setup; setup = setupn) {
2324 setupn = setup->next; 2247 setupn = setup->next;
@@ -2379,21 +2302,28 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
2379 } 2302 }
2380 } while (*str); 2303 } while (*str);
2381 if (setup == NULL) { 2304 if (setup == NULL) {
2382 setup = kmalloc(sizeof(struct snd_pcm_oss_setup), GFP_KERNEL); 2305 setup = kmalloc(sizeof(*setup), GFP_KERNEL);
2383 if (setup) { 2306 if (! setup) {
2384 if (pstr->oss.setup_list == NULL) { 2307 buffer->error = -ENOMEM;
2385 pstr->oss.setup_list = setup; 2308 mutex_lock(&pstr->oss.setup_mutex);
2386 } else { 2309 return;
2387 for (setup1 = pstr->oss.setup_list; setup1->next; setup1 = setup1->next); 2310 }
2388 setup1->next = setup; 2311 if (pstr->oss.setup_list == NULL)
2389 } 2312 pstr->oss.setup_list = setup;
2390 template.task_name = kstrdup(task_name, GFP_KERNEL); 2313 else {
2391 } else { 2314 for (setup1 = pstr->oss.setup_list;
2315 setup1->next; setup1 = setup1->next);
2316 setup1->next = setup;
2317 }
2318 template.task_name = kstrdup(task_name, GFP_KERNEL);
2319 if (! template.task_name) {
2320 kfree(setup);
2392 buffer->error = -ENOMEM; 2321 buffer->error = -ENOMEM;
2322 mutex_lock(&pstr->oss.setup_mutex);
2323 return;
2393 } 2324 }
2394 } 2325 }
2395 if (setup) 2326 *setup = template;
2396 *setup = template;
2397 mutex_unlock(&pstr->oss.setup_mutex); 2327 mutex_unlock(&pstr->oss.setup_mutex);
2398 } 2328 }
2399} 2329}
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 3da6a38c2d0f..5d7eb123b999 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -777,8 +777,9 @@ static void snd_pcm_tick_timer_func(unsigned long data)
777 snd_pcm_tick_elapsed(substream); 777 snd_pcm_tick_elapsed(substream);
778} 778}
779 779
780int snd_pcm_open_substream(struct snd_pcm *pcm, int stream, 780int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
781 struct snd_pcm_substream **rsubstream) 781 struct file *file,
782 struct snd_pcm_substream **rsubstream)
782{ 783{
783 struct snd_pcm_str * pstr; 784 struct snd_pcm_str * pstr;
784 struct snd_pcm_substream *substream; 785 struct snd_pcm_substream *substream;
@@ -793,7 +794,7 @@ int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
793 *rsubstream = NULL; 794 *rsubstream = NULL;
794 snd_assert(pcm != NULL, return -ENXIO); 795 snd_assert(pcm != NULL, return -ENXIO);
795 pstr = &pcm->streams[stream]; 796 pstr = &pcm->streams[stream];
796 if (pstr->substream == NULL) 797 if (pstr->substream == NULL || pstr->substream_count == 0)
797 return -ENODEV; 798 return -ENODEV;
798 799
799 card = pcm->card; 800 card = pcm->card;
@@ -807,8 +808,6 @@ int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
807 } 808 }
808 up_read(&card->controls_rwsem); 809 up_read(&card->controls_rwsem);
809 810
810 if (pstr->substream_count == 0)
811 return -ENODEV;
812 switch (stream) { 811 switch (stream) {
813 case SNDRV_PCM_STREAM_PLAYBACK: 812 case SNDRV_PCM_STREAM_PLAYBACK:
814 if (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX) { 813 if (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX) {
@@ -874,12 +873,13 @@ int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
874 873
875 substream->runtime = runtime; 874 substream->runtime = runtime;
876 substream->private_data = pcm->private_data; 875 substream->private_data = pcm->private_data;
876 substream->ffile = file;
877 pstr->substream_opened++; 877 pstr->substream_opened++;
878 *rsubstream = substream; 878 *rsubstream = substream;
879 return 0; 879 return 0;
880} 880}
881 881
882void snd_pcm_release_substream(struct snd_pcm_substream *substream) 882void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
883{ 883{
884 struct snd_pcm_runtime *runtime; 884 struct snd_pcm_runtime *runtime;
885 substream->file = NULL; 885 substream->file = NULL;
@@ -1111,8 +1111,6 @@ EXPORT_SYMBOL(snd_pcm_link_rwlock);
1111EXPORT_SYMBOL(snd_pcm_suspend); 1111EXPORT_SYMBOL(snd_pcm_suspend);
1112EXPORT_SYMBOL(snd_pcm_suspend_all); 1112EXPORT_SYMBOL(snd_pcm_suspend_all);
1113#endif 1113#endif
1114EXPORT_SYMBOL(snd_pcm_kernel_playback_ioctl);
1115EXPORT_SYMBOL(snd_pcm_kernel_capture_ioctl);
1116EXPORT_SYMBOL(snd_pcm_kernel_ioctl); 1114EXPORT_SYMBOL(snd_pcm_kernel_ioctl);
1117EXPORT_SYMBOL(snd_pcm_mmap_data); 1115EXPORT_SYMBOL(snd_pcm_mmap_data);
1118#if SNDRV_PCM_INFO_MMAP_IOMEM 1116#if SNDRV_PCM_INFO_MMAP_IOMEM
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index eeba2f060955..230a940d00bd 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -2299,19 +2299,7 @@ snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const v
2299 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 2299 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2300 return -EBADFD; 2300 return -EBADFD;
2301 2301
2302 snd_assert(substream->ffile != NULL, return -ENXIO);
2303 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 2302 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK);
2304#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
2305 if (substream->oss.oss) {
2306 struct snd_pcm_oss_setup *setup = substream->oss.setup;
2307 if (setup != NULL) {
2308 if (setup->nonblock)
2309 nonblock = 1;
2310 else if (setup->block)
2311 nonblock = 0;
2312 }
2313 }
2314#endif
2315 2303
2316 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED && 2304 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED &&
2317 runtime->channels > 1) 2305 runtime->channels > 1)
@@ -2374,19 +2362,7 @@ snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream,
2374 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 2362 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2375 return -EBADFD; 2363 return -EBADFD;
2376 2364
2377 snd_assert(substream->ffile != NULL, return -ENXIO);
2378 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 2365 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK);
2379#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
2380 if (substream->oss.oss) {
2381 struct snd_pcm_oss_setup *setup = substream->oss.setup;
2382 if (setup != NULL) {
2383 if (setup->nonblock)
2384 nonblock = 1;
2385 else if (setup->block)
2386 nonblock = 0;
2387 }
2388 }
2389#endif
2390 2366
2391 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) 2367 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
2392 return -EINVAL; 2368 return -EINVAL;
@@ -2596,19 +2572,7 @@ snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream, void __u
2596 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 2572 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2597 return -EBADFD; 2573 return -EBADFD;
2598 2574
2599 snd_assert(substream->ffile != NULL, return -ENXIO);
2600 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 2575 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK);
2601#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
2602 if (substream->oss.oss) {
2603 struct snd_pcm_oss_setup *setup = substream->oss.setup;
2604 if (setup != NULL) {
2605 if (setup->nonblock)
2606 nonblock = 1;
2607 else if (setup->block)
2608 nonblock = 0;
2609 }
2610 }
2611#endif
2612 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED) 2576 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED)
2613 return -EINVAL; 2577 return -EINVAL;
2614 return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer); 2578 return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer);
@@ -2665,20 +2629,7 @@ snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream,
2665 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 2629 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2666 return -EBADFD; 2630 return -EBADFD;
2667 2631
2668 snd_assert(substream->ffile != NULL, return -ENXIO);
2669 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 2632 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK);
2670#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
2671 if (substream->oss.oss) {
2672 struct snd_pcm_oss_setup *setup = substream->oss.setup;
2673 if (setup != NULL) {
2674 if (setup->nonblock)
2675 nonblock = 1;
2676 else if (setup->block)
2677 nonblock = 0;
2678 }
2679 }
2680#endif
2681
2682 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) 2633 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
2683 return -EINVAL; 2634 return -EINVAL;
2684 return snd_pcm_lib_read1(substream, (unsigned long)bufs, frames, nonblock, snd_pcm_lib_readv_transfer); 2635 return snd_pcm_lib_read1(substream, (unsigned long)bufs, frames, nonblock, snd_pcm_lib_readv_transfer);
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 01f150f0990e..964e4c47a7f1 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1170,7 +1170,7 @@ static int snd_pcm_resume(struct snd_pcm_substream *substream)
1170 int res; 1170 int res;
1171 1171
1172 snd_power_lock(card); 1172 snd_power_lock(card);
1173 if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile)) >= 0) 1173 if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0)
1174 res = snd_pcm_action_lock_irq(&snd_pcm_action_resume, substream, 0); 1174 res = snd_pcm_action_lock_irq(&snd_pcm_action_resume, substream, 0);
1175 snd_power_unlock(card); 1175 snd_power_unlock(card);
1176 return res; 1176 return res;
@@ -1198,7 +1198,7 @@ static int snd_pcm_xrun(struct snd_pcm_substream *substream)
1198 1198
1199 snd_power_lock(card); 1199 snd_power_lock(card);
1200 if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { 1200 if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
1201 result = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile); 1201 result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
1202 if (result < 0) 1202 if (result < 0)
1203 goto _unlock; 1203 goto _unlock;
1204 } 1204 }
@@ -1313,13 +1313,13 @@ static struct action_ops snd_pcm_action_prepare = {
1313 * 1313 *
1314 * Prepare the PCM substream to be triggerable. 1314 * Prepare the PCM substream to be triggerable.
1315 */ 1315 */
1316int snd_pcm_prepare(struct snd_pcm_substream *substream) 1316static int snd_pcm_prepare(struct snd_pcm_substream *substream)
1317{ 1317{
1318 int res; 1318 int res;
1319 struct snd_card *card = substream->pcm->card; 1319 struct snd_card *card = substream->pcm->card;
1320 1320
1321 snd_power_lock(card); 1321 snd_power_lock(card);
1322 if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile)) >= 0) 1322 if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0)
1323 res = snd_pcm_action_nonatomic(&snd_pcm_action_prepare, substream, 0); 1323 res = snd_pcm_action_nonatomic(&snd_pcm_action_prepare, substream, 0);
1324 snd_power_unlock(card); 1324 snd_power_unlock(card);
1325 return res; 1325 return res;
@@ -1410,7 +1410,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream)
1410 1410
1411 snd_power_lock(card); 1411 snd_power_lock(card);
1412 if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { 1412 if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
1413 result = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile); 1413 result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
1414 if (result < 0) { 1414 if (result < 0) {
1415 snd_power_unlock(card); 1415 snd_power_unlock(card);
1416 return result; 1416 return result;
@@ -1533,7 +1533,7 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream)
1533 1533
1534 snd_power_lock(card); 1534 snd_power_lock(card);
1535 if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { 1535 if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
1536 result = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile); 1536 result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
1537 if (result < 0) 1537 if (result < 0)
1538 goto _unlock; 1538 goto _unlock;
1539 } 1539 }
@@ -1995,28 +1995,63 @@ static void snd_pcm_remove_file(struct snd_pcm_str *str,
1995 } 1995 }
1996} 1996}
1997 1997
1998static int snd_pcm_release_file(struct snd_pcm_file * pcm_file) 1998static void pcm_release_private(struct snd_pcm_substream *substream)
1999{ 1999{
2000 struct snd_pcm_substream *substream; 2000 struct snd_pcm_file *pcm_file = substream->file;
2001 struct snd_pcm_runtime *runtime;
2002 struct snd_pcm_str * str;
2003 2001
2004 snd_assert(pcm_file != NULL, return -ENXIO);
2005 substream = pcm_file->substream;
2006 snd_assert(substream != NULL, return -ENXIO);
2007 runtime = substream->runtime;
2008 str = substream->pstr;
2009 snd_pcm_unlink(substream); 2002 snd_pcm_unlink(substream);
2010 if (substream->ffile != NULL) { 2003 snd_pcm_remove_file(substream->pstr, pcm_file);
2004 kfree(pcm_file);
2005}
2006
2007void snd_pcm_release_substream(struct snd_pcm_substream *substream)
2008{
2009 snd_pcm_drop(substream);
2010 if (substream->pcm_release)
2011 substream->pcm_release(substream);
2012 if (substream->hw_opened) {
2011 if (substream->ops->hw_free != NULL) 2013 if (substream->ops->hw_free != NULL)
2012 substream->ops->hw_free(substream); 2014 substream->ops->hw_free(substream);
2013 substream->ops->close(substream); 2015 substream->ops->close(substream);
2014 substream->ffile = NULL; 2016 substream->hw_opened = 0;
2015 } 2017 }
2016 snd_pcm_remove_file(str, pcm_file); 2018 snd_pcm_detach_substream(substream);
2017 snd_pcm_release_substream(substream); 2019}
2018 kfree(pcm_file); 2020
2021int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
2022 struct file *file,
2023 struct snd_pcm_substream **rsubstream)
2024{
2025 struct snd_pcm_substream *substream;
2026 int err;
2027
2028 err = snd_pcm_attach_substream(pcm, stream, file, &substream);
2029 if (err < 0)
2030 return err;
2031 substream->no_mmap_ctrl = 0;
2032 err = snd_pcm_hw_constraints_init(substream);
2033 if (err < 0) {
2034 snd_printd("snd_pcm_hw_constraints_init failed\n");
2035 goto error;
2036 }
2037
2038 if ((err = substream->ops->open(substream)) < 0)
2039 goto error;
2040
2041 substream->hw_opened = 1;
2042
2043 err = snd_pcm_hw_constraints_complete(substream);
2044 if (err < 0) {
2045 snd_printd("snd_pcm_hw_constraints_complete failed\n");
2046 goto error;
2047 }
2048
2049 *rsubstream = substream;
2019 return 0; 2050 return 0;
2051
2052 error:
2053 snd_pcm_release_substream(substream);
2054 return err;
2020} 2055}
2021 2056
2022static int snd_pcm_open_file(struct file *file, 2057static int snd_pcm_open_file(struct file *file,
@@ -2024,52 +2059,29 @@ static int snd_pcm_open_file(struct file *file,
2024 int stream, 2059 int stream,
2025 struct snd_pcm_file **rpcm_file) 2060 struct snd_pcm_file **rpcm_file)
2026{ 2061{
2027 int err = 0;
2028 struct snd_pcm_file *pcm_file; 2062 struct snd_pcm_file *pcm_file;
2029 struct snd_pcm_substream *substream; 2063 struct snd_pcm_substream *substream;
2030 struct snd_pcm_str *str; 2064 struct snd_pcm_str *str;
2065 int err;
2031 2066
2032 snd_assert(rpcm_file != NULL, return -EINVAL); 2067 snd_assert(rpcm_file != NULL, return -EINVAL);
2033 *rpcm_file = NULL; 2068 *rpcm_file = NULL;
2034 2069
2070 err = snd_pcm_open_substream(pcm, stream, file, &substream);
2071 if (err < 0)
2072 return err;
2073
2035 pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL); 2074 pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL);
2036 if (pcm_file == NULL) { 2075 if (pcm_file == NULL) {
2076 snd_pcm_release_substream(substream);
2037 return -ENOMEM; 2077 return -ENOMEM;
2038 } 2078 }
2039
2040 if ((err = snd_pcm_open_substream(pcm, stream, &substream)) < 0) {
2041 kfree(pcm_file);
2042 return err;
2043 }
2044
2045 str = substream->pstr; 2079 str = substream->pstr;
2046 substream->file = pcm_file; 2080 substream->file = pcm_file;
2047 substream->no_mmap_ctrl = 0; 2081 substream->pcm_release = pcm_release_private;
2048
2049 pcm_file->substream = substream; 2082 pcm_file->substream = substream;
2050
2051 snd_pcm_add_file(str, pcm_file); 2083 snd_pcm_add_file(str, pcm_file);
2052 2084
2053 err = snd_pcm_hw_constraints_init(substream);
2054 if (err < 0) {
2055 snd_printd("snd_pcm_hw_constraints_init failed\n");
2056 snd_pcm_release_file(pcm_file);
2057 return err;
2058 }
2059
2060 if ((err = substream->ops->open(substream)) < 0) {
2061 snd_pcm_release_file(pcm_file);
2062 return err;
2063 }
2064 substream->ffile = file;
2065
2066 err = snd_pcm_hw_constraints_complete(substream);
2067 if (err < 0) {
2068 snd_printd("snd_pcm_hw_constraints_complete failed\n");
2069 snd_pcm_release_file(pcm_file);
2070 return err;
2071 }
2072
2073 file->private_data = pcm_file; 2085 file->private_data = pcm_file;
2074 *rpcm_file = pcm_file; 2086 *rpcm_file = pcm_file;
2075 return 0; 2087 return 0;
@@ -2158,10 +2170,9 @@ static int snd_pcm_release(struct inode *inode, struct file *file)
2158 snd_assert(substream != NULL, return -ENXIO); 2170 snd_assert(substream != NULL, return -ENXIO);
2159 snd_assert(!atomic_read(&substream->runtime->mmap_count), ); 2171 snd_assert(!atomic_read(&substream->runtime->mmap_count), );
2160 pcm = substream->pcm; 2172 pcm = substream->pcm;
2161 snd_pcm_drop(substream);
2162 fasync_helper(-1, file, 0, &substream->runtime->fasync); 2173 fasync_helper(-1, file, 0, &substream->runtime->fasync);
2163 mutex_lock(&pcm->open_mutex); 2174 mutex_lock(&pcm->open_mutex);
2164 snd_pcm_release_file(pcm_file); 2175 snd_pcm_release_substream(substream);
2165 mutex_unlock(&pcm->open_mutex); 2176 mutex_unlock(&pcm->open_mutex);
2166 wake_up(&pcm->open_wait); 2177 wake_up(&pcm->open_wait);
2167 module_put(pcm->card->module); 2178 module_put(pcm->card->module);
@@ -2480,11 +2491,6 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
2480 return 0; 2491 return 0;
2481} 2492}
2482 2493
2483static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream,
2484 unsigned int cmd, void __user *arg);
2485static int snd_pcm_capture_ioctl1(struct snd_pcm_substream *substream,
2486 unsigned int cmd, void __user *arg);
2487
2488static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream, 2494static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream,
2489 unsigned int cmd, void __user *arg) 2495 unsigned int cmd, void __user *arg)
2490{ 2496{
@@ -2736,41 +2742,28 @@ static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd,
2736 return snd_pcm_capture_ioctl1(pcm_file->substream, cmd, (void __user *)arg); 2742 return snd_pcm_capture_ioctl1(pcm_file->substream, cmd, (void __user *)arg);
2737} 2743}
2738 2744
2739int snd_pcm_kernel_playback_ioctl(struct snd_pcm_substream *substream, 2745int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
2740 unsigned int cmd, void *arg) 2746 unsigned int cmd, void *arg)
2741{
2742 mm_segment_t fs;
2743 int result;
2744
2745 fs = snd_enter_user();
2746 result = snd_pcm_playback_ioctl1(substream, cmd, (void __user *)arg);
2747 snd_leave_user(fs);
2748 return result;
2749}
2750
2751int snd_pcm_kernel_capture_ioctl(struct snd_pcm_substream *substream,
2752 unsigned int cmd, void *arg)
2753{ 2747{
2754 mm_segment_t fs; 2748 mm_segment_t fs;
2755 int result; 2749 int result;
2756 2750
2757 fs = snd_enter_user(); 2751 fs = snd_enter_user();
2758 result = snd_pcm_capture_ioctl1(substream, cmd, (void __user *)arg);
2759 snd_leave_user(fs);
2760 return result;
2761}
2762
2763int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
2764 unsigned int cmd, void *arg)
2765{
2766 switch (substream->stream) { 2752 switch (substream->stream) {
2767 case SNDRV_PCM_STREAM_PLAYBACK: 2753 case SNDRV_PCM_STREAM_PLAYBACK:
2768 return snd_pcm_kernel_playback_ioctl(substream, cmd, arg); 2754 result = snd_pcm_playback_ioctl1(substream,
2755 cmd, (void __user *)arg);
2756 break;
2769 case SNDRV_PCM_STREAM_CAPTURE: 2757 case SNDRV_PCM_STREAM_CAPTURE:
2770 return snd_pcm_kernel_capture_ioctl(substream, cmd, arg); 2758 result = snd_pcm_capture_ioctl1(substream,
2759 cmd, (void __user *)arg);
2760 break;
2771 default: 2761 default:
2772 return -EINVAL; 2762 result = -EINVAL;
2763 break;
2773 } 2764 }
2765 snd_leave_user(fs);
2766 return result;
2774} 2767}
2775 2768
2776static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count, 2769static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count,
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index ff8fef932786..557c4de22960 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -11,6 +11,15 @@ config SND_CS4231_LIB
11 tristate 11 tristate
12 select SND_PCM 12 select SND_PCM
13 13
14config SND_ADLIB
15 tristate "AdLib FM card"
16 select SND_OPL3_LIB
17 help
18 Say Y here to include support for AdLib FM cards.
19
20 To compile this driver as a module, choose M here: the module
21 will be called snd-adlib.
22
14config SND_AD1816A 23config SND_AD1816A
15 tristate "Analog Devices SoundPort AD1816A" 24 tristate "Analog Devices SoundPort AD1816A"
16 depends on SND && PNP && ISA 25 depends on SND && PNP && ISA
@@ -292,6 +301,20 @@ config SND_OPTI93X
292 To compile this driver as a module, choose M here: the module 301 To compile this driver as a module, choose M here: the module
293 will be called snd-opti93x. 302 will be called snd-opti93x.
294 303
304config SND_MIRO
305 tristate "Miro miroSOUND PCM1pro/PCM12/PCM20radio driver"
306 depends on SND
307 select SND_OPL4_LIB
308 select SND_CS4231_LIB
309 select SND_MPU401_UART
310 select SND_PCM
311 help
312 Say 'Y' or 'M' to include support for Miro miroSOUND PCM1 pro,
313 miroSOUND PCM12 and miroSOUND PCM20 Radio soundcards.
314
315 To compile this driver as a module, choose M here: the module
316 will be called snd-miro.
317
295config SND_SB8 318config SND_SB8
296 tristate "Sound Blaster 1.0/2.0/Pro (8-bit)" 319 tristate "Sound Blaster 1.0/2.0/Pro (8-bit)"
297 depends on SND 320 depends on SND
diff --git a/sound/isa/Makefile b/sound/isa/Makefile
index 05724eb7bfe4..bb317ccc170f 100644
--- a/sound/isa/Makefile
+++ b/sound/isa/Makefile
@@ -3,6 +3,7 @@
3# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> 3# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
4# 4#
5 5
6snd-adlib-objs := adlib.o
6snd-als100-objs := als100.o 7snd-als100-objs := als100.o
7snd-azt2320-objs := azt2320.o 8snd-azt2320-objs := azt2320.o
8snd-cmi8330-objs := cmi8330.o 9snd-cmi8330-objs := cmi8330.o
@@ -13,6 +14,7 @@ snd-sgalaxy-objs := sgalaxy.o
13snd-sscape-objs := sscape.o 14snd-sscape-objs := sscape.o
14 15
15# Toplevel Module Dependency 16# Toplevel Module Dependency
17obj-$(CONFIG_SND_ADLIB) += snd-adlib.o
16obj-$(CONFIG_SND_ALS100) += snd-als100.o 18obj-$(CONFIG_SND_ALS100) += snd-als100.o
17obj-$(CONFIG_SND_AZT2320) += snd-azt2320.o 19obj-$(CONFIG_SND_AZT2320) += snd-azt2320.o
18obj-$(CONFIG_SND_CMI8330) += snd-cmi8330.o 20obj-$(CONFIG_SND_CMI8330) += snd-cmi8330.o
diff --git a/sound/isa/adlib.c b/sound/isa/adlib.c
new file mode 100644
index 000000000000..a253a14e6a45
--- /dev/null
+++ b/sound/isa/adlib.c
@@ -0,0 +1,161 @@
1/*
2 * AdLib FM card driver.
3 */
4
5#include <sound/driver.h>
6#include <linux/kernel.h>
7#include <linux/module.h>
8#include <linux/platform_device.h>
9#include <sound/core.h>
10#include <sound/initval.h>
11#include <sound/opl3.h>
12
13#define CRD_NAME "AdLib FM"
14#define DRV_NAME "snd_adlib"
15
16MODULE_DESCRIPTION(CRD_NAME);
17MODULE_AUTHOR("Rene Herman");
18MODULE_LICENSE("GPL");
19
20static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
21static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
22static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
23static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
24
25module_param_array(index, int, NULL, 0444);
26MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
27module_param_array(id, charp, NULL, 0444);
28MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
29module_param_array(enable, bool, NULL, 0444);
30MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
31module_param_array(port, long, NULL, 0444);
32MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
33
34static struct platform_device *devices[SNDRV_CARDS];
35
36static void snd_adlib_free(struct snd_card *card)
37{
38 release_and_free_resource(card->private_data);
39}
40
41static int __devinit snd_adlib_probe(struct platform_device *device)
42{
43 struct snd_card *card;
44 struct snd_opl3 *opl3;
45
46 int error;
47 int i = device->id;
48
49 if (port[i] == SNDRV_AUTO_PORT) {
50 snd_printk(KERN_ERR DRV_NAME ": please specify port\n");
51 error = -EINVAL;
52 goto out0;
53 }
54
55 card = snd_card_new(index[i], id[i], THIS_MODULE, 0);
56 if (!card) {
57 snd_printk(KERN_ERR DRV_NAME ": could not create card\n");
58 error = -EINVAL;
59 goto out0;
60 }
61
62 card->private_data = request_region(port[i], 4, CRD_NAME);
63 if (!card->private_data) {
64 snd_printk(KERN_ERR DRV_NAME ": could not grab ports\n");
65 error = -EBUSY;
66 goto out1;
67 }
68 card->private_free = snd_adlib_free;
69
70 error = snd_opl3_create(card, port[i], port[i] + 2, OPL3_HW_AUTO, 1, &opl3);
71 if (error < 0) {
72 snd_printk(KERN_ERR DRV_NAME ": could not create OPL\n");
73 goto out1;
74 }
75
76 error = snd_opl3_hwdep_new(opl3, 0, 0, NULL);
77 if (error < 0) {
78 snd_printk(KERN_ERR DRV_NAME ": could not create FM\n");
79 goto out1;
80 }
81
82 strcpy(card->driver, DRV_NAME);
83 strcpy(card->shortname, CRD_NAME);
84 sprintf(card->longname, CRD_NAME " at %#lx", port[i]);
85
86 snd_card_set_dev(card, &device->dev);
87
88 error = snd_card_register(card);
89 if (error < 0) {
90 snd_printk(KERN_ERR DRV_NAME ": could not register card\n");
91 goto out1;
92 }
93
94 platform_set_drvdata(device, card);
95 return 0;
96
97out1: snd_card_free(card);
98 out0: error = -EINVAL; /* FIXME: should be the original error code */
99 return error;
100}
101
102static int __devexit snd_adlib_remove(struct platform_device *device)
103{
104 snd_card_free(platform_get_drvdata(device));
105 platform_set_drvdata(device, NULL);
106 return 0;
107}
108
109static struct platform_driver snd_adlib_driver = {
110 .probe = snd_adlib_probe,
111 .remove = __devexit_p(snd_adlib_remove),
112
113 .driver = {
114 .name = DRV_NAME
115 }
116};
117
118static int __init alsa_card_adlib_init(void)
119{
120 int i, cards;
121
122 if (platform_driver_register(&snd_adlib_driver) < 0) {
123 snd_printk(KERN_ERR DRV_NAME ": could not register driver\n");
124 return -ENODEV;
125 }
126
127 for (cards = 0, i = 0; i < SNDRV_CARDS; i++) {
128 struct platform_device *device;
129
130 if (!enable[i])
131 continue;
132
133 device = platform_device_register_simple(DRV_NAME, i, NULL, 0);
134 if (IS_ERR(device))
135 continue;
136
137 devices[i] = device;
138 cards++;
139 }
140
141 if (!cards) {
142#ifdef MODULE
143 printk(KERN_ERR CRD_NAME " soundcard not found or device busy\n");
144#endif
145 platform_driver_unregister(&snd_adlib_driver);
146 return -ENODEV;
147 }
148 return 0;
149}
150
151static void __exit alsa_card_adlib_exit(void)
152{
153 int i;
154
155 for (i = 0; i < SNDRV_CARDS; i++)
156 platform_device_unregister(devices[i]);
157 platform_driver_unregister(&snd_adlib_driver);
158}
159
160module_init(alsa_card_adlib_init);
161module_exit(alsa_card_adlib_exit);
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index fa63048a8b9d..bc0f5ebf5d3c 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -693,9 +693,9 @@ static int __init alsa_card_cmi8330_init(void)
693 if ((err = platform_driver_register(&snd_cmi8330_driver)) < 0) 693 if ((err = platform_driver_register(&snd_cmi8330_driver)) < 0)
694 return err; 694 return err;
695 695
696 for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { 696 for (i = 0; i < SNDRV_CARDS; i++) {
697 struct platform_device *device; 697 struct platform_device *device;
698 if (is_isapnp_selected(i)) 698 if (! enable[i] || is_isapnp_selected(i))
699 continue; 699 continue;
700 device = platform_device_register_simple(CMI8330_DRIVER, 700 device = platform_device_register_simple(CMI8330_DRIVER,
701 i, NULL, 0); 701 i, NULL, 0);
diff --git a/sound/isa/opti9xx/Makefile b/sound/isa/opti9xx/Makefile
index 28c64070cd56..0e41bfd5a403 100644
--- a/sound/isa/opti9xx/Makefile
+++ b/sound/isa/opti9xx/Makefile
@@ -6,8 +6,10 @@
6snd-opti92x-ad1848-objs := opti92x-ad1848.o 6snd-opti92x-ad1848-objs := opti92x-ad1848.o
7snd-opti92x-cs4231-objs := opti92x-cs4231.o 7snd-opti92x-cs4231-objs := opti92x-cs4231.o
8snd-opti93x-objs := opti93x.o 8snd-opti93x-objs := opti93x.o
9snd-miro-objs := miro.o
9 10
10# Toplevel Module Dependency 11# Toplevel Module Dependency
11obj-$(CONFIG_SND_OPTI92X_AD1848) += snd-opti92x-ad1848.o 12obj-$(CONFIG_SND_OPTI92X_AD1848) += snd-opti92x-ad1848.o
12obj-$(CONFIG_SND_OPTI92X_CS4231) += snd-opti92x-cs4231.o 13obj-$(CONFIG_SND_OPTI92X_CS4231) += snd-opti92x-cs4231.o
13obj-$(CONFIG_SND_OPTI93X) += snd-opti93x.o 14obj-$(CONFIG_SND_OPTI93X) += snd-opti93x.o
15obj-$(CONFIG_SND_MIRO) += snd-miro.o
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
new file mode 100644
index 000000000000..09384d03dc31
--- /dev/null
+++ b/sound/isa/opti9xx/miro.c
@@ -0,0 +1,1455 @@
1/*
2 * ALSA soundcard driver for Miro miroSOUND PCM1 pro
3 * miroSOUND PCM12
4 * miroSOUND PCM20 Radio
5 *
6 * Copyright (C) 2004-2005 Martin Langer <martin-langer@gmx.de>
7 *
8 * Based on OSS ACI and ALSA OPTi9xx drivers
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#include <sound/driver.h>
26#include <linux/init.h>
27#include <linux/err.h>
28#include <linux/platform_device.h>
29#include <linux/delay.h>
30#include <linux/slab.h>
31#include <linux/ioport.h>
32#include <linux/moduleparam.h>
33#include <asm/io.h>
34#include <asm/dma.h>
35#include <sound/core.h>
36#include <sound/cs4231.h>
37#include <sound/mpu401.h>
38#include <sound/opl4.h>
39#include <sound/control.h>
40#include <sound/info.h>
41#define SNDRV_LEGACY_FIND_FREE_IRQ
42#define SNDRV_LEGACY_FIND_FREE_DMA
43#include <sound/initval.h>
44#include "miro.h"
45
46MODULE_AUTHOR("Martin Langer <martin-langer@gmx.de>");
47MODULE_LICENSE("GPL");
48MODULE_DESCRIPTION("Miro miroSOUND PCM1 pro, PCM12, PCM20 Radio");
49MODULE_SUPPORTED_DEVICE("{{Miro,miroSOUND PCM1 pro}, "
50 "{Miro,miroSOUND PCM12}, "
51 "{Miro,miroSOUND PCM20 Radio}}");
52
53static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
54static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
55static long port = SNDRV_DEFAULT_PORT1; /* 0x530,0xe80,0xf40,0x604 */
56static long mpu_port = SNDRV_DEFAULT_PORT1; /* 0x300,0x310,0x320,0x330 */
57static long fm_port = SNDRV_DEFAULT_PORT1; /* 0x388 */
58static int irq = SNDRV_DEFAULT_IRQ1; /* 5,7,9,10,11 */
59static int mpu_irq = SNDRV_DEFAULT_IRQ1; /* 5,7,9,10 */
60static int dma1 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */
61static int dma2 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */
62static int wss;
63static int ide;
64
65module_param(index, int, 0444);
66MODULE_PARM_DESC(index, "Index value for miro soundcard.");
67module_param(id, charp, 0444);
68MODULE_PARM_DESC(id, "ID string for miro soundcard.");
69module_param(port, long, 0444);
70MODULE_PARM_DESC(port, "WSS port # for miro driver.");
71module_param(mpu_port, long, 0444);
72MODULE_PARM_DESC(mpu_port, "MPU-401 port # for miro driver.");
73module_param(fm_port, long, 0444);
74MODULE_PARM_DESC(fm_port, "FM Port # for miro driver.");
75module_param(irq, int, 0444);
76MODULE_PARM_DESC(irq, "WSS irq # for miro driver.");
77module_param(mpu_irq, int, 0444);
78MODULE_PARM_DESC(mpu_irq, "MPU-401 irq # for miro driver.");
79module_param(dma1, int, 0444);
80MODULE_PARM_DESC(dma1, "1st dma # for miro driver.");
81module_param(dma2, int, 0444);
82MODULE_PARM_DESC(dma2, "2nd dma # for miro driver.");
83module_param(wss, int, 0444);
84MODULE_PARM_DESC(wss, "wss mode");
85module_param(ide, int, 0444);
86MODULE_PARM_DESC(ide, "enable ide port");
87
88#define OPTi9XX_HW_DETECT 0
89#define OPTi9XX_HW_82C928 1
90#define OPTi9XX_HW_82C929 2
91#define OPTi9XX_HW_82C924 3
92#define OPTi9XX_HW_82C925 4
93#define OPTi9XX_HW_82C930 5
94#define OPTi9XX_HW_82C931 6
95#define OPTi9XX_HW_82C933 7
96#define OPTi9XX_HW_LAST OPTi9XX_HW_82C933
97
98#define OPTi9XX_MC_REG(n) n
99
100
101struct snd_miro {
102 unsigned short hardware;
103 unsigned char password;
104 char name[7];
105
106 struct resource *res_mc_base;
107 struct resource *res_aci_port;
108
109 unsigned long mc_base;
110 unsigned long mc_base_size;
111 unsigned long pwd_reg;
112
113 spinlock_t lock;
114 struct snd_card *card;
115 struct snd_pcm *pcm;
116
117 long wss_base;
118 int irq;
119 int dma1;
120 int dma2;
121
122 long fm_port;
123
124 long mpu_port;
125 int mpu_irq;
126
127 unsigned long aci_port;
128 int aci_vendor;
129 int aci_product;
130 int aci_version;
131 int aci_amp;
132 int aci_preamp;
133 int aci_solomode;
134
135 struct mutex aci_mutex;
136};
137
138static void snd_miro_proc_init(struct snd_miro * miro);
139
140#define DRIVER_NAME "snd-miro"
141
142static struct platform_device *device;
143
144static char * snd_opti9xx_names[] = {
145 "unkown",
146 "82C928", "82C929",
147 "82C924", "82C925",
148 "82C930", "82C931", "82C933"
149};
150
151/*
152 * ACI control
153 */
154
155static int aci_busy_wait(struct snd_miro * miro)
156{
157 long timeout;
158 unsigned char byte;
159
160 for (timeout = 1; timeout <= ACI_MINTIME+30; timeout++) {
161 if (((byte=inb(miro->aci_port + ACI_REG_BUSY)) & 1) == 0) {
162 if (timeout >= ACI_MINTIME)
163 snd_printd("aci ready in round %ld.\n",
164 timeout-ACI_MINTIME);
165 return byte;
166 }
167 if (timeout >= ACI_MINTIME) {
168 long out=10*HZ;
169 switch (timeout-ACI_MINTIME) {
170 case 0 ... 9:
171 out /= 10;
172 case 10 ... 19:
173 out /= 10;
174 case 20 ... 30:
175 out /= 10;
176 default:
177 set_current_state(TASK_UNINTERRUPTIBLE);
178 schedule_timeout(out);
179 break;
180 }
181 }
182 }
183 snd_printk(KERN_ERR "aci_busy_wait() time out\n");
184 return -EBUSY;
185}
186
187static inline int aci_write(struct snd_miro * miro, unsigned char byte)
188{
189 if (aci_busy_wait(miro) >= 0) {
190 outb(byte, miro->aci_port + ACI_REG_COMMAND);
191 return 0;
192 } else {
193 snd_printk(KERN_ERR "aci busy, aci_write(0x%x) stopped.\n", byte);
194 return -EBUSY;
195 }
196}
197
198static inline int aci_read(struct snd_miro * miro)
199{
200 unsigned char byte;
201
202 if (aci_busy_wait(miro) >= 0) {
203 byte=inb(miro->aci_port + ACI_REG_STATUS);
204 return byte;
205 } else {
206 snd_printk(KERN_ERR "aci busy, aci_read() stopped.\n");
207 return -EBUSY;
208 }
209}
210
211static int aci_cmd(struct snd_miro * miro, int write1, int write2, int write3)
212{
213 int write[] = {write1, write2, write3};
214 int value, i;
215
216 if (mutex_lock_interruptible(&miro->aci_mutex))
217 return -EINTR;
218
219 for (i=0; i<3; i++) {
220 if (write[i]< 0 || write[i] > 255)
221 break;
222 else {
223 value = aci_write(miro, write[i]);
224 if (value < 0)
225 goto out;
226 }
227 }
228
229 value = aci_read(miro);
230
231out: mutex_unlock(&miro->aci_mutex);
232 return value;
233}
234
235static int aci_getvalue(struct snd_miro * miro, unsigned char index)
236{
237 return aci_cmd(miro, ACI_STATUS, index, -1);
238}
239
240static int aci_setvalue(struct snd_miro * miro, unsigned char index, int value)
241{
242 return aci_cmd(miro, index, value, -1);
243}
244
245/*
246 * MIXER part
247 */
248
249static int snd_miro_info_capture(struct snd_kcontrol *kcontrol,
250 struct snd_ctl_elem_info *uinfo)
251{
252 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
253 uinfo->count = 1;
254
255 return 0;
256}
257
258static int snd_miro_get_capture(struct snd_kcontrol *kcontrol,
259 struct snd_ctl_elem_value *ucontrol)
260{
261 struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
262 int value;
263
264 if ((value = aci_getvalue(miro, ACI_S_GENERAL)) < 0) {
265 snd_printk(KERN_ERR "snd_miro_get_capture() failed: %d\n", value);
266 return value;
267 }
268
269 ucontrol->value.integer.value[0] = value & 0x20;
270
271 return 0;
272}
273
274static int snd_miro_put_capture(struct snd_kcontrol *kcontrol,
275 struct snd_ctl_elem_value *ucontrol)
276{
277 struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
278 int change, value, error;
279
280 value = !(ucontrol->value.integer.value[0]);
281
282 if ((error = aci_setvalue(miro, ACI_SET_SOLOMODE, value)) < 0) {
283 snd_printk(KERN_ERR "snd_miro_put_capture() failed: %d\n", error);
284 return error;
285 }
286
287 change = (value != miro->aci_solomode);
288 miro->aci_solomode = value;
289
290 return change;
291}
292
293static int snd_miro_info_preamp(struct snd_kcontrol *kcontrol,
294 struct snd_ctl_elem_info *uinfo)
295{
296 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
297 uinfo->count = 1;
298 uinfo->value.integer.min = 0;
299 uinfo->value.integer.max = 3;
300
301 return 0;
302}
303
304static int snd_miro_get_preamp(struct snd_kcontrol *kcontrol,
305 struct snd_ctl_elem_value *ucontrol)
306{
307 struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
308 int value;
309
310 if (miro->aci_version <= 176) {
311
312 /*
313 OSS says it's not readable with versions < 176.
314 But it doesn't work on my card,
315 which is a PCM12 with aci_version = 176.
316 */
317
318 ucontrol->value.integer.value[0] = miro->aci_preamp;
319 return 0;
320 }
321
322 if ((value = aci_getvalue(miro, ACI_GET_PREAMP)) < 0) {
323 snd_printk(KERN_ERR "snd_miro_get_preamp() failed: %d\n", value);
324 return value;
325 }
326
327 ucontrol->value.integer.value[0] = value;
328
329 return 0;
330}
331
332static int snd_miro_put_preamp(struct snd_kcontrol *kcontrol,
333 struct snd_ctl_elem_value *ucontrol)
334{
335 struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
336 int error, value, change;
337
338 value = ucontrol->value.integer.value[0];
339
340 if ((error = aci_setvalue(miro, ACI_SET_PREAMP, value)) < 0) {
341 snd_printk(KERN_ERR "snd_miro_put_preamp() failed: %d\n", error);
342 return error;
343 }
344
345 change = (value != miro->aci_preamp);
346 miro->aci_preamp = value;
347
348 return change;
349}
350
351static int snd_miro_info_amp(struct snd_kcontrol *kcontrol,
352 struct snd_ctl_elem_info *uinfo)
353{
354 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
355 uinfo->count = 1;
356
357 return 0;
358}
359
360static int snd_miro_get_amp(struct snd_kcontrol *kcontrol,
361 struct snd_ctl_elem_value *ucontrol)
362{
363 struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
364 ucontrol->value.integer.value[0] = miro->aci_amp;
365
366 return 0;
367}
368
369static int snd_miro_put_amp(struct snd_kcontrol *kcontrol,
370 struct snd_ctl_elem_value *ucontrol)
371{
372 struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
373 int error, value, change;
374
375 value = ucontrol->value.integer.value[0];
376
377 if ((error = aci_setvalue(miro, ACI_SET_POWERAMP, value)) < 0) {
378 snd_printk(KERN_ERR "snd_miro_put_amp() to %d failed: %d\n", value, error);
379 return error;
380 }
381
382 change = (value != miro->aci_amp);
383 miro->aci_amp = value;
384
385 return change;
386}
387
388#define MIRO_DOUBLE(ctl_name, ctl_index, get_right_reg, set_right_reg) \
389{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
390 .name = ctl_name, \
391 .index = ctl_index, \
392 .info = snd_miro_info_double, \
393 .get = snd_miro_get_double, \
394 .put = snd_miro_put_double, \
395 .private_value = get_right_reg | (set_right_reg << 8) \
396}
397
398static int snd_miro_info_double(struct snd_kcontrol *kcontrol,
399 struct snd_ctl_elem_info *uinfo)
400{
401 int reg = kcontrol->private_value & 0xff;
402
403 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
404 uinfo->count = 2;
405
406 if ((reg >= ACI_GET_EQ1) && (reg <= ACI_GET_EQ7)) {
407
408 /* equalizer elements */
409
410 uinfo->value.integer.min = - 0x7f;
411 uinfo->value.integer.max = 0x7f;
412 } else {
413
414 /* non-equalizer elements */
415
416 uinfo->value.integer.min = 0;
417 uinfo->value.integer.max = 0x20;
418 }
419
420 return 0;
421}
422
423static int snd_miro_get_double(struct snd_kcontrol *kcontrol,
424 struct snd_ctl_elem_value *uinfo)
425{
426 struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
427 int left_val, right_val;
428
429 int right_reg = kcontrol->private_value & 0xff;
430 int left_reg = right_reg + 1;
431
432 if ((right_val = aci_getvalue(miro, right_reg)) < 0) {
433 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", right_reg, right_val);
434 return right_val;
435 }
436
437 if ((left_val = aci_getvalue(miro, left_reg)) < 0) {
438 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", left_reg, left_val);
439 return left_val;
440 }
441
442 if ((right_reg >= ACI_GET_EQ1) && (right_reg <= ACI_GET_EQ7)) {
443
444 /* equalizer elements */
445
446 if (left_val < 0x80) {
447 uinfo->value.integer.value[0] = left_val;
448 } else {
449 uinfo->value.integer.value[0] = 0x80 - left_val;
450 }
451
452 if (right_val < 0x80) {
453 uinfo->value.integer.value[1] = right_val;
454 } else {
455 uinfo->value.integer.value[1] = 0x80 - right_val;
456 }
457
458 } else {
459
460 /* non-equalizer elements */
461
462 uinfo->value.integer.value[0] = 0x20 - left_val;
463 uinfo->value.integer.value[1] = 0x20 - right_val;
464 }
465
466 return 0;
467}
468
469static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
470 struct snd_ctl_elem_value *ucontrol)
471{
472 struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
473 int left, right, left_old, right_old;
474 int setreg_left, setreg_right, getreg_left, getreg_right;
475 int change, error;
476
477 left = ucontrol->value.integer.value[0];
478 right = ucontrol->value.integer.value[1];
479
480 setreg_right = (kcontrol->private_value >> 8) & 0xff;
481 if (setreg_right == ACI_SET_MASTER) {
482 setreg_left = setreg_right + 1;
483 } else {
484 setreg_left = setreg_right + 8;
485 }
486
487 getreg_right = kcontrol->private_value & 0xff;
488 getreg_left = getreg_right + 1;
489
490 if ((left_old = aci_getvalue(miro, getreg_left)) < 0) {
491 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", getreg_left, left_old);
492 return left_old;
493 }
494
495 if ((right_old = aci_getvalue(miro, getreg_right)) < 0) {
496 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", getreg_right, right_old);
497 return right_old;
498 }
499
500 if ((getreg_right >= ACI_GET_EQ1) && (getreg_right <= ACI_GET_EQ7)) {
501
502 /* equalizer elements */
503
504 if (left_old > 0x80)
505 left_old = 0x80 - left_old;
506 if (right_old > 0x80)
507 right_old = 0x80 - right_old;
508
509 if (left >= 0) {
510 if ((error = aci_setvalue(miro, setreg_left, left)) < 0) {
511 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
512 left, error);
513 return error;
514 }
515 } else {
516 if ((error = aci_setvalue(miro, setreg_left, 0x80 - left)) < 0) {
517 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
518 0x80 - left, error);
519 return error;
520 }
521 }
522
523 if (right >= 0) {
524 if ((error = aci_setvalue(miro, setreg_right, right)) < 0) {
525 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
526 right, error);
527 return error;
528 }
529 } else {
530 if ((error = aci_setvalue(miro, setreg_right, 0x80 - right)) < 0) {
531 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
532 0x80 - right, error);
533 return error;
534 }
535 }
536
537 } else {
538
539 /* non-equalizer elements */
540
541 left_old = 0x20 - left_old;
542 right_old = 0x20 - right_old;
543
544 if ((error = aci_setvalue(miro, setreg_left, 0x20 - left)) < 0) {
545 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
546 0x20 - left, error);
547 return error;
548 }
549 if ((error = aci_setvalue(miro, setreg_right, 0x20 - right)) < 0) {
550 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
551 0x20 - right, error);
552 return error;
553 }
554 }
555
556 change = (left != left_old) || (right != right_old);
557
558 return change;
559}
560
561static struct snd_kcontrol_new snd_miro_controls[] = {
562MIRO_DOUBLE("Master Playback Volume", 0, ACI_GET_MASTER, ACI_SET_MASTER),
563MIRO_DOUBLE("Mic Playback Volume", 1, ACI_GET_MIC, ACI_SET_MIC),
564MIRO_DOUBLE("Line Playback Volume", 1, ACI_GET_LINE, ACI_SET_LINE),
565MIRO_DOUBLE("CD Playback Volume", 0, ACI_GET_CD, ACI_SET_CD),
566MIRO_DOUBLE("Synth Playback Volume", 0, ACI_GET_SYNTH, ACI_SET_SYNTH),
567MIRO_DOUBLE("PCM Playback Volume", 1, ACI_GET_PCM, ACI_SET_PCM),
568MIRO_DOUBLE("Aux Playback Volume", 2, ACI_GET_LINE2, ACI_SET_LINE2),
569};
570
571/* Equalizer with seven bands (only PCM20)
572 from -12dB up to +12dB on each band */
573static struct snd_kcontrol_new snd_miro_eq_controls[] = {
574MIRO_DOUBLE("Tone Control - 28 Hz", 0, ACI_GET_EQ1, ACI_SET_EQ1),
575MIRO_DOUBLE("Tone Control - 160 Hz", 0, ACI_GET_EQ2, ACI_SET_EQ2),
576MIRO_DOUBLE("Tone Control - 400 Hz", 0, ACI_GET_EQ3, ACI_SET_EQ3),
577MIRO_DOUBLE("Tone Control - 1 kHz", 0, ACI_GET_EQ4, ACI_SET_EQ4),
578MIRO_DOUBLE("Tone Control - 2.5 kHz", 0, ACI_GET_EQ5, ACI_SET_EQ5),
579MIRO_DOUBLE("Tone Control - 6.3 kHz", 0, ACI_GET_EQ6, ACI_SET_EQ6),
580MIRO_DOUBLE("Tone Control - 16 kHz", 0, ACI_GET_EQ7, ACI_SET_EQ7),
581};
582
583static struct snd_kcontrol_new snd_miro_radio_control[] = {
584MIRO_DOUBLE("Radio Playback Volume", 0, ACI_GET_LINE1, ACI_SET_LINE1),
585};
586
587static struct snd_kcontrol_new snd_miro_line_control[] = {
588MIRO_DOUBLE("Line Playback Volume", 2, ACI_GET_LINE1, ACI_SET_LINE1),
589};
590
591static struct snd_kcontrol_new snd_miro_preamp_control[] = {
592{
593 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
594 .name = "Mic Boost",
595 .index = 1,
596 .info = snd_miro_info_preamp,
597 .get = snd_miro_get_preamp,
598 .put = snd_miro_put_preamp,
599}};
600
601static struct snd_kcontrol_new snd_miro_amp_control[] = {
602{
603 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
604 .name = "Line Boost",
605 .index = 0,
606 .info = snd_miro_info_amp,
607 .get = snd_miro_get_amp,
608 .put = snd_miro_put_amp,
609}};
610
611static struct snd_kcontrol_new snd_miro_capture_control[] = {
612{
613 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
614 .name = "PCM Capture Switch",
615 .index = 0,
616 .info = snd_miro_info_capture,
617 .get = snd_miro_get_capture,
618 .put = snd_miro_put_capture,
619}};
620
621static unsigned char aci_init_values[][2] __initdata = {
622 { ACI_SET_MUTE, 0x00 },
623 { ACI_SET_POWERAMP, 0x00 },
624 { ACI_SET_PREAMP, 0x00 },
625 { ACI_SET_SOLOMODE, 0x00 },
626 { ACI_SET_MIC + 0, 0x20 },
627 { ACI_SET_MIC + 8, 0x20 },
628 { ACI_SET_LINE + 0, 0x20 },
629 { ACI_SET_LINE + 8, 0x20 },
630 { ACI_SET_CD + 0, 0x20 },
631 { ACI_SET_CD + 8, 0x20 },
632 { ACI_SET_PCM + 0, 0x20 },
633 { ACI_SET_PCM + 8, 0x20 },
634 { ACI_SET_LINE1 + 0, 0x20 },
635 { ACI_SET_LINE1 + 8, 0x20 },
636 { ACI_SET_LINE2 + 0, 0x20 },
637 { ACI_SET_LINE2 + 8, 0x20 },
638 { ACI_SET_SYNTH + 0, 0x20 },
639 { ACI_SET_SYNTH + 8, 0x20 },
640 { ACI_SET_MASTER + 0, 0x20 },
641 { ACI_SET_MASTER + 1, 0x20 },
642};
643
644static int __init snd_set_aci_init_values(struct snd_miro *miro)
645{
646 int idx, error;
647
648 /* enable WSS on PCM1 */
649
650 if ((miro->aci_product == 'A') && wss) {
651 if ((error = aci_setvalue(miro, ACI_SET_WSS, wss)) < 0) {
652 snd_printk(KERN_ERR "enabling WSS mode failed\n");
653 return error;
654 }
655 }
656
657 /* enable IDE port */
658
659 if (ide) {
660 if ((error = aci_setvalue(miro, ACI_SET_IDE, ide)) < 0) {
661 snd_printk(KERN_ERR "enabling IDE port failed\n");
662 return error;
663 }
664 }
665
666 /* set common aci values */
667
668 for (idx = 0; idx < ARRAY_SIZE(aci_init_values); idx++)
669 if ((error = aci_setvalue(miro, aci_init_values[idx][0],
670 aci_init_values[idx][1])) < 0) {
671 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
672 aci_init_values[idx][0], error);
673 return error;
674 }
675
676 miro->aci_amp = 0;
677 miro->aci_preamp = 0;
678 miro->aci_solomode = 1;
679
680 return 0;
681}
682
683static int snd_miro_mixer(struct snd_miro *miro)
684{
685 struct snd_card *card;
686 unsigned int idx;
687 int err;
688
689 snd_assert(miro != NULL && miro->card != NULL, return -EINVAL);
690
691 card = miro->card;
692
693 switch (miro->hardware) {
694 case OPTi9XX_HW_82C924:
695 strcpy(card->mixername, "ACI & OPTi924");
696 break;
697 case OPTi9XX_HW_82C929:
698 strcpy(card->mixername, "ACI & OPTi929");
699 break;
700 default:
701 snd_BUG();
702 break;
703 }
704
705 for (idx = 0; idx < ARRAY_SIZE(snd_miro_controls); idx++) {
706 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_controls[idx], miro))) < 0)
707 return err;
708 }
709
710 if ((miro->aci_product == 'A') || (miro->aci_product == 'B')) {
711 /* PCM1/PCM12 with power-amp and Line 2 */
712 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_line_control[0], miro))) < 0)
713 return err;
714 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_amp_control[0], miro))) < 0)
715 return err;
716 }
717
718 if ((miro->aci_product == 'B') || (miro->aci_product == 'C')) {
719 /* PCM12/PCM20 with mic-preamp */
720 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_preamp_control[0], miro))) < 0)
721 return err;
722 if (miro->aci_version >= 176)
723 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_capture_control[0], miro))) < 0)
724 return err;
725 }
726
727 if (miro->aci_product == 'C') {
728 /* PCM20 with radio and 7 band equalizer */
729 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_radio_control[0], miro))) < 0)
730 return err;
731 for (idx = 0; idx < ARRAY_SIZE(snd_miro_eq_controls); idx++) {
732 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_eq_controls[idx], miro))) < 0)
733 return err;
734 }
735 }
736
737 return 0;
738}
739
740static long snd_legacy_find_free_ioport(long *port_table, long size)
741{
742 while (*port_table != -1) {
743 struct resource *res;
744 if ((res = request_region(*port_table, size,
745 "ALSA test")) != NULL) {
746 release_and_free_resource(res);
747 return *port_table;
748 }
749 port_table++;
750 }
751 return -1;
752}
753
754static int __init snd_miro_init(struct snd_miro *chip, unsigned short hardware)
755{
756 static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2};
757
758 chip->hardware = hardware;
759 strcpy(chip->name, snd_opti9xx_names[hardware]);
760
761 chip->mc_base_size = opti9xx_mc_size[hardware];
762
763 spin_lock_init(&chip->lock);
764
765 chip->wss_base = -1;
766 chip->irq = -1;
767 chip->dma1 = -1;
768 chip->dma2 = -1;
769 chip->fm_port = -1;
770 chip->mpu_port = -1;
771 chip->mpu_irq = -1;
772
773 switch (hardware) {
774 case OPTi9XX_HW_82C929:
775 chip->mc_base = 0xf8c;
776 chip->password = 0xe3;
777 chip->pwd_reg = 3;
778 break;
779
780 case OPTi9XX_HW_82C924:
781 chip->mc_base = 0xf8c;
782 chip->password = 0xe5;
783 chip->pwd_reg = 3;
784 break;
785
786 default:
787 snd_printk(KERN_ERR "sorry, no support for %d\n", hardware);
788 return -ENODEV;
789 }
790
791 return 0;
792}
793
794static unsigned char snd_miro_read(struct snd_miro *chip,
795 unsigned char reg)
796{
797 unsigned long flags;
798 unsigned char retval = 0xff;
799
800 spin_lock_irqsave(&chip->lock, flags);
801 outb(chip->password, chip->mc_base + chip->pwd_reg);
802
803 switch (chip->hardware) {
804 case OPTi9XX_HW_82C924:
805 if (reg > 7) {
806 outb(reg, chip->mc_base + 8);
807 outb(chip->password, chip->mc_base + chip->pwd_reg);
808 retval = inb(chip->mc_base + 9);
809 break;
810 }
811
812 case OPTi9XX_HW_82C929:
813 retval = inb(chip->mc_base + reg);
814 break;
815
816 default:
817 snd_printk(KERN_ERR "sorry, no support for %d\n", chip->hardware);
818 }
819
820 spin_unlock_irqrestore(&chip->lock, flags);
821 return retval;
822}
823
824static void snd_miro_write(struct snd_miro *chip, unsigned char reg,
825 unsigned char value)
826{
827 unsigned long flags;
828
829 spin_lock_irqsave(&chip->lock, flags);
830 outb(chip->password, chip->mc_base + chip->pwd_reg);
831
832 switch (chip->hardware) {
833 case OPTi9XX_HW_82C924:
834 if (reg > 7) {
835 outb(reg, chip->mc_base + 8);
836 outb(chip->password, chip->mc_base + chip->pwd_reg);
837 outb(value, chip->mc_base + 9);
838 break;
839 }
840
841 case OPTi9XX_HW_82C929:
842 outb(value, chip->mc_base + reg);
843 break;
844
845 default:
846 snd_printk(KERN_ERR "sorry, no support for %d\n", chip->hardware);
847 }
848
849 spin_unlock_irqrestore(&chip->lock, flags);
850}
851
852
853#define snd_miro_write_mask(chip, reg, value, mask) \
854 snd_miro_write(chip, reg, \
855 (snd_miro_read(chip, reg) & ~(mask)) | ((value) & (mask)))
856
857/*
858 * Proc Interface
859 */
860
861static void snd_miro_proc_read(struct snd_info_entry * entry,
862 struct snd_info_buffer *buffer)
863{
864 struct snd_miro *miro = (struct snd_miro *) entry->private_data;
865 char* model = "unknown";
866
867 /* miroSOUND PCM1 pro, early PCM12 */
868
869 if ((miro->hardware == OPTi9XX_HW_82C929) &&
870 (miro->aci_vendor == 'm') &&
871 (miro->aci_product == 'A')) {
872 switch(miro->aci_version) {
873 case 3:
874 model = "miroSOUND PCM1 pro";
875 break;
876 default:
877 model = "miroSOUND PCM1 pro / (early) PCM12";
878 break;
879 }
880 }
881
882 /* miroSOUND PCM12, PCM12 (Rev. E), PCM12 pnp */
883
884 if ((miro->hardware == OPTi9XX_HW_82C924) &&
885 (miro->aci_vendor == 'm') &&
886 (miro->aci_product == 'B')) {
887 switch(miro->aci_version) {
888 case 4:
889 model = "miroSOUND PCM12";
890 break;
891 case 176:
892 model = "miroSOUND PCM12 (Rev. E)";
893 break;
894 default:
895 model = "miroSOUND PCM12 / PCM12 pnp";
896 break;
897 }
898 }
899
900 /* miroSOUND PCM20 radio */
901
902 if ((miro->hardware == OPTi9XX_HW_82C924) &&
903 (miro->aci_vendor == 'm') &&
904 (miro->aci_product == 'C')) {
905 switch(miro->aci_version) {
906 case 7:
907 model = "miroSOUND PCM20 radio (Rev. E)";
908 break;
909 default:
910 model = "miroSOUND PCM20 radio";
911 break;
912 }
913 }
914
915 snd_iprintf(buffer, "\nGeneral information:\n");
916 snd_iprintf(buffer, " model : %s\n", model);
917 snd_iprintf(buffer, " opti : %s\n", miro->name);
918 snd_iprintf(buffer, " codec : %s\n", miro->pcm->name);
919 snd_iprintf(buffer, " port : 0x%lx\n", miro->wss_base);
920 snd_iprintf(buffer, " irq : %d\n", miro->irq);
921 snd_iprintf(buffer, " dma : %d,%d\n\n", miro->dma1, miro->dma2);
922
923 snd_iprintf(buffer, "MPU-401:\n");
924 snd_iprintf(buffer, " port : 0x%lx\n", miro->mpu_port);
925 snd_iprintf(buffer, " irq : %d\n\n", miro->mpu_irq);
926
927 snd_iprintf(buffer, "ACI information:\n");
928 snd_iprintf(buffer, " vendor : ");
929 switch(miro->aci_vendor) {
930 case 'm':
931 snd_iprintf(buffer, "Miro\n");
932 break;
933 default:
934 snd_iprintf(buffer, "unknown (0x%x)\n", miro->aci_vendor);
935 break;
936 }
937
938 snd_iprintf(buffer, " product : ");
939 switch(miro->aci_product) {
940 case 'A':
941 snd_iprintf(buffer, "miroSOUND PCM1 pro / (early) PCM12\n");
942 break;
943 case 'B':
944 snd_iprintf(buffer, "miroSOUND PCM12\n");
945 break;
946 case 'C':
947 snd_iprintf(buffer, "miroSOUND PCM20 radio\n");
948 break;
949 default:
950 snd_iprintf(buffer, "unknown (0x%x)\n", miro->aci_product);
951 break;
952 }
953
954 snd_iprintf(buffer, " firmware: %d (0x%x)\n",
955 miro->aci_version, miro->aci_version);
956 snd_iprintf(buffer, " port : 0x%lx-0x%lx\n",
957 miro->aci_port, miro->aci_port+2);
958 snd_iprintf(buffer, " wss : 0x%x\n", wss);
959 snd_iprintf(buffer, " ide : 0x%x\n", ide);
960 snd_iprintf(buffer, " solomode: 0x%x\n", miro->aci_solomode);
961 snd_iprintf(buffer, " amp : 0x%x\n", miro->aci_amp);
962 snd_iprintf(buffer, " preamp : 0x%x\n", miro->aci_preamp);
963}
964
965static void __init snd_miro_proc_init(struct snd_miro * miro)
966{
967 struct snd_info_entry *entry;
968
969 if (! snd_card_proc_new(miro->card, "miro", &entry))
970 snd_info_set_text_ops(entry, miro, 1024, snd_miro_proc_read);
971}
972
973/*
974 * Init
975 */
976
977static int __init snd_miro_configure(struct snd_miro *chip)
978{
979 unsigned char wss_base_bits;
980 unsigned char irq_bits;
981 unsigned char dma_bits;
982 unsigned char mpu_port_bits = 0;
983 unsigned char mpu_irq_bits;
984 unsigned long flags;
985
986 switch (chip->hardware) {
987 case OPTi9XX_HW_82C924:
988 snd_miro_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02);
989 snd_miro_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
990 snd_miro_write_mask(chip, OPTi9XX_MC_REG(2), 0x20, 0x20); /* OPL4 */
991 snd_miro_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff);
992 snd_miro_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);
993 break;
994 case OPTi9XX_HW_82C929:
995 /* untested init commands for OPTi929 */
996 snd_miro_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
997 snd_miro_write_mask(chip, OPTi9XX_MC_REG(2), 0x20, 0x20); /* OPL4 */
998 snd_miro_write_mask(chip, OPTi9XX_MC_REG(4), 0x00, 0x0c);
999 snd_miro_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);
1000 break;
1001 default:
1002 snd_printk(KERN_ERR "chip %d not supported\n", chip->hardware);
1003 return -EINVAL;
1004 }
1005
1006 switch (chip->wss_base) {
1007 case 0x530:
1008 wss_base_bits = 0x00;
1009 break;
1010 case 0x604:
1011 wss_base_bits = 0x03;
1012 break;
1013 case 0xe80:
1014 wss_base_bits = 0x01;
1015 break;
1016 case 0xf40:
1017 wss_base_bits = 0x02;
1018 break;
1019 default:
1020 snd_printk(KERN_ERR "WSS port 0x%lx not valid\n", chip->wss_base);
1021 goto __skip_base;
1022 }
1023 snd_miro_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30);
1024
1025__skip_base:
1026 switch (chip->irq) {
1027 case 5:
1028 irq_bits = 0x05;
1029 break;
1030 case 7:
1031 irq_bits = 0x01;
1032 break;
1033 case 9:
1034 irq_bits = 0x02;
1035 break;
1036 case 10:
1037 irq_bits = 0x03;
1038 break;
1039 case 11:
1040 irq_bits = 0x04;
1041 break;
1042 default:
1043 snd_printk(KERN_ERR "WSS irq # %d not valid\n", chip->irq);
1044 goto __skip_resources;
1045 }
1046
1047 switch (chip->dma1) {
1048 case 0:
1049 dma_bits = 0x01;
1050 break;
1051 case 1:
1052 dma_bits = 0x02;
1053 break;
1054 case 3:
1055 dma_bits = 0x03;
1056 break;
1057 default:
1058 snd_printk(KERN_ERR "WSS dma1 # %d not valid\n", chip->dma1);
1059 goto __skip_resources;
1060 }
1061
1062 if (chip->dma1 == chip->dma2) {
1063 snd_printk(KERN_ERR "don't want to share dmas\n");
1064 return -EBUSY;
1065 }
1066
1067 switch (chip->dma2) {
1068 case 0:
1069 case 1:
1070 break;
1071 default:
1072 snd_printk(KERN_ERR "WSS dma2 # %d not valid\n", chip->dma2);
1073 goto __skip_resources;
1074 }
1075 dma_bits |= 0x04;
1076
1077 spin_lock_irqsave(&chip->lock, flags);
1078 outb(irq_bits << 3 | dma_bits, chip->wss_base);
1079 spin_unlock_irqrestore(&chip->lock, flags);
1080
1081__skip_resources:
1082 if (chip->hardware > OPTi9XX_HW_82C928) {
1083 switch (chip->mpu_port) {
1084 case 0:
1085 case -1:
1086 break;
1087 case 0x300:
1088 mpu_port_bits = 0x03;
1089 break;
1090 case 0x310:
1091 mpu_port_bits = 0x02;
1092 break;
1093 case 0x320:
1094 mpu_port_bits = 0x01;
1095 break;
1096 case 0x330:
1097 mpu_port_bits = 0x00;
1098 break;
1099 default:
1100 snd_printk(KERN_ERR "MPU-401 port 0x%lx not valid\n",
1101 chip->mpu_port);
1102 goto __skip_mpu;
1103 }
1104
1105 switch (chip->mpu_irq) {
1106 case 5:
1107 mpu_irq_bits = 0x02;
1108 break;
1109 case 7:
1110 mpu_irq_bits = 0x03;
1111 break;
1112 case 9:
1113 mpu_irq_bits = 0x00;
1114 break;
1115 case 10:
1116 mpu_irq_bits = 0x01;
1117 break;
1118 default:
1119 snd_printk(KERN_ERR "MPU-401 irq # %d not valid\n",
1120 chip->mpu_irq);
1121 goto __skip_mpu;
1122 }
1123
1124 snd_miro_write_mask(chip, OPTi9XX_MC_REG(6),
1125 (chip->mpu_port <= 0) ? 0x00 :
1126 0x80 | mpu_port_bits << 5 | mpu_irq_bits << 3,
1127 0xf8);
1128 }
1129__skip_mpu:
1130
1131 return 0;
1132}
1133
1134static int __init snd_card_miro_detect(struct snd_card *card, struct snd_miro *chip)
1135{
1136 int i, err;
1137 unsigned char value;
1138
1139 for (i = OPTi9XX_HW_82C929; i <= OPTi9XX_HW_82C924; i++) {
1140
1141 if ((err = snd_miro_init(chip, i)) < 0)
1142 return err;
1143
1144 if ((chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL)
1145 continue;
1146
1147 value = snd_miro_read(chip, OPTi9XX_MC_REG(1));
1148 if ((value != 0xff) && (value != inb(chip->mc_base + 1)))
1149 if (value == snd_miro_read(chip, OPTi9XX_MC_REG(1)))
1150 return 1;
1151
1152 release_and_free_resource(chip->res_mc_base);
1153 chip->res_mc_base = NULL;
1154
1155 }
1156
1157 return -ENODEV;
1158}
1159
1160static int __init snd_card_miro_aci_detect(struct snd_card *card, struct snd_miro * miro)
1161{
1162 unsigned char regval;
1163 int i;
1164
1165 mutex_init(&miro->aci_mutex);
1166
1167 /* get ACI port from OPTi9xx MC 4 */
1168
1169 miro->mc_base = 0xf8c;
1170 regval=inb(miro->mc_base + 4);
1171 miro->aci_port = (regval & 0x10) ? 0x344: 0x354;
1172
1173 if ((miro->res_aci_port = request_region(miro->aci_port, 3, "miro aci")) == NULL) {
1174 snd_printk(KERN_ERR "aci i/o area 0x%lx-0x%lx already used.\n",
1175 miro->aci_port, miro->aci_port+2);
1176 return -ENOMEM;
1177 }
1178
1179 /* force ACI into a known state */
1180 for (i = 0; i < 3; i++)
1181 if (aci_cmd(miro, ACI_ERROR_OP, -1, -1) < 0) {
1182 snd_card_free(card);
1183 snd_printk(KERN_ERR "can't force aci into known state.\n");
1184 return -ENXIO;
1185 }
1186
1187 if ((miro->aci_vendor=aci_cmd(miro, ACI_READ_IDCODE, -1, -1)) < 0 ||
1188 (miro->aci_product=aci_cmd(miro, ACI_READ_IDCODE, -1, -1)) < 0) {
1189 snd_card_free(card);
1190 snd_printk(KERN_ERR "can't read aci id on 0x%lx.\n", miro->aci_port);
1191 return -ENXIO;
1192 }
1193
1194 if ((miro->aci_version=aci_cmd(miro, ACI_READ_VERSION, -1, -1)) < 0) {
1195 snd_card_free(card);
1196 snd_printk(KERN_ERR "can't read aci version on 0x%lx.\n",
1197 miro->aci_port);
1198 return -ENXIO;
1199 }
1200
1201 if (aci_cmd(miro, ACI_INIT, -1, -1) < 0 ||
1202 aci_cmd(miro, ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP) < 0 ||
1203 aci_cmd(miro, ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP) < 0) {
1204 snd_printk(KERN_ERR "can't initialize aci.\n");
1205 return -ENXIO;
1206 }
1207
1208 return 0;
1209}
1210
1211static void snd_card_miro_free(struct snd_card *card)
1212{
1213 struct snd_miro *miro = card->private_data;
1214
1215 release_and_free_resource(miro->res_aci_port);
1216 release_and_free_resource(miro->res_mc_base);
1217}
1218
1219static int __init snd_miro_probe(struct platform_device *devptr)
1220{
1221 static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
1222 static long possible_mpu_ports[] = {0x330, 0x300, 0x310, 0x320, -1};
1223 static int possible_irqs[] = {11, 9, 10, 7, -1};
1224 static int possible_mpu_irqs[] = {10, 5, 9, 7, -1};
1225 static int possible_dma1s[] = {3, 1, 0, -1};
1226 static int possible_dma2s[][2] = {{1,-1}, {0,-1}, {-1,-1}, {0,-1}};
1227
1228 int error;
1229 struct snd_miro *miro;
1230 struct snd_cs4231 *codec;
1231 struct snd_timer *timer;
1232 struct snd_card *card;
1233 struct snd_pcm *pcm;
1234 struct snd_rawmidi *rmidi;
1235
1236 if (!(card = snd_card_new(index, id, THIS_MODULE,
1237 sizeof(struct snd_miro))))
1238 return -ENOMEM;
1239
1240 card->private_free = snd_card_miro_free;
1241 miro = card->private_data;
1242 miro->card = card;
1243
1244 if ((error = snd_card_miro_aci_detect(card, miro)) < 0) {
1245 snd_card_free(card);
1246 snd_printk(KERN_ERR "unable to detect aci chip\n");
1247 return -ENODEV;
1248 }
1249
1250 /* init proc interface */
1251 snd_miro_proc_init(miro);
1252
1253 if ((error = snd_card_miro_detect(card, miro)) < 0) {
1254 snd_card_free(card);
1255 snd_printk(KERN_ERR "unable to detect OPTi9xx chip\n");
1256 return -ENODEV;
1257 }
1258
1259 if (! miro->res_mc_base &&
1260 (miro->res_mc_base = request_region(miro->mc_base, miro->mc_base_size,
1261 "miro (OPTi9xx MC)")) == NULL) {
1262 snd_card_free(card);
1263 snd_printk(KERN_ERR "request for OPTI9xx MC failed\n");
1264 return -ENOMEM;
1265 }
1266
1267 miro->wss_base = port;
1268 miro->fm_port = fm_port;
1269 miro->mpu_port = mpu_port;
1270 miro->irq = irq;
1271 miro->mpu_irq = mpu_irq;
1272 miro->dma1 = dma1;
1273 miro->dma2 = dma2;
1274
1275 if (miro->wss_base == SNDRV_AUTO_PORT) {
1276 if ((miro->wss_base = snd_legacy_find_free_ioport(possible_ports, 4)) < 0) {
1277 snd_card_free(card);
1278 snd_printk(KERN_ERR "unable to find a free WSS port\n");
1279 return -EBUSY;
1280 }
1281 }
1282
1283 if (miro->mpu_port == SNDRV_AUTO_PORT) {
1284 if ((miro->mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2)) < 0) {
1285 snd_card_free(card);
1286 snd_printk(KERN_ERR "unable to find a free MPU401 port\n");
1287 return -EBUSY;
1288 }
1289 }
1290 if (miro->irq == SNDRV_AUTO_IRQ) {
1291 if ((miro->irq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
1292 snd_card_free(card);
1293 snd_printk(KERN_ERR "unable to find a free IRQ\n");
1294 return -EBUSY;
1295 }
1296 }
1297 if (miro->mpu_irq == SNDRV_AUTO_IRQ) {
1298 if ((miro->mpu_irq = snd_legacy_find_free_irq(possible_mpu_irqs)) < 0) {
1299 snd_card_free(card);
1300 snd_printk(KERN_ERR "unable to find a free MPU401 IRQ\n");
1301 return -EBUSY;
1302 }
1303 }
1304 if (miro->dma1 == SNDRV_AUTO_DMA) {
1305 if ((miro->dma1 = snd_legacy_find_free_dma(possible_dma1s)) < 0) {
1306 snd_card_free(card);
1307 snd_printk(KERN_ERR "unable to find a free DMA1\n");
1308 return -EBUSY;
1309 }
1310 }
1311 if (miro->dma2 == SNDRV_AUTO_DMA) {
1312 if ((miro->dma2 = snd_legacy_find_free_dma(possible_dma2s[miro->dma1 % 4])) < 0) {
1313 snd_card_free(card);
1314 snd_printk(KERN_ERR "unable to find a free DMA2\n");
1315 return -EBUSY;
1316 }
1317 }
1318
1319 if ((error = snd_miro_configure(miro))) {
1320 snd_card_free(card);
1321 return error;
1322 }
1323
1324 if ((error = snd_cs4231_create(card, miro->wss_base + 4, -1,
1325 miro->irq, miro->dma1, miro->dma2,
1326 CS4231_HW_AD1845,
1327 0,
1328 &codec)) < 0) {
1329 snd_card_free(card);
1330 return error;
1331 }
1332
1333 if ((error = snd_cs4231_pcm(codec, 0, &pcm)) < 0) {
1334 snd_card_free(card);
1335 return error;
1336 }
1337 if ((error = snd_cs4231_mixer(codec)) < 0) {
1338 snd_card_free(card);
1339 return error;
1340 }
1341 if ((error = snd_cs4231_timer(codec, 0, &timer)) < 0) {
1342 snd_card_free(card);
1343 return error;
1344 }
1345
1346 miro->pcm = pcm;
1347
1348 if ((error = snd_miro_mixer(miro)) < 0) {
1349 snd_card_free(card);
1350 return error;
1351 }
1352
1353 if (miro->aci_vendor == 'm') {
1354 /* It looks like a miro sound card. */
1355 switch (miro->aci_product) {
1356 case 'A':
1357 sprintf(card->shortname,
1358 "miroSOUND PCM1 pro / PCM12");
1359 break;
1360 case 'B':
1361 sprintf(card->shortname,
1362 "miroSOUND PCM12");
1363 break;
1364 case 'C':
1365 sprintf(card->shortname,
1366 "miroSOUND PCM20 radio");
1367 break;
1368 default:
1369 sprintf(card->shortname,
1370 "unknown miro");
1371 snd_printk(KERN_INFO "unknown miro aci id\n");
1372 break;
1373 }
1374 } else {
1375 snd_printk(KERN_INFO "found unsupported aci card\n");
1376 sprintf(card->shortname, "unknown Cardinal Technologies");
1377 }
1378
1379 strcpy(card->driver, "miro");
1380 sprintf(card->longname, "%s: OPTi%s, %s at 0x%lx, irq %d, dma %d&%d",
1381 card->shortname, miro->name, pcm->name, miro->wss_base + 4,
1382 miro->irq, miro->dma1, miro->dma2);
1383
1384 if (miro->mpu_port <= 0 || miro->mpu_port == SNDRV_AUTO_PORT)
1385 rmidi = NULL;
1386 else
1387 if ((error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
1388 miro->mpu_port, 0, miro->mpu_irq, SA_INTERRUPT,
1389 &rmidi)))
1390 snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n", miro->mpu_port);
1391
1392 if (miro->fm_port > 0 && miro->fm_port != SNDRV_AUTO_PORT) {
1393 struct snd_opl3 *opl3 = NULL;
1394 struct snd_opl4 *opl4;
1395 if (snd_opl4_create(card, miro->fm_port, miro->fm_port - 8,
1396 2, &opl3, &opl4) < 0)
1397 snd_printk(KERN_WARNING "no OPL4 device at 0x%lx\n", miro->fm_port);
1398 }
1399
1400 if ((error = snd_set_aci_init_values(miro)) < 0) {
1401 snd_card_free(card);
1402 return error;
1403 }
1404
1405 snd_card_set_dev(card, &devptr->dev);
1406
1407 if ((error = snd_card_register(card))) {
1408 snd_card_free(card);
1409 return error;
1410 }
1411
1412 platform_set_drvdata(devptr, card);
1413 return 0;
1414}
1415
1416static int __devexit snd_miro_remove(struct platform_device *devptr)
1417{
1418 snd_card_free(platform_get_drvdata(devptr));
1419 platform_set_drvdata(devptr, NULL);
1420 return 0;
1421}
1422
1423static struct platform_driver snd_miro_driver = {
1424 .probe = snd_miro_probe,
1425 .remove = __devexit_p(snd_miro_remove),
1426 /* FIXME: suspend/resume */
1427 .driver = {
1428 .name = DRIVER_NAME
1429 },
1430};
1431
1432static int __init alsa_card_miro_init(void)
1433{
1434 int error;
1435
1436 if ((error = platform_driver_register(&snd_miro_driver)) < 0)
1437 return error;
1438 device = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
1439 if (! IS_ERR(device))
1440 return 0;
1441#ifdef MODULE
1442 printk(KERN_ERR "no miro soundcard found\n");
1443#endif
1444 platform_driver_unregister(&snd_miro_driver);
1445 return PTR_ERR(device);
1446}
1447
1448static void __exit alsa_card_miro_exit(void)
1449{
1450 platform_device_unregister(device);
1451 platform_driver_unregister(&snd_miro_driver);
1452}
1453
1454module_init(alsa_card_miro_init)
1455module_exit(alsa_card_miro_exit)
diff --git a/sound/isa/opti9xx/miro.h b/sound/isa/opti9xx/miro.h
new file mode 100644
index 000000000000..6e1385b8e07e
--- /dev/null
+++ b/sound/isa/opti9xx/miro.h
@@ -0,0 +1,73 @@
1#ifndef _MIRO_H_
2#define _MIRO_H_
3
4#define ACI_REG_COMMAND 0 /* write register offset */
5#define ACI_REG_STATUS 1 /* read register offset */
6#define ACI_REG_BUSY 2 /* busy register offset */
7#define ACI_REG_RDS 2 /* PCM20: RDS register offset */
8#define ACI_MINTIME 500 /* ACI time out limit */
9
10#define ACI_SET_MUTE 0x0d
11#define ACI_SET_POWERAMP 0x0f
12#define ACI_SET_TUNERMUTE 0xa3
13#define ACI_SET_TUNERMONO 0xa4
14#define ACI_SET_IDE 0xd0
15#define ACI_SET_WSS 0xd1
16#define ACI_SET_SOLOMODE 0xd2
17#define ACI_SET_PREAMP 0x03
18#define ACI_GET_PREAMP 0x21
19#define ACI_WRITE_TUNE 0xa7
20#define ACI_READ_TUNERSTEREO 0xa8
21#define ACI_READ_TUNERSTATION 0xa9
22#define ACI_READ_VERSION 0xf1
23#define ACI_READ_IDCODE 0xf2
24#define ACI_INIT 0xff
25#define ACI_STATUS 0xf0
26#define ACI_S_GENERAL 0x00
27#define ACI_ERROR_OP 0xdf
28
29/* ACI Mixer */
30
31/* These are the values for the right channel GET registers.
32 Add an offset of 0x01 for the left channel register.
33 (left=right+0x01) */
34
35#define ACI_GET_MASTER 0x03
36#define ACI_GET_MIC 0x05
37#define ACI_GET_LINE 0x07
38#define ACI_GET_CD 0x09
39#define ACI_GET_SYNTH 0x0b
40#define ACI_GET_PCM 0x0d
41#define ACI_GET_LINE1 0x10 /* Radio on PCM20 */
42#define ACI_GET_LINE2 0x12
43
44#define ACI_GET_EQ1 0x22 /* from Bass ... */
45#define ACI_GET_EQ2 0x24
46#define ACI_GET_EQ3 0x26
47#define ACI_GET_EQ4 0x28
48#define ACI_GET_EQ5 0x2a
49#define ACI_GET_EQ6 0x2c
50#define ACI_GET_EQ7 0x2e /* ... to Treble */
51
52/* And these are the values for the right channel SET registers.
53 For left channel access you have to add an offset of 0x08.
54 MASTER is an exception, which needs an offset of 0x01 */
55
56#define ACI_SET_MASTER 0x00
57#define ACI_SET_MIC 0x30
58#define ACI_SET_LINE 0x31
59#define ACI_SET_CD 0x34
60#define ACI_SET_SYNTH 0x33
61#define ACI_SET_PCM 0x32
62#define ACI_SET_LINE1 0x35 /* Radio on PCM20 */
63#define ACI_SET_LINE2 0x36
64
65#define ACI_SET_EQ1 0x40 /* from Bass ... */
66#define ACI_SET_EQ2 0x41
67#define ACI_SET_EQ3 0x42
68#define ACI_SET_EQ4 0x43
69#define ACI_SET_EQ5 0x44
70#define ACI_SET_EQ6 0x45
71#define ACI_SET_EQ7 0x46 /* ... to Treble */
72
73#endif /* _MIRO_H_ */
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 1e2e19305e38..a2081803a827 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -15,6 +15,18 @@ config SND_AD1889
15 To compile this as a module, choose M here: the module 15 To compile this as a module, choose M here: the module
16 will be called snd-ad1889. 16 will be called snd-ad1889.
17 17
18config SND_ALS300
19 tristate "Avance Logic ALS300/ALS300+"
20 depends on SND
21 select SND_PCM
22 select SND_AC97_CODEC
23 select SND_OPL3_LIB
24 help
25 Say 'Y' or 'M' to include support for Avance Logic ALS300/ALS300+
26
27 To compile this driver as a module, choose M here: the module
28 will be called snd-als300
29
18config SND_ALS4000 30config SND_ALS4000
19 tristate "Avance Logic ALS4000" 31 tristate "Avance Logic ALS4000"
20 depends on SND && ISA_DMA_API 32 depends on SND && ISA_DMA_API
@@ -195,8 +207,9 @@ config SND_CS46XX
195 will be called snd-cs46xx. 207 will be called snd-cs46xx.
196 208
197config SND_CS46XX_NEW_DSP 209config SND_CS46XX_NEW_DSP
198 bool "Cirrus Logic (Sound Fusion) New DSP support (EXPERIMENTAL)" 210 bool "Cirrus Logic (Sound Fusion) New DSP support"
199 depends on SND_CS46XX && EXPERIMENTAL 211 depends on SND_CS46XX
212 default y
200 help 213 help
201 Say Y here to use a new DSP image for SPDIF and dual codecs. 214 Say Y here to use a new DSP image for SPDIF and dual codecs.
202 215
@@ -466,6 +479,19 @@ config SND_PCXHR
466 To compile this driver as a module, choose M here: the module 479 To compile this driver as a module, choose M here: the module
467 will be called snd-pcxhr. 480 will be called snd-pcxhr.
468 481
482config SND_RIPTIDE
483 tristate "Conexant Riptide"
484 depends on SND
485 depends on FW_LOADER
486 select SND_OPL3_LIB
487 select SND_MPU401_UART
488 select SND_AC97_CODEC
489 help
490 Say 'Y' or 'M' to include support for Conexant Riptide chip.
491
492 To compile this driver as a module, choose M here: the module
493 will be called snd-riptide
494
469config SND_RME32 495config SND_RME32
470 tristate "RME Digi32, 32/8, 32 PRO" 496 tristate "RME Digi32, 32/8, 32 PRO"
471 depends on SND 497 depends on SND
diff --git a/sound/pci/Makefile b/sound/pci/Makefile
index a6c3cd58fe94..cba5105aafea 100644
--- a/sound/pci/Makefile
+++ b/sound/pci/Makefile
@@ -4,6 +4,7 @@
4# 4#
5 5
6snd-ad1889-objs := ad1889.o 6snd-ad1889-objs := ad1889.o
7snd-als300-objs := als300.o
7snd-als4000-objs := als4000.o 8snd-als4000-objs := als4000.o
8snd-atiixp-objs := atiixp.o 9snd-atiixp-objs := atiixp.o
9snd-atiixp-modem-objs := atiixp_modem.o 10snd-atiixp-modem-objs := atiixp_modem.o
@@ -27,6 +28,7 @@ snd-via82xx-modem-objs := via82xx_modem.o
27 28
28# Toplevel Module Dependency 29# Toplevel Module Dependency
29obj-$(CONFIG_SND_AD1889) += snd-ad1889.o 30obj-$(CONFIG_SND_AD1889) += snd-ad1889.o
31obj-$(CONFIG_SND_ALS300) += snd-als300.o
30obj-$(CONFIG_SND_ALS4000) += snd-als4000.o 32obj-$(CONFIG_SND_ALS4000) += snd-als4000.o
31obj-$(CONFIG_SND_ATIIXP) += snd-atiixp.o 33obj-$(CONFIG_SND_ATIIXP) += snd-atiixp.o
32obj-$(CONFIG_SND_ATIIXP_MODEM) += snd-atiixp-modem.o 34obj-$(CONFIG_SND_ATIIXP_MODEM) += snd-atiixp-modem.o
@@ -62,6 +64,7 @@ obj-$(CONFIG_SND) += \
62 mixart/ \ 64 mixart/ \
63 nm256/ \ 65 nm256/ \
64 pcxhr/ \ 66 pcxhr/ \
67 riptide/ \
65 rme9652/ \ 68 rme9652/ \
66 trident/ \ 69 trident/ \
67 ymfpci/ \ 70 ymfpci/ \
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
new file mode 100644
index 000000000000..37b80570a5c6
--- /dev/null
+++ b/sound/pci/als300.c
@@ -0,0 +1,866 @@
1/*
2 * als300.c - driver for Avance Logic ALS300/ALS300+ soundcards.
3 * Copyright (C) 2005 by Ash Willis <ashwillis@programmer.net>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * TODO
20 * 4 channel playback for ALS300+
21 * gameport
22 * mpu401
23 * opl3
24 *
25 * NOTES
26 * The BLOCK_COUNTER registers for the ALS300(+) return a figure related to
27 * the position in the current period, NOT the whole buffer. It is important
28 * to know which period we are in so we can calculate the correct pointer.
29 * This is why we always use 2 periods. We can then use a flip-flop variable
30 * to keep track of what period we are in.
31 */
32
33#include <sound/driver.h>
34#include <linux/delay.h>
35#include <linux/init.h>
36#include <linux/moduleparam.h>
37#include <linux/pci.h>
38#include <linux/interrupt.h>
39#include <linux/slab.h>
40
41#include <asm/io.h>
42
43#include <sound/core.h>
44#include <sound/control.h>
45#include <sound/initval.h>
46#include <sound/pcm.h>
47#include <sound/pcm_params.h>
48#include <sound/ac97_codec.h>
49#include <sound/opl3.h>
50
51/* snd_als300_set_irq_flag */
52#define IRQ_DISABLE 0
53#define IRQ_ENABLE 1
54
55/* I/O port layout */
56#define AC97_ACCESS 0x00
57#define AC97_READ 0x04
58#define AC97_STATUS 0x06
59#define AC97_DATA_AVAIL (1<<6)
60#define AC97_BUSY (1<<7)
61#define ALS300_IRQ_STATUS 0x07 /* ALS300 Only */
62#define IRQ_PLAYBACK (1<<3)
63#define IRQ_CAPTURE (1<<2)
64#define GCR_DATA 0x08
65#define GCR_INDEX 0x0C
66#define ALS300P_DRAM_IRQ_STATUS 0x0D /* ALS300+ Only */
67#define MPU_IRQ_STATUS 0x0E /* ALS300 Rev. E+, ALS300+ */
68#define ALS300P_IRQ_STATUS 0x0F /* ALS300+ Only */
69
70/* General Control Registers */
71#define PLAYBACK_START 0x80
72#define PLAYBACK_END 0x81
73#define PLAYBACK_CONTROL 0x82
74#define TRANSFER_START (1<<16)
75#define FIFO_PAUSE (1<<17)
76#define RECORD_START 0x83
77#define RECORD_END 0x84
78#define RECORD_CONTROL 0x85
79#define DRAM_WRITE_CONTROL 0x8B
80#define WRITE_TRANS_START (1<<16)
81#define DRAM_MODE_2 (1<<17)
82#define MISC_CONTROL 0x8C
83#define IRQ_SET_BIT (1<<15)
84#define VMUTE_NORMAL (1<<20)
85#define MMUTE_NORMAL (1<<21)
86#define MUS_VOC_VOL 0x8E
87#define PLAYBACK_BLOCK_COUNTER 0x9A
88#define RECORD_BLOCK_COUNTER 0x9B
89
90#define DEBUG_CALLS 1
91#define DEBUG_PLAY_REC 1
92
93#if DEBUG_CALLS
94#define snd_als300_dbgcalls(format, args...) printk(format, ##args)
95#define snd_als300_dbgcallenter() printk(KERN_ERR "--> %s\n", __FUNCTION__)
96#define snd_als300_dbgcallleave() printk(KERN_ERR "<-- %s\n", __FUNCTION__)
97#else
98#define snd_als300_dbgcalls(format, args...)
99#define snd_als300_dbgcallenter()
100#define snd_als300_dbgcallleave()
101#endif
102
103#if DEBUG_PLAY_REC
104#define snd_als300_dbgplay(format, args...) printk(KERN_ERR format, ##args)
105#else
106#define snd_als300_dbgplay(format, args...)
107#endif
108
109enum {DEVICE_ALS300, DEVICE_ALS300_PLUS};
110
111MODULE_AUTHOR("Ash Willis <ashwillis@programmer.net>");
112MODULE_DESCRIPTION("Avance Logic ALS300");
113MODULE_LICENSE("GPL");
114MODULE_SUPPORTED_DEVICE("{{Avance Logic,ALS300},{Avance Logic,ALS300+}}");
115
116static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
117static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
118static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
119
120struct snd_als300 {
121 unsigned long port;
122 spinlock_t reg_lock;
123 struct snd_card *card;
124 struct pci_dev *pci;
125
126 struct snd_pcm *pcm;
127 struct snd_pcm_substream *playback_substream;
128 struct snd_pcm_substream *capture_substream;
129
130 struct snd_ac97 *ac97;
131 struct snd_opl3 *opl3;
132
133 struct resource *res_port;
134
135 int irq;
136
137 int chip_type; /* ALS300 or ALS300+ */
138
139 char revision;
140};
141
142struct snd_als300_substream_data {
143 int period_flipflop;
144 int control_register;
145 int block_counter_register;
146};
147
148static struct pci_device_id snd_als300_ids[] = {
149 { 0x4005, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300 },
150 { 0x4005, 0x0308, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300_PLUS },
151 { 0, }
152};
153
154MODULE_DEVICE_TABLE(pci, snd_als300_ids);
155
156static inline u32 snd_als300_gcr_read(unsigned long port, unsigned short reg)
157{
158 outb(reg, port+GCR_INDEX);
159 return inl(port+GCR_DATA);
160}
161
162static inline void snd_als300_gcr_write(unsigned long port,
163 unsigned short reg, u32 val)
164{
165 outb(reg, port+GCR_INDEX);
166 outl(val, port+GCR_DATA);
167}
168
169/* Enable/Disable Interrupts */
170static void snd_als300_set_irq_flag(struct snd_als300 *chip, int cmd)
171{
172 u32 tmp = snd_als300_gcr_read(chip->port, MISC_CONTROL);
173 snd_als300_dbgcallenter();
174
175 /* boolean XOR check, since old vs. new hardware have
176 directly reversed bit setting for ENABLE and DISABLE.
177 ALS300+ acts like newer versions of ALS300 */
178 if (((chip->revision > 5 || chip->chip_type == DEVICE_ALS300_PLUS) ^
179 (cmd == IRQ_ENABLE)) == 0)
180 tmp |= IRQ_SET_BIT;
181 else
182 tmp &= ~IRQ_SET_BIT;
183 snd_als300_gcr_write(chip->port, MISC_CONTROL, tmp);
184 snd_als300_dbgcallleave();
185}
186
187static int snd_als300_free(struct snd_als300 *chip)
188{
189 snd_als300_dbgcallenter();
190 snd_als300_set_irq_flag(chip, IRQ_DISABLE);
191 if (chip->irq >= 0)
192 free_irq(chip->irq, (void *)chip);
193 pci_release_regions(chip->pci);
194 pci_disable_device(chip->pci);
195 kfree(chip);
196 snd_als300_dbgcallleave();
197 return 0;
198}
199
200static int snd_als300_dev_free(struct snd_device *device)
201{
202 struct snd_als300 *chip = device->device_data;
203 return snd_als300_free(chip);
204}
205
206static irqreturn_t snd_als300_interrupt(int irq, void *dev_id,
207 struct pt_regs *regs)
208{
209 u8 status;
210 struct snd_als300 *chip = dev_id;
211 struct snd_als300_substream_data *data;
212
213 status = inb(chip->port+ALS300_IRQ_STATUS);
214 if (!status) /* shared IRQ, for different device?? Exit ASAP! */
215 return IRQ_NONE;
216
217 /* ACK everything ASAP */
218 outb(status, chip->port+ALS300_IRQ_STATUS);
219 if (status & IRQ_PLAYBACK) {
220 if (chip->pcm && chip->playback_substream) {
221 data = chip->playback_substream->runtime->private_data;
222 data->period_flipflop ^= 1;
223 snd_pcm_period_elapsed(chip->playback_substream);
224 snd_als300_dbgplay("IRQ_PLAYBACK\n");
225 }
226 }
227 if (status & IRQ_CAPTURE) {
228 if (chip->pcm && chip->capture_substream) {
229 data = chip->capture_substream->runtime->private_data;
230 data->period_flipflop ^= 1;
231 snd_pcm_period_elapsed(chip->capture_substream);
232 snd_als300_dbgplay("IRQ_CAPTURE\n");
233 }
234 }
235 return IRQ_HANDLED;
236}
237
238static irqreturn_t snd_als300plus_interrupt(int irq, void *dev_id,
239 struct pt_regs *regs)
240{
241 u8 general, mpu, dram;
242 struct snd_als300 *chip = dev_id;
243 struct snd_als300_substream_data *data;
244
245 general = inb(chip->port+ALS300P_IRQ_STATUS);
246 mpu = inb(chip->port+MPU_IRQ_STATUS);
247 dram = inb(chip->port+ALS300P_DRAM_IRQ_STATUS);
248
249 /* shared IRQ, for different device?? Exit ASAP! */
250 if ((general == 0) && ((mpu & 0x80) == 0) && ((dram & 0x01) == 0))
251 return IRQ_NONE;
252
253 if (general & IRQ_PLAYBACK) {
254 if (chip->pcm && chip->playback_substream) {
255 outb(IRQ_PLAYBACK, chip->port+ALS300P_IRQ_STATUS);
256 data = chip->playback_substream->runtime->private_data;
257 data->period_flipflop ^= 1;
258 snd_pcm_period_elapsed(chip->playback_substream);
259 snd_als300_dbgplay("IRQ_PLAYBACK\n");
260 }
261 }
262 if (general & IRQ_CAPTURE) {
263 if (chip->pcm && chip->capture_substream) {
264 outb(IRQ_CAPTURE, chip->port+ALS300P_IRQ_STATUS);
265 data = chip->capture_substream->runtime->private_data;
266 data->period_flipflop ^= 1;
267 snd_pcm_period_elapsed(chip->capture_substream);
268 snd_als300_dbgplay("IRQ_CAPTURE\n");
269 }
270 }
271 /* FIXME: Ack other interrupt types. Not important right now as
272 * those other devices aren't enabled. */
273 return IRQ_HANDLED;
274}
275
276static void __devexit snd_als300_remove(struct pci_dev *pci)
277{
278 snd_als300_dbgcallenter();
279 snd_card_free(pci_get_drvdata(pci));
280 pci_set_drvdata(pci, NULL);
281 snd_als300_dbgcallleave();
282}
283
284static unsigned short snd_als300_ac97_read(struct snd_ac97 *ac97,
285 unsigned short reg)
286{
287 int i;
288 struct snd_als300 *chip = ac97->private_data;
289
290 for (i = 0; i < 1000; i++) {
291 if ((inb(chip->port+AC97_STATUS) & (AC97_BUSY)) == 0)
292 break;
293 udelay(10);
294 }
295 outl((reg << 24) | (1 << 31), chip->port+AC97_ACCESS);
296
297 for (i = 0; i < 1000; i++) {
298 if ((inb(chip->port+AC97_STATUS) & (AC97_DATA_AVAIL)) != 0)
299 break;
300 udelay(10);
301 }
302 return inw(chip->port+AC97_READ);
303}
304
305static void snd_als300_ac97_write(struct snd_ac97 *ac97,
306 unsigned short reg, unsigned short val)
307{
308 int i;
309 struct snd_als300 *chip = ac97->private_data;
310
311 for (i = 0; i < 1000; i++) {
312 if ((inb(chip->port+AC97_STATUS) & (AC97_BUSY)) == 0)
313 break;
314 udelay(10);
315 }
316 outl((reg << 24) | val, chip->port+AC97_ACCESS);
317}
318
319static int snd_als300_ac97(struct snd_als300 *chip)
320{
321 struct snd_ac97_bus *bus;
322 struct snd_ac97_template ac97;
323 int err;
324 static struct snd_ac97_bus_ops ops = {
325 .write = snd_als300_ac97_write,
326 .read = snd_als300_ac97_read,
327 };
328
329 snd_als300_dbgcallenter();
330 if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &bus)) < 0)
331 return err;
332
333 memset(&ac97, 0, sizeof(ac97));
334 ac97.private_data = chip;
335
336 snd_als300_dbgcallleave();
337 return snd_ac97_mixer(bus, &ac97, &chip->ac97);
338}
339
340/* hardware definition
341 *
342 * In AC97 mode, we always use 48k/16bit/stereo.
343 * Any request to change data type is ignored by
344 * the card when it is running outside of legacy
345 * mode.
346 */
347static struct snd_pcm_hardware snd_als300_playback_hw =
348{
349 .info = (SNDRV_PCM_INFO_MMAP |
350 SNDRV_PCM_INFO_INTERLEAVED |
351 SNDRV_PCM_INFO_PAUSE |
352 SNDRV_PCM_INFO_MMAP_VALID),
353 .formats = SNDRV_PCM_FMTBIT_S16,
354 .rates = SNDRV_PCM_RATE_48000,
355 .rate_min = 48000,
356 .rate_max = 48000,
357 .channels_min = 2,
358 .channels_max = 2,
359 .buffer_bytes_max = 64 * 1024,
360 .period_bytes_min = 64,
361 .period_bytes_max = 32 * 1024,
362 .periods_min = 2,
363 .periods_max = 2,
364};
365
366static struct snd_pcm_hardware snd_als300_capture_hw =
367{
368 .info = (SNDRV_PCM_INFO_MMAP |
369 SNDRV_PCM_INFO_INTERLEAVED |
370 SNDRV_PCM_INFO_PAUSE |
371 SNDRV_PCM_INFO_MMAP_VALID),
372 .formats = SNDRV_PCM_FMTBIT_S16,
373 .rates = SNDRV_PCM_RATE_48000,
374 .rate_min = 48000,
375 .rate_max = 48000,
376 .channels_min = 2,
377 .channels_max = 2,
378 .buffer_bytes_max = 64 * 1024,
379 .period_bytes_min = 64,
380 .period_bytes_max = 32 * 1024,
381 .periods_min = 2,
382 .periods_max = 2,
383};
384
385static int snd_als300_playback_open(struct snd_pcm_substream *substream)
386{
387 struct snd_als300 *chip = snd_pcm_substream_chip(substream);
388 struct snd_pcm_runtime *runtime = substream->runtime;
389 struct snd_als300_substream_data *data = kzalloc(sizeof(*data),
390 GFP_KERNEL);
391
392 snd_als300_dbgcallenter();
393 chip->playback_substream = substream;
394 runtime->hw = snd_als300_playback_hw;
395 runtime->private_data = data;
396 data->control_register = PLAYBACK_CONTROL;
397 data->block_counter_register = PLAYBACK_BLOCK_COUNTER;
398 snd_als300_dbgcallleave();
399 return 0;
400}
401
402static int snd_als300_playback_close(struct snd_pcm_substream *substream)
403{
404 struct snd_als300 *chip = snd_pcm_substream_chip(substream);
405 struct snd_als300_substream_data *data;
406
407 data = substream->runtime->private_data;
408 snd_als300_dbgcallenter();
409 kfree(data);
410 chip->playback_substream = NULL;
411 snd_pcm_lib_free_pages(substream);
412 snd_als300_dbgcallleave();
413 return 0;
414}
415
416static int snd_als300_capture_open(struct snd_pcm_substream *substream)
417{
418 struct snd_als300 *chip = snd_pcm_substream_chip(substream);
419 struct snd_pcm_runtime *runtime = substream->runtime;
420 struct snd_als300_substream_data *data = kzalloc(sizeof(*data),
421 GFP_KERNEL);
422
423 snd_als300_dbgcallenter();
424 chip->capture_substream = substream;
425 runtime->hw = snd_als300_capture_hw;
426 runtime->private_data = data;
427 data->control_register = RECORD_CONTROL;
428 data->block_counter_register = RECORD_BLOCK_COUNTER;
429 snd_als300_dbgcallleave();
430 return 0;
431}
432
433static int snd_als300_capture_close(struct snd_pcm_substream *substream)
434{
435 struct snd_als300 *chip = snd_pcm_substream_chip(substream);
436 struct snd_als300_substream_data *data;
437
438 data = substream->runtime->private_data;
439 snd_als300_dbgcallenter();
440 kfree(data);
441 chip->capture_substream = NULL;
442 snd_pcm_lib_free_pages(substream);
443 snd_als300_dbgcallleave();
444 return 0;
445}
446
447static int snd_als300_pcm_hw_params(struct snd_pcm_substream *substream,
448 snd_pcm_hw_params_t * hw_params)
449{
450 return snd_pcm_lib_malloc_pages(substream,
451 params_buffer_bytes(hw_params));
452}
453
454static int snd_als300_pcm_hw_free(struct snd_pcm_substream *substream)
455{
456 return snd_pcm_lib_free_pages(substream);
457}
458
459static int snd_als300_playback_prepare(struct snd_pcm_substream *substream)
460{
461 u32 tmp;
462 struct snd_als300 *chip = snd_pcm_substream_chip(substream);
463 struct snd_pcm_runtime *runtime = substream->runtime;
464 unsigned short period_bytes = snd_pcm_lib_period_bytes(substream);
465 unsigned short buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
466
467 snd_als300_dbgcallenter();
468 spin_lock_irq(&chip->reg_lock);
469 tmp = snd_als300_gcr_read(chip->port, PLAYBACK_CONTROL);
470 tmp &= ~TRANSFER_START;
471
472 snd_als300_dbgplay("Period bytes: %d Buffer bytes %d\n",
473 period_bytes, buffer_bytes);
474
475 /* set block size */
476 tmp &= 0xffff0000;
477 tmp |= period_bytes - 1;
478 snd_als300_gcr_write(chip->port, PLAYBACK_CONTROL, tmp);
479
480 /* set dma area */
481 snd_als300_gcr_write(chip->port, PLAYBACK_START,
482 runtime->dma_addr);
483 snd_als300_gcr_write(chip->port, PLAYBACK_END,
484 runtime->dma_addr + buffer_bytes - 1);
485 spin_unlock_irq(&chip->reg_lock);
486 snd_als300_dbgcallleave();
487 return 0;
488}
489
490static int snd_als300_capture_prepare(struct snd_pcm_substream *substream)
491{
492 u32 tmp;
493 struct snd_als300 *chip = snd_pcm_substream_chip(substream);
494 struct snd_pcm_runtime *runtime = substream->runtime;
495 unsigned short period_bytes = snd_pcm_lib_period_bytes(substream);
496 unsigned short buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
497
498 snd_als300_dbgcallenter();
499 spin_lock_irq(&chip->reg_lock);
500 tmp = snd_als300_gcr_read(chip->port, RECORD_CONTROL);
501 tmp &= ~TRANSFER_START;
502
503 snd_als300_dbgplay("Period bytes: %d Buffer bytes %d\n", period_bytes,
504 buffer_bytes);
505
506 /* set block size */
507 tmp &= 0xffff0000;
508 tmp |= period_bytes - 1;
509
510 /* set dma area */
511 snd_als300_gcr_write(chip->port, RECORD_CONTROL, tmp);
512 snd_als300_gcr_write(chip->port, RECORD_START,
513 runtime->dma_addr);
514 snd_als300_gcr_write(chip->port, RECORD_END,
515 runtime->dma_addr + buffer_bytes - 1);
516 spin_unlock_irq(&chip->reg_lock);
517 snd_als300_dbgcallleave();
518 return 0;
519}
520
521static int snd_als300_trigger(struct snd_pcm_substream *substream, int cmd)
522{
523 struct snd_als300 *chip = snd_pcm_substream_chip(substream);
524 u32 tmp;
525 struct snd_als300_substream_data *data;
526 unsigned short reg;
527 int ret = 0;
528
529 data = substream->runtime->private_data;
530 reg = data->control_register;
531
532 snd_als300_dbgcallenter();
533 spin_lock(&chip->reg_lock);
534 switch (cmd) {
535 case SNDRV_PCM_TRIGGER_START:
536 case SNDRV_PCM_TRIGGER_RESUME:
537 tmp = snd_als300_gcr_read(chip->port, reg);
538 data->period_flipflop = 1;
539 snd_als300_gcr_write(chip->port, reg, tmp | TRANSFER_START);
540 snd_als300_dbgplay("TRIGGER START\n");
541 break;
542 case SNDRV_PCM_TRIGGER_STOP:
543 case SNDRV_PCM_TRIGGER_SUSPEND:
544 tmp = snd_als300_gcr_read(chip->port, reg);
545 snd_als300_gcr_write(chip->port, reg, tmp & ~TRANSFER_START);
546 snd_als300_dbgplay("TRIGGER STOP\n");
547 break;
548 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
549 tmp = snd_als300_gcr_read(chip->port, reg);
550 snd_als300_gcr_write(chip->port, reg, tmp | FIFO_PAUSE);
551 snd_als300_dbgplay("TRIGGER PAUSE\n");
552 break;
553 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
554 tmp = snd_als300_gcr_read(chip->port, reg);
555 snd_als300_gcr_write(chip->port, reg, tmp & ~FIFO_PAUSE);
556 snd_als300_dbgplay("TRIGGER RELEASE\n");
557 break;
558 default:
559 snd_als300_dbgplay("TRIGGER INVALID\n");
560 ret = -EINVAL;
561 }
562 spin_unlock(&chip->reg_lock);
563 snd_als300_dbgcallleave();
564 return ret;
565}
566
567static snd_pcm_uframes_t snd_als300_pointer(struct snd_pcm_substream *substream)
568{
569 u16 current_ptr;
570 struct snd_als300 *chip = snd_pcm_substream_chip(substream);
571 struct snd_als300_substream_data *data;
572 unsigned short period_bytes;
573
574 data = substream->runtime->private_data;
575 period_bytes = snd_pcm_lib_period_bytes(substream);
576
577 snd_als300_dbgcallenter();
578 spin_lock(&chip->reg_lock);
579 current_ptr = (u16) snd_als300_gcr_read(chip->port,
580 data->block_counter_register) + 4;
581 spin_unlock(&chip->reg_lock);
582 if (current_ptr > period_bytes)
583 current_ptr = 0;
584 else
585 current_ptr = period_bytes - current_ptr;
586
587 if (data->period_flipflop == 0)
588 current_ptr += period_bytes;
589 snd_als300_dbgplay("Pointer (bytes): %d\n", current_ptr);
590 snd_als300_dbgcallleave();
591 return bytes_to_frames(substream->runtime, current_ptr);
592}
593
594static struct snd_pcm_ops snd_als300_playback_ops = {
595 .open = snd_als300_playback_open,
596 .close = snd_als300_playback_close,
597 .ioctl = snd_pcm_lib_ioctl,
598 .hw_params = snd_als300_pcm_hw_params,
599 .hw_free = snd_als300_pcm_hw_free,
600 .prepare = snd_als300_playback_prepare,
601 .trigger = snd_als300_trigger,
602 .pointer = snd_als300_pointer,
603};
604
605static struct snd_pcm_ops snd_als300_capture_ops = {
606 .open = snd_als300_capture_open,
607 .close = snd_als300_capture_close,
608 .ioctl = snd_pcm_lib_ioctl,
609 .hw_params = snd_als300_pcm_hw_params,
610 .hw_free = snd_als300_pcm_hw_free,
611 .prepare = snd_als300_capture_prepare,
612 .trigger = snd_als300_trigger,
613 .pointer = snd_als300_pointer,
614};
615
616static int __devinit snd_als300_new_pcm(struct snd_als300 *chip)
617{
618 struct snd_pcm *pcm;
619 int err;
620
621 snd_als300_dbgcallenter();
622 err = snd_pcm_new(chip->card, "ALS300", 0, 1, 1, &pcm);
623 if (err < 0)
624 return err;
625 pcm->private_data = chip;
626 strcpy(pcm->name, "ALS300");
627 chip->pcm = pcm;
628
629 /* set operators */
630 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
631 &snd_als300_playback_ops);
632 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
633 &snd_als300_capture_ops);
634
635 /* pre-allocation of buffers */
636 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
637 snd_dma_pci_data(chip->pci), 64*1024, 64*1024);
638 snd_als300_dbgcallleave();
639 return 0;
640}
641
642static void snd_als300_init(struct snd_als300 *chip)
643{
644 unsigned long flags;
645 u32 tmp;
646
647 snd_als300_dbgcallenter();
648 spin_lock_irqsave(&chip->reg_lock, flags);
649 chip->revision = (snd_als300_gcr_read(chip->port, MISC_CONTROL) >> 16)
650 & 0x0000000F;
651 /* Setup DRAM */
652 tmp = snd_als300_gcr_read(chip->port, DRAM_WRITE_CONTROL);
653 snd_als300_gcr_write(chip->port, DRAM_WRITE_CONTROL,
654 (tmp | DRAM_MODE_2)
655 & ~WRITE_TRANS_START);
656
657 /* Enable IRQ output */
658 snd_als300_set_irq_flag(chip, IRQ_ENABLE);
659
660 /* Unmute hardware devices so their outputs get routed to
661 * the onboard mixer */
662 tmp = snd_als300_gcr_read(chip->port, MISC_CONTROL);
663 snd_als300_gcr_write(chip->port, MISC_CONTROL,
664 tmp | VMUTE_NORMAL | MMUTE_NORMAL);
665
666 /* Reset volumes */
667 snd_als300_gcr_write(chip->port, MUS_VOC_VOL, 0);
668
669 /* Make sure playback transfer is stopped */
670 tmp = snd_als300_gcr_read(chip->port, PLAYBACK_CONTROL);
671 snd_als300_gcr_write(chip->port, PLAYBACK_CONTROL,
672 tmp & ~TRANSFER_START);
673 spin_unlock_irqrestore(&chip->reg_lock, flags);
674 snd_als300_dbgcallleave();
675}
676
677static int __devinit snd_als300_create(snd_card_t *card,
678 struct pci_dev *pci, int chip_type,
679 struct snd_als300 **rchip)
680{
681 struct snd_als300 *chip;
682 void *irq_handler;
683 int err;
684
685 static snd_device_ops_t ops = {
686 .dev_free = snd_als300_dev_free,
687 };
688 *rchip = NULL;
689
690 snd_als300_dbgcallenter();
691 if ((err = pci_enable_device(pci)) < 0)
692 return err;
693
694 if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
695 pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
696 printk(KERN_ERR "error setting 28bit DMA mask\n");
697 pci_disable_device(pci);
698 return -ENXIO;
699 }
700 pci_set_master(pci);
701
702 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
703 if (chip == NULL) {
704 pci_disable_device(pci);
705 return -ENOMEM;
706 }
707
708 chip->card = card;
709 chip->pci = pci;
710 chip->irq = -1;
711 chip->chip_type = chip_type;
712 spin_lock_init(&chip->reg_lock);
713
714 if ((err = pci_request_regions(pci, "ALS300")) < 0) {
715 kfree(chip);
716 pci_disable_device(pci);
717 return err;
718 }
719 chip->port = pci_resource_start(pci, 0);
720
721 if (chip->chip_type == DEVICE_ALS300_PLUS)
722 irq_handler = snd_als300plus_interrupt;
723 else
724 irq_handler = snd_als300_interrupt;
725
726 if (request_irq(pci->irq, irq_handler, SA_INTERRUPT|SA_SHIRQ,
727 card->shortname, (void *)chip)) {
728 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
729 snd_als300_free(chip);
730 return -EBUSY;
731 }
732 chip->irq = pci->irq;
733
734
735 snd_als300_init(chip);
736
737 if (snd_als300_ac97(chip) < 0) {
738 snd_printk(KERN_WARNING "Could not create ac97\n");
739 snd_als300_free(chip);
740 return err;
741 }
742
743 if ((err = snd_als300_new_pcm(chip)) < 0) {
744 snd_printk(KERN_WARNING "Could not create PCM\n");
745 snd_als300_free(chip);
746 return err;
747 }
748
749 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
750 chip, &ops)) < 0) {
751 snd_als300_free(chip);
752 return err;
753 }
754
755 snd_card_set_dev(card, &pci->dev);
756
757 *rchip = chip;
758 snd_als300_dbgcallleave();
759 return 0;
760}
761
762#ifdef CONFIG_PM
763static int snd_als300_suspend(struct pci_dev *pci, pm_message_t state)
764{
765 struct snd_card *card = pci_get_drvdata(pci);
766 struct snd_als300 *chip = card->private_data;
767
768 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
769 snd_pcm_suspend_all(chip->pcm);
770 snd_ac97_suspend(chip->ac97);
771
772 pci_set_power_state(pci, PCI_D3hot);
773 pci_disable_device(pci);
774 pci_save_state(pci);
775 return 0;
776}
777
778static int snd_als300_resume(struct pci_dev *pci)
779{
780 struct snd_card *card = pci_get_drvdata(pci);
781 struct snd_als300 *chip = card->private_data;
782
783 pci_restore_state(pci);
784 pci_enable_device(pci);
785 pci_set_power_state(pci, PCI_D0);
786 pci_set_master(pci);
787
788 snd_als300_init(chip);
789 snd_ac97_resume(chip->ac97);
790
791 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
792 return 0;
793}
794#endif
795
796static int __devinit snd_als300_probe(struct pci_dev *pci,
797 const struct pci_device_id *pci_id)
798{
799 static int dev;
800 struct snd_card *card;
801 struct snd_als300 *chip;
802 int err, chip_type;
803
804 if (dev >= SNDRV_CARDS)
805 return -ENODEV;
806 if (!enable[dev]) {
807 dev++;
808 return -ENOENT;
809 }
810
811 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
812
813 if (card == NULL)
814 return -ENOMEM;
815
816 chip_type = pci_id->driver_data;
817
818 if ((err = snd_als300_create(card, pci, chip_type, &chip)) < 0) {
819 snd_card_free(card);
820 return err;
821 }
822 card->private_data = chip;
823
824 strcpy(card->driver, "ALS300");
825 if (chip->chip_type == DEVICE_ALS300_PLUS)
826 /* don't know much about ALS300+ yet
827 * print revision number for now */
828 sprintf(card->shortname, "ALS300+ (Rev. %d)", chip->revision);
829 else
830 sprintf(card->shortname, "ALS300 (Rev. %c)", 'A' +
831 chip->revision - 1);
832 sprintf(card->longname, "%s at 0x%lx irq %i",
833 card->shortname, chip->port, chip->irq);
834
835 if ((err = snd_card_register(card)) < 0) {
836 snd_card_free(card);
837 return err;
838 }
839 pci_set_drvdata(pci, card);
840 dev++;
841 return 0;
842}
843
844static struct pci_driver driver = {
845 .name = "ALS300",
846 .id_table = snd_als300_ids,
847 .probe = snd_als300_probe,
848 .remove = __devexit_p(snd_als300_remove),
849#ifdef CONFIG_PM
850 .suspend = snd_als300_suspend,
851 .resume = snd_als300_resume,
852#endif
853};
854
855static int __init alsa_card_als300_init(void)
856{
857 return pci_register_driver(&driver);
858}
859
860static void __exit alsa_card_als300_exit(void)
861{
862 pci_unregister_driver(&driver);
863}
864
865module_init(alsa_card_als300_init)
866module_exit(alsa_card_als300_exit)
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index 4f65ec56bf35..ac4e73f69c1d 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -1046,7 +1046,7 @@ static int snd_cs4281_put_volume(struct snd_kcontrol *kcontrol,
1046 snd_cs4281_pokeBA0(chip, regL, volL); 1046 snd_cs4281_pokeBA0(chip, regL, volL);
1047 change = 1; 1047 change = 1;
1048 } 1048 }
1049 if (ucontrol->value.integer.value[0] != volL) { 1049 if (ucontrol->value.integer.value[1] != volR) {
1050 volR = CS_VOL_MASK - (ucontrol->value.integer.value[1] & CS_VOL_MASK); 1050 volR = CS_VOL_MASK - (ucontrol->value.integer.value[1] & CS_VOL_MASK);
1051 snd_cs4281_pokeBA0(chip, regR, volR); 1051 snd_cs4281_pokeBA0(chip, regR, volR);
1052 change = 1; 1052 change = 1;
@@ -1416,7 +1416,7 @@ static int __devinit snd_cs4281_create(struct snd_card *card,
1416static int snd_cs4281_chip_init(struct cs4281 *chip) 1416static int snd_cs4281_chip_init(struct cs4281 *chip)
1417{ 1417{
1418 unsigned int tmp; 1418 unsigned int tmp;
1419 int timeout; 1419 unsigned long end_time;
1420 int retry_count = 2; 1420 int retry_count = 2;
1421 1421
1422 /* Having EPPMC.FPDN=1 prevent proper chip initialisation */ 1422 /* Having EPPMC.FPDN=1 prevent proper chip initialisation */
@@ -1496,7 +1496,7 @@ static int snd_cs4281_chip_init(struct cs4281 *chip)
1496 /* 1496 /*
1497 * Wait for the DLL ready signal from the clock logic. 1497 * Wait for the DLL ready signal from the clock logic.
1498 */ 1498 */
1499 timeout = 100; 1499 end_time = jiffies + HZ;
1500 do { 1500 do {
1501 /* 1501 /*
1502 * Read the AC97 status register to see if we've seen a CODEC 1502 * Read the AC97 status register to see if we've seen a CODEC
@@ -1504,8 +1504,8 @@ static int snd_cs4281_chip_init(struct cs4281 *chip)
1504 */ 1504 */
1505 if (snd_cs4281_peekBA0(chip, BA0_CLKCR1) & BA0_CLKCR1_DLLRDY) 1505 if (snd_cs4281_peekBA0(chip, BA0_CLKCR1) & BA0_CLKCR1_DLLRDY)
1506 goto __ok0; 1506 goto __ok0;
1507 msleep(1); 1507 schedule_timeout_uninterruptible(1);
1508 } while (timeout-- > 0); 1508 } while (time_after_eq(end_time, jiffies));
1509 1509
1510 snd_printk(KERN_ERR "DLLRDY not seen\n"); 1510 snd_printk(KERN_ERR "DLLRDY not seen\n");
1511 return -EIO; 1511 return -EIO;
@@ -1522,7 +1522,7 @@ static int snd_cs4281_chip_init(struct cs4281 *chip)
1522 /* 1522 /*
1523 * Wait for the codec ready signal from the AC97 codec. 1523 * Wait for the codec ready signal from the AC97 codec.
1524 */ 1524 */
1525 timeout = 100; 1525 end_time = jiffies + HZ;
1526 do { 1526 do {
1527 /* 1527 /*
1528 * Read the AC97 status register to see if we've seen a CODEC 1528 * Read the AC97 status register to see if we've seen a CODEC
@@ -1530,20 +1530,20 @@ static int snd_cs4281_chip_init(struct cs4281 *chip)
1530 */ 1530 */
1531 if (snd_cs4281_peekBA0(chip, BA0_ACSTS) & BA0_ACSTS_CRDY) 1531 if (snd_cs4281_peekBA0(chip, BA0_ACSTS) & BA0_ACSTS_CRDY)
1532 goto __ok1; 1532 goto __ok1;
1533 msleep(1); 1533 schedule_timeout_uninterruptible(1);
1534 } while (timeout-- > 0); 1534 } while (time_after_eq(end_time, jiffies));
1535 1535
1536 snd_printk(KERN_ERR "never read codec ready from AC'97 (0x%x)\n", snd_cs4281_peekBA0(chip, BA0_ACSTS)); 1536 snd_printk(KERN_ERR "never read codec ready from AC'97 (0x%x)\n", snd_cs4281_peekBA0(chip, BA0_ACSTS));
1537 return -EIO; 1537 return -EIO;
1538 1538
1539 __ok1: 1539 __ok1:
1540 if (chip->dual_codec) { 1540 if (chip->dual_codec) {
1541 timeout = 100; 1541 end_time = jiffies + HZ;
1542 do { 1542 do {
1543 if (snd_cs4281_peekBA0(chip, BA0_ACSTS2) & BA0_ACSTS_CRDY) 1543 if (snd_cs4281_peekBA0(chip, BA0_ACSTS2) & BA0_ACSTS_CRDY)
1544 goto __codec2_ok; 1544 goto __codec2_ok;
1545 msleep(1); 1545 schedule_timeout_uninterruptible(1);
1546 } while (timeout-- > 0); 1546 } while (time_after_eq(end_time, jiffies));
1547 snd_printk(KERN_INFO "secondary codec doesn't respond. disable it...\n"); 1547 snd_printk(KERN_INFO "secondary codec doesn't respond. disable it...\n");
1548 chip->dual_codec = 0; 1548 chip->dual_codec = 0;
1549 __codec2_ok: ; 1549 __codec2_ok: ;
@@ -1561,7 +1561,7 @@ static int snd_cs4281_chip_init(struct cs4281 *chip)
1561 * the codec is pumping ADC data across the AC-link. 1561 * the codec is pumping ADC data across the AC-link.
1562 */ 1562 */
1563 1563
1564 timeout = 100; 1564 end_time = jiffies + HZ;
1565 do { 1565 do {
1566 /* 1566 /*
1567 * Read the input slot valid register and see if input slots 3 1567 * Read the input slot valid register and see if input slots 3
@@ -1569,8 +1569,8 @@ static int snd_cs4281_chip_init(struct cs4281 *chip)
1569 */ 1569 */
1570 if ((snd_cs4281_peekBA0(chip, BA0_ACISV) & (BA0_ACISV_SLV(3) | BA0_ACISV_SLV(4))) == (BA0_ACISV_SLV(3) | BA0_ACISV_SLV(4))) 1570 if ((snd_cs4281_peekBA0(chip, BA0_ACISV) & (BA0_ACISV_SLV(3) | BA0_ACISV_SLV(4))) == (BA0_ACISV_SLV(3) | BA0_ACISV_SLV(4)))
1571 goto __ok2; 1571 goto __ok2;
1572 msleep(1); 1572 schedule_timeout_uninterruptible(1);
1573 } while (timeout-- > 0); 1573 } while (time_after_eq(end_time, jiffies));
1574 1574
1575 if (--retry_count > 0) 1575 if (--retry_count > 0)
1576 goto __retry; 1576 goto __retry;
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index b42dff7ceed0..5bee3b536478 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -295,7 +295,7 @@ static int init_unsol_queue(struct hda_bus *bus)
295 snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n"); 295 snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n");
296 return -ENOMEM; 296 return -ENOMEM;
297 } 297 }
298 unsol->workq = create_workqueue("hda_codec"); 298 unsol->workq = create_singlethread_workqueue("hda_codec");
299 if (! unsol->workq) { 299 if (! unsol->workq) {
300 snd_printk(KERN_ERR "hda_codec: can't create workqueue\n"); 300 snd_printk(KERN_ERR "hda_codec: can't create workqueue\n");
301 kfree(unsol); 301 kfree(unsol);
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index c096606970ff..0ad60ae29011 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -81,6 +81,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
81 "{Intel, ESB2}," 81 "{Intel, ESB2},"
82 "{Intel, ICH8}," 82 "{Intel, ICH8},"
83 "{ATI, SB450}," 83 "{ATI, SB450},"
84 "{ATI, SB600},"
84 "{VIA, VT8251}," 85 "{VIA, VT8251},"
85 "{VIA, VT8237A}," 86 "{VIA, VT8237A},"
86 "{SiS, SIS966}," 87 "{SiS, SIS966},"
@@ -1619,6 +1620,7 @@ static struct pci_device_id azx_ids[] = {
1619 { 0x8086, 0x269a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ESB2 */ 1620 { 0x8086, 0x269a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ESB2 */
1620 { 0x8086, 0x284b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH8 */ 1621 { 0x8086, 0x284b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH8 */
1621 { 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB450 */ 1622 { 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB450 */
1623 { 0x1002, 0x4383, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB600 */
1622 { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */ 1624 { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */
1623 { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */ 1625 { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */
1624 { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */ 1626 { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 32401bd8c229..2bfe37e8543c 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -44,6 +44,7 @@ struct ad198x_spec {
44 * dig_out_nid and hp_nid are optional 44 * dig_out_nid and hp_nid are optional
45 */ 45 */
46 unsigned int cur_eapd; 46 unsigned int cur_eapd;
47 unsigned int need_dac_fix;
47 48
48 /* capture */ 49 /* capture */
49 unsigned int num_adc_nids; 50 unsigned int num_adc_nids;
@@ -836,10 +837,14 @@ static int patch_ad1986a(struct hda_codec *codec)
836 case AD1986A_3STACK: 837 case AD1986A_3STACK:
837 spec->num_mixers = 2; 838 spec->num_mixers = 2;
838 spec->mixers[1] = ad1986a_3st_mixers; 839 spec->mixers[1] = ad1986a_3st_mixers;
839 spec->num_init_verbs = 2; 840 spec->num_init_verbs = 3;
840 spec->init_verbs[1] = ad1986a_3st_init_verbs; 841 spec->init_verbs[1] = ad1986a_3st_init_verbs;
842 spec->init_verbs[2] = ad1986a_ch2_init;
841 spec->channel_mode = ad1986a_modes; 843 spec->channel_mode = ad1986a_modes;
842 spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes); 844 spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes);
845 spec->need_dac_fix = 1;
846 spec->multiout.max_channels = 2;
847 spec->multiout.num_dacs = 1;
843 break; 848 break;
844 case AD1986A_LAPTOP: 849 case AD1986A_LAPTOP:
845 spec->mixers[0] = ad1986a_laptop_mixers; 850 spec->mixers[0] = ad1986a_laptop_mixers;
@@ -1555,6 +1560,8 @@ static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
1555{ 1560{
1556 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1561 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1557 struct ad198x_spec *spec = codec->spec; 1562 struct ad198x_spec *spec = codec->spec;
1563 if (spec->need_dac_fix)
1564 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
1558 return snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, 1565 return snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
1559 spec->num_channel_mode, &spec->multiout.max_channels); 1566 spec->num_channel_mode, &spec->multiout.max_channels);
1560} 1567}
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 4c6c9ec8ea5b..66bbdb60f50b 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -52,6 +52,7 @@ enum {
52 ALC880_CLEVO, 52 ALC880_CLEVO,
53 ALC880_TCL_S700, 53 ALC880_TCL_S700,
54 ALC880_LG, 54 ALC880_LG,
55 ALC880_LG_LW,
55#ifdef CONFIG_SND_DEBUG 56#ifdef CONFIG_SND_DEBUG
56 ALC880_TEST, 57 ALC880_TEST,
57#endif 58#endif
@@ -131,6 +132,7 @@ struct alc_spec {
131 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 132 hda_nid_t dig_in_nid; /* digital-in NID; optional */
132 133
133 /* capture source */ 134 /* capture source */
135 unsigned int num_mux_defs;
134 const struct hda_input_mux *input_mux; 136 const struct hda_input_mux *input_mux;
135 unsigned int cur_mux[3]; 137 unsigned int cur_mux[3];
136 138
@@ -172,6 +174,7 @@ struct alc_config_preset {
172 hda_nid_t dig_in_nid; 174 hda_nid_t dig_in_nid;
173 unsigned int num_channel_mode; 175 unsigned int num_channel_mode;
174 const struct hda_channel_mode *channel_mode; 176 const struct hda_channel_mode *channel_mode;
177 unsigned int num_mux_defs;
175 const struct hda_input_mux *input_mux; 178 const struct hda_input_mux *input_mux;
176 void (*unsol_event)(struct hda_codec *, unsigned int); 179 void (*unsol_event)(struct hda_codec *, unsigned int);
177 void (*init_hook)(struct hda_codec *); 180 void (*init_hook)(struct hda_codec *);
@@ -185,7 +188,10 @@ static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
185{ 188{
186 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 189 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
187 struct alc_spec *spec = codec->spec; 190 struct alc_spec *spec = codec->spec;
188 return snd_hda_input_mux_info(spec->input_mux, uinfo); 191 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
192 if (mux_idx >= spec->num_mux_defs)
193 mux_idx = 0;
194 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
189} 195}
190 196
191static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 197static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
@@ -203,7 +209,8 @@ static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v
203 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 209 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
204 struct alc_spec *spec = codec->spec; 210 struct alc_spec *spec = codec->spec;
205 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 211 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
206 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 212 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
213 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
207 spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]); 214 spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]);
208} 215}
209 216
@@ -245,7 +252,8 @@ static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va
245 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these 252 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
246 * are requested. Therefore order this list so that this behaviour will not 253 * are requested. Therefore order this list so that this behaviour will not
247 * cause problems when mixer clients move through the enum sequentially. 254 * cause problems when mixer clients move through the enum sequentially.
248 * NIDs 0x0f and 0x10 have been observed to have this behaviour. 255 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
256 * March 2006.
249 */ 257 */
250static char *alc_pin_mode_names[] = { 258static char *alc_pin_mode_names[] = {
251 "Mic 50pc bias", "Mic 80pc bias", 259 "Mic 50pc bias", "Mic 80pc bias",
@@ -255,19 +263,27 @@ static unsigned char alc_pin_mode_values[] = {
255 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, 263 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
256}; 264};
257/* The control can present all 5 options, or it can limit the options based 265/* The control can present all 5 options, or it can limit the options based
258 * in the pin being assumed to be exclusively an input or an output pin. 266 * in the pin being assumed to be exclusively an input or an output pin. In
267 * addition, "input" pins may or may not process the mic bias option
268 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
269 * accept requests for bias as of chip versions up to March 2006) and/or
270 * wiring in the computer.
259 */ 271 */
260#define ALC_PIN_DIR_IN 0x00 272#define ALC_PIN_DIR_IN 0x00
261#define ALC_PIN_DIR_OUT 0x01 273#define ALC_PIN_DIR_OUT 0x01
262#define ALC_PIN_DIR_INOUT 0x02 274#define ALC_PIN_DIR_INOUT 0x02
275#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
276#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
263 277
264/* Info about the pin modes supported by the three different pin directions. 278/* Info about the pin modes supported by the different pin direction modes.
265 * For each direction the minimum and maximum values are given. 279 * For each direction the minimum and maximum values are given.
266 */ 280 */
267static signed char alc_pin_mode_dir_info[3][2] = { 281static signed char alc_pin_mode_dir_info[5][2] = {
268 { 0, 2 }, /* ALC_PIN_DIR_IN */ 282 { 0, 2 }, /* ALC_PIN_DIR_IN */
269 { 3, 4 }, /* ALC_PIN_DIR_OUT */ 283 { 3, 4 }, /* ALC_PIN_DIR_OUT */
270 { 0, 4 }, /* ALC_PIN_DIR_INOUT */ 284 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
285 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
286 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
271}; 287};
272#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0]) 288#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
273#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1]) 289#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
@@ -329,9 +345,10 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v
329 * input modes. 345 * input modes.
330 * 346 *
331 * Dynamically switching the input/output buffers probably 347 * Dynamically switching the input/output buffers probably
332 * reduces noise slightly, particularly on input. However, 348 * reduces noise slightly (particularly on input) so we'll
333 * havingboth input and output buffers enabled 349 * do it. However, having both input and output buffers
334 * simultaneously doesn't seem to be problematic. 350 * enabled simultaneously doesn't seem to be problematic if
351 * this turns out to be necessary in the future.
335 */ 352 */
336 if (val <= 2) { 353 if (val <= 2) {
337 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE, 354 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE,
@@ -483,6 +500,9 @@ static void setup_preset(struct alc_spec *spec, const struct alc_config_preset *
483 spec->multiout.dig_out_nid = preset->dig_out_nid; 500 spec->multiout.dig_out_nid = preset->dig_out_nid;
484 spec->multiout.hp_nid = preset->hp_nid; 501 spec->multiout.hp_nid = preset->hp_nid;
485 502
503 spec->num_mux_defs = preset->num_mux_defs;
504 if (! spec->num_mux_defs)
505 spec->num_mux_defs = 1;
486 spec->input_mux = preset->input_mux; 506 spec->input_mux = preset->input_mux;
487 507
488 spec->num_adc_nids = preset->num_adc_nids; 508 spec->num_adc_nids = preset->num_adc_nids;
@@ -1427,6 +1447,82 @@ static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
1427} 1447}
1428 1448
1429/* 1449/*
1450 * LG LW20
1451 *
1452 * Pin assignment:
1453 * Speaker-out: 0x14
1454 * Mic-In: 0x18
1455 * Built-in Mic-In: 0x19 (?)
1456 * HP-Out: 0x1b
1457 * SPDIF-Out: 0x1e
1458 */
1459
1460/* seems analog CD is not working */
1461static struct hda_input_mux alc880_lg_lw_capture_source = {
1462 .num_items = 2,
1463 .items = {
1464 { "Mic", 0x0 },
1465 { "Internal Mic", 0x1 },
1466 },
1467};
1468
1469static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
1470 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1471 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
1472 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1473 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1474 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1475 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1476 { } /* end */
1477};
1478
1479static struct hda_verb alc880_lg_lw_init_verbs[] = {
1480 /* set capture source to mic-in */
1481 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1482 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1483 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1484 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1485 /* speaker-out */
1486 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1487 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1488 /* HP-out */
1489 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1490 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1491 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1492 /* mic-in to input */
1493 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1494 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1495 /* built-in mic */
1496 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1497 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1498 /* jack sense */
1499 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1500 { }
1501};
1502
1503/* toggle speaker-output according to the hp-jack state */
1504static void alc880_lg_lw_automute(struct hda_codec *codec)
1505{
1506 unsigned int present;
1507
1508 present = snd_hda_codec_read(codec, 0x1b, 0,
1509 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1510 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
1511 0x80, present ? 0x80 : 0);
1512 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
1513 0x80, present ? 0x80 : 0);
1514}
1515
1516static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
1517{
1518 /* Looks like the unsol event is incompatible with the standard
1519 * definition. 4bit tag is placed at 28 bit!
1520 */
1521 if ((res >> 28) == 0x01)
1522 alc880_lg_lw_automute(codec);
1523}
1524
1525/*
1430 * Common callbacks 1526 * Common callbacks
1431 */ 1527 */
1432 1528
@@ -2078,6 +2174,9 @@ static struct hda_board_config alc880_cfg_tbl[] = {
2078 { .modelname = "lg", .config = ALC880_LG }, 2174 { .modelname = "lg", .config = ALC880_LG },
2079 { .pci_subvendor = 0x1854, .pci_subdevice = 0x003b, .config = ALC880_LG }, 2175 { .pci_subvendor = 0x1854, .pci_subdevice = 0x003b, .config = ALC880_LG },
2080 2176
2177 { .modelname = "lg-lw", .config = ALC880_LG_LW },
2178 { .pci_subvendor = 0x1854, .pci_subdevice = 0x0018, .config = ALC880_LG_LW },
2179
2081#ifdef CONFIG_SND_DEBUG 2180#ifdef CONFIG_SND_DEBUG
2082 { .modelname = "test", .config = ALC880_TEST }, 2181 { .modelname = "test", .config = ALC880_TEST },
2083#endif 2182#endif
@@ -2268,6 +2367,19 @@ static struct alc_config_preset alc880_presets[] = {
2268 .unsol_event = alc880_lg_unsol_event, 2367 .unsol_event = alc880_lg_unsol_event,
2269 .init_hook = alc880_lg_automute, 2368 .init_hook = alc880_lg_automute,
2270 }, 2369 },
2370 [ALC880_LG_LW] = {
2371 .mixers = { alc880_lg_lw_mixer },
2372 .init_verbs = { alc880_volume_init_verbs,
2373 alc880_lg_lw_init_verbs },
2374 .num_dacs = 1,
2375 .dac_nids = alc880_dac_nids,
2376 .dig_out_nid = ALC880_DIGOUT_NID,
2377 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2378 .channel_mode = alc880_2_jack_modes,
2379 .input_mux = &alc880_lg_lw_capture_source,
2380 .unsol_event = alc880_lg_lw_unsol_event,
2381 .init_hook = alc880_lg_lw_automute,
2382 },
2271#ifdef CONFIG_SND_DEBUG 2383#ifdef CONFIG_SND_DEBUG
2272 [ALC880_TEST] = { 2384 [ALC880_TEST] = {
2273 .mixers = { alc880_test_mixer }, 2385 .mixers = { alc880_test_mixer },
@@ -2593,6 +2705,7 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
2593 2705
2594 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs; 2706 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
2595 2707
2708 spec->num_mux_defs = 1;
2596 spec->input_mux = &spec->private_imux; 2709 spec->input_mux = &spec->private_imux;
2597 2710
2598 return 1; 2711 return 1;
@@ -2722,30 +2835,56 @@ static struct hda_input_mux alc260_capture_source = {
2722}; 2835};
2723 2836
2724/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack, 2837/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
2725 * headphone jack and the internal CD lines. 2838 * headphone jack and the internal CD lines since these are the only pins at
2839 * which audio can appear. For flexibility, also allow the option of
2840 * recording the mixer output on the second ADC (ADC0 doesn't have a
2841 * connection to the mixer output).
2726 */ 2842 */
2727static struct hda_input_mux alc260_fujitsu_capture_source = { 2843static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
2728 .num_items = 3, 2844 {
2729 .items = { 2845 .num_items = 3,
2730 { "Mic/Line", 0x0 }, 2846 .items = {
2731 { "CD", 0x4 }, 2847 { "Mic/Line", 0x0 },
2732 { "Headphone", 0x2 }, 2848 { "CD", 0x4 },
2849 { "Headphone", 0x2 },
2850 },
2733 }, 2851 },
2852 {
2853 .num_items = 4,
2854 .items = {
2855 { "Mic/Line", 0x0 },
2856 { "CD", 0x4 },
2857 { "Headphone", 0x2 },
2858 { "Mixer", 0x5 },
2859 },
2860 },
2861
2734}; 2862};
2735 2863
2736/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configutation to 2864/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
2737 * the Fujitsu S702x, but jacks are marked differently. We won't allow 2865 * the Fujitsu S702x, but jacks are marked differently.
2738 * retasking the Headphone jack, so it won't be available here.
2739 */ 2866 */
2740static struct hda_input_mux alc260_acer_capture_source = { 2867static struct hda_input_mux alc260_acer_capture_sources[2] = {
2741 .num_items = 3, 2868 {
2742 .items = { 2869 .num_items = 4,
2743 { "Mic", 0x0 }, 2870 .items = {
2744 { "Line", 0x2 }, 2871 { "Mic", 0x0 },
2745 { "CD", 0x4 }, 2872 { "Line", 0x2 },
2873 { "CD", 0x4 },
2874 { "Headphone", 0x5 },
2875 },
2876 },
2877 {
2878 .num_items = 5,
2879 .items = {
2880 { "Mic", 0x0 },
2881 { "Line", 0x2 },
2882 { "CD", 0x4 },
2883 { "Headphone", 0x6 },
2884 { "Mixer", 0x5 },
2885 },
2746 }, 2886 },
2747}; 2887};
2748
2749/* 2888/*
2750 * This is just place-holder, so there's something for alc_build_pcms to look 2889 * This is just place-holder, so there's something for alc_build_pcms to look
2751 * at when it calculates the maximum number of channels. ALC260 has no mixer 2890 * at when it calculates the maximum number of channels. ALC260 has no mixer
@@ -2806,6 +2945,9 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
2806 { } /* end */ 2945 { } /* end */
2807}; 2946};
2808 2947
2948/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
2949 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
2950 */
2809static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { 2951static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
2810 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 2952 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
2811 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), 2953 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
@@ -2822,9 +2964,28 @@ static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
2822 { } /* end */ 2964 { } /* end */
2823}; 2965};
2824 2966
2967/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
2968 * versions of the ALC260 don't act on requests to enable mic bias from NID
2969 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
2970 * datasheet doesn't mention this restriction. At this stage it's not clear
2971 * whether this behaviour is intentional or is a hardware bug in chip
2972 * revisions available in early 2006. Therefore for now allow the
2973 * "Headphone Jack Mode" control to span all choices, but if it turns out
2974 * that the lack of mic bias for this NID is intentional we could change the
2975 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
2976 *
2977 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
2978 * don't appear to make the mic bias available from the "line" jack, even
2979 * though the NID used for this jack (0x14) can supply it. The theory is
2980 * that perhaps Acer have included blocking capacitors between the ALC260
2981 * and the output jack. If this turns out to be the case for all such
2982 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
2983 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
2984 */
2825static struct snd_kcontrol_new alc260_acer_mixer[] = { 2985static struct snd_kcontrol_new alc260_acer_mixer[] = {
2826 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 2986 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
2827 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 2987 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
2988 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
2828 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 2989 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
2829 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 2990 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
2830 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 2991 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
@@ -3038,7 +3199,8 @@ static struct hda_verb alc260_hp_3013_init_verbs[] = {
3038}; 3199};
3039 3200
3040/* Initialisation sequence for ALC260 as configured in Fujitsu S702x 3201/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
3041 * laptops. 3202 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
3203 * audio = 0x16, internal speaker = 0x10.
3042 */ 3204 */
3043static struct hda_verb alc260_fujitsu_init_verbs[] = { 3205static struct hda_verb alc260_fujitsu_init_verbs[] = {
3044 /* Disable all GPIOs */ 3206 /* Disable all GPIOs */
@@ -3185,10 +3347,10 @@ static struct hda_verb alc260_acer_init_verbs[] = {
3185 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 3347 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3186 3348
3187 /* Do similar with the second ADC: mute capture input amp and 3349 /* Do similar with the second ADC: mute capture input amp and
3188 * set ADC connection to line (on line1 pin) 3350 * set ADC connection to mic to match ALSA's default state.
3189 */ 3351 */
3190 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3352 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3191 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02}, 3353 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3192 3354
3193 /* Mute all inputs to mixer widget (even unconnected ones) */ 3355 /* Mute all inputs to mixer widget (even unconnected ones) */
3194 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 3356 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
@@ -3213,26 +3375,35 @@ static hda_nid_t alc260_test_dac_nids[1] = {
3213static hda_nid_t alc260_test_adc_nids[2] = { 3375static hda_nid_t alc260_test_adc_nids[2] = {
3214 0x04, 0x05, 3376 0x04, 0x05,
3215}; 3377};
3216/* This is a bit messy since the two input muxes in the ALC260 have slight 3378/* For testing the ALC260, each input MUX needs its own definition since
3217 * variations in their signal assignments. The ideal way to deal with this 3379 * the signal assignments are different. This assumes that the first ADC
3218 * is to extend alc_spec.input_mux to allow a different input MUX for each 3380 * is NID 0x04.
3219 * ADC. For the purposes of the test model it's sufficient to just list
3220 * both options for affected signal indices. The separate input mux
3221 * functionality only needs to be considered if a model comes along which
3222 * actually uses signals 0x5, 0x6 and 0x7 for something which makes sense to
3223 * record.
3224 */ 3381 */
3225static struct hda_input_mux alc260_test_capture_source = { 3382static struct hda_input_mux alc260_test_capture_sources[2] = {
3226 .num_items = 8, 3383 {
3227 .items = { 3384 .num_items = 7,
3228 { "MIC1 pin", 0x0 }, 3385 .items = {
3229 { "MIC2 pin", 0x1 }, 3386 { "MIC1 pin", 0x0 },
3230 { "LINE1 pin", 0x2 }, 3387 { "MIC2 pin", 0x1 },
3231 { "LINE2 pin", 0x3 }, 3388 { "LINE1 pin", 0x2 },
3232 { "CD pin", 0x4 }, 3389 { "LINE2 pin", 0x3 },
3233 { "LINE-OUT pin (cap1), Mixer (cap2)", 0x5 }, 3390 { "CD pin", 0x4 },
3234 { "HP-OUT pin (cap1), LINE-OUT pin (cap2)", 0x6 }, 3391 { "LINE-OUT pin", 0x5 },
3235 { "HP-OUT pin (cap2 only)", 0x7 }, 3392 { "HP-OUT pin", 0x6 },
3393 },
3394 },
3395 {
3396 .num_items = 8,
3397 .items = {
3398 { "MIC1 pin", 0x0 },
3399 { "MIC2 pin", 0x1 },
3400 { "LINE1 pin", 0x2 },
3401 { "LINE2 pin", 0x3 },
3402 { "CD pin", 0x4 },
3403 { "Mixer", 0x5 },
3404 { "LINE-OUT pin", 0x6 },
3405 { "HP-OUT pin", 0x7 },
3406 },
3236 }, 3407 },
3237}; 3408};
3238static struct snd_kcontrol_new alc260_test_mixer[] = { 3409static struct snd_kcontrol_new alc260_test_mixer[] = {
@@ -3244,7 +3415,17 @@ static struct snd_kcontrol_new alc260_test_mixer[] = {
3244 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3415 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3245 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT), 3416 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
3246 3417
3247 /* Modes for retasking pin widgets */ 3418 /* Modes for retasking pin widgets
3419 * Note: the ALC260 doesn't seem to act on requests to enable mic
3420 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
3421 * mention this restriction. At this stage it's not clear whether
3422 * this behaviour is intentional or is a hardware bug in chip
3423 * revisions available at least up until early 2006. Therefore for
3424 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
3425 * choices, but if it turns out that the lack of mic bias for these
3426 * NIDs is intentional we could change their modes from
3427 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3428 */
3248 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT), 3429 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
3249 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT), 3430 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
3250 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT), 3431 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
@@ -3606,6 +3787,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
3606 3787
3607 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs; 3788 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
3608 3789
3790 spec->num_mux_defs = 1;
3609 spec->input_mux = &spec->private_imux; 3791 spec->input_mux = &spec->private_imux;
3610 3792
3611 /* check whether NID 0x04 is valid */ 3793 /* check whether NID 0x04 is valid */
@@ -3711,7 +3893,8 @@ static struct alc_config_preset alc260_presets[] = {
3711 .adc_nids = alc260_dual_adc_nids, 3893 .adc_nids = alc260_dual_adc_nids,
3712 .num_channel_mode = ARRAY_SIZE(alc260_modes), 3894 .num_channel_mode = ARRAY_SIZE(alc260_modes),
3713 .channel_mode = alc260_modes, 3895 .channel_mode = alc260_modes,
3714 .input_mux = &alc260_fujitsu_capture_source, 3896 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
3897 .input_mux = alc260_fujitsu_capture_sources,
3715 }, 3898 },
3716 [ALC260_ACER] = { 3899 [ALC260_ACER] = {
3717 .mixers = { alc260_acer_mixer, 3900 .mixers = { alc260_acer_mixer,
@@ -3723,7 +3906,8 @@ static struct alc_config_preset alc260_presets[] = {
3723 .adc_nids = alc260_dual_adc_nids, 3906 .adc_nids = alc260_dual_adc_nids,
3724 .num_channel_mode = ARRAY_SIZE(alc260_modes), 3907 .num_channel_mode = ARRAY_SIZE(alc260_modes),
3725 .channel_mode = alc260_modes, 3908 .channel_mode = alc260_modes,
3726 .input_mux = &alc260_acer_capture_source, 3909 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
3910 .input_mux = alc260_acer_capture_sources,
3727 }, 3911 },
3728#ifdef CONFIG_SND_DEBUG 3912#ifdef CONFIG_SND_DEBUG
3729 [ALC260_TEST] = { 3913 [ALC260_TEST] = {
@@ -3736,7 +3920,8 @@ static struct alc_config_preset alc260_presets[] = {
3736 .adc_nids = alc260_test_adc_nids, 3920 .adc_nids = alc260_test_adc_nids,
3737 .num_channel_mode = ARRAY_SIZE(alc260_modes), 3921 .num_channel_mode = ARRAY_SIZE(alc260_modes),
3738 .channel_mode = alc260_modes, 3922 .channel_mode = alc260_modes,
3739 .input_mux = &alc260_test_capture_source, 3923 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
3924 .input_mux = alc260_test_capture_sources,
3740 }, 3925 },
3741#endif 3926#endif
3742}; 3927};
@@ -3828,7 +4013,6 @@ static struct hda_input_mux alc882_capture_source = {
3828 { "CD", 0x4 }, 4013 { "CD", 0x4 },
3829 }, 4014 },
3830}; 4015};
3831
3832#define alc882_mux_enum_info alc_mux_enum_info 4016#define alc882_mux_enum_info alc_mux_enum_info
3833#define alc882_mux_enum_get alc_mux_enum_get 4017#define alc882_mux_enum_get alc_mux_enum_get
3834 4018
@@ -4730,6 +4914,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
4730 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 4914 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4731 4915
4732 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs; 4916 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
4917 spec->num_mux_defs = 1;
4733 spec->input_mux = &spec->private_imux; 4918 spec->input_mux = &spec->private_imux;
4734 4919
4735 return 1; 4920 return 1;
@@ -5406,6 +5591,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
5406 5591
5407 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs; 5592 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
5408 5593
5594 spec->num_mux_defs = 1;
5409 spec->input_mux = &spec->private_imux; 5595 spec->input_mux = &spec->private_imux;
5410 5596
5411 spec->adc_nids = alc861_adc_nids; 5597 spec->adc_nids = alc861_adc_nids;
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index b56ca4019392..abe9493f0a2c 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -534,6 +534,22 @@ static int stac92xx_build_pcms(struct hda_codec *codec)
534 return 0; 534 return 0;
535} 535}
536 536
537static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid)
538{
539 unsigned int pincap = snd_hda_param_read(codec, nid,
540 AC_PAR_PIN_CAP);
541 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
542 if (pincap & AC_PINCAP_VREF_100)
543 return AC_PINCTL_VREF_100;
544 if (pincap & AC_PINCAP_VREF_80)
545 return AC_PINCTL_VREF_80;
546 if (pincap & AC_PINCAP_VREF_50)
547 return AC_PINCTL_VREF_50;
548 if (pincap & AC_PINCAP_VREF_GRD)
549 return AC_PINCTL_VREF_GRD;
550 return 0;
551}
552
537static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type) 553static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
538 554
539{ 555{
@@ -571,9 +587,12 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
571 587
572 if (val) 588 if (val)
573 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN); 589 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
574 else 590 else {
575 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_IN_EN); 591 unsigned int pinctl = AC_PINCTL_IN_EN;
576 592 if (io_idx) /* set VREF for mic */
593 pinctl |= stac92xx_get_vref(codec, nid);
594 stac92xx_auto_set_pinctl(codec, nid, pinctl);
595 }
577 return 1; 596 return 1;
578} 597}
579 598
@@ -767,13 +786,8 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, struct auto_pin
767 return 0; 786 return 0;
768 787
769 wid_caps = get_wcaps(codec, pin); 788 wid_caps = get_wcaps(codec, pin);
770 if (wid_caps & AC_WCAP_UNSOL_CAP) { 789 if (wid_caps & AC_WCAP_UNSOL_CAP)
771 /* Enable unsolicited responses on the HP widget */
772 snd_hda_codec_write(codec, pin, 0,
773 AC_VERB_SET_UNSOLICITED_ENABLE,
774 STAC_UNSOL_ENABLE);
775 spec->hp_detect = 1; 790 spec->hp_detect = 1;
776 }
777 791
778 nid = snd_hda_codec_read(codec, pin, 0, AC_VERB_GET_CONNECT_LIST, 0) & 0xff; 792 nid = snd_hda_codec_read(codec, pin, 0, AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
779 for (i = 0; i < cfg->line_outs; i++) { 793 for (i = 0; i < cfg->line_outs; i++) {
@@ -896,13 +910,8 @@ static int stac9200_auto_create_hp_ctls(struct hda_codec *codec,
896 return 0; 910 return 0;
897 911
898 wid_caps = get_wcaps(codec, pin); 912 wid_caps = get_wcaps(codec, pin);
899 if (wid_caps & AC_WCAP_UNSOL_CAP) { 913 if (wid_caps & AC_WCAP_UNSOL_CAP)
900 /* Enable unsolicited responses on the HP widget */
901 snd_hda_codec_write(codec, pin, 0,
902 AC_VERB_SET_UNSOLICITED_ENABLE,
903 STAC_UNSOL_ENABLE);
904 spec->hp_detect = 1; 914 spec->hp_detect = 1;
905 }
906 915
907 return 0; 916 return 0;
908} 917}
@@ -944,6 +953,10 @@ static int stac92xx_init(struct hda_codec *codec)
944 953
945 /* set up pins */ 954 /* set up pins */
946 if (spec->hp_detect) { 955 if (spec->hp_detect) {
956 /* Enable unsolicited responses on the HP widget */
957 snd_hda_codec_write(codec, cfg->hp_pin, 0,
958 AC_VERB_SET_UNSOLICITED_ENABLE,
959 STAC_UNSOL_ENABLE);
947 /* fake event to set up pins */ 960 /* fake event to set up pins */
948 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); 961 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
949 } else { 962 } else {
@@ -951,9 +964,13 @@ static int stac92xx_init(struct hda_codec *codec)
951 stac92xx_auto_init_hp_out(codec); 964 stac92xx_auto_init_hp_out(codec);
952 } 965 }
953 for (i = 0; i < AUTO_PIN_LAST; i++) { 966 for (i = 0; i < AUTO_PIN_LAST; i++) {
954 if (cfg->input_pins[i]) 967 hda_nid_t nid = cfg->input_pins[i];
955 stac92xx_auto_set_pinctl(codec, cfg->input_pins[i], 968 if (nid) {
956 AC_PINCTL_IN_EN); 969 unsigned int pinctl = AC_PINCTL_IN_EN;
970 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC)
971 pinctl |= stac92xx_get_vref(codec, nid);
972 stac92xx_auto_set_pinctl(codec, nid, pinctl);
973 }
957 } 974 }
958 if (cfg->dig_out_pin) 975 if (cfg->dig_out_pin)
959 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin, 976 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 7e6608b14abc..336dc489aee1 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -87,7 +87,151 @@
87#define CS8415_C_BUFFER 0x20 87#define CS8415_C_BUFFER 0x20
88#define CS8415_ID 0x7F 88#define CS8415_ID 0x7F
89 89
90static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg, unsigned short val) { 90/* PCA9554 registers */
91#define PCA9554_DEV 0x40 /* I2C device address */
92#define PCA9554_IN 0x00 /* input port */
93#define PCA9554_OUT 0x01 /* output port */
94#define PCA9554_INVERT 0x02 /* input invert */
95#define PCA9554_DIR 0x03 /* port directions */
96
97/*
98 * Aureon Universe additional controls using PCA9554
99 */
100
101/*
102 * Send data to pca9554
103 */
104static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg,
105 unsigned char data)
106{
107 unsigned int tmp;
108 int i, j;
109 unsigned char dev = PCA9554_DEV; /* ID 0100000, write */
110 unsigned char val = 0;
111
112 tmp = snd_ice1712_gpio_read(ice);
113
114 snd_ice1712_gpio_set_mask(ice, ~(AUREON_SPI_MOSI|AUREON_SPI_CLK|
115 AUREON_WM_RW|AUREON_WM_CS|
116 AUREON_CS8415_CS));
117 tmp |= AUREON_WM_RW;
118 tmp |= AUREON_CS8415_CS | AUREON_WM_CS; /* disable SPI devices */
119
120 tmp &= ~AUREON_SPI_MOSI;
121 tmp &= ~AUREON_SPI_CLK;
122 snd_ice1712_gpio_write(ice, tmp);
123 udelay(50);
124
125 /*
126 * send i2c stop condition and start condition
127 * to obtain sane state
128 */
129 tmp |= AUREON_SPI_CLK;
130 snd_ice1712_gpio_write(ice, tmp);
131 udelay(50);
132 tmp |= AUREON_SPI_MOSI;
133 snd_ice1712_gpio_write(ice, tmp);
134 udelay(100);
135 tmp &= ~AUREON_SPI_MOSI;
136 snd_ice1712_gpio_write(ice, tmp);
137 udelay(50);
138 tmp &= ~AUREON_SPI_CLK;
139 snd_ice1712_gpio_write(ice, tmp);
140 udelay(100);
141 /*
142 * send device address, command and value,
143 * skipping ack cycles inbetween
144 */
145 for (j = 0; j < 3; j++) {
146 switch(j) {
147 case 0: val = dev; break;
148 case 1: val = reg; break;
149 case 2: val = data; break;
150 }
151 for (i = 7; i >= 0; i--) {
152 tmp &= ~AUREON_SPI_CLK;
153 snd_ice1712_gpio_write(ice, tmp);
154 udelay(40);
155 if (val & (1 << i))
156 tmp |= AUREON_SPI_MOSI;
157 else
158 tmp &= ~AUREON_SPI_MOSI;
159 snd_ice1712_gpio_write(ice, tmp);
160 udelay(40);
161 tmp |= AUREON_SPI_CLK;
162 snd_ice1712_gpio_write(ice, tmp);
163 udelay(40);
164 }
165 tmp &= ~AUREON_SPI_CLK;
166 snd_ice1712_gpio_write(ice, tmp);
167 udelay(40);
168 tmp |= AUREON_SPI_CLK;
169 snd_ice1712_gpio_write(ice, tmp);
170 udelay(40);
171 tmp &= ~AUREON_SPI_CLK;
172 snd_ice1712_gpio_write(ice, tmp);
173 udelay(40);
174 }
175 tmp &= ~AUREON_SPI_CLK;
176 snd_ice1712_gpio_write(ice, tmp);
177 udelay(40);
178 tmp &= ~AUREON_SPI_MOSI;
179 snd_ice1712_gpio_write(ice, tmp);
180 udelay(40);
181 tmp |= AUREON_SPI_CLK;
182 snd_ice1712_gpio_write(ice, tmp);
183 udelay(50);
184 tmp |= AUREON_SPI_MOSI;
185 snd_ice1712_gpio_write(ice, tmp);
186 udelay(100);
187}
188
189static int aureon_universe_inmux_info(struct snd_kcontrol *kcontrol,
190 struct snd_ctl_elem_info *uinfo)
191{
192 char *texts[3] = {"Internal Aux", "Wavetable", "Rear Line-In"};
193
194 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
195 uinfo->count = 1;
196 uinfo->value.enumerated.items = 3;
197 if(uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
198 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
199 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
200 return 0;
201}
202
203static int aureon_universe_inmux_get(struct snd_kcontrol *kcontrol,
204 struct snd_ctl_elem_value *ucontrol)
205{
206 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
207 ucontrol->value.integer.value[0] = ice->spec.aureon.pca9554_out;
208 return 0;
209}
210
211static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol,
212 struct snd_ctl_elem_value *ucontrol)
213{
214 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
215 unsigned char oval, nval;
216 int change;
217
218 snd_ice1712_save_gpio_status(ice);
219
220 oval = ice->spec.aureon.pca9554_out;
221 nval = ucontrol->value.integer.value[0];
222 if ((change = (oval != nval))) {
223 aureon_pca9554_write(ice, PCA9554_OUT, nval);
224 ice->spec.aureon.pca9554_out = nval;
225 }
226 snd_ice1712_restore_gpio_status(ice);
227
228 return change;
229}
230
231
232static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
233 unsigned short val)
234{
91 unsigned int tmp; 235 unsigned int tmp;
92 236
93 /* Send address to XILINX chip */ 237 /* Send address to XILINX chip */
@@ -146,7 +290,8 @@ static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short r
146/* 290/*
147 * Initialize STAC9744 chip 291 * Initialize STAC9744 chip
148 */ 292 */
149static int aureon_ac97_init (struct snd_ice1712 *ice) { 293static int aureon_ac97_init (struct snd_ice1712 *ice)
294{
150 int i; 295 int i;
151 static unsigned short ac97_defaults[] = { 296 static unsigned short ac97_defaults[] = {
152 0x00, 0x9640, 297 0x00, 0x9640,
@@ -1598,7 +1743,15 @@ static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
1598 .get = aureon_ac97_vol_get, 1743 .get = aureon_ac97_vol_get,
1599 .put = aureon_ac97_vol_put, 1744 .put = aureon_ac97_vol_put,
1600 .private_value = AC97_VIDEO|AUREON_AC97_STEREO 1745 .private_value = AC97_VIDEO|AUREON_AC97_STEREO
1601 } 1746 },
1747 {
1748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1749 .name = "Aux Source",
1750 .info = aureon_universe_inmux_info,
1751 .get = aureon_universe_inmux_get,
1752 .put = aureon_universe_inmux_put
1753 }
1754
1602}; 1755};
1603 1756
1604 1757
@@ -1856,6 +2009,10 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
1856 } 2009 }
1857 2010
1858 snd_ice1712_restore_gpio_status(ice); 2011 snd_ice1712_restore_gpio_status(ice);
2012
2013 /* initialize PCA9554 pin directions & set default input*/
2014 aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
2015 aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */
1859 2016
1860 ice->spec.aureon.master[0] = WM_VOL_MUTE; 2017 ice->spec.aureon.master[0] = WM_VOL_MUTE;
1861 ice->spec.aureon.master[1] = WM_VOL_MUTE; 2018 ice->spec.aureon.master[1] = WM_VOL_MUTE;
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index b88eeba2f5d1..32f8415558a5 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -2402,7 +2402,7 @@ static int __devinit snd_ice1712_chip_init(struct snd_ice1712 *ice)
2402 if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DMX6FIRE && !ice->dxr_enable) { 2402 if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DMX6FIRE && !ice->dxr_enable) {
2403 /* Limit active ADCs and DACs to 6; */ 2403 /* Limit active ADCs and DACs to 6; */
2404 /* Note: DXR extension not supported */ 2404 /* Note: DXR extension not supported */
2405 pci_write_config_byte(ice->pci, 0x60, 0x0a); 2405 pci_write_config_byte(ice->pci, 0x60, 0x2a);
2406 } else { 2406 } else {
2407 pci_write_config_byte(ice->pci, 0x60, ice->eeprom.data[ICE_EEP1_CODEC]); 2407 pci_write_config_byte(ice->pci, 0x60, ice->eeprom.data[ICE_EEP1_CODEC]);
2408 } 2408 }
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
index f9b22d4a3932..053f8e56fd68 100644
--- a/sound/pci/ice1712/ice1712.h
+++ b/sound/pci/ice1712/ice1712.h
@@ -373,6 +373,7 @@ struct snd_ice1712 {
373 unsigned int cs8415_mux; 373 unsigned int cs8415_mux;
374 unsigned short master[2]; 374 unsigned short master[2];
375 unsigned short vol[8]; 375 unsigned short vol[8];
376 unsigned char pca9554_out;
376 } aureon; 377 } aureon;
377 /* AC97 register cache for Phase28 */ 378 /* AC97 register cache for Phase28 */
378 struct phase28_spec { 379 struct phase28_spec {
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 44393e190929..9c90d901e6b9 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -831,8 +831,8 @@ struct snd_m3 {
831 struct snd_pcm *pcm; 831 struct snd_pcm *pcm;
832 832
833 struct pci_dev *pci; 833 struct pci_dev *pci;
834 struct m3_quirk *quirk; 834 const struct m3_quirk *quirk;
835 struct m3_hv_quirk *hv_quirk; 835 const struct m3_hv_quirk *hv_quirk;
836 836
837 int dacs_active; 837 int dacs_active;
838 int timer_users; 838 int timer_users;
@@ -892,7 +892,7 @@ static struct pci_device_id snd_m3_ids[] = {
892 892
893MODULE_DEVICE_TABLE(pci, snd_m3_ids); 893MODULE_DEVICE_TABLE(pci, snd_m3_ids);
894 894
895static struct m3_quirk m3_quirk_list[] = { 895static const struct m3_quirk m3_quirk_list[] = {
896 /* panasonic CF-28 "toughbook" */ 896 /* panasonic CF-28 "toughbook" */
897 { 897 {
898 .name = "Panasonic CF-28", 898 .name = "Panasonic CF-28",
@@ -950,7 +950,7 @@ static struct m3_quirk m3_quirk_list[] = {
950}; 950};
951 951
952/* These values came from the Windows driver. */ 952/* These values came from the Windows driver. */
953static struct m3_hv_quirk m3_hv_quirk_list[] = { 953static const struct m3_hv_quirk m3_hv_quirk_list[] = {
954 /* Allegro chips */ 954 /* Allegro chips */
955 { 0x125D, 0x1988, 0x0E11, 0x002E, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 955 { 0x125D, 0x1988, 0x0E11, 0x002E, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
956 { 0x125D, 0x1988, 0x0E11, 0x0094, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 956 { 0x125D, 0x1988, 0x0E11, 0x0094, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
@@ -1361,7 +1361,7 @@ static void snd_m3_pcm_setup2(struct snd_m3 *chip, struct m3_dma *s,
1361} 1361}
1362 1362
1363 1363
1364static struct play_vals { 1364static const struct play_vals {
1365 u16 addr, val; 1365 u16 addr, val;
1366} pv[] = { 1366} pv[] = {
1367 {CDATA_LEFT_VOLUME, ARB_VOLUME}, 1367 {CDATA_LEFT_VOLUME, ARB_VOLUME},
@@ -1428,7 +1428,7 @@ snd_m3_playback_setup(struct snd_m3 *chip, struct m3_dma *s,
1428/* 1428/*
1429 * Native record driver 1429 * Native record driver
1430 */ 1430 */
1431static struct rec_vals { 1431static const struct rec_vals {
1432 u16 addr, val; 1432 u16 addr, val;
1433} rv[] = { 1433} rv[] = {
1434 {CDATA_LEFT_VOLUME, ARB_VOLUME}, 1434 {CDATA_LEFT_VOLUME, ARB_VOLUME},
@@ -1598,12 +1598,26 @@ static void snd_m3_update_ptr(struct snd_m3 *chip, struct m3_dma *s)
1598 if (! s->running) 1598 if (! s->running)
1599 return; 1599 return;
1600 1600
1601 hwptr = snd_m3_get_pointer(chip, s, subs) % s->dma_size; 1601 hwptr = snd_m3_get_pointer(chip, s, subs);
1602 diff = (s->dma_size + hwptr - s->hwptr) % s->dma_size; 1602
1603 /* try to avoid expensive modulo divisions */
1604 if (hwptr >= s->dma_size)
1605 hwptr %= s->dma_size;
1606
1607 diff = s->dma_size + hwptr - s->hwptr;
1608 if (diff >= s->dma_size)
1609 diff %= s->dma_size;
1610
1603 s->hwptr = hwptr; 1611 s->hwptr = hwptr;
1604 s->count += diff; 1612 s->count += diff;
1613
1605 if (s->count >= (signed)s->period_size) { 1614 if (s->count >= (signed)s->period_size) {
1606 s->count %= s->period_size; 1615
1616 if (s->count < 2 * (signed)s->period_size)
1617 s->count -= (signed)s->period_size;
1618 else
1619 s->count %= s->period_size;
1620
1607 spin_unlock(&chip->reg_lock); 1621 spin_unlock(&chip->reg_lock);
1608 snd_pcm_period_elapsed(subs); 1622 snd_pcm_period_elapsed(subs);
1609 spin_lock(&chip->reg_lock); 1623 spin_lock(&chip->reg_lock);
@@ -1942,6 +1956,7 @@ static int snd_m3_ac97_wait(struct snd_m3 *chip)
1942 do { 1956 do {
1943 if (! (snd_m3_inb(chip, 0x30) & 1)) 1957 if (! (snd_m3_inb(chip, 0x30) & 1))
1944 return 0; 1958 return 0;
1959 cpu_relax();
1945 } while (i-- > 0); 1960 } while (i-- > 0);
1946 1961
1947 snd_printk(KERN_ERR "ac97 serial bus busy\n"); 1962 snd_printk(KERN_ERR "ac97 serial bus busy\n");
@@ -1953,16 +1968,18 @@ snd_m3_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
1953{ 1968{
1954 struct snd_m3 *chip = ac97->private_data; 1969 struct snd_m3 *chip = ac97->private_data;
1955 unsigned long flags; 1970 unsigned long flags;
1956 unsigned short data; 1971 unsigned short data = 0xffff;
1957 1972
1958 if (snd_m3_ac97_wait(chip)) 1973 if (snd_m3_ac97_wait(chip))
1959 return 0xffff; 1974 goto fail;
1960 spin_lock_irqsave(&chip->ac97_lock, flags); 1975 spin_lock_irqsave(&chip->ac97_lock, flags);
1961 snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND); 1976 snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND);
1962 if (snd_m3_ac97_wait(chip)) 1977 if (snd_m3_ac97_wait(chip))
1963 return 0xffff; 1978 goto fail_unlock;
1964 data = snd_m3_inw(chip, CODEC_DATA); 1979 data = snd_m3_inw(chip, CODEC_DATA);
1980fail_unlock:
1965 spin_unlock_irqrestore(&chip->ac97_lock, flags); 1981 spin_unlock_irqrestore(&chip->ac97_lock, flags);
1982fail:
1966 return data; 1983 return data;
1967} 1984}
1968 1985
@@ -2121,7 +2138,7 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip)
2121 * DSP Code images 2138 * DSP Code images
2122 */ 2139 */
2123 2140
2124static u16 assp_kernel_image[] __devinitdata = { 2141static const u16 assp_kernel_image[] __devinitdata = {
2125 0x7980, 0x0030, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x00FB, 0x7980, 0x00DD, 0x7980, 0x03B4, 2142 0x7980, 0x0030, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x00FB, 0x7980, 0x00DD, 0x7980, 0x03B4,
2126 0x7980, 0x0332, 0x7980, 0x0287, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 2143 0x7980, 0x0332, 0x7980, 0x0287, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4,
2127 0x7980, 0x031A, 0x7980, 0x03B4, 0x7980, 0x022F, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 2144 0x7980, 0x031A, 0x7980, 0x03B4, 0x7980, 0x022F, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4,
@@ -2208,7 +2225,7 @@ static u16 assp_kernel_image[] __devinitdata = {
2208 * Mini sample rate converter code image 2225 * Mini sample rate converter code image
2209 * that is to be loaded at 0x400 on the DSP. 2226 * that is to be loaded at 0x400 on the DSP.
2210 */ 2227 */
2211static u16 assp_minisrc_image[] __devinitdata = { 2228static const u16 assp_minisrc_image[] __devinitdata = {
2212 2229
2213 0xBF80, 0x101E, 0x906E, 0x006E, 0x8B88, 0x6980, 0xEF88, 0x906F, 0x0D6F, 0x6900, 0xEB08, 0x0412, 2230 0xBF80, 0x101E, 0x906E, 0x006E, 0x8B88, 0x6980, 0xEF88, 0x906F, 0x0D6F, 0x6900, 0xEB08, 0x0412,
2214 0xBC20, 0x696E, 0xB801, 0x906E, 0x7980, 0x0403, 0xB90E, 0x8807, 0xBE43, 0xBF01, 0xBE47, 0xBE41, 2231 0xBC20, 0x696E, 0xB801, 0x906E, 0x7980, 0x0403, 0xB90E, 0x8807, 0xBE43, 0xBF01, 0xBE47, 0xBE41,
@@ -2251,7 +2268,7 @@ static u16 assp_minisrc_image[] __devinitdata = {
2251 */ 2268 */
2252 2269
2253#define MINISRC_LPF_LEN 10 2270#define MINISRC_LPF_LEN 10
2254static u16 minisrc_lpf[MINISRC_LPF_LEN] __devinitdata = { 2271static const u16 minisrc_lpf[MINISRC_LPF_LEN] __devinitdata = {
2255 0X0743, 0X1104, 0X0A4C, 0XF88D, 0X242C, 2272 0X0743, 0X1104, 0X0A4C, 0XF88D, 0X242C,
2256 0X1023, 0X1AA9, 0X0B60, 0XEFDD, 0X186F 2273 0X1023, 0X1AA9, 0X0B60, 0XEFDD, 0X186F
2257}; 2274};
@@ -2358,7 +2375,7 @@ static int __devinit snd_m3_assp_client_init(struct snd_m3 *chip, struct m3_dma
2358 */ 2375 */
2359 2376
2360 /* 2377 /*
2361 * align instance address to 256 bytes so that it's 2378 * align instance address to 256 bytes so that its
2362 * shifted list address is aligned. 2379 * shifted list address is aligned.
2363 * list address = (mem address >> 1) >> 7; 2380 * list address = (mem address >> 1) >> 7;
2364 */ 2381 */
@@ -2647,8 +2664,8 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
2647{ 2664{
2648 struct snd_m3 *chip; 2665 struct snd_m3 *chip;
2649 int i, err; 2666 int i, err;
2650 struct m3_quirk *quirk; 2667 const struct m3_quirk *quirk;
2651 struct m3_hv_quirk *hv_quirk; 2668 const struct m3_hv_quirk *hv_quirk;
2652 static struct snd_device_ops ops = { 2669 static struct snd_device_ops ops = {
2653 .dev_free = snd_m3_dev_free, 2670 .dev_free = snd_m3_dev_free,
2654 }; 2671 };
@@ -2843,12 +2860,12 @@ snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
2843 } 2860 }
2844 2861
2845#if 0 /* TODO: not supported yet */ 2862#if 0 /* TODO: not supported yet */
2846 /* TODO enable midi irq and i/o */ 2863 /* TODO enable MIDI IRQ and I/O */
2847 err = snd_mpu401_uart_new(chip->card, 0, MPU401_HW_MPU401, 2864 err = snd_mpu401_uart_new(chip->card, 0, MPU401_HW_MPU401,
2848 chip->iobase + MPU401_DATA_PORT, 1, 2865 chip->iobase + MPU401_DATA_PORT, 1,
2849 chip->irq, 0, &chip->rmidi); 2866 chip->irq, 0, &chip->rmidi);
2850 if (err < 0) 2867 if (err < 0)
2851 printk(KERN_WARNING "maestro3: no midi support.\n"); 2868 printk(KERN_WARNING "maestro3: no MIDI support.\n");
2852#endif 2869#endif
2853 2870
2854 pci_set_drvdata(pci, card); 2871 pci_set_drvdata(pci, card);
diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c
index fdc652c6992d..c40f59062684 100644
--- a/sound/pci/pcxhr/pcxhr_core.c
+++ b/sound/pci/pcxhr/pcxhr_core.c
@@ -274,12 +274,9 @@ int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr, const struct firmware *xilin
274 274
275 /* test first xilinx */ 275 /* test first xilinx */
276 chipsc = PCXHR_INPL(mgr, PCXHR_PLX_CHIPSC); 276 chipsc = PCXHR_INPL(mgr, PCXHR_PLX_CHIPSC);
277 if (!second) { 277 /* REV01 cards do not support the PCXHR_CHIPSC_GPI_USERI bit anymore */
278 if (chipsc & PCXHR_CHIPSC_GPI_USERI) { 278 /* this bit will always be 1; no possibility to test presence of first xilinx */
279 snd_printdd("no need to load first xilinx\n"); 279 if(second) {
280 return 0; /* first xilinx is already present and cannot be reset */
281 }
282 } else {
283 if ((chipsc & PCXHR_CHIPSC_GPI_USERI) == 0) { 280 if ((chipsc & PCXHR_CHIPSC_GPI_USERI) == 0) {
284 snd_printk(KERN_ERR "error loading first xilinx\n"); 281 snd_printk(KERN_ERR "error loading first xilinx\n");
285 return -EINVAL; 282 return -EINVAL;
diff --git a/sound/pci/riptide/Makefile b/sound/pci/riptide/Makefile
new file mode 100644
index 000000000000..dcd2e64e4818
--- /dev/null
+++ b/sound/pci/riptide/Makefile
@@ -0,0 +1,3 @@
1snd-riptide-objs := riptide.o
2
3obj-$(CONFIG_SND_RIPTIDE) += snd-riptide.o
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
new file mode 100644
index 000000000000..f148ee434a6b
--- /dev/null
+++ b/sound/pci/riptide/riptide.c
@@ -0,0 +1,2223 @@
1/*
2 * Driver for the Conexant Riptide Soundchip
3 *
4 * Copyright (c) 2004 Peter Gruber <nokos@gmx.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21/*
22 History:
23 - 02/15/2004 first release
24
25 This Driver is based on the OSS Driver version from Linuxant (riptide-0.6lnxtbeta03111100)
26 credits from the original files:
27
28 MODULE NAME: cnxt_rt.h
29 AUTHOR: K. Lazarev (Transcribed by KNL)
30 HISTORY: Major Revision Date By
31 ----------------------------- -------- -----
32 Created 02/1/2000 KNL
33
34 MODULE NAME: int_mdl.c
35 AUTHOR: Konstantin Lazarev (Transcribed by KNL)
36 HISTORY: Major Revision Date By
37 ----------------------------- -------- -----
38 Created 10/01/99 KNL
39
40 MODULE NAME: riptide.h
41 AUTHOR: O. Druzhinin (Transcribed by OLD)
42 HISTORY: Major Revision Date By
43 ----------------------------- -------- -----
44 Created 10/16/97 OLD
45
46 MODULE NAME: Rp_Cmdif.cpp
47 AUTHOR: O. Druzhinin (Transcribed by OLD)
48 K. Lazarev (Transcribed by KNL)
49 HISTORY: Major Revision Date By
50 ----------------------------- -------- -----
51 Adopted from NT4 driver 6/22/99 OLD
52 Ported to Linux 9/01/99 KNL
53
54 MODULE NAME: rt_hw.c
55 AUTHOR: O. Druzhinin (Transcribed by OLD)
56 C. Lazarev (Transcribed by CNL)
57 HISTORY: Major Revision Date By
58 ----------------------------- -------- -----
59 Created 11/18/97 OLD
60 Hardware functions for RipTide 11/24/97 CNL
61 (ES1) are coded
62 Hardware functions for RipTide 12/24/97 CNL
63 (A0) are coded
64 Hardware functions for RipTide 03/20/98 CNL
65 (A1) are coded
66 Boot loader is included 05/07/98 CNL
67 Redesigned for WDM 07/27/98 CNL
68 Redesigned for Linux 09/01/99 CNL
69
70 MODULE NAME: rt_hw.h
71 AUTHOR: C. Lazarev (Transcribed by CNL)
72 HISTORY: Major Revision Date By
73 ----------------------------- -------- -----
74 Created 11/18/97 CNL
75
76 MODULE NAME: rt_mdl.c
77 AUTHOR: Konstantin Lazarev (Transcribed by KNL)
78 HISTORY: Major Revision Date By
79 ----------------------------- -------- -----
80 Created 10/01/99 KNL
81
82 MODULE NAME: mixer.h
83 AUTHOR: K. Kenney
84 HISTORY: Major Revision Date By
85 ----------------------------- -------- -----
86 Created from MS W95 Sample 11/28/95 KRS
87 RipTide 10/15/97 KRS
88 Adopted for Windows NT driver 01/20/98 CNL
89*/
90
91#include <sound/driver.h>
92#include <linux/delay.h>
93#include <linux/init.h>
94#include <linux/interrupt.h>
95#include <linux/pci.h>
96#include <linux/slab.h>
97#include <linux/wait.h>
98#include <linux/gameport.h>
99#include <linux/device.h>
100#include <linux/firmware.h>
101#include <asm/io.h>
102#include <sound/core.h>
103#include <sound/info.h>
104#include <sound/control.h>
105#include <sound/pcm.h>
106#include <sound/pcm_params.h>
107#include <sound/ac97_codec.h>
108#include <sound/mpu401.h>
109#include <sound/opl3.h>
110#include <sound/initval.h>
111
112#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
113#define SUPPORT_JOYSTICK 1
114#endif
115
116MODULE_AUTHOR("Peter Gruber <nokos@gmx.net>");
117MODULE_DESCRIPTION("riptide");
118MODULE_LICENSE("GPL");
119MODULE_SUPPORTED_DEVICE("{{Conexant,Riptide}}");
120
121static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
122static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
123static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
124
125#ifdef SUPPORT_JOYSTICK
126static int joystick_port[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS - 1)] = 0x200 };
127#endif
128static int mpu_port[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS - 1)] = 0x330 };
129static int opl3_port[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS - 1)] = 0x388 };
130
131module_param_array(index, int, NULL, 0444);
132MODULE_PARM_DESC(index, "Index value for Riptide soundcard.");
133module_param_array(id, charp, NULL, 0444);
134MODULE_PARM_DESC(id, "ID string for Riptide soundcard.");
135module_param_array(enable, bool, NULL, 0444);
136MODULE_PARM_DESC(enable, "Enable Riptide soundcard.");
137#ifdef SUPPORT_JOYSTICK
138module_param_array(joystick_port, int, NULL, 0444);
139MODULE_PARM_DESC(joystick_port, "Joystick port # for Riptide soundcard.");
140#endif
141module_param_array(mpu_port, int, NULL, 0444);
142MODULE_PARM_DESC(mpu_port, "MPU401 port # for Riptide driver.");
143module_param_array(opl3_port, int, NULL, 0444);
144MODULE_PARM_DESC(opl3_port, "OPL3 port # for Riptide driver.");
145
146/*
147 */
148
149#define MPU401_HW_RIPTIDE MPU401_HW_MPU401
150#define OPL3_HW_RIPTIDE OPL3_HW_OPL3
151
152#define PCI_EXT_CapId 0x40
153#define PCI_EXT_NextCapPrt 0x41
154#define PCI_EXT_PWMC 0x42
155#define PCI_EXT_PWSCR 0x44
156#define PCI_EXT_Data00 0x46
157#define PCI_EXT_PMSCR_BSE 0x47
158#define PCI_EXT_SB_Base 0x48
159#define PCI_EXT_FM_Base 0x4a
160#define PCI_EXT_MPU_Base 0x4C
161#define PCI_EXT_Game_Base 0x4E
162#define PCI_EXT_Legacy_Mask 0x50
163#define PCI_EXT_AsicRev 0x52
164#define PCI_EXT_Reserved3 0x53
165
166#define LEGACY_ENABLE_ALL 0x8000 /* legacy device options */
167#define LEGACY_ENABLE_SB 0x4000
168#define LEGACY_ENABLE_FM 0x2000
169#define LEGACY_ENABLE_MPU_INT 0x1000
170#define LEGACY_ENABLE_MPU 0x0800
171#define LEGACY_ENABLE_GAMEPORT 0x0400
172
173#define MAX_WRITE_RETRY 10 /* cmd interface limits */
174#define MAX_ERROR_COUNT 10
175#define CMDIF_TIMEOUT 500000
176#define RESET_TRIES 5
177
178#define READ_PORT_ULONG(p) inl((unsigned long)&(p))
179#define WRITE_PORT_ULONG(p,x) outl(x,(unsigned long)&(p))
180
181#define READ_AUDIO_CONTROL(p) READ_PORT_ULONG(p->audio_control)
182#define WRITE_AUDIO_CONTROL(p,x) WRITE_PORT_ULONG(p->audio_control,x)
183#define UMASK_AUDIO_CONTROL(p,x) WRITE_PORT_ULONG(p->audio_control,READ_PORT_ULONG(p->audio_control)|x)
184#define MASK_AUDIO_CONTROL(p,x) WRITE_PORT_ULONG(p->audio_control,READ_PORT_ULONG(p->audio_control)&x)
185#define READ_AUDIO_STATUS(p) READ_PORT_ULONG(p->audio_status)
186
187#define SET_GRESET(p) UMASK_AUDIO_CONTROL(p,0x0001) /* global reset switch */
188#define UNSET_GRESET(p) MASK_AUDIO_CONTROL(p,~0x0001)
189#define SET_AIE(p) UMASK_AUDIO_CONTROL(p,0x0004) /* interrupt enable */
190#define UNSET_AIE(p) MASK_AUDIO_CONTROL(p,~0x0004)
191#define SET_AIACK(p) UMASK_AUDIO_CONTROL(p,0x0008) /* interrupt acknowledge */
192#define UNSET_AIACKT(p) MASKAUDIO_CONTROL(p,~0x0008)
193#define SET_ECMDAE(p) UMASK_AUDIO_CONTROL(p,0x0010)
194#define UNSET_ECMDAE(p) MASK_AUDIO_CONTROL(p,~0x0010)
195#define SET_ECMDBE(p) UMASK_AUDIO_CONTROL(p,0x0020)
196#define UNSET_ECMDBE(p) MASK_AUDIO_CONTROL(p,~0x0020)
197#define SET_EDATAF(p) UMASK_AUDIO_CONTROL(p,0x0040)
198#define UNSET_EDATAF(p) MASK_AUDIO_CONTROL(p,~0x0040)
199#define SET_EDATBF(p) UMASK_AUDIO_CONTROL(p,0x0080)
200#define UNSET_EDATBF(p) MASK_AUDIO_CONTROL(p,~0x0080)
201#define SET_ESBIRQON(p) UMASK_AUDIO_CONTROL(p,0x0100)
202#define UNSET_ESBIRQON(p) MASK_AUDIO_CONTROL(p,~0x0100)
203#define SET_EMPUIRQ(p) UMASK_AUDIO_CONTROL(p,0x0200)
204#define UNSET_EMPUIRQ(p) MASK_AUDIO_CONTROL(p,~0x0200)
205#define IS_CMDE(a) (READ_PORT_ULONG(a->stat)&0x1) /* cmd empty */
206#define IS_DATF(a) (READ_PORT_ULONG(a->stat)&0x2) /* data filled */
207#define IS_READY(p) (READ_AUDIO_STATUS(p)&0x0001)
208#define IS_DLREADY(p) (READ_AUDIO_STATUS(p)&0x0002)
209#define IS_DLERR(p) (READ_AUDIO_STATUS(p)&0x0004)
210#define IS_GERR(p) (READ_AUDIO_STATUS(p)&0x0008) /* error ! */
211#define IS_CMDAEIRQ(p) (READ_AUDIO_STATUS(p)&0x0010)
212#define IS_CMDBEIRQ(p) (READ_AUDIO_STATUS(p)&0x0020)
213#define IS_DATAFIRQ(p) (READ_AUDIO_STATUS(p)&0x0040)
214#define IS_DATBFIRQ(p) (READ_AUDIO_STATUS(p)&0x0080)
215#define IS_EOBIRQ(p) (READ_AUDIO_STATUS(p)&0x0100) /* interrupt status */
216#define IS_EOSIRQ(p) (READ_AUDIO_STATUS(p)&0x0200)
217#define IS_EOCIRQ(p) (READ_AUDIO_STATUS(p)&0x0400)
218#define IS_UNSLIRQ(p) (READ_AUDIO_STATUS(p)&0x0800)
219#define IS_SBIRQ(p) (READ_AUDIO_STATUS(p)&0x1000)
220#define IS_MPUIRQ(p) (READ_AUDIO_STATUS(p)&0x2000)
221
222#define RESP 0x00000001 /* command flags */
223#define PARM 0x00000002
224#define CMDA 0x00000004
225#define CMDB 0x00000008
226#define NILL 0x00000000
227
228#define LONG0(a) ((u32)a) /* shifts and masks */
229#define BYTE0(a) (LONG0(a)&0xff)
230#define BYTE1(a) (BYTE0(a)<<8)
231#define BYTE2(a) (BYTE0(a)<<16)
232#define BYTE3(a) (BYTE0(a)<<24)
233#define WORD0(a) (LONG0(a)&0xffff)
234#define WORD1(a) (WORD0(a)<<8)
235#define WORD2(a) (WORD0(a)<<16)
236#define TRINIB0(a) (LONG0(a)&0xffffff)
237#define TRINIB1(a) (TRINIB0(a)<<8)
238
239#define RET(a) ((union cmdret *)(a))
240
241#define SEND_GETV(p,b) sendcmd(p,RESP,GETV,0,RET(b)) /* get version */
242#define SEND_GETC(p,b,c) sendcmd(p,PARM|RESP,GETC,c,RET(b))
243#define SEND_GUNS(p,b) sendcmd(p,RESP,GUNS,0,RET(b))
244#define SEND_SCID(p,b) sendcmd(p,RESP,SCID,0,RET(b))
245#define SEND_RMEM(p,b,c,d) sendcmd(p,PARM|RESP,RMEM|BYTE1(b),LONG0(c),RET(d)) /* memory access for firmware write */
246#define SEND_SMEM(p,b,c) sendcmd(p,PARM,SMEM|BYTE1(b),LONG0(c),RET(0)) /* memory access for firmware write */
247#define SEND_WMEM(p,b,c) sendcmd(p,PARM,WMEM|BYTE1(b),LONG0(c),RET(0)) /* memory access for firmware write */
248#define SEND_SDTM(p,b,c) sendcmd(p,PARM|RESP,SDTM|TRINIB1(b),0,RET(c)) /* memory access for firmware write */
249#define SEND_GOTO(p,b) sendcmd(p,PARM,GOTO,LONG0(b),RET(0)) /* memory access for firmware write */
250#define SEND_SETDPLL(p) sendcmd(p,0,ARM_SETDPLL,0,RET(0))
251#define SEND_SSTR(p,b,c) sendcmd(p,PARM,SSTR|BYTE3(b),LONG0(c),RET(0)) /* start stream */
252#define SEND_PSTR(p,b) sendcmd(p,PARM,PSTR,BYTE3(b),RET(0)) /* pause stream */
253#define SEND_KSTR(p,b) sendcmd(p,PARM,KSTR,BYTE3(b),RET(0)) /* stop stream */
254#define SEND_KDMA(p) sendcmd(p,0,KDMA,0,RET(0)) /* stop all dma */
255#define SEND_GPOS(p,b,c,d) sendcmd(p,PARM|RESP,GPOS,BYTE3(c)|BYTE2(b),RET(d)) /* get position in dma */
256#define SEND_SETF(p,b,c,d,e,f,g) sendcmd(p,PARM,SETF|WORD1(b)|BYTE3(c),d|BYTE1(e)|BYTE2(f)|BYTE3(g),RET(0)) /* set sample format at mixer */
257#define SEND_GSTS(p,b,c,d) sendcmd(p,PARM|RESP,GSTS,BYTE3(c)|BYTE2(b),RET(d))
258#define SEND_NGPOS(p,b,c,d) sendcmd(p,PARM|RESP,NGPOS,BYTE3(c)|BYTE2(b),RET(d))
259#define SEND_PSEL(p,b,c) sendcmd(p,PARM,PSEL,BYTE2(b)|BYTE3(c),RET(0)) /* activate lbus path */
260#define SEND_PCLR(p,b,c) sendcmd(p,PARM,PCLR,BYTE2(b)|BYTE3(c),RET(0)) /* deactivate lbus path */
261#define SEND_PLST(p,b) sendcmd(p,PARM,PLST,BYTE3(b),RET(0))
262#define SEND_RSSV(p,b,c,d) sendcmd(p,PARM|RESP,RSSV,BYTE2(b)|BYTE3(c),RET(d))
263#define SEND_LSEL(p,b,c,d,e,f,g,h) sendcmd(p,PARM,LSEL|BYTE1(b)|BYTE2(c)|BYTE3(d),BYTE0(e)|BYTE1(f)|BYTE2(g)|BYTE3(h),RET(0)) /* select paths for internal connections */
264#define SEND_SSRC(p,b,c,d,e) sendcmd(p,PARM,SSRC|BYTE1(b)|WORD2(c),WORD0(d)|WORD2(e),RET(0)) /* configure source */
265#define SEND_SLST(p,b) sendcmd(p,PARM,SLST,BYTE3(b),RET(0))
266#define SEND_RSRC(p,b,c) sendcmd(p,RESP,RSRC|BYTE1(b),0,RET(c)) /* read source config */
267#define SEND_SSRB(p,b,c) sendcmd(p,PARM,SSRB|BYTE1(b),WORD2(c),RET(0))
268#define SEND_SDGV(p,b,c,d,e) sendcmd(p,PARM,SDGV|BYTE2(b)|BYTE3(c),WORD0(d)|WORD2(e),RET(0)) /* set digital mixer */
269#define SEND_RDGV(p,b,c,d) sendcmd(p,PARM|RESP,RDGV|BYTE2(b)|BYTE3(c),0,RET(d)) /* read digital mixer */
270#define SEND_DLST(p,b) sendcmd(p,PARM,DLST,BYTE3(b),RET(0))
271#define SEND_SACR(p,b,c) sendcmd(p,PARM,SACR,WORD0(b)|WORD2(c),RET(0)) /* set AC97 register */
272#define SEND_RACR(p,b,c) sendcmd(p,PARM|RESP,RACR,WORD2(b),RET(c)) /* get AC97 register */
273#define SEND_ALST(p,b) sendcmd(p,PARM,ALST,BYTE3(b),RET(0))
274#define SEND_TXAC(p,b,c,d,e,f) sendcmd(p,PARM,TXAC|BYTE1(b)|WORD2(c),WORD0(d)|BYTE2(e)|BYTE3(f),RET(0))
275#define SEND_RXAC(p,b,c,d) sendcmd(p,PARM|RESP,RXAC,BYTE2(b)|BYTE3(c),RET(d))
276#define SEND_SI2S(p,b) sendcmd(p,PARM,SI2S,WORD2(b),RET(0))
277
278#define EOB_STATUS 0x80000000 /* status flags : block boundary */
279#define EOS_STATUS 0x40000000 /* : stoppped */
280#define EOC_STATUS 0x20000000 /* : stream end */
281#define ERR_STATUS 0x10000000
282#define EMPTY_STATUS 0x08000000
283
284#define IEOB_ENABLE 0x1 /* enable interrupts for status notification above */
285#define IEOS_ENABLE 0x2
286#define IEOC_ENABLE 0x4
287#define RDONCE 0x8
288#define DESC_MAX_MASK 0xff
289
290#define ST_PLAY 0x1 /* stream states */
291#define ST_STOP 0x2
292#define ST_PAUSE 0x4
293
294#define I2S_INTDEC 3 /* config for I2S link */
295#define I2S_MERGER 0
296#define I2S_SPLITTER 0
297#define I2S_MIXER 7
298#define I2S_RATE 44100
299
300#define MODEM_INTDEC 4 /* config for modem link */
301#define MODEM_MERGER 3
302#define MODEM_SPLITTER 0
303#define MODEM_MIXER 11
304
305#define FM_INTDEC 3 /* config for FM/OPL3 link */
306#define FM_MERGER 0
307#define FM_SPLITTER 0
308#define FM_MIXER 9
309
310#define SPLIT_PATH 0x80 /* path splitting flag */
311
312enum FIRMWARE {
313 DATA_REC = 0, EXT_END_OF_FILE, EXT_SEG_ADDR_REC, EXT_GOTO_CMD_REC,
314 EXT_LIN_ADDR_REC,
315};
316
317enum CMDS {
318 GETV = 0x00, GETC, GUNS, SCID, RMEM =
319 0x10, SMEM, WMEM, SDTM, GOTO, SSTR =
320 0x20, PSTR, KSTR, KDMA, GPOS, SETF, GSTS, NGPOS, PSEL =
321 0x30, PCLR, PLST, RSSV, LSEL, SSRC = 0x40, SLST, RSRC, SSRB, SDGV =
322 0x50, RDGV, DLST, SACR = 0x60, RACR, ALST, TXAC, RXAC, SI2S =
323 0x70, ARM_SETDPLL = 0x72,
324};
325
326enum E1SOURCE {
327 ARM2LBUS_FIFO0 = 0, ARM2LBUS_FIFO1, ARM2LBUS_FIFO2, ARM2LBUS_FIFO3,
328 ARM2LBUS_FIFO4, ARM2LBUS_FIFO5, ARM2LBUS_FIFO6, ARM2LBUS_FIFO7,
329 ARM2LBUS_FIFO8, ARM2LBUS_FIFO9, ARM2LBUS_FIFO10, ARM2LBUS_FIFO11,
330 ARM2LBUS_FIFO12, ARM2LBUS_FIFO13, ARM2LBUS_FIFO14, ARM2LBUS_FIFO15,
331 INTER0_OUT, INTER1_OUT, INTER2_OUT, INTER3_OUT, INTER4_OUT,
332 INTERM0_OUT, INTERM1_OUT, INTERM2_OUT, INTERM3_OUT, INTERM4_OUT,
333 INTERM5_OUT, INTERM6_OUT, DECIMM0_OUT, DECIMM1_OUT, DECIMM2_OUT,
334 DECIMM3_OUT, DECIM0_OUT, SR3_4_OUT, OPL3_SAMPLE, ASRC0, ASRC1,
335 ACLNK2PADC, ACLNK2MODEM0RX, ACLNK2MIC, ACLNK2MODEM1RX, ACLNK2HNDMIC,
336 DIGITAL_MIXER_OUT0, GAINFUNC0_OUT, GAINFUNC1_OUT, GAINFUNC2_OUT,
337 GAINFUNC3_OUT, GAINFUNC4_OUT, SOFTMODEMTX, SPLITTER0_OUTL,
338 SPLITTER0_OUTR, SPLITTER1_OUTL, SPLITTER1_OUTR, SPLITTER2_OUTL,
339 SPLITTER2_OUTR, SPLITTER3_OUTL, SPLITTER3_OUTR, MERGER0_OUT,
340 MERGER1_OUT, MERGER2_OUT, MERGER3_OUT, ARM2LBUS_FIFO_DIRECT, NO_OUT
341};
342
343enum E2SINK {
344 LBUS2ARM_FIFO0 = 0, LBUS2ARM_FIFO1, LBUS2ARM_FIFO2, LBUS2ARM_FIFO3,
345 LBUS2ARM_FIFO4, LBUS2ARM_FIFO5, LBUS2ARM_FIFO6, LBUS2ARM_FIFO7,
346 INTER0_IN, INTER1_IN, INTER2_IN, INTER3_IN, INTER4_IN, INTERM0_IN,
347 INTERM1_IN, INTERM2_IN, INTERM3_IN, INTERM4_IN, INTERM5_IN, INTERM6_IN,
348 DECIMM0_IN, DECIMM1_IN, DECIMM2_IN, DECIMM3_IN, DECIM0_IN, SR3_4_IN,
349 PDAC2ACLNK, MODEM0TX2ACLNK, MODEM1TX2ACLNK, HNDSPK2ACLNK,
350 DIGITAL_MIXER_IN0, DIGITAL_MIXER_IN1, DIGITAL_MIXER_IN2,
351 DIGITAL_MIXER_IN3, DIGITAL_MIXER_IN4, DIGITAL_MIXER_IN5,
352 DIGITAL_MIXER_IN6, DIGITAL_MIXER_IN7, DIGITAL_MIXER_IN8,
353 DIGITAL_MIXER_IN9, DIGITAL_MIXER_IN10, DIGITAL_MIXER_IN11,
354 GAINFUNC0_IN, GAINFUNC1_IN, GAINFUNC2_IN, GAINFUNC3_IN, GAINFUNC4_IN,
355 SOFTMODEMRX, SPLITTER0_IN, SPLITTER1_IN, SPLITTER2_IN, SPLITTER3_IN,
356 MERGER0_INL, MERGER0_INR, MERGER1_INL, MERGER1_INR, MERGER2_INL,
357 MERGER2_INR, MERGER3_INL, MERGER3_INR, E2SINK_MAX
358};
359
360enum LBUS_SINK {
361 LS_SRC_INTERPOLATOR = 0, LS_SRC_INTERPOLATORM, LS_SRC_DECIMATOR,
362 LS_SRC_DECIMATORM, LS_MIXER_IN, LS_MIXER_GAIN_FUNCTION,
363 LS_SRC_SPLITTER, LS_SRC_MERGER, LS_NONE1, LS_NONE2,
364};
365
366enum RT_CHANNEL_IDS {
367 M0TX = 0, M1TX, TAMTX, HSSPKR, PDAC, DSNDTX0, DSNDTX1, DSNDTX2,
368 DSNDTX3, DSNDTX4, DSNDTX5, DSNDTX6, DSNDTX7, WVSTRTX, COP3DTX, SPARE,
369 M0RX, HSMIC, M1RX, CLEANRX, MICADC, PADC, COPRX1, COPRX2,
370 CHANNEL_ID_COUNTER
371};
372
373enum { SB_CMD = 0, MODEM_CMD, I2S_CMD0, I2S_CMD1, FM_CMD, MAX_CMD };
374
375struct lbuspath {
376 unsigned char *noconv;
377 unsigned char *stereo;
378 unsigned char *mono;
379};
380
381struct cmdport {
382 u32 data1; /* cmd,param */
383 u32 data2; /* param */
384 u32 stat; /* status */
385 u32 pad[5];
386};
387
388struct riptideport {
389 u32 audio_control; /* status registers */
390 u32 audio_status;
391 u32 pad[2];
392 struct cmdport port[2]; /* command ports */
393};
394
395struct cmdif {
396 struct riptideport *hwport;
397 spinlock_t lock;
398 unsigned int cmdcnt; /* cmd statistics */
399 unsigned int cmdtime;
400 unsigned int cmdtimemax;
401 unsigned int cmdtimemin;
402 unsigned int errcnt;
403 int is_reset;
404};
405
406struct riptide_firmware {
407 u16 ASIC;
408 u16 CODEC;
409 u16 AUXDSP;
410 u16 PROG;
411};
412
413union cmdret {
414 u8 retbytes[8];
415 u16 retwords[4];
416 u32 retlongs[2];
417};
418
419union firmware_version {
420 union cmdret ret;
421 struct riptide_firmware firmware;
422};
423
424#define get_pcmhwdev(substream) (struct pcmhw *)(substream->runtime->private_data)
425
426#define PLAYBACK_SUBSTREAMS 3
427struct snd_riptide {
428 struct snd_card *card;
429 struct pci_dev *pci;
430 const struct firmware *fw_entry;
431
432 struct cmdif *cif;
433
434 struct snd_pcm *pcm;
435 struct snd_pcm *pcm_i2s;
436 struct snd_rawmidi *rmidi;
437 struct snd_opl3 *opl3;
438 struct snd_ac97 *ac97;
439 struct snd_ac97_bus *ac97_bus;
440
441 struct snd_pcm_substream *playback_substream[PLAYBACK_SUBSTREAMS];
442 struct snd_pcm_substream *capture_substream;
443
444 int openstreams;
445
446 int irq;
447 unsigned long port;
448 unsigned short mpuaddr;
449 unsigned short opladdr;
450#ifdef SUPPORT_JOYSTICK
451 unsigned short gameaddr;
452#endif
453 struct resource *res_port;
454
455 unsigned short device_id;
456
457 union firmware_version firmware;
458
459 spinlock_t lock;
460 struct tasklet_struct riptide_tq;
461 struct snd_info_entry *proc_entry;
462
463 unsigned long received_irqs;
464 unsigned long handled_irqs;
465#ifdef CONFIG_PM
466 int in_suspend;
467#endif
468};
469
470struct sgd { /* scatter gather desriptor */
471 u32 dwNextLink;
472 u32 dwSegPtrPhys;
473 u32 dwSegLen;
474 u32 dwStat_Ctl;
475};
476
477struct pcmhw { /* pcm descriptor */
478 struct lbuspath paths;
479 unsigned char *lbuspath;
480 unsigned char source;
481 unsigned char intdec[2];
482 unsigned char mixer;
483 unsigned char id;
484 unsigned char state;
485 unsigned int rate;
486 unsigned int channels;
487 snd_pcm_format_t format;
488 struct snd_dma_buffer sgdlist;
489 struct sgd *sgdbuf;
490 unsigned int size;
491 unsigned int pages;
492 unsigned int oldpos;
493 unsigned int pointer;
494};
495
496#define CMDRET_ZERO (union cmdret){{(u32)0, (u32) 0}}
497
498static int sendcmd(struct cmdif *cif, u32 flags, u32 cmd, u32 parm,
499 union cmdret *ret);
500static int getsourcesink(struct cmdif *cif, unsigned char source,
501 unsigned char sink, unsigned char *a,
502 unsigned char *b);
503static int snd_riptide_initialize(struct snd_riptide *chip);
504static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip);
505
506/*
507 */
508
509static struct pci_device_id snd_riptide_ids[] = {
510 {
511 .vendor = 0x127a,.device = 0x4310,
512 .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,
513 },
514 {
515 .vendor = 0x127a,.device = 0x4320,
516 .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,
517 },
518 {
519 .vendor = 0x127a,.device = 0x4330,
520 .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,
521 },
522 {
523 .vendor = 0x127a,.device = 0x4340,
524 .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,
525 },
526 {0,},
527};
528
529#ifdef SUPPORT_JOYSTICK
530static struct pci_device_id snd_riptide_joystick_ids[] = {
531 {
532 .vendor = 0x127a,.device = 0x4312,
533 .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,
534 },
535 {
536 .vendor = 0x127a,.device = 0x4322,
537 .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,
538 },
539 {.vendor = 0x127a,.device = 0x4332,
540 .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,
541 },
542 {.vendor = 0x127a,.device = 0x4342,
543 .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,
544 },
545 {0,},
546};
547#endif
548
549MODULE_DEVICE_TABLE(pci, snd_riptide_ids);
550
551/*
552 */
553
554static unsigned char lbusin2out[E2SINK_MAX + 1][2] = {
555 {NO_OUT, LS_NONE1}, {NO_OUT, LS_NONE2}, {NO_OUT, LS_NONE1}, {NO_OUT,
556 LS_NONE2},
557 {NO_OUT, LS_NONE1}, {NO_OUT, LS_NONE2}, {NO_OUT, LS_NONE1}, {NO_OUT,
558 LS_NONE2},
559 {INTER0_OUT, LS_SRC_INTERPOLATOR}, {INTER1_OUT, LS_SRC_INTERPOLATOR},
560 {INTER2_OUT, LS_SRC_INTERPOLATOR}, {INTER3_OUT, LS_SRC_INTERPOLATOR},
561 {INTER4_OUT, LS_SRC_INTERPOLATOR}, {INTERM0_OUT, LS_SRC_INTERPOLATORM},
562 {INTERM1_OUT, LS_SRC_INTERPOLATORM}, {INTERM2_OUT,
563 LS_SRC_INTERPOLATORM},
564 {INTERM3_OUT, LS_SRC_INTERPOLATORM}, {INTERM4_OUT,
565 LS_SRC_INTERPOLATORM},
566 {INTERM5_OUT, LS_SRC_INTERPOLATORM}, {INTERM6_OUT,
567 LS_SRC_INTERPOLATORM},
568 {DECIMM0_OUT, LS_SRC_DECIMATORM}, {DECIMM1_OUT, LS_SRC_DECIMATORM},
569 {DECIMM2_OUT, LS_SRC_DECIMATORM}, {DECIMM3_OUT, LS_SRC_DECIMATORM},
570 {DECIM0_OUT, LS_SRC_DECIMATOR}, {SR3_4_OUT, LS_NONE1}, {NO_OUT,
571 LS_NONE2},
572 {NO_OUT, LS_NONE1}, {NO_OUT, LS_NONE2}, {NO_OUT, LS_NONE1},
573 {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},
574 {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},
575 {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},
576 {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},
577 {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},
578 {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},
579 {GAINFUNC0_OUT, LS_MIXER_GAIN_FUNCTION}, {GAINFUNC1_OUT,
580 LS_MIXER_GAIN_FUNCTION},
581 {GAINFUNC2_OUT, LS_MIXER_GAIN_FUNCTION}, {GAINFUNC3_OUT,
582 LS_MIXER_GAIN_FUNCTION},
583 {GAINFUNC4_OUT, LS_MIXER_GAIN_FUNCTION}, {SOFTMODEMTX, LS_NONE1},
584 {SPLITTER0_OUTL, LS_SRC_SPLITTER}, {SPLITTER1_OUTL, LS_SRC_SPLITTER},
585 {SPLITTER2_OUTL, LS_SRC_SPLITTER}, {SPLITTER3_OUTL, LS_SRC_SPLITTER},
586 {MERGER0_OUT, LS_SRC_MERGER}, {MERGER0_OUT, LS_SRC_MERGER},
587 {MERGER1_OUT, LS_SRC_MERGER},
588 {MERGER1_OUT, LS_SRC_MERGER}, {MERGER2_OUT, LS_SRC_MERGER},
589 {MERGER2_OUT, LS_SRC_MERGER},
590 {MERGER3_OUT, LS_SRC_MERGER}, {MERGER3_OUT, LS_SRC_MERGER}, {NO_OUT,
591 LS_NONE2},
592};
593
594static unsigned char lbus_play_opl3[] = {
595 DIGITAL_MIXER_IN0 + FM_MIXER, 0xff
596};
597static unsigned char lbus_play_modem[] = {
598 DIGITAL_MIXER_IN0 + MODEM_MIXER, 0xff
599};
600static unsigned char lbus_play_i2s[] = {
601 INTER0_IN + I2S_INTDEC, DIGITAL_MIXER_IN0 + I2S_MIXER, 0xff
602};
603static unsigned char lbus_play_out[] = {
604 PDAC2ACLNK, 0xff
605};
606static unsigned char lbus_play_outhp[] = {
607 HNDSPK2ACLNK, 0xff
608};
609static unsigned char lbus_play_noconv1[] = {
610 DIGITAL_MIXER_IN0, 0xff
611};
612static unsigned char lbus_play_stereo1[] = {
613 INTER0_IN, DIGITAL_MIXER_IN0, 0xff
614};
615static unsigned char lbus_play_mono1[] = {
616 INTERM0_IN, DIGITAL_MIXER_IN0, 0xff
617};
618static unsigned char lbus_play_noconv2[] = {
619 DIGITAL_MIXER_IN1, 0xff
620};
621static unsigned char lbus_play_stereo2[] = {
622 INTER1_IN, DIGITAL_MIXER_IN1, 0xff
623};
624static unsigned char lbus_play_mono2[] = {
625 INTERM1_IN, DIGITAL_MIXER_IN1, 0xff
626};
627static unsigned char lbus_play_noconv3[] = {
628 DIGITAL_MIXER_IN2, 0xff
629};
630static unsigned char lbus_play_stereo3[] = {
631 INTER2_IN, DIGITAL_MIXER_IN2, 0xff
632};
633static unsigned char lbus_play_mono3[] = {
634 INTERM2_IN, DIGITAL_MIXER_IN2, 0xff
635};
636static unsigned char lbus_rec_noconv1[] = {
637 LBUS2ARM_FIFO5, 0xff
638};
639static unsigned char lbus_rec_stereo1[] = {
640 DECIM0_IN, LBUS2ARM_FIFO5, 0xff
641};
642static unsigned char lbus_rec_mono1[] = {
643 DECIMM3_IN, LBUS2ARM_FIFO5, 0xff
644};
645
646static unsigned char play_ids[] = { 4, 1, 2, };
647static unsigned char play_sources[] = {
648 ARM2LBUS_FIFO4, ARM2LBUS_FIFO1, ARM2LBUS_FIFO2,
649};
650static struct lbuspath lbus_play_paths[] = {
651 {
652 .noconv = lbus_play_noconv1,
653 .stereo = lbus_play_stereo1,
654 .mono = lbus_play_mono1,
655 },
656 {
657 .noconv = lbus_play_noconv2,
658 .stereo = lbus_play_stereo2,
659 .mono = lbus_play_mono2,
660 },
661 {
662 .noconv = lbus_play_noconv3,
663 .stereo = lbus_play_stereo3,
664 .mono = lbus_play_mono3,
665 },
666};
667static struct lbuspath lbus_rec_path = {
668 .noconv = lbus_rec_noconv1,
669 .stereo = lbus_rec_stereo1,
670 .mono = lbus_rec_mono1,
671};
672
673#define FIRMWARE_VERSIONS 1
674static union firmware_version firmware_versions[] = {
675 {
676 .firmware.ASIC = 3,.firmware.CODEC = 2,
677 .firmware.AUXDSP = 3,.firmware.PROG = 773,
678 },
679};
680
681static u32 atoh(unsigned char *in, unsigned int len)
682{
683 u32 sum = 0;
684 unsigned int mult = 1;
685 unsigned char c;
686
687 while (len) {
688 c = in[len - 1];
689 if ((c >= '0') && (c <= '9'))
690 sum += mult * (c - '0');
691 else if ((c >= 'A') && (c <= 'F'))
692 sum += mult * (c - ('A' - 10));
693 else if ((c >= 'a') && (c <= 'f'))
694 sum += mult * (c - ('a' - 10));
695 mult *= 16;
696 --len;
697 }
698 return sum;
699}
700
701static int senddata(struct cmdif *cif, unsigned char *in, u32 offset)
702{
703 u32 addr;
704 u32 data;
705 u32 i;
706 unsigned char *p;
707
708 i = atoh(&in[1], 2);
709 addr = offset + atoh(&in[3], 4);
710 if (SEND_SMEM(cif, 0, addr) != 0)
711 return -EACCES;
712 p = in + 9;
713 while (i) {
714 data = atoh(p, 8);
715 if (SEND_WMEM(cif, 2,
716 ((data & 0x0f0f0f0f) << 4) | ((data & 0xf0f0f0f0)
717 >> 4)))
718 return -EACCES;
719 i -= 4;
720 p += 8;
721 }
722 return 0;
723}
724
725static int loadfirmware(struct cmdif *cif, unsigned char *img,
726 unsigned int size)
727{
728 unsigned char *in;
729 u32 laddr, saddr, t, val;
730 int err = 0;
731
732 laddr = saddr = 0;
733 while (size > 0 && err == 0) {
734 in = img;
735 if (in[0] == ':') {
736 t = atoh(&in[7], 2);
737 switch (t) {
738 case DATA_REC:
739 err = senddata(cif, in, laddr + saddr);
740 break;
741 case EXT_SEG_ADDR_REC:
742 saddr = atoh(&in[9], 4) << 4;
743 break;
744 case EXT_LIN_ADDR_REC:
745 laddr = atoh(&in[9], 4) << 16;
746 break;
747 case EXT_GOTO_CMD_REC:
748 val = atoh(&in[9], 8);
749 if (SEND_GOTO(cif, val) != 0)
750 err = -EACCES;
751 break;
752 case EXT_END_OF_FILE:
753 size = 0;
754 break;
755 default:
756 break;
757 }
758 while (size > 0) {
759 size--;
760 if (*img++ == '\n')
761 break;
762 }
763 }
764 }
765 snd_printdd("load firmware return %d\n", err);
766 return err;
767}
768
769static void
770alloclbuspath(struct cmdif *cif, unsigned char source,
771 unsigned char *path, unsigned char *mixer, unsigned char *s)
772{
773 while (*path != 0xff) {
774 unsigned char sink, type;
775
776 sink = *path & (~SPLIT_PATH);
777 if (sink != E2SINK_MAX) {
778 snd_printdd("alloc path 0x%x->0x%x\n", source, sink);
779 SEND_PSEL(cif, source, sink);
780 source = lbusin2out[sink][0];
781 type = lbusin2out[sink][1];
782 if (type == LS_MIXER_IN) {
783 if (mixer)
784 *mixer = sink - DIGITAL_MIXER_IN0;
785 }
786 if (type == LS_SRC_DECIMATORM ||
787 type == LS_SRC_DECIMATOR ||
788 type == LS_SRC_INTERPOLATORM ||
789 type == LS_SRC_INTERPOLATOR) {
790 if (s) {
791 if (s[0] != 0xff)
792 s[1] = sink;
793 else
794 s[0] = sink;
795 }
796 }
797 }
798 if (*path++ & SPLIT_PATH) {
799 unsigned char *npath = path;
800
801 while (*npath != 0xff)
802 npath++;
803 alloclbuspath(cif, source + 1, ++npath, mixer, s);
804 }
805 }
806}
807
808static void
809freelbuspath(struct cmdif *cif, unsigned char source, unsigned char *path)
810{
811 while (*path != 0xff) {
812 unsigned char sink;
813
814 sink = *path & (~SPLIT_PATH);
815 if (sink != E2SINK_MAX) {
816 snd_printdd("free path 0x%x->0x%x\n", source, sink);
817 SEND_PCLR(cif, source, sink);
818 source = lbusin2out[sink][0];
819 }
820 if (*path++ & SPLIT_PATH) {
821 unsigned char *npath = path;
822
823 while (*npath != 0xff)
824 npath++;
825 freelbuspath(cif, source + 1, ++npath);
826 }
827 }
828}
829
830static int writearm(struct cmdif *cif, u32 addr, u32 data, u32 mask)
831{
832 union cmdret rptr = CMDRET_ZERO;
833 unsigned int i = MAX_WRITE_RETRY;
834 int flag = 1;
835
836 SEND_RMEM(cif, 0x02, addr, &rptr);
837 rptr.retlongs[0] &= (~mask);
838
839 while (--i) {
840 SEND_SMEM(cif, 0x01, addr);
841 SEND_WMEM(cif, 0x02, (rptr.retlongs[0] | data));
842 SEND_RMEM(cif, 0x02, addr, &rptr);
843 if ((rptr.retlongs[0] & data) == data) {
844 flag = 0;
845 break;
846 } else
847 rptr.retlongs[0] &= ~mask;
848 }
849 snd_printdd("send arm 0x%x 0x%x 0x%x return %d\n", addr, data, mask,
850 flag);
851 return flag;
852}
853
854static int sendcmd(struct cmdif *cif, u32 flags, u32 cmd, u32 parm,
855 union cmdret *ret)
856{
857 int i, j;
858 int err;
859 unsigned int time = 0;
860 unsigned long irqflags;
861 struct riptideport *hwport;
862 struct cmdport *cmdport = NULL;
863
864 snd_assert(cif, return -EINVAL);
865
866 hwport = cif->hwport;
867 if (cif->errcnt > MAX_ERROR_COUNT) {
868 if (cif->is_reset) {
869 snd_printk(KERN_ERR
870 "Riptide: Too many failed cmds, reinitializing\n");
871 if (riptide_reset(cif, NULL) == 0) {
872 cif->errcnt = 0;
873 return -EIO;
874 }
875 }
876 snd_printk(KERN_ERR "Riptide: Initialization failed.\n");
877 return -EINVAL;
878 }
879 if (ret) {
880 ret->retlongs[0] = 0;
881 ret->retlongs[1] = 0;
882 }
883 i = 0;
884 spin_lock_irqsave(&cif->lock, irqflags);
885 while (i++ < CMDIF_TIMEOUT && !IS_READY(cif->hwport))
886 udelay(10);
887 if (i >= CMDIF_TIMEOUT) {
888 err = -EBUSY;
889 goto errout;
890 }
891
892 err = 0;
893 for (j = 0, time = 0; time < CMDIF_TIMEOUT; j++, time += 2) {
894 cmdport = &(hwport->port[j % 2]);
895 if (IS_DATF(cmdport)) { /* free pending data */
896 READ_PORT_ULONG(cmdport->data1);
897 READ_PORT_ULONG(cmdport->data2);
898 }
899 if (IS_CMDE(cmdport)) {
900 if (flags & PARM) /* put data */
901 WRITE_PORT_ULONG(cmdport->data2, parm);
902 WRITE_PORT_ULONG(cmdport->data1, cmd); /* write cmd */
903 if ((flags & RESP) && ret) {
904 while (!IS_DATF(cmdport) &&
905 time++ < CMDIF_TIMEOUT)
906 udelay(10);
907 if (time < CMDIF_TIMEOUT) { /* read response */
908 ret->retlongs[0] =
909 READ_PORT_ULONG(cmdport->data1);
910 ret->retlongs[1] =
911 READ_PORT_ULONG(cmdport->data2);
912 } else {
913 err = -ENOSYS;
914 goto errout;
915 }
916 }
917 break;
918 }
919 udelay(20);
920 }
921 if (time == CMDIF_TIMEOUT) {
922 err = -ENODATA;
923 goto errout;
924 }
925 spin_unlock_irqrestore(&cif->lock, irqflags);
926
927 cif->cmdcnt++; /* update command statistics */
928 cif->cmdtime += time;
929 if (time > cif->cmdtimemax)
930 cif->cmdtimemax = time;
931 if (time < cif->cmdtimemin)
932 cif->cmdtimemin = time;
933 if ((cif->cmdcnt) % 1000 == 0)
934 snd_printdd
935 ("send cmd %d time: %d mintime: %d maxtime %d err: %d\n",
936 cif->cmdcnt, cif->cmdtime, cif->cmdtimemin,
937 cif->cmdtimemax, cif->errcnt);
938 return 0;
939
940 errout:
941 cif->errcnt++;
942 spin_unlock_irqrestore(&cif->lock, irqflags);
943 snd_printdd
944 ("send cmd %d hw: 0x%x flag: 0x%x cmd: 0x%x parm: 0x%x ret: 0x%x 0x%x CMDE: %d DATF: %d failed %d\n",
945 cif->cmdcnt, (int)((void *)&(cmdport->stat) - (void *)hwport),
946 flags, cmd, parm, ret ? ret->retlongs[0] : 0,
947 ret ? ret->retlongs[1] : 0, IS_CMDE(cmdport), IS_DATF(cmdport),
948 err);
949 return err;
950}
951
952static int
953setmixer(struct cmdif *cif, short num, unsigned short rval, unsigned short lval)
954{
955 union cmdret rptr = CMDRET_ZERO;
956 int i = 0;
957
958 snd_printdd("sent mixer %d: 0x%d 0x%d\n", num, rval, lval);
959 do {
960 SEND_SDGV(cif, num, num, rval, lval);
961 SEND_RDGV(cif, num, num, &rptr);
962 if (rptr.retwords[0] == lval && rptr.retwords[1] == rval)
963 return 0;
964 } while (i++ < MAX_WRITE_RETRY);
965 snd_printdd("sent mixer failed\n");
966 return -EIO;
967}
968
969static int getpaths(struct cmdif *cif, unsigned char *o)
970{
971 unsigned char src[E2SINK_MAX];
972 unsigned char sink[E2SINK_MAX];
973 int i, j = 0;
974
975 for (i = 0; i < E2SINK_MAX; i++) {
976 getsourcesink(cif, i, i, &src[i], &sink[i]);
977 if (sink[i] < E2SINK_MAX) {
978 o[j++] = sink[i];
979 o[j++] = i;
980 }
981 }
982 return j;
983}
984
985static int
986getsourcesink(struct cmdif *cif, unsigned char source, unsigned char sink,
987 unsigned char *a, unsigned char *b)
988{
989 union cmdret rptr = CMDRET_ZERO;
990
991 if (SEND_RSSV(cif, source, sink, &rptr) &&
992 SEND_RSSV(cif, source, sink, &rptr))
993 return -EIO;
994 *a = rptr.retbytes[0];
995 *b = rptr.retbytes[1];
996 snd_printdd("getsourcesink 0x%x 0x%x\n", *a, *b);
997 return 0;
998}
999
1000static int
1001getsamplerate(struct cmdif *cif, unsigned char *intdec, unsigned int *rate)
1002{
1003 unsigned char *s;
1004 unsigned int p[2] = { 0, 0 };
1005 int i;
1006 union cmdret rptr = CMDRET_ZERO;
1007
1008 s = intdec;
1009 for (i = 0; i < 2; i++) {
1010 if (*s != 0xff) {
1011 if (SEND_RSRC(cif, *s, &rptr) &&
1012 SEND_RSRC(cif, *s, &rptr))
1013 return -EIO;
1014 p[i] += rptr.retwords[1];
1015 p[i] *= rptr.retwords[2];
1016 p[i] += rptr.retwords[3];
1017 p[i] /= 65536;
1018 }
1019 s++;
1020 }
1021 if (p[0]) {
1022 if (p[1] != p[0])
1023 snd_printdd("rates differ %d %d\n", p[0], p[1]);
1024 *rate = (unsigned int)p[0];
1025 } else
1026 *rate = (unsigned int)p[1];
1027 snd_printdd("getsampleformat %d %d %d\n", intdec[0], intdec[1], *rate);
1028 return 0;
1029}
1030
1031static int
1032setsampleformat(struct cmdif *cif,
1033 unsigned char mixer, unsigned char id,
1034 unsigned char channels, unsigned char format)
1035{
1036 unsigned char w, ch, sig, order;
1037
1038 snd_printdd
1039 ("setsampleformat mixer: %d id: %d channels: %d format: %d\n",
1040 mixer, id, channels, format);
1041 ch = channels == 1;
1042 w = snd_pcm_format_width(format) == 8;
1043 sig = snd_pcm_format_unsigned(format) != 0;
1044 order = snd_pcm_format_big_endian(format) != 0;
1045
1046 if (SEND_SETF(cif, mixer, w, ch, order, sig, id) &&
1047 SEND_SETF(cif, mixer, w, ch, order, sig, id)) {
1048 snd_printdd("setsampleformat failed\n");
1049 return -EIO;
1050 }
1051 return 0;
1052}
1053
1054static int
1055setsamplerate(struct cmdif *cif, unsigned char *intdec, unsigned int rate)
1056{
1057 u32 D, M, N;
1058 union cmdret rptr = CMDRET_ZERO;
1059 int i;
1060
1061 snd_printdd("setsamplerate intdec: %d,%d rate: %d\n", intdec[0],
1062 intdec[1], rate);
1063 D = 48000;
1064 M = ((rate == 48000) ? 47999 : rate) * 65536;
1065 N = M % D;
1066 M /= D;
1067 for (i = 0; i < 2; i++) {
1068 if (*intdec != 0xff) {
1069 do {
1070 SEND_SSRC(cif, *intdec, D, M, N);
1071 SEND_RSRC(cif, *intdec, &rptr);
1072 } while (rptr.retwords[1] != D &&
1073 rptr.retwords[2] != M &&
1074 rptr.retwords[3] != N &&
1075 i++ < MAX_WRITE_RETRY);
1076 if (i == MAX_WRITE_RETRY) {
1077 snd_printdd("sent samplerate %d: %d failed\n",
1078 *intdec, rate);
1079 return -EIO;
1080 }
1081 }
1082 intdec++;
1083 }
1084 return 0;
1085}
1086
1087static int
1088getmixer(struct cmdif *cif, short num, unsigned short *rval,
1089 unsigned short *lval)
1090{
1091 union cmdret rptr = CMDRET_ZERO;
1092
1093 if (SEND_RDGV(cif, num, num, &rptr) && SEND_RDGV(cif, num, num, &rptr))
1094 return -EIO;
1095 *rval = rptr.retwords[0];
1096 *lval = rptr.retwords[1];
1097 snd_printdd("got mixer %d: 0x%d 0x%d\n", num, *rval, *lval);
1098 return 0;
1099}
1100
1101static void riptide_handleirq(unsigned long dev_id)
1102{
1103 struct snd_riptide *chip = (void *)dev_id;
1104 struct cmdif *cif = chip->cif;
1105 struct snd_pcm_substream *substream[PLAYBACK_SUBSTREAMS + 1];
1106 struct snd_pcm_runtime *runtime;
1107 struct pcmhw *data = NULL;
1108 unsigned int pos, period_bytes;
1109 struct sgd *c;
1110 int i, j;
1111 unsigned int flag;
1112
1113 if (!cif)
1114 return;
1115
1116 for (i = 0; i < PLAYBACK_SUBSTREAMS; i++)
1117 substream[i] = chip->playback_substream[i];
1118 substream[i] = chip->capture_substream;
1119 for (i = 0; i < PLAYBACK_SUBSTREAMS + 1; i++) {
1120 if (substream[i] &&
1121 (runtime = substream[i]->runtime) &&
1122 (data = runtime->private_data) && data->state != ST_STOP) {
1123 pos = 0;
1124 for (j = 0; j < data->pages; j++) {
1125 c = &data->sgdbuf[j];
1126 flag = le32_to_cpu(c->dwStat_Ctl);
1127 if (flag & EOB_STATUS)
1128 pos += le32_to_cpu(c->dwSegLen);
1129 if (flag & EOC_STATUS)
1130 pos += le32_to_cpu(c->dwSegLen);
1131 if ((flag & EOS_STATUS)
1132 && (data->state == ST_PLAY)) {
1133 data->state = ST_STOP;
1134 snd_printk(KERN_ERR
1135 "Riptide: DMA stopped unexpectedly\n");
1136 }
1137 c->dwStat_Ctl =
1138 cpu_to_le32(flag &
1139 ~(EOS_STATUS | EOB_STATUS |
1140 EOC_STATUS));
1141 }
1142 data->pointer += pos;
1143 pos += data->oldpos;
1144 if (data->state != ST_STOP) {
1145 period_bytes =
1146 frames_to_bytes(runtime,
1147 runtime->period_size);
1148 snd_printdd
1149 ("interrupt 0x%x after 0x%lx of 0x%lx frames in period\n",
1150 READ_AUDIO_STATUS(cif->hwport),
1151 bytes_to_frames(runtime, pos),
1152 runtime->period_size);
1153 j = 0;
1154 if (pos >= period_bytes) {
1155 j++;
1156 while (pos >= period_bytes)
1157 pos -= period_bytes;
1158 }
1159 data->oldpos = pos;
1160 if (j > 0)
1161 snd_pcm_period_elapsed(substream[i]);
1162 }
1163 }
1164 }
1165}
1166
1167#ifdef CONFIG_PM
1168static int riptide_suspend(struct pci_dev *pci, pm_message_t state)
1169{
1170 struct snd_card *card = pci_get_drvdata(pci);
1171 struct snd_riptide *chip = card->private_data;
1172
1173 chip->in_suspend = 1;
1174 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
1175 snd_pcm_suspend_all(chip->pcm);
1176 snd_ac97_suspend(chip->ac97);
1177 pci_set_power_state(pci, PCI_D3hot);
1178 pci_disable_device(pci);
1179 pci_save_state(pci);
1180 return 0;
1181}
1182
1183static int riptide_resume(struct pci_dev *pci)
1184{
1185 struct snd_card *card = pci_get_drvdata(pci);
1186 struct snd_riptide *chip = card->private_data;
1187
1188 pci_restore_state(pci);
1189 pci_enable_device(pci);
1190 pci_set_power_state(pci, PCI_D0);
1191 pci_set_master(pci);
1192 snd_riptide_initialize(chip);
1193 snd_ac97_resume(chip->ac97);
1194 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1195 chip->in_suspend = 0;
1196 return 0;
1197}
1198#endif
1199
1200static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip)
1201{
1202 int timeout, tries;
1203 union cmdret rptr = CMDRET_ZERO;
1204 union firmware_version firmware;
1205 int i, j, err, has_firmware;
1206
1207 if (!cif)
1208 return -EINVAL;
1209
1210 cif->cmdcnt = 0;
1211 cif->cmdtime = 0;
1212 cif->cmdtimemax = 0;
1213 cif->cmdtimemin = 0xffffffff;
1214 cif->errcnt = 0;
1215 cif->is_reset = 0;
1216
1217 tries = RESET_TRIES;
1218 has_firmware = 0;
1219 while (has_firmware == 0 && tries-- > 0) {
1220 for (i = 0; i < 2; i++) {
1221 WRITE_PORT_ULONG(cif->hwport->port[i].data1, 0);
1222 WRITE_PORT_ULONG(cif->hwport->port[i].data2, 0);
1223 }
1224 SET_GRESET(cif->hwport);
1225 udelay(100);
1226 UNSET_GRESET(cif->hwport);
1227 udelay(100);
1228
1229 for (timeout = 100000; --timeout; udelay(10)) {
1230 if (IS_READY(cif->hwport) && !IS_GERR(cif->hwport))
1231 break;
1232 }
1233 if (timeout == 0) {
1234 snd_printk(KERN_ERR
1235 "Riptide: device not ready, audio status: 0x%x ready: %d gerr: %d\n",
1236 READ_AUDIO_STATUS(cif->hwport),
1237 IS_READY(cif->hwport), IS_GERR(cif->hwport));
1238 return -EIO;
1239 } else {
1240 snd_printdd
1241 ("Riptide: audio status: 0x%x ready: %d gerr: %d\n",
1242 READ_AUDIO_STATUS(cif->hwport),
1243 IS_READY(cif->hwport), IS_GERR(cif->hwport));
1244 }
1245
1246 SEND_GETV(cif, &rptr);
1247 for (i = 0; i < 4; i++)
1248 firmware.ret.retwords[i] = rptr.retwords[i];
1249
1250 snd_printdd
1251 ("Firmware version: ASIC: %d CODEC %d AUXDSP %d PROG %d\n",
1252 firmware.firmware.ASIC, firmware.firmware.CODEC,
1253 firmware.firmware.AUXDSP, firmware.firmware.PROG);
1254
1255 for (j = 0; j < FIRMWARE_VERSIONS; j++) {
1256 has_firmware = 1;
1257 for (i = 0; i < 4; i++) {
1258 if (firmware_versions[j].ret.retwords[i] !=
1259 firmware.ret.retwords[i])
1260 has_firmware = 0;
1261 }
1262 if (has_firmware)
1263 break;
1264 }
1265
1266 if (chip != NULL && has_firmware == 0) {
1267 snd_printdd("Writing Firmware\n");
1268 if (!chip->fw_entry) {
1269 if ((err =
1270 request_firmware(&chip->fw_entry,
1271 "riptide.hex",
1272 &chip->pci->dev)) != 0) {
1273 snd_printk(KERN_ERR
1274 "Riptide: Firmware not available %d\n",
1275 err);
1276 return -EIO;
1277 }
1278 }
1279 err = loadfirmware(cif, chip->fw_entry->data,
1280 chip->fw_entry->size);
1281 if (err)
1282 snd_printk(KERN_ERR
1283 "Riptide: Could not load firmware %d\n",
1284 err);
1285 }
1286 }
1287
1288 SEND_SACR(cif, 0, AC97_RESET);
1289 SEND_RACR(cif, AC97_RESET, &rptr);
1290 snd_printdd("AC97: 0x%x 0x%x\n", rptr.retlongs[0], rptr.retlongs[1]);
1291
1292 SEND_PLST(cif, 0);
1293 SEND_SLST(cif, 0);
1294 SEND_DLST(cif, 0);
1295 SEND_ALST(cif, 0);
1296 SEND_KDMA(cif);
1297
1298 writearm(cif, 0x301F8, 1, 1);
1299 writearm(cif, 0x301F4, 1, 1);
1300
1301 SEND_LSEL(cif, MODEM_CMD, 0, 0, MODEM_INTDEC, MODEM_MERGER,
1302 MODEM_SPLITTER, MODEM_MIXER);
1303 setmixer(cif, MODEM_MIXER, 0x7fff, 0x7fff);
1304 alloclbuspath(cif, ARM2LBUS_FIFO13, lbus_play_modem, NULL, NULL);
1305
1306 SEND_LSEL(cif, FM_CMD, 0, 0, FM_INTDEC, FM_MERGER, FM_SPLITTER,
1307 FM_MIXER);
1308 setmixer(cif, FM_MIXER, 0x7fff, 0x7fff);
1309 writearm(cif, 0x30648 + FM_MIXER * 4, 0x01, 0x00000005);
1310 writearm(cif, 0x301A8, 0x02, 0x00000002);
1311 writearm(cif, 0x30264, 0x08, 0xffffffff);
1312 alloclbuspath(cif, OPL3_SAMPLE, lbus_play_opl3, NULL, NULL);
1313
1314 SEND_SSRC(cif, I2S_INTDEC, 48000,
1315 ((u32) I2S_RATE * 65536) / 48000,
1316 ((u32) I2S_RATE * 65536) % 48000);
1317 SEND_LSEL(cif, I2S_CMD0, 0, 0, I2S_INTDEC, I2S_MERGER, I2S_SPLITTER,
1318 I2S_MIXER);
1319 SEND_SI2S(cif, 1);
1320 alloclbuspath(cif, ARM2LBUS_FIFO0, lbus_play_i2s, NULL, NULL);
1321 alloclbuspath(cif, DIGITAL_MIXER_OUT0, lbus_play_out, NULL, NULL);
1322 alloclbuspath(cif, DIGITAL_MIXER_OUT0, lbus_play_outhp, NULL, NULL);
1323
1324 SET_AIACK(cif->hwport);
1325 SET_AIE(cif->hwport);
1326 SET_AIACK(cif->hwport);
1327 cif->is_reset = 1;
1328 if (chip) {
1329 for (i = 0; i < 4; i++)
1330 chip->firmware.ret.retwords[i] =
1331 firmware.ret.retwords[i];
1332 }
1333
1334 return 0;
1335}
1336
1337static struct snd_pcm_hardware snd_riptide_playback = {
1338 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1339 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1340 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID),
1341 .formats =
1342 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8
1343 | SNDRV_PCM_FMTBIT_U16_LE,
1344 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
1345 .rate_min = 5500,
1346 .rate_max = 48000,
1347 .channels_min = 1,
1348 .channels_max = 2,
1349 .buffer_bytes_max = (64 * 1024),
1350 .period_bytes_min = PAGE_SIZE >> 1,
1351 .period_bytes_max = PAGE_SIZE << 8,
1352 .periods_min = 2,
1353 .periods_max = 64,
1354 .fifo_size = 0,
1355};
1356static struct snd_pcm_hardware snd_riptide_capture = {
1357 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1358 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1359 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID),
1360 .formats =
1361 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8
1362 | SNDRV_PCM_FMTBIT_U16_LE,
1363 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
1364 .rate_min = 5500,
1365 .rate_max = 48000,
1366 .channels_min = 1,
1367 .channels_max = 2,
1368 .buffer_bytes_max = (64 * 1024),
1369 .period_bytes_min = PAGE_SIZE >> 1,
1370 .period_bytes_max = PAGE_SIZE << 3,
1371 .periods_min = 2,
1372 .periods_max = 64,
1373 .fifo_size = 0,
1374};
1375
1376static snd_pcm_uframes_t snd_riptide_pointer(struct snd_pcm_substream
1377 *substream)
1378{
1379 struct snd_riptide *chip = snd_pcm_substream_chip(substream);
1380 struct snd_pcm_runtime *runtime = substream->runtime;
1381 struct pcmhw *data = get_pcmhwdev(substream);
1382 struct cmdif *cif = chip->cif;
1383 union cmdret rptr = CMDRET_ZERO;
1384 snd_pcm_uframes_t ret;
1385
1386 SEND_GPOS(cif, 0, data->id, &rptr);
1387 if (data->size && runtime->period_size) {
1388 snd_printdd
1389 ("pointer stream %d position 0x%x(0x%x in buffer) bytes 0x%lx(0x%lx in period) frames\n",
1390 data->id, rptr.retlongs[1], rptr.retlongs[1] % data->size,
1391 bytes_to_frames(runtime, rptr.retlongs[1]),
1392 bytes_to_frames(runtime,
1393 rptr.retlongs[1]) % runtime->period_size);
1394 if (rptr.retlongs[1] > data->pointer)
1395 ret =
1396 bytes_to_frames(runtime,
1397 rptr.retlongs[1] % data->size);
1398 else
1399 ret =
1400 bytes_to_frames(runtime,
1401 data->pointer % data->size);
1402 } else {
1403 snd_printdd("stream not started or strange parms (%d %ld)\n",
1404 data->size, runtime->period_size);
1405 ret = bytes_to_frames(runtime, 0);
1406 }
1407 return ret;
1408}
1409
1410static int snd_riptide_trigger(struct snd_pcm_substream *substream, int cmd)
1411{
1412 int i, j;
1413 struct snd_riptide *chip = snd_pcm_substream_chip(substream);
1414 struct pcmhw *data = get_pcmhwdev(substream);
1415 struct cmdif *cif = chip->cif;
1416 union cmdret rptr = CMDRET_ZERO;
1417
1418 spin_lock(&chip->lock);
1419 switch (cmd) {
1420 case SNDRV_PCM_TRIGGER_START:
1421 case SNDRV_PCM_TRIGGER_RESUME:
1422 if (!(data->state & ST_PLAY)) {
1423 SEND_SSTR(cif, data->id, data->sgdlist.addr);
1424 SET_AIE(cif->hwport);
1425 data->state = ST_PLAY;
1426 if (data->mixer != 0xff)
1427 setmixer(cif, data->mixer, 0x7fff, 0x7fff);
1428 chip->openstreams++;
1429 data->oldpos = 0;
1430 data->pointer = 0;
1431 }
1432 break;
1433 case SNDRV_PCM_TRIGGER_STOP:
1434 case SNDRV_PCM_TRIGGER_SUSPEND:
1435 if (data->mixer != 0xff)
1436 setmixer(cif, data->mixer, 0, 0);
1437 setmixer(cif, data->mixer, 0, 0);
1438 SEND_KSTR(cif, data->id);
1439 data->state = ST_STOP;
1440 chip->openstreams--;
1441 j = 0;
1442 do {
1443 i = rptr.retlongs[1];
1444 SEND_GPOS(cif, 0, data->id, &rptr);
1445 udelay(1);
1446 } while (i != rptr.retlongs[1] && j++ < MAX_WRITE_RETRY);
1447 if (j >= MAX_WRITE_RETRY)
1448 snd_printk(KERN_ERR "Riptide: Could not stop stream!");
1449 break;
1450 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1451 if (!(data->state & ST_PAUSE)) {
1452 SEND_PSTR(cif, data->id);
1453 data->state |= ST_PAUSE;
1454 chip->openstreams--;
1455 }
1456 break;
1457 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1458 if (data->state & ST_PAUSE) {
1459 SEND_SSTR(cif, data->id, data->sgdlist.addr);
1460 data->state &= ~ST_PAUSE;
1461 chip->openstreams++;
1462 }
1463 break;
1464 default:
1465 spin_unlock(&chip->lock);
1466 return -EINVAL;
1467 }
1468 spin_unlock(&chip->lock);
1469 return 0;
1470}
1471
1472static int snd_riptide_prepare(struct snd_pcm_substream *substream)
1473{
1474 struct snd_riptide *chip = snd_pcm_substream_chip(substream);
1475 struct snd_pcm_runtime *runtime = substream->runtime;
1476 struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
1477 struct pcmhw *data = get_pcmhwdev(substream);
1478 struct cmdif *cif = chip->cif;
1479 unsigned char *lbuspath = NULL;
1480 unsigned int rate, channels;
1481 int err = 0;
1482 snd_pcm_format_t format;
1483
1484 snd_assert(cif && data, return -EINVAL);
1485
1486 snd_printdd("prepare id %d ch: %d f:0x%x r:%d\n", data->id,
1487 runtime->channels, runtime->format, runtime->rate);
1488
1489 spin_lock_irq(&chip->lock);
1490 channels = runtime->channels;
1491 format = runtime->format;
1492 rate = runtime->rate;
1493 switch (channels) {
1494 case 1:
1495 if (rate == 48000 && format == SNDRV_PCM_FORMAT_S16_LE)
1496 lbuspath = data->paths.noconv;
1497 else
1498 lbuspath = data->paths.mono;
1499 break;
1500 case 2:
1501 if (rate == 48000 && format == SNDRV_PCM_FORMAT_S16_LE)
1502 lbuspath = data->paths.noconv;
1503 else
1504 lbuspath = data->paths.stereo;
1505 break;
1506 }
1507 snd_printdd("use sgdlist at 0x%p and buffer at 0x%p\n",
1508 data->sgdlist.area, sgbuf);
1509 if (data->sgdlist.area && sgbuf) {
1510 unsigned int i, j, size, pages, f, pt, period;
1511 struct sgd *c, *p = NULL;
1512
1513 size = frames_to_bytes(runtime, runtime->buffer_size);
1514 period = frames_to_bytes(runtime, runtime->period_size);
1515 f = PAGE_SIZE;
1516 while ((size + (f >> 1) - 1) <= (f << 7) && (f << 1) > period)
1517 f = f >> 1;
1518 pages = (size + f - 1) / f;
1519 data->size = size;
1520 data->pages = pages;
1521 snd_printdd
1522 ("create sgd size: 0x%x pages %d of size 0x%x for period 0x%x\n",
1523 size, pages, f, period);
1524 pt = 0;
1525 j = 0;
1526 for (i = 0; i < pages; i++) {
1527 c = &data->sgdbuf[i];
1528 if (p)
1529 p->dwNextLink = cpu_to_le32(data->sgdlist.addr +
1530 (i *
1531 sizeof(struct
1532 sgd)));
1533 c->dwNextLink = cpu_to_le32(data->sgdlist.addr);
1534 c->dwSegPtrPhys =
1535 cpu_to_le32(sgbuf->table[j].addr + pt);
1536 pt = (pt + f) % PAGE_SIZE;
1537 if (pt == 0)
1538 j++;
1539 c->dwSegLen = cpu_to_le32(f);
1540 c->dwStat_Ctl =
1541 cpu_to_le32(IEOB_ENABLE | IEOS_ENABLE |
1542 IEOC_ENABLE);
1543 p = c;
1544 size -= f;
1545 }
1546 data->sgdbuf[i].dwSegLen = cpu_to_le32(size);
1547 }
1548 if (lbuspath && lbuspath != data->lbuspath) {
1549 if (data->lbuspath)
1550 freelbuspath(cif, data->source, data->lbuspath);
1551 alloclbuspath(cif, data->source, lbuspath,
1552 &data->mixer, data->intdec);
1553 data->lbuspath = lbuspath;
1554 data->rate = 0;
1555 }
1556 if (data->rate != rate || data->format != format ||
1557 data->channels != channels) {
1558 data->rate = rate;
1559 data->format = format;
1560 data->channels = channels;
1561 if (setsampleformat
1562 (cif, data->mixer, data->id, channels, format)
1563 || setsamplerate(cif, data->intdec, rate))
1564 err = -EIO;
1565 }
1566 spin_unlock_irq(&chip->lock);
1567 return err;
1568}
1569
1570static int
1571snd_riptide_hw_params(struct snd_pcm_substream *substream,
1572 struct snd_pcm_hw_params *hw_params)
1573{
1574 struct snd_riptide *chip = snd_pcm_substream_chip(substream);
1575 struct pcmhw *data = get_pcmhwdev(substream);
1576 struct snd_dma_buffer *sgdlist = &data->sgdlist;
1577 int err;
1578
1579 snd_printdd("hw params id %d (sgdlist: 0x%p 0x%lx %d)\n", data->id,
1580 sgdlist->area, (unsigned long)sgdlist->addr,
1581 (int)sgdlist->bytes);
1582 if (sgdlist->area)
1583 snd_dma_free_pages(sgdlist);
1584 if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
1585 snd_dma_pci_data(chip->pci),
1586 sizeof(struct sgd) * (DESC_MAX_MASK + 1),
1587 sgdlist)) < 0) {
1588 snd_printk(KERN_ERR "Riptide: failed to alloc %d dma bytes\n",
1589 (int)sizeof(struct sgd) * (DESC_MAX_MASK + 1));
1590 return err;
1591 }
1592 data->sgdbuf = (struct sgd *)sgdlist->area;
1593 return snd_pcm_lib_malloc_pages(substream,
1594 params_buffer_bytes(hw_params));
1595}
1596
1597static int snd_riptide_hw_free(struct snd_pcm_substream *substream)
1598{
1599 struct snd_riptide *chip = snd_pcm_substream_chip(substream);
1600 struct pcmhw *data = get_pcmhwdev(substream);
1601 struct cmdif *cif = chip->cif;
1602
1603 if (cif && data) {
1604 if (data->lbuspath)
1605 freelbuspath(cif, data->source, data->lbuspath);
1606 data->lbuspath = NULL;
1607 data->source = 0xff;
1608 data->intdec[0] = 0xff;
1609 data->intdec[1] = 0xff;
1610
1611 if (data->sgdlist.area) {
1612 snd_dma_free_pages(&data->sgdlist);
1613 data->sgdlist.area = NULL;
1614 }
1615 }
1616 return snd_pcm_lib_free_pages(substream);
1617}
1618
1619static int snd_riptide_playback_open(struct snd_pcm_substream *substream)
1620{
1621 struct snd_riptide *chip = snd_pcm_substream_chip(substream);
1622 struct snd_pcm_runtime *runtime = substream->runtime;
1623 struct pcmhw *data;
1624 int index = substream->number;
1625
1626 chip->playback_substream[index] = substream;
1627 runtime->hw = snd_riptide_playback;
1628 data = kzalloc(sizeof(struct pcmhw), GFP_KERNEL);
1629 data->paths = lbus_play_paths[index];
1630 data->id = play_ids[index];
1631 data->source = play_sources[index];
1632 data->intdec[0] = 0xff;
1633 data->intdec[1] = 0xff;
1634 data->state = ST_STOP;
1635 runtime->private_data = data;
1636 return snd_pcm_hw_constraint_integer(runtime,
1637 SNDRV_PCM_HW_PARAM_PERIODS);
1638}
1639
1640static int snd_riptide_capture_open(struct snd_pcm_substream *substream)
1641{
1642 struct snd_riptide *chip = snd_pcm_substream_chip(substream);
1643 struct snd_pcm_runtime *runtime = substream->runtime;
1644 struct pcmhw *data;
1645
1646 chip->capture_substream = substream;
1647 runtime->hw = snd_riptide_capture;
1648 data = kzalloc(sizeof(struct pcmhw), GFP_KERNEL);
1649 data->paths = lbus_rec_path;
1650 data->id = PADC;
1651 data->source = ACLNK2PADC;
1652 data->intdec[0] = 0xff;
1653 data->intdec[1] = 0xff;
1654 data->state = ST_STOP;
1655 runtime->private_data = data;
1656 return snd_pcm_hw_constraint_integer(runtime,
1657 SNDRV_PCM_HW_PARAM_PERIODS);
1658}
1659
1660static int snd_riptide_playback_close(struct snd_pcm_substream *substream)
1661{
1662 struct snd_riptide *chip = snd_pcm_substream_chip(substream);
1663 struct pcmhw *data = get_pcmhwdev(substream);
1664 int index = substream->number;
1665
1666 substream->runtime->private_data = NULL;
1667 chip->playback_substream[index] = NULL;
1668 kfree(data);
1669 return 0;
1670}
1671
1672static int snd_riptide_capture_close(struct snd_pcm_substream *substream)
1673{
1674 struct snd_riptide *chip = snd_pcm_substream_chip(substream);
1675 struct pcmhw *data = get_pcmhwdev(substream);
1676
1677 substream->runtime->private_data = NULL;
1678 chip->capture_substream = NULL;
1679 kfree(data);
1680 return 0;
1681}
1682
1683static struct snd_pcm_ops snd_riptide_playback_ops = {
1684 .open = snd_riptide_playback_open,
1685 .close = snd_riptide_playback_close,
1686 .ioctl = snd_pcm_lib_ioctl,
1687 .hw_params = snd_riptide_hw_params,
1688 .hw_free = snd_riptide_hw_free,
1689 .prepare = snd_riptide_prepare,
1690 .page = snd_pcm_sgbuf_ops_page,
1691 .trigger = snd_riptide_trigger,
1692 .pointer = snd_riptide_pointer,
1693};
1694static struct snd_pcm_ops snd_riptide_capture_ops = {
1695 .open = snd_riptide_capture_open,
1696 .close = snd_riptide_capture_close,
1697 .ioctl = snd_pcm_lib_ioctl,
1698 .hw_params = snd_riptide_hw_params,
1699 .hw_free = snd_riptide_hw_free,
1700 .prepare = snd_riptide_prepare,
1701 .page = snd_pcm_sgbuf_ops_page,
1702 .trigger = snd_riptide_trigger,
1703 .pointer = snd_riptide_pointer,
1704};
1705
1706static int __devinit
1707snd_riptide_pcm(struct snd_riptide *chip, int device, struct snd_pcm **rpcm)
1708{
1709 struct snd_pcm *pcm;
1710 int err;
1711
1712 if (rpcm)
1713 *rpcm = NULL;
1714 if ((err =
1715 snd_pcm_new(chip->card, "RIPTIDE", device, PLAYBACK_SUBSTREAMS, 1,
1716 &pcm)) < 0)
1717 return err;
1718 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1719 &snd_riptide_playback_ops);
1720 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1721 &snd_riptide_capture_ops);
1722 pcm->private_data = chip;
1723 pcm->info_flags = 0;
1724 strcpy(pcm->name, "RIPTIDE");
1725 chip->pcm = pcm;
1726 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
1727 snd_dma_pci_data(chip->pci),
1728 64 * 1024, 128 * 1024);
1729 if (rpcm)
1730 *rpcm = pcm;
1731 return 0;
1732}
1733
1734static irqreturn_t
1735snd_riptide_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1736{
1737 struct snd_riptide *chip = dev_id;
1738 struct cmdif *cif = chip->cif;
1739
1740 if (cif) {
1741 chip->received_irqs++;
1742 if (IS_EOBIRQ(cif->hwport) || IS_EOSIRQ(cif->hwport) ||
1743 IS_EOCIRQ(cif->hwport)) {
1744 chip->handled_irqs++;
1745 tasklet_hi_schedule(&chip->riptide_tq);
1746 }
1747 if (chip->rmidi && IS_MPUIRQ(cif->hwport)) {
1748 chip->handled_irqs++;
1749 snd_mpu401_uart_interrupt(irq,
1750 chip->rmidi->private_data,
1751 regs);
1752 }
1753 SET_AIACK(cif->hwport);
1754 }
1755 return IRQ_HANDLED;
1756}
1757
1758static void
1759snd_riptide_codec_write(struct snd_ac97 *ac97, unsigned short reg,
1760 unsigned short val)
1761{
1762 struct snd_riptide *chip = ac97->private_data;
1763 struct cmdif *cif = chip->cif;
1764 union cmdret rptr = CMDRET_ZERO;
1765 int i = 0;
1766
1767 snd_assert(cif, return);
1768
1769 snd_printdd("Write AC97 reg 0x%x 0x%x\n", reg, val);
1770 do {
1771 SEND_SACR(cif, val, reg);
1772 SEND_RACR(cif, reg, &rptr);
1773 } while (rptr.retwords[1] != val && i++ < MAX_WRITE_RETRY);
1774 if (i == MAX_WRITE_RETRY)
1775 snd_printdd("Write AC97 reg failed\n");
1776}
1777
1778static unsigned short snd_riptide_codec_read(struct snd_ac97 *ac97,
1779 unsigned short reg)
1780{
1781 struct snd_riptide *chip = ac97->private_data;
1782 struct cmdif *cif = chip->cif;
1783 union cmdret rptr = CMDRET_ZERO;
1784
1785 snd_assert(cif, return 0);
1786
1787 if (SEND_RACR(cif, reg, &rptr) != 0)
1788 SEND_RACR(cif, reg, &rptr);
1789 snd_printdd("Read AC97 reg 0x%x got 0x%x\n", reg, rptr.retwords[1]);
1790 return rptr.retwords[1];
1791}
1792
1793static int snd_riptide_initialize(struct snd_riptide *chip)
1794{
1795 struct cmdif *cif;
1796 unsigned int device_id;
1797 int err;
1798
1799 snd_assert(chip, return -EINVAL);
1800
1801 cif = chip->cif;
1802 if (!cif) {
1803 if ((cif = kzalloc(sizeof(struct cmdif), GFP_KERNEL)) == NULL)
1804 return -ENOMEM;
1805 cif->hwport = (struct riptideport *)chip->port;
1806 spin_lock_init(&cif->lock);
1807 chip->cif = cif;
1808 }
1809 cif->is_reset = 0;
1810 if ((err = riptide_reset(cif, chip)) != 0)
1811 return err;
1812 device_id = chip->device_id;
1813 switch (device_id) {
1814 case 0x4310:
1815 case 0x4320:
1816 case 0x4330:
1817 snd_printdd("Modem enable?\n");
1818 SEND_SETDPLL(cif);
1819 break;
1820 }
1821 snd_printdd("Enabling MPU IRQs\n");
1822 if (chip->rmidi)
1823 SET_EMPUIRQ(cif->hwport);
1824 return err;
1825}
1826
1827static int snd_riptide_free(struct snd_riptide *chip)
1828{
1829 struct cmdif *cif;
1830
1831 snd_assert(chip, return 0);
1832
1833 if ((cif = chip->cif)) {
1834 SET_GRESET(cif->hwport);
1835 udelay(100);
1836 UNSET_GRESET(cif->hwport);
1837 kfree(chip->cif);
1838 }
1839 if (chip->fw_entry)
1840 release_firmware(chip->fw_entry);
1841 release_and_free_resource(chip->res_port);
1842 if (chip->irq >= 0)
1843 free_irq(chip->irq, chip);
1844 kfree(chip);
1845 return 0;
1846}
1847
1848static int snd_riptide_dev_free(struct snd_device *device)
1849{
1850 struct snd_riptide *chip = device->device_data;
1851
1852 return snd_riptide_free(chip);
1853}
1854
1855static int __devinit
1856snd_riptide_create(struct snd_card *card, struct pci_dev *pci,
1857 struct snd_riptide **rchip)
1858{
1859 struct snd_riptide *chip;
1860 struct riptideport *hwport;
1861 int err;
1862 static struct snd_device_ops ops = {
1863 .dev_free = snd_riptide_dev_free,
1864 };
1865
1866 *rchip = NULL;
1867 if ((err = pci_enable_device(pci)) < 0)
1868 return err;
1869 if (!(chip = kzalloc(sizeof(struct snd_riptide), GFP_KERNEL)))
1870 return -ENOMEM;
1871
1872 spin_lock_init(&chip->lock);
1873 chip->card = card;
1874 chip->pci = pci;
1875 chip->irq = -1;
1876 chip->openstreams = 0;
1877 chip->port = pci_resource_start(pci, 0);
1878 chip->received_irqs = 0;
1879 chip->handled_irqs = 0;
1880 chip->cif = NULL;
1881 tasklet_init(&chip->riptide_tq, riptide_handleirq, (unsigned long)chip);
1882
1883 if ((chip->res_port =
1884 request_region(chip->port, 64, "RIPTIDE")) == NULL) {
1885 snd_printk(KERN_ERR
1886 "Riptide: unable to grab region 0x%lx-0x%lx\n",
1887 chip->port, chip->port + 64 - 1);
1888 snd_riptide_free(chip);
1889 return -EBUSY;
1890 }
1891 hwport = (struct riptideport *)chip->port;
1892 UNSET_AIE(hwport);
1893
1894 if (request_irq
1895 (pci->irq, snd_riptide_interrupt, SA_INTERRUPT | SA_SHIRQ,
1896 "RIPTIDE", chip)) {
1897 snd_printk(KERN_ERR "Riptide: unable to grab IRQ %d\n",
1898 pci->irq);
1899 snd_riptide_free(chip);
1900 return -EBUSY;
1901 }
1902 chip->irq = pci->irq;
1903 chip->device_id = pci->device;
1904 pci_set_master(pci);
1905 if ((err = snd_riptide_initialize(chip)) < 0) {
1906 snd_riptide_free(chip);
1907 return err;
1908 }
1909
1910 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
1911 snd_riptide_free(chip);
1912 return err;
1913 }
1914
1915 *rchip = chip;
1916 return 0;
1917}
1918
1919static void
1920snd_riptide_proc_read(struct snd_info_entry *entry,
1921 struct snd_info_buffer *buffer)
1922{
1923 struct snd_riptide *chip = entry->private_data;
1924 struct pcmhw *data;
1925 int i;
1926 struct cmdif *cif = NULL;
1927 unsigned char p[256];
1928 unsigned short rval = 0, lval = 0;
1929 unsigned int rate;
1930
1931 if (!chip)
1932 return;
1933
1934 snd_iprintf(buffer, "%s\n\n", chip->card->longname);
1935 snd_iprintf(buffer, "Device ID: 0x%x\nReceived IRQs: (%ld)%ld\nPorts:",
1936 chip->device_id, chip->handled_irqs, chip->received_irqs);
1937 for (i = 0; i < 64; i += 4)
1938 snd_iprintf(buffer, "%c%02x: %08x",
1939 (i % 16) ? ' ' : '\n', i, inl(chip->port + i));
1940 if ((cif = chip->cif)) {
1941 snd_iprintf(buffer,
1942 "\nVersion: ASIC: %d CODEC: %d AUXDSP: %d PROG: %d",
1943 chip->firmware.firmware.ASIC,
1944 chip->firmware.firmware.CODEC,
1945 chip->firmware.firmware.AUXDSP,
1946 chip->firmware.firmware.PROG);
1947 snd_iprintf(buffer, "\nDigital mixer:");
1948 for (i = 0; i < 12; i++) {
1949 getmixer(cif, i, &rval, &lval);
1950 snd_iprintf(buffer, "\n %d: %d %d", i, rval, lval);
1951 }
1952 snd_iprintf(buffer,
1953 "\nARM Commands num: %d failed: %d time: %d max: %d min: %d",
1954 cif->cmdcnt, cif->errcnt,
1955 cif->cmdtime, cif->cmdtimemax, cif->cmdtimemin);
1956 }
1957 snd_iprintf(buffer, "\nOpen streams %d:\n", chip->openstreams);
1958 for (i = 0; i < PLAYBACK_SUBSTREAMS; i++) {
1959 if (chip->playback_substream[i]
1960 && chip->playback_substream[i]->runtime
1961 && (data =
1962 chip->playback_substream[i]->runtime->private_data)) {
1963 snd_iprintf(buffer,
1964 "stream: %d mixer: %d source: %d (%d,%d)\n",
1965 data->id, data->mixer, data->source,
1966 data->intdec[0], data->intdec[1]);
1967 if (!(getsamplerate(cif, data->intdec, &rate)))
1968 snd_iprintf(buffer, "rate: %d\n", rate);
1969 }
1970 }
1971 if (chip->capture_substream
1972 && chip->capture_substream->runtime
1973 && (data = chip->capture_substream->runtime->private_data)) {
1974 snd_iprintf(buffer,
1975 "stream: %d mixer: %d source: %d (%d,%d)\n",
1976 data->id, data->mixer,
1977 data->source, data->intdec[0], data->intdec[1]);
1978 if (!(getsamplerate(cif, data->intdec, &rate)))
1979 snd_iprintf(buffer, "rate: %d\n", rate);
1980 }
1981 snd_iprintf(buffer, "Paths:\n");
1982 i = getpaths(cif, p);
1983 while (i--) {
1984 snd_iprintf(buffer, "%x->%x ", p[i - 1], p[i]);
1985 i--;
1986 }
1987 snd_iprintf(buffer, "\n");
1988}
1989
1990static void __devinit snd_riptide_proc_init(struct snd_riptide *chip)
1991{
1992 struct snd_info_entry *entry;
1993
1994 if (!snd_card_proc_new(chip->card, "riptide", &entry))
1995 snd_info_set_text_ops(entry, chip, 4096, snd_riptide_proc_read);
1996}
1997
1998static int __devinit snd_riptide_mixer(struct snd_riptide *chip)
1999{
2000 struct snd_ac97_bus *pbus;
2001 struct snd_ac97_template ac97;
2002 int err = 0;
2003 static struct snd_ac97_bus_ops ops = {
2004 .write = snd_riptide_codec_write,
2005 .read = snd_riptide_codec_read,
2006 };
2007
2008 memset(&ac97, 0, sizeof(ac97));
2009 ac97.private_data = chip;
2010 ac97.scaps = AC97_SCAP_SKIP_MODEM;
2011
2012 if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
2013 return err;
2014
2015 chip->ac97_bus = pbus;
2016 ac97.pci = chip->pci;
2017 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97)) < 0)
2018 return err;
2019 return err;
2020}
2021
2022#ifdef SUPPORT_JOYSTICK
2023static int have_joystick;
2024static struct pci_dev *riptide_gameport_pci;
2025static struct gameport *riptide_gameport;
2026
2027static int __devinit
2028snd_riptide_joystick_probe(struct pci_dev *pci, const struct pci_device_id *id)
2029{
2030 static int dev;
2031
2032 if (dev >= SNDRV_CARDS)
2033 return -ENODEV;
2034 if (!enable[dev]) {
2035 dev++;
2036 return -ENOENT;
2037 }
2038
2039 if (joystick_port[dev]) {
2040 riptide_gameport = gameport_allocate_port();
2041 if (riptide_gameport) {
2042 if (!request_region
2043 (joystick_port[dev], 8, "Riptide gameport")) {
2044 snd_printk(KERN_WARNING
2045 "Riptide: cannot grab gameport 0x%x\n",
2046 joystick_port[dev]);
2047 gameport_free_port(riptide_gameport);
2048 riptide_gameport = NULL;
2049 } else {
2050 riptide_gameport_pci = pci;
2051 riptide_gameport->io = joystick_port[dev];
2052 gameport_register_port(riptide_gameport);
2053 }
2054 }
2055 }
2056 dev++;
2057 return 0;
2058}
2059
2060static void __devexit snd_riptide_joystick_remove(struct pci_dev *pci)
2061{
2062 if (riptide_gameport) {
2063 if (riptide_gameport_pci == pci) {
2064 release_region(riptide_gameport->io, 8);
2065 riptide_gameport_pci = NULL;
2066 gameport_unregister_port(riptide_gameport);
2067 riptide_gameport = NULL;
2068 }
2069 }
2070}
2071#endif
2072
2073static int __devinit
2074snd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
2075{
2076 static int dev;
2077 struct snd_card *card;
2078 struct snd_riptide *chip;
2079 unsigned short addr;
2080 int err = 0;
2081
2082 if (dev >= SNDRV_CARDS)
2083 return -ENODEV;
2084 if (!enable[dev]) {
2085 dev++;
2086 return -ENOENT;
2087 }
2088
2089 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
2090 if (card == NULL)
2091 return -ENOMEM;
2092 if ((err = snd_riptide_create(card, pci, &chip)) < 0) {
2093 snd_card_free(card);
2094 return err;
2095 }
2096 card->private_data = chip;
2097 if ((err = snd_riptide_pcm(chip, 0, NULL)) < 0) {
2098 snd_card_free(card);
2099 return err;
2100 }
2101 if ((err = snd_riptide_mixer(chip)) < 0) {
2102 snd_card_free(card);
2103 return err;
2104 }
2105 pci_write_config_word(chip->pci, PCI_EXT_Legacy_Mask, LEGACY_ENABLE_ALL
2106 | (opl3_port[dev] ? LEGACY_ENABLE_FM : 0)
2107#ifdef SUPPORT_JOYSTICK
2108 | (joystick_port[dev] ? LEGACY_ENABLE_GAMEPORT :
2109 0)
2110#endif
2111 | (mpu_port[dev]
2112 ? (LEGACY_ENABLE_MPU_INT | LEGACY_ENABLE_MPU) :
2113 0)
2114 | ((chip->irq << 4) & 0xF0));
2115 if ((addr = mpu_port[dev]) != 0) {
2116 pci_write_config_word(chip->pci, PCI_EXT_MPU_Base, addr);
2117 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_RIPTIDE,
2118 addr, 0, chip->irq, 0,
2119 &chip->rmidi)) < 0)
2120 snd_printk(KERN_WARNING
2121 "Riptide: Can't Allocate MPU at 0x%x\n",
2122 addr);
2123 else
2124 chip->mpuaddr = addr;
2125 }
2126 if ((addr = opl3_port[dev]) != 0) {
2127 pci_write_config_word(chip->pci, PCI_EXT_FM_Base, addr);
2128 if ((err = snd_opl3_create(card, addr, addr + 2,
2129 OPL3_HW_RIPTIDE, 0,
2130 &chip->opl3)) < 0)
2131 snd_printk(KERN_WARNING
2132 "Riptide: Can't Allocate OPL3 at 0x%x\n",
2133 addr);
2134 else {
2135 chip->opladdr = addr;
2136 if ((err =
2137 snd_opl3_hwdep_new(chip->opl3, 0, 1, NULL)) < 0)
2138 snd_printk(KERN_WARNING
2139 "Riptide: Can't Allocate OPL3-HWDEP\n");
2140 }
2141 }
2142#ifdef SUPPORT_JOYSTICK
2143 if ((addr = joystick_port[dev]) != 0) {
2144 pci_write_config_word(chip->pci, PCI_EXT_Game_Base, addr);
2145 chip->gameaddr = addr;
2146 }
2147#endif
2148
2149 strcpy(card->driver, "RIPTIDE");
2150 strcpy(card->shortname, "Riptide");
2151#ifdef SUPPORT_JOYSTICK
2152 snprintf(card->longname, sizeof(card->longname),
2153 "%s at 0x%lx, irq %i mpu 0x%x opl3 0x%x gameport 0x%x",
2154 card->shortname, chip->port, chip->irq, chip->mpuaddr,
2155 chip->opladdr, chip->gameaddr);
2156#else
2157 snprintf(card->longname, sizeof(card->longname),
2158 "%s at 0x%lx, irq %i mpu 0x%x opl3 0x%x",
2159 card->shortname, chip->port, chip->irq, chip->mpuaddr,
2160 chip->opladdr);
2161#endif
2162 snd_riptide_proc_init(chip);
2163 if ((err = snd_card_register(card)) < 0) {
2164 snd_card_free(card);
2165 return err;
2166 }
2167 pci_set_drvdata(pci, card);
2168 dev++;
2169 return 0;
2170}
2171
2172static void __devexit snd_card_riptide_remove(struct pci_dev *pci)
2173{
2174 snd_card_free(pci_get_drvdata(pci));
2175 pci_set_drvdata(pci, NULL);
2176}
2177
2178static struct pci_driver driver = {
2179 .name = "RIPTIDE",
2180 .id_table = snd_riptide_ids,
2181 .probe = snd_card_riptide_probe,
2182 .remove = __devexit_p(snd_card_riptide_remove),
2183#ifdef CONFIG_PM
2184 .suspend = riptide_suspend,
2185 .resume = riptide_resume,
2186#endif
2187};
2188
2189#ifdef SUPPORT_JOYSTICK
2190static struct pci_driver joystick_driver = {
2191 .name = "Riptide Joystick",
2192 .id_table = snd_riptide_joystick_ids,
2193 .probe = snd_riptide_joystick_probe,
2194 .remove = __devexit_p(snd_riptide_joystick_remove),
2195};
2196#endif
2197
2198static int __init alsa_card_riptide_init(void)
2199{
2200 int err;
2201 if ((err = pci_register_driver(&driver)) < 0)
2202 return err;
2203#if defined(SUPPORT_JOYSTICK)
2204 if (pci_register_driver(&joystick_driver) < 0) {
2205 have_joystick = 0;
2206 snd_printk(KERN_INFO "no joystick found\n");
2207 } else
2208 have_joystick = 1;
2209#endif
2210 return 0;
2211}
2212
2213static void __exit alsa_card_riptide_exit(void)
2214{
2215 pci_unregister_driver(&driver);
2216#if defined(SUPPORT_JOYSTICK)
2217 if (have_joystick)
2218 pci_unregister_driver(&joystick_driver);
2219#endif
2220}
2221
2222module_init(alsa_card_riptide_init);
2223module_exit(alsa_card_riptide_exit);
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 1957d29c119e..1e7398de2865 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -2373,6 +2373,7 @@ static int __devinit check_dxs_list(struct pci_dev *pci)
2373 { .subvendor = 0x161f, .subdevice = 0x2032, .action = VIA_DXS_48K }, /* m680x machines */ 2373 { .subvendor = 0x161f, .subdevice = 0x2032, .action = VIA_DXS_48K }, /* m680x machines */
2374 { .subvendor = 0x1631, .subdevice = 0xe004, .action = VIA_DXS_ENABLE }, /* Easy Note 3174, Packard Bell */ 2374 { .subvendor = 0x1631, .subdevice = 0xe004, .action = VIA_DXS_ENABLE }, /* Easy Note 3174, Packard Bell */
2375 { .subvendor = 0x1695, .subdevice = 0x3005, .action = VIA_DXS_ENABLE }, /* EPoX EP-8K9A */ 2375 { .subvendor = 0x1695, .subdevice = 0x3005, .action = VIA_DXS_ENABLE }, /* EPoX EP-8K9A */
2376 { .subvendor = 0x1695, .subdevice = 0x300c, .action = VIA_DXS_SRC }, /* EPoX EP-8KRAI */
2376 { .subvendor = 0x1695, .subdevice = 0x300e, .action = VIA_DXS_SRC }, /* EPoX 9HEAI */ 2377 { .subvendor = 0x1695, .subdevice = 0x300e, .action = VIA_DXS_SRC }, /* EPoX 9HEAI */
2377 { .subvendor = 0x16f3, .subdevice = 0x6405, .action = VIA_DXS_SRC }, /* Jetway K8M8MS */ 2378 { .subvendor = 0x16f3, .subdevice = 0x6405, .action = VIA_DXS_SRC }, /* Jetway K8M8MS */
2378 { .subvendor = 0x1734, .subdevice = 0x1078, .action = VIA_DXS_SRC }, /* FSC Amilo L7300 */ 2379 { .subvendor = 0x1734, .subdevice = 0x1078, .action = VIA_DXS_SRC }, /* FSC Amilo L7300 */
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index 8d08b34a1cb5..ce86283ee0fa 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -306,8 +306,8 @@ static int get_relative_value(struct usb_mixer_elem_info *cval, int val)
306 cval->res = 1; 306 cval->res = 1;
307 if (val < cval->min) 307 if (val < cval->min)
308 return 0; 308 return 0;
309 else if (val > cval->max) 309 else if (val >= cval->max)
310 return (cval->max - cval->min) / cval->res; 310 return (cval->max - cval->min + cval->res - 1) / cval->res;
311 else 311 else
312 return (val - cval->min) / cval->res; 312 return (val - cval->min) / cval->res;
313} 313}
@@ -670,6 +670,36 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
670 } 670 }
671 if (cval->res == 0) 671 if (cval->res == 0)
672 cval->res = 1; 672 cval->res = 1;
673
674 /* Additional checks for the proper resolution
675 *
676 * Some devices report smaller resolutions than actually
677 * reacting. They don't return errors but simply clip
678 * to the lower aligned value.
679 */
680 if (cval->min + cval->res < cval->max) {
681 int last_valid_res = cval->res;
682 int saved, test, check;
683 get_cur_mix_value(cval, minchn, &saved);
684 for (;;) {
685 test = saved;
686 if (test < cval->max)
687 test += cval->res;
688 else
689 test -= cval->res;
690 if (test < cval->min || test > cval->max ||
691 set_cur_mix_value(cval, minchn, test) ||
692 get_cur_mix_value(cval, minchn, &check)) {
693 cval->res = last_valid_res;
694 break;
695 }
696 if (test == check)
697 break;
698 cval->res *= 2;
699 }
700 set_cur_mix_value(cval, minchn, saved);
701 }
702
673 cval->initialized = 1; 703 cval->initialized = 1;
674 } 704 }
675 return 0; 705 return 0;
@@ -695,7 +725,8 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
695 if (! cval->initialized) 725 if (! cval->initialized)
696 get_min_max(cval, 0); 726 get_min_max(cval, 0);
697 uinfo->value.integer.min = 0; 727 uinfo->value.integer.min = 0;
698 uinfo->value.integer.max = (cval->max - cval->min) / cval->res; 728 uinfo->value.integer.max =
729 (cval->max - cval->min + cval->res - 1) / cval->res;
699 } 730 }
700 return 0; 731 return 0;
701} 732}