diff options
| -rw-r--r-- | Documentation/DocBook/videobook.tmpl | 2 | ||||
| -rw-r--r-- | Documentation/cciss.txt | 21 | ||||
| -rw-r--r-- | Documentation/hwmon/dme1737 | 53 | ||||
| -rw-r--r-- | Documentation/hwmon/it87 | 13 | ||||
| -rw-r--r-- | Documentation/hwmon/w83627hf | 4 | ||||
| -rw-r--r-- | Documentation/hwmon/w83791d | 6 | ||||
| -rw-r--r-- | Documentation/video4linux/gspca.txt | 1 | ||||
| -rw-r--r-- | arch/ia64/Kconfig | 10 | ||||
| -rw-r--r-- | arch/ia64/configs/generic_defconfig | 586 | ||||
| -rw-r--r-- | arch/ia64/kernel/.gitignore | 1 | ||||
| -rw-r--r-- | arch/ia64/kernel/ivt.S | 4 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/Kbuild (renamed from include/asm-m68knommu/Kbuild) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/MC68328.h (renamed from include/asm-m68knommu/MC68328.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/MC68332.h (renamed from include/asm-m68knommu/MC68332.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/MC68EZ328.h (renamed from include/asm-m68knommu/MC68EZ328.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/MC68VZ328.h (renamed from include/asm-m68knommu/MC68VZ328.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/a.out.h (renamed from include/asm-m68knommu/a.out.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/anchor.h (renamed from include/asm-m68knommu/anchor.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/atomic.h (renamed from include/asm-m68knommu/atomic.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/auxvec.h (renamed from include/asm-m68knommu/auxvec.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/bitops.h (renamed from include/asm-m68knommu/bitops.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/bootinfo.h (renamed from include/asm-m68knommu/bootinfo.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/bootstd.h (renamed from include/asm-m68knommu/bootstd.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/bug.h (renamed from include/asm-m68knommu/bug.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/bugs.h (renamed from include/asm-m68knommu/bugs.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/byteorder.h (renamed from include/asm-m68knommu/byteorder.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/cache.h (renamed from include/asm-m68knommu/cache.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/cachectl.h (renamed from include/asm-m68knommu/cachectl.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/cacheflush.h (renamed from include/asm-m68knommu/cacheflush.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/checksum.h (renamed from include/asm-m68knommu/checksum.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/coldfire.h (renamed from include/asm-m68knommu/coldfire.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/commproc.h (renamed from include/asm-m68knommu/commproc.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/cputime.h (renamed from include/asm-m68knommu/cputime.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/current.h (renamed from include/asm-m68knommu/current.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/dbg.h (renamed from include/asm-m68knommu/dbg.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/delay.h (renamed from include/asm-m68knommu/delay.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/device.h (renamed from include/asm-m68knommu/device.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/div64.h (renamed from include/asm-m68knommu/div64.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/dma-mapping.h (renamed from include/asm-m68knommu/dma-mapping.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/dma.h (renamed from include/asm-m68knommu/dma.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/elf.h (renamed from include/asm-m68knommu/elf.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/elia.h (renamed from include/asm-m68knommu/elia.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/emergency-restart.h (renamed from include/asm-m68knommu/emergency-restart.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/entry.h (renamed from include/asm-m68knommu/entry.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/errno.h (renamed from include/asm-m68knommu/errno.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/fb.h (renamed from include/asm-m68knommu/fb.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/fcntl.h (renamed from include/asm-m68knommu/fcntl.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/flat.h (renamed from include/asm-m68knommu/flat.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/fpu.h (renamed from include/asm-m68knommu/fpu.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/futex.h (renamed from include/asm-m68knommu/futex.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/hardirq.h (renamed from include/asm-m68knommu/hardirq.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/hw_irq.h (renamed from include/asm-m68knommu/hw_irq.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/hwtest.h (renamed from include/asm-m68knommu/hwtest.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/io.h (renamed from include/asm-m68knommu/io.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/ioctl.h (renamed from include/asm-m68knommu/ioctl.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/ioctls.h (renamed from include/asm-m68knommu/ioctls.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/ipcbuf.h (renamed from include/asm-m68knommu/ipcbuf.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/irq.h (renamed from include/asm-m68knommu/irq.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/irq_regs.h (renamed from include/asm-m68knommu/irq_regs.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/kdebug.h (renamed from include/asm-m68knommu/kdebug.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/kmap_types.h (renamed from include/asm-m68knommu/kmap_types.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/linkage.h (renamed from include/asm-m68knommu/linkage.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/local.h (renamed from include/asm-m68knommu/local.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/m5206sim.h (renamed from include/asm-m68knommu/m5206sim.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/m520xsim.h (renamed from include/asm-m68knommu/m520xsim.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/m523xsim.h (renamed from include/asm-m68knommu/m523xsim.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/m5249sim.h (renamed from include/asm-m68knommu/m5249sim.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/m5272sim.h (renamed from include/asm-m68knommu/m5272sim.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/m527xsim.h (renamed from include/asm-m68knommu/m527xsim.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/m528xsim.h (renamed from include/asm-m68knommu/m528xsim.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/m5307sim.h (renamed from include/asm-m68knommu/m5307sim.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/m532xsim.h (renamed from include/asm-m68knommu/m532xsim.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/m5407sim.h (renamed from include/asm-m68knommu/m5407sim.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/m68360.h (renamed from include/asm-m68knommu/m68360.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/m68360_enet.h (renamed from include/asm-m68knommu/m68360_enet.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/m68360_pram.h (renamed from include/asm-m68knommu/m68360_pram.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/m68360_quicc.h (renamed from include/asm-m68knommu/m68360_quicc.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/m68360_regs.h (renamed from include/asm-m68knommu/m68360_regs.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/machdep.h (renamed from include/asm-m68knommu/machdep.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/math-emu.h (renamed from include/asm-m68knommu/math-emu.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/mc146818rtc.h (renamed from include/asm-m68knommu/mc146818rtc.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/mcfcache.h (renamed from include/asm-m68knommu/mcfcache.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/mcfdma.h (renamed from include/asm-m68knommu/mcfdma.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/mcfmbus.h (renamed from include/asm-m68knommu/mcfmbus.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/mcfne.h (renamed from include/asm-m68knommu/mcfne.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/mcfpci.h (renamed from include/asm-m68knommu/mcfpci.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/mcfpit.h (renamed from include/asm-m68knommu/mcfpit.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/mcfsim.h (renamed from include/asm-m68knommu/mcfsim.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/mcfsmc.h (renamed from include/asm-m68knommu/mcfsmc.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/mcftimer.h (renamed from include/asm-m68knommu/mcftimer.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/mcfuart.h (renamed from include/asm-m68knommu/mcfuart.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/mcfwdebug.h (renamed from include/asm-m68knommu/mcfwdebug.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/md.h (renamed from include/asm-m68knommu/md.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/mman.h (renamed from include/asm-m68knommu/mman.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/mmu.h (renamed from include/asm-m68knommu/mmu.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/mmu_context.h (renamed from include/asm-m68knommu/mmu_context.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/module.h (renamed from include/asm-m68knommu/module.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/movs.h (renamed from include/asm-m68knommu/movs.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/msgbuf.h (renamed from include/asm-m68knommu/msgbuf.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/mutex.h (renamed from include/asm-m68knommu/mutex.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/nettel.h (renamed from include/asm-m68knommu/nettel.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/openprom.h (renamed from include/asm-m68knommu/openprom.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/oplib.h (renamed from include/asm-m68knommu/oplib.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/page.h (renamed from include/asm-m68knommu/page.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/page_offset.h (renamed from include/asm-m68knommu/page_offset.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/param.h (renamed from include/asm-m68knommu/param.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/pci.h (renamed from include/asm-m68knommu/pci.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/percpu.h (renamed from include/asm-m68knommu/percpu.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/pgalloc.h (renamed from include/asm-m68knommu/pgalloc.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/pgtable.h (renamed from include/asm-m68knommu/pgtable.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/poll.h (renamed from include/asm-m68knommu/poll.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/posix_types.h (renamed from include/asm-m68knommu/posix_types.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/processor.h (renamed from include/asm-m68knommu/processor.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/ptrace.h (renamed from include/asm-m68knommu/ptrace.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/quicc_simple.h (renamed from include/asm-m68knommu/quicc_simple.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/resource.h (renamed from include/asm-m68knommu/resource.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/rtc.h (renamed from include/asm-m68knommu/rtc.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/scatterlist.h (renamed from include/asm-m68knommu/scatterlist.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/sections.h (renamed from include/asm-m68knommu/sections.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/segment.h (renamed from include/asm-m68knommu/segment.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/sembuf.h (renamed from include/asm-m68knommu/sembuf.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/setup.h (renamed from include/asm-m68knommu/setup.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/shm.h (renamed from include/asm-m68knommu/shm.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/shmbuf.h (renamed from include/asm-m68knommu/shmbuf.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/shmparam.h (renamed from include/asm-m68knommu/shmparam.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/sigcontext.h (renamed from include/asm-m68knommu/sigcontext.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/siginfo.h (renamed from include/asm-m68knommu/siginfo.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/signal.h (renamed from include/asm-m68knommu/signal.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/smp.h (renamed from include/asm-m68knommu/smp.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/socket.h (renamed from include/asm-m68knommu/socket.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/sockios.h (renamed from include/asm-m68knommu/sockios.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/spinlock.h (renamed from include/asm-m68knommu/spinlock.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/stat.h (renamed from include/asm-m68knommu/stat.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/statfs.h (renamed from include/asm-m68knommu/statfs.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/string.h (renamed from include/asm-m68knommu/string.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/system.h (renamed from include/asm-m68knommu/system.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/termbits.h (renamed from include/asm-m68knommu/termbits.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/termios.h (renamed from include/asm-m68knommu/termios.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/thread_info.h (renamed from include/asm-m68knommu/thread_info.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/timex.h (renamed from include/asm-m68knommu/timex.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/tlb.h (renamed from include/asm-m68knommu/tlb.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/tlbflush.h (renamed from include/asm-m68knommu/tlbflush.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/topology.h (renamed from include/asm-m68knommu/topology.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/traps.h (renamed from include/asm-m68knommu/traps.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/types.h (renamed from include/asm-m68knommu/types.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/uaccess.h (renamed from include/asm-m68knommu/uaccess.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/ucontext.h (renamed from include/asm-m68knommu/ucontext.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/unaligned.h (renamed from include/asm-m68knommu/unaligned.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/unistd.h (renamed from include/asm-m68knommu/unistd.h) | 0 | ||||
| -rw-r--r-- | arch/m68knommu/include/asm/user.h (renamed from include/asm-m68knommu/user.h) | 0 | ||||
| -rw-r--r-- | arch/powerpc/platforms/iseries/Kconfig | 11 | ||||
| -rw-r--r-- | crypto/async_tx/async_xor.c | 3 | ||||
| -rw-r--r-- | drivers/block/cciss.c | 748 | ||||
| -rw-r--r-- | drivers/block/cciss.h | 2 | ||||
| -rw-r--r-- | drivers/block/cciss_scsi.c | 195 | ||||
| -rw-r--r-- | drivers/block/xen-blkfront.c | 4 | ||||
| -rw-r--r-- | drivers/char/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/char/Makefile | 1 | ||||
| -rw-r--r-- | drivers/char/amiserial.c | 2 | ||||
| -rw-r--r-- | drivers/char/viocons.c | 1171 | ||||
| -rw-r--r-- | drivers/firewire/fw-cdev.c | 29 | ||||
| -rw-r--r-- | drivers/hwmon/Kconfig | 16 | ||||
| -rw-r--r-- | drivers/hwmon/Makefile | 1 | ||||
| -rw-r--r-- | drivers/hwmon/ad7414.c | 268 | ||||
| -rw-r--r-- | drivers/hwmon/dme1737.c | 292 | ||||
| -rw-r--r-- | drivers/hwmon/f71882fg.c | 6 | ||||
| -rw-r--r-- | drivers/hwmon/hwmon-vid.c | 144 | ||||
| -rw-r--r-- | drivers/hwmon/it87.c | 45 | ||||
| -rw-r--r-- | drivers/hwmon/thmc50.c | 28 | ||||
| -rw-r--r-- | drivers/hwmon/w83627hf.c | 101 | ||||
| -rw-r--r-- | drivers/hwmon/w83791d.c | 24 | ||||
| -rw-r--r-- | drivers/infiniband/core/cma.c | 37 | ||||
| -rw-r--r-- | drivers/infiniband/core/mad_rmpp.c | 2 | ||||
| -rw-r--r-- | drivers/infiniband/core/ucma.c | 14 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb3/cxio_hal.c | 6 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb3/iwch_provider.c | 28 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb3/iwch_provider.h | 7 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb3/iwch_qp.c | 25 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ipath/ipath_driver.c | 5 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ipath/ipath_iba7220.c | 7 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ipath/ipath_intr.c | 12 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ipath/ipath_verbs.c | 6 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mlx4/cq.c | 33 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mlx4/qp.c | 2 | ||||
| -rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_cm.c | 2 | ||||
| -rw-r--r-- | drivers/media/dvb/dvb-usb/cxusb.c | 7 | ||||
| -rw-r--r-- | drivers/media/dvb/frontends/Kconfig | 3 | ||||
| -rw-r--r-- | drivers/media/video/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/media/video/arv.c | 2 | ||||
| -rw-r--r-- | drivers/media/video/em28xx/em28xx-cards.c | 1 | ||||
| -rw-r--r-- | drivers/media/video/gspca/conex.c | 4 | ||||
| -rw-r--r-- | drivers/media/video/gspca/etoms.c | 137 | ||||
| -rw-r--r-- | drivers/media/video/gspca/gspca.c | 12 | ||||
| -rw-r--r-- | drivers/media/video/gspca/gspca.h | 5 | ||||
| -rw-r--r-- | drivers/media/video/gspca/ov519.c | 476 | ||||
| -rw-r--r-- | drivers/media/video/gspca/pac7311.c | 54 | ||||
| -rw-r--r-- | drivers/media/video/gspca/sonixb.c | 2 | ||||
| -rw-r--r-- | drivers/media/video/gspca/sonixj.c | 287 | ||||
| -rw-r--r-- | drivers/media/video/gspca/spca505.c | 12 | ||||
| -rw-r--r-- | drivers/media/video/gspca/spca506.c | 12 | ||||
| -rw-r--r-- | drivers/media/video/gspca/spca508.c | 18 | ||||
| -rw-r--r-- | drivers/media/video/gspca/spca561.c | 42 | ||||
| -rw-r--r-- | drivers/media/video/gspca/vc032x.c | 4 | ||||
| -rw-r--r-- | drivers/media/video/gspca/zc3xx.c | 6 | ||||
| -rw-r--r-- | drivers/media/video/pxa_camera.c | 58 | ||||
| -rw-r--r-- | drivers/media/video/sh_mobile_ceu_camera.c | 2 | ||||
| -rw-r--r-- | drivers/media/video/soc_camera.c | 26 | ||||
| -rw-r--r-- | drivers/media/video/soc_camera_platform.c | 2 | ||||
| -rw-r--r-- | drivers/media/video/uvc/uvc_ctrl.c | 33 | ||||
| -rw-r--r-- | drivers/media/video/uvc/uvc_driver.c | 26 | ||||
| -rw-r--r-- | drivers/media/video/uvc/uvc_video.c | 33 | ||||
| -rw-r--r-- | drivers/media/video/v4l2-dev.c | 4 | ||||
| -rw-r--r-- | drivers/media/video/vino.c | 1 | ||||
| -rw-r--r-- | drivers/misc/Kconfig | 4 | ||||
| -rw-r--r-- | drivers/watchdog/Kconfig | 16 | ||||
| -rw-r--r-- | drivers/watchdog/Makefile | 4 | ||||
| -rw-r--r-- | drivers/watchdog/acquirewdt.c | 130 | ||||
| -rw-r--r-- | drivers/watchdog/advantechwdt.c | 162 | ||||
| -rw-r--r-- | drivers/watchdog/alim1535_wdt.c | 189 | ||||
| -rw-r--r-- | drivers/watchdog/alim7101_wdt.c | 228 | ||||
| -rw-r--r-- | drivers/watchdog/ar7_wdt.c | 8 | ||||
| -rw-r--r-- | drivers/watchdog/at32ap700x_wdt.c | 43 | ||||
| -rw-r--r-- | drivers/watchdog/at91rm9200_wdt.c | 109 | ||||
| -rw-r--r-- | drivers/watchdog/bfin_wdt.c | 147 | ||||
| -rw-r--r-- | drivers/watchdog/booke_wdt.c | 44 | ||||
| -rw-r--r-- | drivers/watchdog/cpu5wdt.c | 144 | ||||
| -rw-r--r-- | drivers/watchdog/davinci_wdt.c | 20 | ||||
| -rw-r--r-- | drivers/watchdog/ep93xx_wdt.c | 28 | ||||
| -rw-r--r-- | drivers/watchdog/eurotechwdt.c | 95 | ||||
| -rw-r--r-- | drivers/watchdog/geodewdt.c | 96 | ||||
| -rw-r--r-- | drivers/watchdog/hpwdt.c | 6 | ||||
| -rw-r--r-- | drivers/watchdog/i6300esb.c | 366 | ||||
| -rw-r--r-- | drivers/watchdog/iTCO_vendor.h | 15 | ||||
| -rw-r--r-- | drivers/watchdog/iTCO_vendor_support.c | 62 | ||||
| -rw-r--r-- | drivers/watchdog/iTCO_wdt.c | 310 | ||||
| -rw-r--r-- | drivers/watchdog/ib700wdt.c | 123 | ||||
| -rw-r--r-- | drivers/watchdog/ibmasr.c | 151 | ||||
| -rw-r--r-- | drivers/watchdog/indydog.c | 114 | ||||
| -rw-r--r-- | drivers/watchdog/iop_wdt.c | 62 | ||||
| -rw-r--r-- | drivers/watchdog/it8712f_wdt.c | 6 | ||||
| -rw-r--r-- | drivers/watchdog/ixp2000_wdt.c | 61 | ||||
| -rw-r--r-- | drivers/watchdog/ixp4xx_wdt.c | 67 | ||||
| -rw-r--r-- | drivers/watchdog/ks8695_wdt.c | 120 | ||||
| -rw-r--r-- | drivers/watchdog/machzwd.c | 108 | ||||
| -rw-r--r-- | drivers/watchdog/mixcomwd.c | 133 | ||||
| -rw-r--r-- | drivers/watchdog/mpc5200_wdt.c | 24 | ||||
| -rw-r--r-- | drivers/watchdog/mpc83xx_wdt.c | 230 | ||||
| -rw-r--r-- | drivers/watchdog/mpc8xx_wdt.c | 37 | ||||
| -rw-r--r-- | drivers/watchdog/mpc8xxx_wdt.c | 316 | ||||
| -rw-r--r-- | drivers/watchdog/mpcore_wdt.c | 73 | ||||
| -rw-r--r-- | drivers/watchdog/mtx-1_wdt.c | 111 | ||||
| -rw-r--r-- | drivers/watchdog/mv64x60_wdt.c | 21 | ||||
| -rw-r--r-- | drivers/watchdog/omap_wdt.c | 41 | ||||
| -rw-r--r-- | drivers/watchdog/pc87413_wdt.c | 249 | ||||
| -rw-r--r-- | drivers/watchdog/pcwd.c | 191 | ||||
| -rw-r--r-- | drivers/watchdog/pcwd_pci.c | 161 | ||||
| -rw-r--r-- | drivers/watchdog/pcwd_usb.c | 168 | ||||
| -rw-r--r-- | drivers/watchdog/pnx4008_wdt.c | 29 | ||||
| -rw-r--r-- | drivers/watchdog/rm9k_wdt.c | 34 | ||||
| -rw-r--r-- | drivers/watchdog/s3c2410_wdt.c | 15 | ||||
| -rw-r--r-- | drivers/watchdog/sa1100_wdt.c | 42 | ||||
| -rw-r--r-- | drivers/watchdog/sb_wdog.c | 92 | ||||
| -rw-r--r-- | drivers/watchdog/sbc60xxwdt.c | 223 | ||||
| -rw-r--r-- | drivers/watchdog/sbc7240_wdt.c | 70 | ||||
| -rw-r--r-- | drivers/watchdog/sbc8360.c | 46 | ||||
| -rw-r--r-- | drivers/watchdog/sbc_epx_c3.c | 22 | ||||
| -rw-r--r-- | drivers/watchdog/sc1200wdt.c | 39 | ||||
| -rw-r--r-- | drivers/watchdog/sc520_wdt.c | 162 | ||||
| -rw-r--r-- | drivers/watchdog/scx200_wdt.c | 65 | ||||
| -rw-r--r-- | drivers/watchdog/shwdt.c | 139 | ||||
| -rw-r--r-- | drivers/watchdog/smsc37b787_wdt.c | 448 | ||||
| -rw-r--r-- | drivers/watchdog/softdog.c | 87 | ||||
| -rw-r--r-- | drivers/watchdog/txx9wdt.c | 37 | ||||
| -rw-r--r-- | drivers/watchdog/w83627hf_wdt.c | 190 | ||||
| -rw-r--r-- | drivers/watchdog/w83697hf_wdt.c | 189 | ||||
| -rw-r--r-- | drivers/watchdog/w83877f_wdt.c | 199 | ||||
| -rw-r--r-- | drivers/watchdog/w83977f_wdt.c | 239 | ||||
| -rw-r--r-- | drivers/watchdog/wafer5823wdt.c | 132 | ||||
| -rw-r--r-- | drivers/watchdog/wd501p.h | 2 | ||||
| -rw-r--r-- | drivers/watchdog/wdrtas.c | 105 | ||||
| -rw-r--r-- | drivers/watchdog/wdt.c | 4 | ||||
| -rw-r--r-- | drivers/watchdog/wdt285.c | 33 | ||||
| -rw-r--r-- | drivers/watchdog/wdt977.c | 162 | ||||
| -rw-r--r-- | drivers/watchdog/wdt_pci.c | 8 | ||||
| -rw-r--r-- | fs/bio.c | 9 | ||||
| -rw-r--r-- | include/linux/mlx4/cq.h | 36 | ||||
| -rw-r--r-- | include/linux/ptrace.h | 2 | ||||
| -rw-r--r-- | include/linux/tracehook.h | 2 | ||||
| -rw-r--r-- | include/media/soc_camera.h | 5 | ||||
| -rw-r--r-- | include/rdma/rdma_cm.h | 8 | ||||
| -rw-r--r-- | mm/hugetlb.c | 2 | ||||
| -rw-r--r-- | sound/soc/fsl/fsl_dma.c | 235 |
292 files changed, 6420 insertions, 6736 deletions
diff --git a/Documentation/DocBook/videobook.tmpl b/Documentation/DocBook/videobook.tmpl index 89817795e668..0bc25949b668 100644 --- a/Documentation/DocBook/videobook.tmpl +++ b/Documentation/DocBook/videobook.tmpl | |||
| @@ -1648,7 +1648,7 @@ static struct video_buffer capture_fb; | |||
| 1648 | 1648 | ||
| 1649 | <chapter id="pubfunctions"> | 1649 | <chapter id="pubfunctions"> |
| 1650 | <title>Public Functions Provided</title> | 1650 | <title>Public Functions Provided</title> |
| 1651 | !Edrivers/media/video/videodev.c | 1651 | !Edrivers/media/video/v4l2-dev.c |
| 1652 | </chapter> | 1652 | </chapter> |
| 1653 | 1653 | ||
| 1654 | </book> | 1654 | </book> |
diff --git a/Documentation/cciss.txt b/Documentation/cciss.txt index 63e59b8847c5..8244c6442faa 100644 --- a/Documentation/cciss.txt +++ b/Documentation/cciss.txt | |||
| @@ -112,27 +112,18 @@ Hot plug support for SCSI tape drives | |||
| 112 | 112 | ||
| 113 | Hot plugging of SCSI tape drives is supported, with some caveats. | 113 | Hot plugging of SCSI tape drives is supported, with some caveats. |
| 114 | The cciss driver must be informed that changes to the SCSI bus | 114 | The cciss driver must be informed that changes to the SCSI bus |
| 115 | have been made, in addition to and prior to informing the SCSI | 115 | have been made. This may be done via the /proc filesystem. |
| 116 | mid layer. This may be done via the /proc filesystem. For example: | 116 | For example: |
| 117 | 117 | ||
| 118 | echo "rescan" > /proc/scsi/cciss0/1 | 118 | echo "rescan" > /proc/scsi/cciss0/1 |
| 119 | 119 | ||
| 120 | This causes the adapter to query the adapter about changes to the | 120 | This causes the driver to query the adapter about changes to the |
| 121 | physical SCSI buses and/or fibre channel arbitrated loop and the | 121 | physical SCSI buses and/or fibre channel arbitrated loop and the |
| 122 | driver to make note of any new or removed sequential access devices | 122 | driver to make note of any new or removed sequential access devices |
| 123 | or medium changers. The driver will output messages indicating what | 123 | or medium changers. The driver will output messages indicating what |
| 124 | devices have been added or removed and the controller, bus, target and | 124 | devices have been added or removed and the controller, bus, target and |
| 125 | lun used to address the device. Once this is done, the SCSI mid layer | 125 | lun used to address the device. It then notifies the SCSI mid layer |
| 126 | can be informed of changes to the virtual SCSI bus which the driver | 126 | of these changes. |
| 127 | presents to it in the usual way. For example: | ||
| 128 | |||
| 129 | echo scsi add-single-device 3 2 1 0 > /proc/scsi/scsi | ||
| 130 | |||
| 131 | to add a device on controller 3, bus 2, target 1, lun 0. Note that | ||
| 132 | the driver makes an effort to preserve the devices positions | ||
| 133 | in the virtual SCSI bus, so if you are only moving tape drives | ||
| 134 | around on the same adapter and not adding or removing tape drives | ||
| 135 | from the adapter, informing the SCSI mid layer may not be necessary. | ||
| 136 | 127 | ||
| 137 | Note that the naming convention of the /proc filesystem entries | 128 | Note that the naming convention of the /proc filesystem entries |
| 138 | contains a number in addition to the driver name. (E.g. "cciss0" | 129 | contains a number in addition to the driver name. (E.g. "cciss0" |
diff --git a/Documentation/hwmon/dme1737 b/Documentation/hwmon/dme1737 index b1fe00999439..001d2e70bc11 100644 --- a/Documentation/hwmon/dme1737 +++ b/Documentation/hwmon/dme1737 | |||
| @@ -10,6 +10,10 @@ Supported chips: | |||
| 10 | Prefix: 'sch311x' | 10 | Prefix: 'sch311x' |
| 11 | Addresses scanned: none, address read from Super-I/O config space | 11 | Addresses scanned: none, address read from Super-I/O config space |
| 12 | Datasheet: http://www.nuhorizons.com/FeaturedProducts/Volume1/SMSC/311x.pdf | 12 | Datasheet: http://www.nuhorizons.com/FeaturedProducts/Volume1/SMSC/311x.pdf |
| 13 | * SMSC SCH5027 | ||
| 14 | Prefix: 'sch5027' | ||
| 15 | Addresses scanned: I2C 0x2c, 0x2d, 0x2e | ||
| 16 | Datasheet: Provided by SMSC upon request and under NDA | ||
| 13 | 17 | ||
| 14 | Authors: | 18 | Authors: |
| 15 | Juerg Haefliger <juergh@gmail.com> | 19 | Juerg Haefliger <juergh@gmail.com> |
| @@ -27,33 +31,31 @@ Module Parameters | |||
| 27 | following boards: | 31 | following boards: |
| 28 | - VIA EPIA SN18000 | 32 | - VIA EPIA SN18000 |
| 29 | 33 | ||
| 30 | Note that there is no need to use this parameter if the driver loads without | ||
| 31 | complaining. The driver will say so if it is necessary. | ||
| 32 | |||
| 33 | 34 | ||
| 34 | Description | 35 | Description |
| 35 | ----------- | 36 | ----------- |
| 36 | 37 | ||
| 37 | This driver implements support for the hardware monitoring capabilities of the | 38 | This driver implements support for the hardware monitoring capabilities of the |
| 38 | SMSC DME1737 and Asus A8000 (which are the same) and SMSC SCH311x Super-I/O | 39 | SMSC DME1737 and Asus A8000 (which are the same), SMSC SCH5027, and SMSC |
| 39 | chips. These chips feature monitoring of 3 temp sensors temp[1-3] (2 remote | 40 | SCH311x Super-I/O chips. These chips feature monitoring of 3 temp sensors |
| 40 | diodes and 1 internal), 7 voltages in[0-6] (6 external and 1 internal) and up | 41 | temp[1-3] (2 remote diodes and 1 internal), 7 voltages in[0-6] (6 external and |
| 41 | to 6 fan speeds fan[1-6]. Additionally, the chips implement up to 5 PWM | 42 | 1 internal) and up to 6 fan speeds fan[1-6]. Additionally, the chips implement |
| 42 | outputs pwm[1-3,5-6] for controlling fan speeds both manually and | 43 | up to 5 PWM outputs pwm[1-3,5-6] for controlling fan speeds both manually and |
| 43 | automatically. | 44 | automatically. |
| 44 | 45 | ||
| 45 | For the DME1737 and A8000, fan[1-2] and pwm[1-2] are always present. Fan[3-6] | 46 | For the DME1737, A8000 and SCH5027, fan[1-2] and pwm[1-2] are always present. |
| 46 | and pwm[3,5-6] are optional features and their availability depends on the | 47 | Fan[3-6] and pwm[3,5-6] are optional features and their availability depends on |
| 47 | configuration of the chip. The driver will detect which features are present | 48 | the configuration of the chip. The driver will detect which features are |
| 48 | during initialization and create the sysfs attributes accordingly. | 49 | present during initialization and create the sysfs attributes accordingly. |
| 49 | 50 | ||
| 50 | For the SCH311x, fan[1-3] and pwm[1-3] are always present and fan[4-6] and | 51 | For the SCH311x, fan[1-3] and pwm[1-3] are always present and fan[4-6] and |
| 51 | pwm[5-6] don't exist. | 52 | pwm[5-6] don't exist. |
| 52 | 53 | ||
| 53 | The hardware monitoring features of the DME1737 and A8000 are only accessible | 54 | The hardware monitoring features of the DME1737, A8000, and SCH5027 are only |
| 54 | via SMBus, while the SCH311x only provides access via the ISA bus. The driver | 55 | accessible via SMBus, while the SCH311x only provides access via the ISA bus. |
| 55 | will therefore register itself as an I2C client driver if it detects a DME1737 | 56 | The driver will therefore register itself as an I2C client driver if it detects |
| 56 | or A8000 and as a platform driver if it detects a SCH311x chip. | 57 | a DME1737, A8000, or SCH5027 and as a platform driver if it detects a SCH311x |
| 58 | chip. | ||
| 57 | 59 | ||
| 58 | 60 | ||
| 59 | Voltage Monitoring | 61 | Voltage Monitoring |
| @@ -64,6 +66,7 @@ scaling resistors. The values returned by the driver therefore reflect true | |||
| 64 | millivolts and don't need scaling. The voltage inputs are mapped as follows | 66 | millivolts and don't need scaling. The voltage inputs are mapped as follows |
| 65 | (the last column indicates the input ranges): | 67 | (the last column indicates the input ranges): |
| 66 | 68 | ||
| 69 | DME1737, A8000: | ||
| 67 | in0: +5VTR (+5V standby) 0V - 6.64V | 70 | in0: +5VTR (+5V standby) 0V - 6.64V |
| 68 | in1: Vccp (processor core) 0V - 3V | 71 | in1: Vccp (processor core) 0V - 3V |
| 69 | in2: VCC (internal +3.3V) 0V - 4.38V | 72 | in2: VCC (internal +3.3V) 0V - 4.38V |
| @@ -72,6 +75,24 @@ millivolts and don't need scaling. The voltage inputs are mapped as follows | |||
| 72 | in5: VTR (+3.3V standby) 0V - 4.38V | 75 | in5: VTR (+3.3V standby) 0V - 4.38V |
| 73 | in6: Vbat (+3.0V) 0V - 4.38V | 76 | in6: Vbat (+3.0V) 0V - 4.38V |
| 74 | 77 | ||
| 78 | SCH311x: | ||
| 79 | in0: +2.5V 0V - 6.64V | ||
| 80 | in1: Vccp (processor core) 0V - 2V | ||
| 81 | in2: VCC (internal +3.3V) 0V - 4.38V | ||
| 82 | in3: +5V 0V - 6.64V | ||
| 83 | in4: +12V 0V - 16V | ||
| 84 | in5: VTR (+3.3V standby) 0V - 4.38V | ||
| 85 | in6: Vbat (+3.0V) 0V - 4.38V | ||
| 86 | |||
| 87 | SCH5027: | ||
| 88 | in0: +5VTR (+5V standby) 0V - 6.64V | ||
| 89 | in1: Vccp (processor core) 0V - 3V | ||
| 90 | in2: VCC (internal +3.3V) 0V - 4.38V | ||
| 91 | in3: V2_IN 0V - 1.5V | ||
| 92 | in4: V1_IN 0V - 1.5V | ||
| 93 | in5: VTR (+3.3V standby) 0V - 4.38V | ||
| 94 | in6: Vbat (+3.0V) 0V - 4.38V | ||
| 95 | |||
| 75 | Each voltage input has associated min and max limits which trigger an alarm | 96 | Each voltage input has associated min and max limits which trigger an alarm |
| 76 | when crossed. | 97 | when crossed. |
| 77 | 98 | ||
diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87 index f4ce1fdbeff6..3496b7020e7c 100644 --- a/Documentation/hwmon/it87 +++ b/Documentation/hwmon/it87 | |||
| @@ -6,12 +6,14 @@ Supported chips: | |||
| 6 | Prefix: 'it87' | 6 | Prefix: 'it87' |
| 7 | Addresses scanned: from Super I/O config space (8 I/O ports) | 7 | Addresses scanned: from Super I/O config space (8 I/O ports) |
| 8 | Datasheet: Publicly available at the ITE website | 8 | Datasheet: Publicly available at the ITE website |
| 9 | http://www.ite.com.tw/ | 9 | http://www.ite.com.tw/product_info/file/pc/IT8705F_V.0.4.1.pdf |
| 10 | * IT8712F | 10 | * IT8712F |
| 11 | Prefix: 'it8712' | 11 | Prefix: 'it8712' |
| 12 | Addresses scanned: from Super I/O config space (8 I/O ports) | 12 | Addresses scanned: from Super I/O config space (8 I/O ports) |
| 13 | Datasheet: Publicly available at the ITE website | 13 | Datasheet: Publicly available at the ITE website |
| 14 | http://www.ite.com.tw/ | 14 | http://www.ite.com.tw/product_info/file/pc/IT8712F_V0.9.1.pdf |
| 15 | http://www.ite.com.tw/product_info/file/pc/Errata%20V0.1%20for%20IT8712F%20V0.9.1.pdf | ||
| 16 | http://www.ite.com.tw/product_info/file/pc/IT8712F_V0.9.3.pdf | ||
| 15 | * IT8716F/IT8726F | 17 | * IT8716F/IT8726F |
| 16 | Prefix: 'it8716' | 18 | Prefix: 'it8716' |
| 17 | Addresses scanned: from Super I/O config space (8 I/O ports) | 19 | Addresses scanned: from Super I/O config space (8 I/O ports) |
| @@ -90,14 +92,13 @@ upper VID bits share their pins with voltage inputs (in5 and in6) so you | |||
| 90 | can't have both on a given board. | 92 | can't have both on a given board. |
| 91 | 93 | ||
| 92 | The IT8716F, IT8718F and later IT8712F revisions have support for | 94 | The IT8716F, IT8718F and later IT8712F revisions have support for |
| 93 | 2 additional fans. They are supported by the driver for the IT8716F and | 95 | 2 additional fans. The additional fans are supported by the driver. |
| 94 | IT8718F but not for the IT8712F | ||
| 95 | 96 | ||
| 96 | The IT8716F and IT8718F, and late IT8712F and IT8705F also have optional | 97 | The IT8716F and IT8718F, and late IT8712F and IT8705F also have optional |
| 97 | 16-bit tachometer counters for fans 1 to 3. This is better (no more fan | 98 | 16-bit tachometer counters for fans 1 to 3. This is better (no more fan |
| 98 | clock divider mess) but not compatible with the older chips and | 99 | clock divider mess) but not compatible with the older chips and |
| 99 | revisions. For now, the driver only uses the 16-bit mode on the | 100 | revisions. The 16-bit tachometer mode is enabled by the driver when one |
| 100 | IT8716F and IT8718F. | 101 | of the above chips is detected. |
| 101 | 102 | ||
| 102 | The IT8726F is just bit enhanced IT8716F with additional hardware | 103 | The IT8726F is just bit enhanced IT8716F with additional hardware |
| 103 | for AMD power sequencing. Therefore the chip will appear as IT8716F | 104 | for AMD power sequencing. Therefore the chip will appear as IT8716F |
diff --git a/Documentation/hwmon/w83627hf b/Documentation/hwmon/w83627hf index 880a59f53da9..6ee36dbafd64 100644 --- a/Documentation/hwmon/w83627hf +++ b/Documentation/hwmon/w83627hf | |||
| @@ -40,10 +40,6 @@ Module Parameters | |||
| 40 | (default is 1) | 40 | (default is 1) |
| 41 | Use 'init=0' to bypass initializing the chip. | 41 | Use 'init=0' to bypass initializing the chip. |
| 42 | Try this if your computer crashes when you load the module. | 42 | Try this if your computer crashes when you load the module. |
| 43 | * reset: int | ||
| 44 | (default is 0) | ||
| 45 | The driver used to reset the chip on load, but does no more. Use | ||
| 46 | 'reset=1' to restore the old behavior. Report if you need to do this. | ||
| 47 | 43 | ||
| 48 | Description | 44 | Description |
| 49 | ----------- | 45 | ----------- |
diff --git a/Documentation/hwmon/w83791d b/Documentation/hwmon/w83791d index f153b2f6d62c..a67d3b7a7098 100644 --- a/Documentation/hwmon/w83791d +++ b/Documentation/hwmon/w83791d | |||
| @@ -22,6 +22,7 @@ Credits: | |||
| 22 | 22 | ||
| 23 | Additional contributors: | 23 | Additional contributors: |
| 24 | Sven Anders <anders@anduras.de> | 24 | Sven Anders <anders@anduras.de> |
| 25 | Marc Hulsman <m.hulsman@tudelft.nl> | ||
| 25 | 26 | ||
| 26 | Module Parameters | 27 | Module Parameters |
| 27 | ----------------- | 28 | ----------------- |
| @@ -67,9 +68,8 @@ on until the temperature falls below the Hysteresis value. | |||
| 67 | 68 | ||
| 68 | Fan rotation speeds are reported in RPM (rotations per minute). An alarm is | 69 | Fan rotation speeds are reported in RPM (rotations per minute). An alarm is |
| 69 | triggered if the rotation speed has dropped below a programmable limit. Fan | 70 | triggered if the rotation speed has dropped below a programmable limit. Fan |
| 70 | readings can be divided by a programmable divider (1, 2, 4, 8 for fan 1/2/3 | 71 | readings can be divided by a programmable divider (1, 2, 4, 8, 16, |
| 71 | and 1, 2, 4, 8, 16, 32, 64 or 128 for fan 4/5) to give the readings more | 72 | 32, 64 or 128 for all fans) to give the readings more range or accuracy. |
| 72 | range or accuracy. | ||
| 73 | 73 | ||
| 74 | Voltage sensors (also known as IN sensors) report their values in millivolts. | 74 | Voltage sensors (also known as IN sensors) report their values in millivolts. |
| 75 | An alarm is triggered if the voltage has crossed a programmable minimum | 75 | An alarm is triggered if the voltage has crossed a programmable minimum |
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt index bcaf4ab383be..78a863ab8a5a 100644 --- a/Documentation/video4linux/gspca.txt +++ b/Documentation/video4linux/gspca.txt | |||
| @@ -226,6 +226,7 @@ sonixj 0c45:6130 Sonix Pccam | |||
| 226 | sonixj 0c45:6138 Sn9c120 Mo4000 | 226 | sonixj 0c45:6138 Sn9c120 Mo4000 |
| 227 | sonixj 0c45:613b Surfer SN-206 | 227 | sonixj 0c45:613b Surfer SN-206 |
| 228 | sonixj 0c45:613c Sonix Pccam168 | 228 | sonixj 0c45:613c Sonix Pccam168 |
| 229 | sonixj 0c45:6143 Sonix Pccam168 | ||
| 229 | sunplus 0d64:0303 Sunplus FashionCam DXG | 230 | sunplus 0d64:0303 Sunplus FashionCam DXG |
| 230 | etoms 102c:6151 Qcam Sangha CIF | 231 | etoms 102c:6151 Qcam Sangha CIF |
| 231 | etoms 102c:6251 Qcam xxxxxx VGA | 232 | etoms 102c:6251 Qcam xxxxxx VGA |
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 451f2ffb137b..48e496fe1e75 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
| @@ -171,8 +171,8 @@ config IA64_SGI_SN2 | |||
| 171 | to select this option. If in doubt, select ia64 generic support | 171 | to select this option. If in doubt, select ia64 generic support |
| 172 | instead. | 172 | instead. |
| 173 | 173 | ||
| 174 | config IA64_SGI_UV` | 174 | config IA64_SGI_UV |
| 175 | bool "SGI-UV`" | 175 | bool "SGI-UV" |
| 176 | select NUMA | 176 | select NUMA |
| 177 | select ACPI_NUMA | 177 | select ACPI_NUMA |
| 178 | select SWIOTLB | 178 | select SWIOTLB |
| @@ -321,10 +321,10 @@ config SMP | |||
| 321 | If you don't know what to do here, say N. | 321 | If you don't know what to do here, say N. |
| 322 | 322 | ||
| 323 | config NR_CPUS | 323 | config NR_CPUS |
| 324 | int "Maximum number of CPUs (2-1024)" | 324 | int "Maximum number of CPUs (2-4096)" |
| 325 | range 2 1024 | 325 | range 2 4096 |
| 326 | depends on SMP | 326 | depends on SMP |
| 327 | default "1024" | 327 | default "4096" |
| 328 | help | 328 | help |
| 329 | You should set this to the number of CPUs in your system, but | 329 | You should set this to the number of CPUs in your system, but |
| 330 | keep in mind that a kernel compiled for, e.g., 2 CPUs will boot but | 330 | keep in mind that a kernel compiled for, e.g., 2 CPUs will boot but |
diff --git a/arch/ia64/configs/generic_defconfig b/arch/ia64/configs/generic_defconfig index 0210545e7f61..9f483976228f 100644 --- a/arch/ia64/configs/generic_defconfig +++ b/arch/ia64/configs/generic_defconfig | |||
| @@ -1,20 +1,16 @@ | |||
| 1 | # | 1 | # |
| 2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
| 3 | # Linux kernel version: 2.6.22 | 3 | # Linux kernel version: 2.6.27-rc1 |
| 4 | # Thu Jul 19 13:55:32 2007 | 4 | # Mon Aug 4 15:38:01 2008 |
| 5 | # | 5 | # |
| 6 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | 6 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" |
| 7 | 7 | ||
| 8 | # | 8 | # |
| 9 | # Code maturity level options | 9 | # General setup |
| 10 | # | 10 | # |
| 11 | CONFIG_EXPERIMENTAL=y | 11 | CONFIG_EXPERIMENTAL=y |
| 12 | CONFIG_LOCK_KERNEL=y | 12 | CONFIG_LOCK_KERNEL=y |
| 13 | CONFIG_INIT_ENV_ARG_LIMIT=32 | 13 | CONFIG_INIT_ENV_ARG_LIMIT=32 |
| 14 | |||
| 15 | # | ||
| 16 | # General setup | ||
| 17 | # | ||
| 18 | CONFIG_LOCALVERSION="" | 14 | CONFIG_LOCALVERSION="" |
| 19 | CONFIG_LOCALVERSION_AUTO=y | 15 | CONFIG_LOCALVERSION_AUTO=y |
| 20 | CONFIG_SWAP=y | 16 | CONFIG_SWAP=y |
| @@ -23,20 +19,34 @@ CONFIG_SYSVIPC_SYSCTL=y | |||
| 23 | CONFIG_POSIX_MQUEUE=y | 19 | CONFIG_POSIX_MQUEUE=y |
| 24 | # CONFIG_BSD_PROCESS_ACCT is not set | 20 | # CONFIG_BSD_PROCESS_ACCT is not set |
| 25 | # CONFIG_TASKSTATS is not set | 21 | # CONFIG_TASKSTATS is not set |
| 26 | # CONFIG_USER_NS is not set | ||
| 27 | # CONFIG_AUDIT is not set | 22 | # CONFIG_AUDIT is not set |
| 28 | CONFIG_IKCONFIG=y | 23 | CONFIG_IKCONFIG=y |
| 29 | CONFIG_IKCONFIG_PROC=y | 24 | CONFIG_IKCONFIG_PROC=y |
| 30 | CONFIG_LOG_BUF_SHIFT=20 | 25 | CONFIG_LOG_BUF_SHIFT=20 |
| 31 | # CONFIG_CPUSETS is not set | 26 | CONFIG_CGROUPS=y |
| 27 | # CONFIG_CGROUP_DEBUG is not set | ||
| 28 | # CONFIG_CGROUP_NS is not set | ||
| 29 | # CONFIG_CGROUP_DEVICE is not set | ||
| 30 | CONFIG_CPUSETS=y | ||
| 31 | # CONFIG_GROUP_SCHED is not set | ||
| 32 | # CONFIG_CGROUP_CPUACCT is not set | ||
| 33 | # CONFIG_RESOURCE_COUNTERS is not set | ||
| 32 | CONFIG_SYSFS_DEPRECATED=y | 34 | CONFIG_SYSFS_DEPRECATED=y |
| 35 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
| 36 | CONFIG_PROC_PID_CPUSET=y | ||
| 33 | # CONFIG_RELAY is not set | 37 | # CONFIG_RELAY is not set |
| 38 | CONFIG_NAMESPACES=y | ||
| 39 | # CONFIG_UTS_NS is not set | ||
| 40 | # CONFIG_IPC_NS is not set | ||
| 41 | # CONFIG_USER_NS is not set | ||
| 42 | # CONFIG_PID_NS is not set | ||
| 34 | CONFIG_BLK_DEV_INITRD=y | 43 | CONFIG_BLK_DEV_INITRD=y |
| 35 | CONFIG_INITRAMFS_SOURCE="" | 44 | CONFIG_INITRAMFS_SOURCE="" |
| 36 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | 45 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y |
| 37 | CONFIG_SYSCTL=y | 46 | CONFIG_SYSCTL=y |
| 38 | # CONFIG_EMBEDDED is not set | 47 | # CONFIG_EMBEDDED is not set |
| 39 | CONFIG_SYSCTL_SYSCALL=y | 48 | CONFIG_SYSCTL_SYSCALL=y |
| 49 | CONFIG_SYSCTL_SYSCALL_CHECK=y | ||
| 40 | CONFIG_KALLSYMS=y | 50 | CONFIG_KALLSYMS=y |
| 41 | CONFIG_KALLSYMS_ALL=y | 51 | CONFIG_KALLSYMS_ALL=y |
| 42 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 52 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
| @@ -44,6 +54,7 @@ CONFIG_HOTPLUG=y | |||
| 44 | CONFIG_PRINTK=y | 54 | CONFIG_PRINTK=y |
| 45 | CONFIG_BUG=y | 55 | CONFIG_BUG=y |
| 46 | CONFIG_ELF_CORE=y | 56 | CONFIG_ELF_CORE=y |
| 57 | CONFIG_COMPAT_BRK=y | ||
| 47 | CONFIG_BASE_FULL=y | 58 | CONFIG_BASE_FULL=y |
| 48 | CONFIG_FUTEX=y | 59 | CONFIG_FUTEX=y |
| 49 | CONFIG_ANON_INODES=y | 60 | CONFIG_ANON_INODES=y |
| @@ -53,12 +64,30 @@ CONFIG_TIMERFD=y | |||
| 53 | CONFIG_EVENTFD=y | 64 | CONFIG_EVENTFD=y |
| 54 | CONFIG_SHMEM=y | 65 | CONFIG_SHMEM=y |
| 55 | CONFIG_VM_EVENT_COUNTERS=y | 66 | CONFIG_VM_EVENT_COUNTERS=y |
| 67 | CONFIG_SLUB_DEBUG=y | ||
| 68 | # CONFIG_SLAB is not set | ||
| 56 | CONFIG_SLUB=y | 69 | CONFIG_SLUB=y |
| 57 | # CONFIG_SLOB is not set | 70 | # CONFIG_SLOB is not set |
| 71 | # CONFIG_PROFILING is not set | ||
| 72 | # CONFIG_MARKERS is not set | ||
| 73 | CONFIG_HAVE_OPROFILE=y | ||
| 74 | # CONFIG_KPROBES is not set | ||
| 75 | # CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set | ||
| 76 | # CONFIG_HAVE_IOREMAP_PROT is not set | ||
| 77 | CONFIG_HAVE_KPROBES=y | ||
| 78 | CONFIG_HAVE_KRETPROBES=y | ||
| 79 | # CONFIG_HAVE_ARCH_TRACEHOOK is not set | ||
| 80 | CONFIG_HAVE_DMA_ATTRS=y | ||
| 81 | CONFIG_USE_GENERIC_SMP_HELPERS=y | ||
| 82 | # CONFIG_HAVE_CLK is not set | ||
| 83 | CONFIG_PROC_PAGE_MONITOR=y | ||
| 84 | # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set | ||
| 85 | CONFIG_SLABINFO=y | ||
| 58 | CONFIG_RT_MUTEXES=y | 86 | CONFIG_RT_MUTEXES=y |
| 59 | # CONFIG_TINY_SHMEM is not set | 87 | # CONFIG_TINY_SHMEM is not set |
| 60 | CONFIG_BASE_SMALL=0 | 88 | CONFIG_BASE_SMALL=0 |
| 61 | CONFIG_MODULES=y | 89 | CONFIG_MODULES=y |
| 90 | # CONFIG_MODULE_FORCE_LOAD is not set | ||
| 62 | CONFIG_MODULE_UNLOAD=y | 91 | CONFIG_MODULE_UNLOAD=y |
| 63 | # CONFIG_MODULE_FORCE_UNLOAD is not set | 92 | # CONFIG_MODULE_FORCE_UNLOAD is not set |
| 64 | CONFIG_MODVERSIONS=y | 93 | CONFIG_MODVERSIONS=y |
| @@ -68,6 +97,8 @@ CONFIG_STOP_MACHINE=y | |||
| 68 | CONFIG_BLOCK=y | 97 | CONFIG_BLOCK=y |
| 69 | # CONFIG_BLK_DEV_IO_TRACE is not set | 98 | # CONFIG_BLK_DEV_IO_TRACE is not set |
| 70 | # CONFIG_BLK_DEV_BSG is not set | 99 | # CONFIG_BLK_DEV_BSG is not set |
| 100 | # CONFIG_BLK_DEV_INTEGRITY is not set | ||
| 101 | CONFIG_BLOCK_COMPAT=y | ||
| 71 | 102 | ||
| 72 | # | 103 | # |
| 73 | # IO Schedulers | 104 | # IO Schedulers |
| @@ -81,6 +112,7 @@ CONFIG_DEFAULT_AS=y | |||
| 81 | # CONFIG_DEFAULT_CFQ is not set | 112 | # CONFIG_DEFAULT_CFQ is not set |
| 82 | # CONFIG_DEFAULT_NOOP is not set | 113 | # CONFIG_DEFAULT_NOOP is not set |
| 83 | CONFIG_DEFAULT_IOSCHED="anticipatory" | 114 | CONFIG_DEFAULT_IOSCHED="anticipatory" |
| 115 | CONFIG_CLASSIC_RCU=y | ||
| 84 | 116 | ||
| 85 | # | 117 | # |
| 86 | # Processor type and features | 118 | # Processor type and features |
| @@ -91,22 +123,28 @@ CONFIG_ZONE_DMA=y | |||
| 91 | CONFIG_QUICKLIST=y | 123 | CONFIG_QUICKLIST=y |
| 92 | CONFIG_MMU=y | 124 | CONFIG_MMU=y |
| 93 | CONFIG_SWIOTLB=y | 125 | CONFIG_SWIOTLB=y |
| 126 | CONFIG_IOMMU_HELPER=y | ||
| 94 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | 127 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y |
| 95 | # CONFIG_ARCH_HAS_ILOG2_U32 is not set | 128 | # CONFIG_ARCH_HAS_ILOG2_U32 is not set |
| 96 | # CONFIG_ARCH_HAS_ILOG2_U64 is not set | 129 | # CONFIG_ARCH_HAS_ILOG2_U64 is not set |
| 130 | CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y | ||
| 97 | CONFIG_GENERIC_FIND_NEXT_BIT=y | 131 | CONFIG_GENERIC_FIND_NEXT_BIT=y |
| 98 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 132 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
| 99 | CONFIG_GENERIC_TIME=y | 133 | CONFIG_GENERIC_TIME=y |
| 134 | CONFIG_GENERIC_TIME_VSYSCALL=y | ||
| 135 | CONFIG_HAVE_SETUP_PER_CPU_AREA=y | ||
| 100 | CONFIG_DMI=y | 136 | CONFIG_DMI=y |
| 101 | CONFIG_EFI=y | 137 | CONFIG_EFI=y |
| 102 | CONFIG_GENERIC_IOMAP=y | 138 | CONFIG_GENERIC_IOMAP=y |
| 103 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y | 139 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y |
| 140 | CONFIG_IA64_UNCACHED_ALLOCATOR=y | ||
| 104 | CONFIG_AUDIT_ARCH=y | 141 | CONFIG_AUDIT_ARCH=y |
| 105 | CONFIG_IA64_GENERIC=y | 142 | CONFIG_IA64_GENERIC=y |
| 106 | # CONFIG_IA64_DIG is not set | 143 | # CONFIG_IA64_DIG is not set |
| 107 | # CONFIG_IA64_HP_ZX1 is not set | 144 | # CONFIG_IA64_HP_ZX1 is not set |
| 108 | # CONFIG_IA64_HP_ZX1_SWIOTLB is not set | 145 | # CONFIG_IA64_HP_ZX1_SWIOTLB is not set |
| 109 | # CONFIG_IA64_SGI_SN2 is not set | 146 | # CONFIG_IA64_SGI_SN2 is not set |
| 147 | # CONFIG_IA64_SGI_UV is not set | ||
| 110 | # CONFIG_IA64_HP_SIM is not set | 148 | # CONFIG_IA64_HP_SIM is not set |
| 111 | # CONFIG_ITANIUM is not set | 149 | # CONFIG_ITANIUM is not set |
| 112 | CONFIG_MCKINLEY=y | 150 | CONFIG_MCKINLEY=y |
| @@ -116,22 +154,26 @@ CONFIG_MCKINLEY=y | |||
| 116 | CONFIG_IA64_PAGE_SIZE_64KB=y | 154 | CONFIG_IA64_PAGE_SIZE_64KB=y |
| 117 | CONFIG_PGTABLE_3=y | 155 | CONFIG_PGTABLE_3=y |
| 118 | # CONFIG_PGTABLE_4 is not set | 156 | # CONFIG_PGTABLE_4 is not set |
| 157 | CONFIG_HZ=250 | ||
| 119 | # CONFIG_HZ_100 is not set | 158 | # CONFIG_HZ_100 is not set |
| 120 | CONFIG_HZ_250=y | 159 | CONFIG_HZ_250=y |
| 121 | # CONFIG_HZ_300 is not set | 160 | # CONFIG_HZ_300 is not set |
| 122 | # CONFIG_HZ_1000 is not set | 161 | # CONFIG_HZ_1000 is not set |
| 123 | CONFIG_HZ=250 | 162 | # CONFIG_SCHED_HRTICK is not set |
| 124 | CONFIG_IA64_L1_CACHE_SHIFT=7 | 163 | CONFIG_IA64_L1_CACHE_SHIFT=7 |
| 125 | CONFIG_IA64_CYCLONE=y | 164 | CONFIG_IA64_CYCLONE=y |
| 126 | CONFIG_IOSAPIC=y | 165 | CONFIG_IOSAPIC=y |
| 127 | # CONFIG_IA64_SGI_SN_XP is not set | ||
| 128 | CONFIG_FORCE_MAX_ZONEORDER=17 | 166 | CONFIG_FORCE_MAX_ZONEORDER=17 |
| 167 | # CONFIG_VIRT_CPU_ACCOUNTING is not set | ||
| 129 | CONFIG_SMP=y | 168 | CONFIG_SMP=y |
| 130 | CONFIG_NR_CPUS=512 | 169 | CONFIG_NR_CPUS=4096 |
| 131 | CONFIG_HOTPLUG_CPU=y | 170 | CONFIG_HOTPLUG_CPU=y |
| 132 | CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y | 171 | CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y |
| 172 | CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y | ||
| 133 | # CONFIG_SCHED_SMT is not set | 173 | # CONFIG_SCHED_SMT is not set |
| 134 | # CONFIG_PERMIT_BSP_REMOVE is not set | 174 | # CONFIG_PERMIT_BSP_REMOVE is not set |
| 175 | CONFIG_PREEMPT_NONE=y | ||
| 176 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
| 135 | # CONFIG_PREEMPT is not set | 177 | # CONFIG_PREEMPT is not set |
| 136 | CONFIG_SELECT_MEMORY_MODEL=y | 178 | CONFIG_SELECT_MEMORY_MODEL=y |
| 137 | # CONFIG_FLATMEM_MANUAL is not set | 179 | # CONFIG_FLATMEM_MANUAL is not set |
| @@ -141,6 +183,8 @@ CONFIG_DISCONTIGMEM=y | |||
| 141 | CONFIG_FLAT_NODE_MEM_MAP=y | 183 | CONFIG_FLAT_NODE_MEM_MAP=y |
| 142 | CONFIG_NEED_MULTIPLE_NODES=y | 184 | CONFIG_NEED_MULTIPLE_NODES=y |
| 143 | # CONFIG_SPARSEMEM_STATIC is not set | 185 | # CONFIG_SPARSEMEM_STATIC is not set |
| 186 | CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y | ||
| 187 | CONFIG_PAGEFLAGS_EXTENDED=y | ||
| 144 | CONFIG_SPLIT_PTLOCK_CPUS=4 | 188 | CONFIG_SPLIT_PTLOCK_CPUS=4 |
| 145 | CONFIG_MIGRATION=y | 189 | CONFIG_MIGRATION=y |
| 146 | CONFIG_RESOURCES_64BIT=y | 190 | CONFIG_RESOURCES_64BIT=y |
| @@ -148,6 +192,7 @@ CONFIG_ZONE_DMA_FLAG=1 | |||
| 148 | CONFIG_BOUNCE=y | 192 | CONFIG_BOUNCE=y |
| 149 | CONFIG_NR_QUICK=1 | 193 | CONFIG_NR_QUICK=1 |
| 150 | CONFIG_VIRT_TO_BUS=y | 194 | CONFIG_VIRT_TO_BUS=y |
| 195 | CONFIG_MMU_NOTIFIER=y | ||
| 151 | CONFIG_ARCH_SELECT_MEMORY_MODEL=y | 196 | CONFIG_ARCH_SELECT_MEMORY_MODEL=y |
| 152 | CONFIG_ARCH_DISCONTIGMEM_ENABLE=y | 197 | CONFIG_ARCH_DISCONTIGMEM_ENABLE=y |
| 153 | CONFIG_ARCH_FLATMEM_ENABLE=y | 198 | CONFIG_ARCH_FLATMEM_ENABLE=y |
| @@ -162,12 +207,14 @@ CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y | |||
| 162 | CONFIG_HAVE_ARCH_NODEDATA_EXTENSION=y | 207 | CONFIG_HAVE_ARCH_NODEDATA_EXTENSION=y |
| 163 | CONFIG_IA32_SUPPORT=y | 208 | CONFIG_IA32_SUPPORT=y |
| 164 | CONFIG_COMPAT=y | 209 | CONFIG_COMPAT=y |
| 210 | CONFIG_COMPAT_FOR_U64_ALIGNMENT=y | ||
| 165 | CONFIG_IA64_MCA_RECOVERY=y | 211 | CONFIG_IA64_MCA_RECOVERY=y |
| 166 | CONFIG_PERFMON=y | 212 | CONFIG_PERFMON=y |
| 167 | CONFIG_IA64_PALINFO=y | 213 | CONFIG_IA64_PALINFO=y |
| 168 | # CONFIG_IA64_MC_ERR_INJECT is not set | 214 | # CONFIG_IA64_MC_ERR_INJECT is not set |
| 169 | CONFIG_SGI_SN=y | 215 | CONFIG_SGI_SN=y |
| 170 | # CONFIG_IA64_ESI is not set | 216 | # CONFIG_IA64_ESI is not set |
| 217 | # CONFIG_IA64_HP_AML_NFW is not set | ||
| 171 | 218 | ||
| 172 | # | 219 | # |
| 173 | # SN Devices | 220 | # SN Devices |
| @@ -179,6 +226,7 @@ CONFIG_CRASH_DUMP=y | |||
| 179 | # | 226 | # |
| 180 | # Firmware Drivers | 227 | # Firmware Drivers |
| 181 | # | 228 | # |
| 229 | # CONFIG_FIRMWARE_MEMMAP is not set | ||
| 182 | CONFIG_EFI_VARS=y | 230 | CONFIG_EFI_VARS=y |
| 183 | CONFIG_EFI_PCDP=y | 231 | CONFIG_EFI_PCDP=y |
| 184 | CONFIG_DMIID=y | 232 | CONFIG_DMIID=y |
| @@ -189,24 +237,25 @@ CONFIG_BINFMT_MISC=m | |||
| 189 | # Power management and ACPI | 237 | # Power management and ACPI |
| 190 | # | 238 | # |
| 191 | CONFIG_PM=y | 239 | CONFIG_PM=y |
| 192 | CONFIG_PM_LEGACY=y | ||
| 193 | # CONFIG_PM_DEBUG is not set | 240 | # CONFIG_PM_DEBUG is not set |
| 194 | |||
| 195 | # | ||
| 196 | # ACPI (Advanced Configuration and Power Interface) Support | ||
| 197 | # | ||
| 198 | CONFIG_ACPI=y | 241 | CONFIG_ACPI=y |
| 199 | CONFIG_ACPI_PROCFS=y | 242 | CONFIG_ACPI_PROCFS=y |
| 243 | CONFIG_ACPI_PROCFS_POWER=y | ||
| 244 | CONFIG_ACPI_SYSFS_POWER=y | ||
| 245 | CONFIG_ACPI_PROC_EVENT=y | ||
| 200 | CONFIG_ACPI_BUTTON=m | 246 | CONFIG_ACPI_BUTTON=m |
| 201 | CONFIG_ACPI_FAN=m | 247 | CONFIG_ACPI_FAN=m |
| 202 | # CONFIG_ACPI_DOCK is not set | 248 | CONFIG_ACPI_DOCK=y |
| 249 | # CONFIG_ACPI_BAY is not set | ||
| 203 | CONFIG_ACPI_PROCESSOR=m | 250 | CONFIG_ACPI_PROCESSOR=m |
| 204 | CONFIG_ACPI_HOTPLUG_CPU=y | 251 | CONFIG_ACPI_HOTPLUG_CPU=y |
| 205 | CONFIG_ACPI_THERMAL=m | 252 | CONFIG_ACPI_THERMAL=m |
| 206 | CONFIG_ACPI_NUMA=y | 253 | CONFIG_ACPI_NUMA=y |
| 254 | # CONFIG_ACPI_CUSTOM_DSDT is not set | ||
| 207 | CONFIG_ACPI_BLACKLIST_YEAR=0 | 255 | CONFIG_ACPI_BLACKLIST_YEAR=0 |
| 208 | # CONFIG_ACPI_DEBUG is not set | 256 | # CONFIG_ACPI_DEBUG is not set |
| 209 | CONFIG_ACPI_EC=y | 257 | CONFIG_ACPI_EC=y |
| 258 | # CONFIG_ACPI_PCI_SLOT is not set | ||
| 210 | CONFIG_ACPI_POWER=y | 259 | CONFIG_ACPI_POWER=y |
| 211 | CONFIG_ACPI_SYSTEM=y | 260 | CONFIG_ACPI_SYSTEM=y |
| 212 | CONFIG_ACPI_CONTAINER=m | 261 | CONFIG_ACPI_CONTAINER=m |
| @@ -225,6 +274,7 @@ CONFIG_PCI_SYSCALL=y | |||
| 225 | # CONFIG_PCIEPORTBUS is not set | 274 | # CONFIG_PCIEPORTBUS is not set |
| 226 | CONFIG_ARCH_SUPPORTS_MSI=y | 275 | CONFIG_ARCH_SUPPORTS_MSI=y |
| 227 | # CONFIG_PCI_MSI is not set | 276 | # CONFIG_PCI_MSI is not set |
| 277 | CONFIG_PCI_LEGACY=y | ||
| 228 | # CONFIG_PCI_DEBUG is not set | 278 | # CONFIG_PCI_DEBUG is not set |
| 229 | CONFIG_HOTPLUG_PCI=m | 279 | CONFIG_HOTPLUG_PCI=m |
| 230 | # CONFIG_HOTPLUG_PCI_FAKE is not set | 280 | # CONFIG_HOTPLUG_PCI_FAKE is not set |
| @@ -233,15 +283,7 @@ CONFIG_HOTPLUG_PCI_ACPI=m | |||
| 233 | # CONFIG_HOTPLUG_PCI_CPCI is not set | 283 | # CONFIG_HOTPLUG_PCI_CPCI is not set |
| 234 | # CONFIG_HOTPLUG_PCI_SHPC is not set | 284 | # CONFIG_HOTPLUG_PCI_SHPC is not set |
| 235 | # CONFIG_HOTPLUG_PCI_SGI is not set | 285 | # CONFIG_HOTPLUG_PCI_SGI is not set |
| 236 | |||
| 237 | # | ||
| 238 | # PCCARD (PCMCIA/CardBus) support | ||
| 239 | # | ||
| 240 | # CONFIG_PCCARD is not set | 286 | # CONFIG_PCCARD is not set |
| 241 | |||
| 242 | # | ||
| 243 | # Networking | ||
| 244 | # | ||
| 245 | CONFIG_NET=y | 287 | CONFIG_NET=y |
| 246 | 288 | ||
| 247 | # | 289 | # |
| @@ -254,6 +296,7 @@ CONFIG_XFRM=y | |||
| 254 | # CONFIG_XFRM_USER is not set | 296 | # CONFIG_XFRM_USER is not set |
| 255 | # CONFIG_XFRM_SUB_POLICY is not set | 297 | # CONFIG_XFRM_SUB_POLICY is not set |
| 256 | # CONFIG_XFRM_MIGRATE is not set | 298 | # CONFIG_XFRM_MIGRATE is not set |
| 299 | # CONFIG_XFRM_STATISTICS is not set | ||
| 257 | # CONFIG_NET_KEY is not set | 300 | # CONFIG_NET_KEY is not set |
| 258 | CONFIG_INET=y | 301 | CONFIG_INET=y |
| 259 | CONFIG_IP_MULTICAST=y | 302 | CONFIG_IP_MULTICAST=y |
| @@ -273,6 +316,7 @@ CONFIG_SYN_COOKIES=y | |||
| 273 | CONFIG_INET_XFRM_MODE_TRANSPORT=y | 316 | CONFIG_INET_XFRM_MODE_TRANSPORT=y |
| 274 | CONFIG_INET_XFRM_MODE_TUNNEL=y | 317 | CONFIG_INET_XFRM_MODE_TUNNEL=y |
| 275 | CONFIG_INET_XFRM_MODE_BEET=y | 318 | CONFIG_INET_XFRM_MODE_BEET=y |
| 319 | CONFIG_INET_LRO=m | ||
| 276 | CONFIG_INET_DIAG=y | 320 | CONFIG_INET_DIAG=y |
| 277 | CONFIG_INET_TCP_DIAG=y | 321 | CONFIG_INET_TCP_DIAG=y |
| 278 | # CONFIG_TCP_CONG_ADVANCED is not set | 322 | # CONFIG_TCP_CONG_ADVANCED is not set |
| @@ -280,8 +324,6 @@ CONFIG_TCP_CONG_CUBIC=y | |||
| 280 | CONFIG_DEFAULT_TCP_CONG="cubic" | 324 | CONFIG_DEFAULT_TCP_CONG="cubic" |
| 281 | # CONFIG_TCP_MD5SIG is not set | 325 | # CONFIG_TCP_MD5SIG is not set |
| 282 | # CONFIG_IPV6 is not set | 326 | # CONFIG_IPV6 is not set |
| 283 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
| 284 | # CONFIG_INET6_TUNNEL is not set | ||
| 285 | # CONFIG_NETWORK_SECMARK is not set | 327 | # CONFIG_NETWORK_SECMARK is not set |
| 286 | # CONFIG_NETFILTER is not set | 328 | # CONFIG_NETFILTER is not set |
| 287 | # CONFIG_IP_DCCP is not set | 329 | # CONFIG_IP_DCCP is not set |
| @@ -298,10 +340,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" | |||
| 298 | # CONFIG_LAPB is not set | 340 | # CONFIG_LAPB is not set |
| 299 | # CONFIG_ECONET is not set | 341 | # CONFIG_ECONET is not set |
| 300 | # CONFIG_WAN_ROUTER is not set | 342 | # CONFIG_WAN_ROUTER is not set |
| 301 | |||
| 302 | # | ||
| 303 | # QoS and/or fair queueing | ||
| 304 | # | ||
| 305 | # CONFIG_NET_SCHED is not set | 343 | # CONFIG_NET_SCHED is not set |
| 306 | 344 | ||
| 307 | # | 345 | # |
| @@ -309,6 +347,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" | |||
| 309 | # | 347 | # |
| 310 | # CONFIG_NET_PKTGEN is not set | 348 | # CONFIG_NET_PKTGEN is not set |
| 311 | # CONFIG_HAMRADIO is not set | 349 | # CONFIG_HAMRADIO is not set |
| 350 | # CONFIG_CAN is not set | ||
| 312 | # CONFIG_IRDA is not set | 351 | # CONFIG_IRDA is not set |
| 313 | # CONFIG_BT is not set | 352 | # CONFIG_BT is not set |
| 314 | # CONFIG_AF_RXRPC is not set | 353 | # CONFIG_AF_RXRPC is not set |
| @@ -330,13 +369,17 @@ CONFIG_DEFAULT_TCP_CONG="cubic" | |||
| 330 | # | 369 | # |
| 331 | # Generic Driver Options | 370 | # Generic Driver Options |
| 332 | # | 371 | # |
| 372 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
| 333 | CONFIG_STANDALONE=y | 373 | CONFIG_STANDALONE=y |
| 334 | CONFIG_PREVENT_FIRMWARE_BUILD=y | 374 | CONFIG_PREVENT_FIRMWARE_BUILD=y |
| 335 | CONFIG_FW_LOADER=m | 375 | CONFIG_FW_LOADER=y |
| 376 | CONFIG_FIRMWARE_IN_KERNEL=y | ||
| 377 | CONFIG_EXTRA_FIRMWARE="" | ||
| 336 | # CONFIG_DEBUG_DRIVER is not set | 378 | # CONFIG_DEBUG_DRIVER is not set |
| 337 | # CONFIG_DEBUG_DEVRES is not set | 379 | # CONFIG_DEBUG_DEVRES is not set |
| 338 | # CONFIG_SYS_HYPERVISOR is not set | 380 | # CONFIG_SYS_HYPERVISOR is not set |
| 339 | # CONFIG_CONNECTOR is not set | 381 | CONFIG_CONNECTOR=y |
| 382 | CONFIG_PROC_EVENTS=y | ||
| 340 | # CONFIG_MTD is not set | 383 | # CONFIG_MTD is not set |
| 341 | # CONFIG_PARPORT is not set | 384 | # CONFIG_PARPORT is not set |
| 342 | CONFIG_PNP=y | 385 | CONFIG_PNP=y |
| @@ -360,25 +403,35 @@ CONFIG_BLK_DEV_NBD=m | |||
| 360 | CONFIG_BLK_DEV_RAM=y | 403 | CONFIG_BLK_DEV_RAM=y |
| 361 | CONFIG_BLK_DEV_RAM_COUNT=16 | 404 | CONFIG_BLK_DEV_RAM_COUNT=16 |
| 362 | CONFIG_BLK_DEV_RAM_SIZE=4096 | 405 | CONFIG_BLK_DEV_RAM_SIZE=4096 |
| 363 | CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 | 406 | # CONFIG_BLK_DEV_XIP is not set |
| 364 | # CONFIG_CDROM_PKTCDVD is not set | 407 | # CONFIG_CDROM_PKTCDVD is not set |
| 365 | # CONFIG_ATA_OVER_ETH is not set | 408 | # CONFIG_ATA_OVER_ETH is not set |
| 409 | # CONFIG_BLK_DEV_HD is not set | ||
| 366 | CONFIG_MISC_DEVICES=y | 410 | CONFIG_MISC_DEVICES=y |
| 367 | # CONFIG_PHANTOM is not set | 411 | # CONFIG_PHANTOM is not set |
| 368 | # CONFIG_EEPROM_93CX6 is not set | 412 | # CONFIG_EEPROM_93CX6 is not set |
| 369 | CONFIG_SGI_IOC4=y | 413 | CONFIG_SGI_IOC4=y |
| 370 | # CONFIG_TIFM_CORE is not set | 414 | # CONFIG_TIFM_CORE is not set |
| 415 | # CONFIG_ENCLOSURE_SERVICES is not set | ||
| 416 | CONFIG_SGI_XP=m | ||
| 417 | # CONFIG_HP_ILO is not set | ||
| 418 | CONFIG_SGI_GRU=m | ||
| 419 | # CONFIG_SGI_GRU_DEBUG is not set | ||
| 420 | CONFIG_HAVE_IDE=y | ||
| 371 | CONFIG_IDE=y | 421 | CONFIG_IDE=y |
| 372 | CONFIG_IDE_MAX_HWIFS=4 | 422 | CONFIG_IDE_MAX_HWIFS=4 |
| 373 | CONFIG_BLK_DEV_IDE=y | 423 | CONFIG_BLK_DEV_IDE=y |
| 374 | 424 | ||
| 375 | # | 425 | # |
| 376 | # Please see Documentation/ide.txt for help/info on IDE drives | 426 | # Please see Documentation/ide/ide.txt for help/info on IDE drives |
| 377 | # | 427 | # |
| 428 | CONFIG_IDE_TIMINGS=y | ||
| 429 | CONFIG_IDE_ATAPI=y | ||
| 378 | # CONFIG_BLK_DEV_IDE_SATA is not set | 430 | # CONFIG_BLK_DEV_IDE_SATA is not set |
| 379 | CONFIG_BLK_DEV_IDEDISK=y | 431 | CONFIG_BLK_DEV_IDEDISK=y |
| 380 | # CONFIG_IDEDISK_MULTI_MODE is not set | 432 | # CONFIG_IDEDISK_MULTI_MODE is not set |
| 381 | CONFIG_BLK_DEV_IDECD=y | 433 | CONFIG_BLK_DEV_IDECD=y |
| 434 | CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y | ||
| 382 | # CONFIG_BLK_DEV_IDETAPE is not set | 435 | # CONFIG_BLK_DEV_IDETAPE is not set |
| 383 | CONFIG_BLK_DEV_IDEFLOPPY=y | 436 | CONFIG_BLK_DEV_IDEFLOPPY=y |
| 384 | CONFIG_BLK_DEV_IDESCSI=m | 437 | CONFIG_BLK_DEV_IDESCSI=m |
| @@ -390,25 +443,26 @@ CONFIG_IDE_PROC_FS=y | |||
| 390 | # IDE chipset support/bugfixes | 443 | # IDE chipset support/bugfixes |
| 391 | # | 444 | # |
| 392 | # CONFIG_IDE_GENERIC is not set | 445 | # CONFIG_IDE_GENERIC is not set |
| 446 | # CONFIG_BLK_DEV_PLATFORM is not set | ||
| 393 | # CONFIG_BLK_DEV_IDEPNP is not set | 447 | # CONFIG_BLK_DEV_IDEPNP is not set |
| 448 | CONFIG_BLK_DEV_IDEDMA_SFF=y | ||
| 449 | |||
| 450 | # | ||
| 451 | # PCI IDE chipsets support | ||
| 452 | # | ||
| 394 | CONFIG_BLK_DEV_IDEPCI=y | 453 | CONFIG_BLK_DEV_IDEPCI=y |
| 395 | CONFIG_IDEPCI_SHARE_IRQ=y | ||
| 396 | CONFIG_IDEPCI_PCIBUS_ORDER=y | 454 | CONFIG_IDEPCI_PCIBUS_ORDER=y |
| 397 | # CONFIG_BLK_DEV_OFFBOARD is not set | 455 | # CONFIG_BLK_DEV_OFFBOARD is not set |
| 398 | CONFIG_BLK_DEV_GENERIC=y | 456 | CONFIG_BLK_DEV_GENERIC=y |
| 399 | # CONFIG_BLK_DEV_OPTI621 is not set | 457 | # CONFIG_BLK_DEV_OPTI621 is not set |
| 400 | CONFIG_BLK_DEV_IDEDMA_PCI=y | 458 | CONFIG_BLK_DEV_IDEDMA_PCI=y |
| 401 | # CONFIG_BLK_DEV_IDEDMA_FORCED is not set | ||
| 402 | # CONFIG_IDEDMA_ONLYDISK is not set | ||
| 403 | # CONFIG_BLK_DEV_AEC62XX is not set | 459 | # CONFIG_BLK_DEV_AEC62XX is not set |
| 404 | # CONFIG_BLK_DEV_ALI15X3 is not set | 460 | # CONFIG_BLK_DEV_ALI15X3 is not set |
| 405 | # CONFIG_BLK_DEV_AMD74XX is not set | 461 | # CONFIG_BLK_DEV_AMD74XX is not set |
| 406 | CONFIG_BLK_DEV_CMD64X=y | 462 | CONFIG_BLK_DEV_CMD64X=y |
| 407 | # CONFIG_BLK_DEV_TRIFLEX is not set | 463 | # CONFIG_BLK_DEV_TRIFLEX is not set |
| 408 | # CONFIG_BLK_DEV_CY82C693 is not set | ||
| 409 | # CONFIG_BLK_DEV_CS5520 is not set | 464 | # CONFIG_BLK_DEV_CS5520 is not set |
| 410 | # CONFIG_BLK_DEV_CS5530 is not set | 465 | # CONFIG_BLK_DEV_CS5530 is not set |
| 411 | # CONFIG_BLK_DEV_HPT34X is not set | ||
| 412 | # CONFIG_BLK_DEV_HPT366 is not set | 466 | # CONFIG_BLK_DEV_HPT366 is not set |
| 413 | # CONFIG_BLK_DEV_JMICRON is not set | 467 | # CONFIG_BLK_DEV_JMICRON is not set |
| 414 | # CONFIG_BLK_DEV_SC1200 is not set | 468 | # CONFIG_BLK_DEV_SC1200 is not set |
| @@ -425,10 +479,7 @@ CONFIG_BLK_DEV_SGIIOC4=y | |||
| 425 | # CONFIG_BLK_DEV_TRM290 is not set | 479 | # CONFIG_BLK_DEV_TRM290 is not set |
| 426 | # CONFIG_BLK_DEV_VIA82CXXX is not set | 480 | # CONFIG_BLK_DEV_VIA82CXXX is not set |
| 427 | # CONFIG_BLK_DEV_TC86C001 is not set | 481 | # CONFIG_BLK_DEV_TC86C001 is not set |
| 428 | # CONFIG_IDE_ARM is not set | ||
| 429 | CONFIG_BLK_DEV_IDEDMA=y | 482 | CONFIG_BLK_DEV_IDEDMA=y |
| 430 | # CONFIG_IDEDMA_IVB is not set | ||
| 431 | # CONFIG_BLK_DEV_HD is not set | ||
| 432 | 483 | ||
| 433 | # | 484 | # |
| 434 | # SCSI device support | 485 | # SCSI device support |
| @@ -468,10 +519,8 @@ CONFIG_SCSI_FC_ATTRS=y | |||
| 468 | # CONFIG_SCSI_ISCSI_ATTRS is not set | 519 | # CONFIG_SCSI_ISCSI_ATTRS is not set |
| 469 | CONFIG_SCSI_SAS_ATTRS=y | 520 | CONFIG_SCSI_SAS_ATTRS=y |
| 470 | # CONFIG_SCSI_SAS_LIBSAS is not set | 521 | # CONFIG_SCSI_SAS_LIBSAS is not set |
| 471 | 522 | # CONFIG_SCSI_SRP_ATTRS is not set | |
| 472 | # | 523 | CONFIG_SCSI_LOWLEVEL=y |
| 473 | # SCSI low-level drivers | ||
| 474 | # | ||
| 475 | # CONFIG_ISCSI_TCP is not set | 524 | # CONFIG_ISCSI_TCP is not set |
| 476 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set | 525 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set |
| 477 | # CONFIG_SCSI_3W_9XXX is not set | 526 | # CONFIG_SCSI_3W_9XXX is not set |
| @@ -481,6 +530,8 @@ CONFIG_SCSI_SAS_ATTRS=y | |||
| 481 | # CONFIG_SCSI_AIC7XXX_OLD is not set | 530 | # CONFIG_SCSI_AIC7XXX_OLD is not set |
| 482 | # CONFIG_SCSI_AIC79XX is not set | 531 | # CONFIG_SCSI_AIC79XX is not set |
| 483 | # CONFIG_SCSI_AIC94XX is not set | 532 | # CONFIG_SCSI_AIC94XX is not set |
| 533 | # CONFIG_SCSI_DPT_I2O is not set | ||
| 534 | # CONFIG_SCSI_ADVANSYS is not set | ||
| 484 | # CONFIG_SCSI_ARCMSR is not set | 535 | # CONFIG_SCSI_ARCMSR is not set |
| 485 | # CONFIG_MEGARAID_NEWGEN is not set | 536 | # CONFIG_MEGARAID_NEWGEN is not set |
| 486 | # CONFIG_MEGARAID_LEGACY is not set | 537 | # CONFIG_MEGARAID_LEGACY is not set |
| @@ -491,12 +542,14 @@ CONFIG_SCSI_SAS_ATTRS=y | |||
| 491 | # CONFIG_SCSI_IPS is not set | 542 | # CONFIG_SCSI_IPS is not set |
| 492 | # CONFIG_SCSI_INITIO is not set | 543 | # CONFIG_SCSI_INITIO is not set |
| 493 | # CONFIG_SCSI_INIA100 is not set | 544 | # CONFIG_SCSI_INIA100 is not set |
| 545 | # CONFIG_SCSI_MVSAS is not set | ||
| 494 | # CONFIG_SCSI_STEX is not set | 546 | # CONFIG_SCSI_STEX is not set |
| 495 | CONFIG_SCSI_SYM53C8XX_2=y | 547 | CONFIG_SCSI_SYM53C8XX_2=y |
| 496 | CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 | 548 | CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 |
| 497 | CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 | 549 | CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 |
| 498 | CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 | 550 | CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 |
| 499 | CONFIG_SCSI_SYM53C8XX_MMIO=y | 551 | CONFIG_SCSI_SYM53C8XX_MMIO=y |
| 552 | # CONFIG_SCSI_IPR is not set | ||
| 500 | CONFIG_SCSI_QLOGIC_1280=y | 553 | CONFIG_SCSI_QLOGIC_1280=y |
| 501 | # CONFIG_SCSI_QLA_FC is not set | 554 | # CONFIG_SCSI_QLA_FC is not set |
| 502 | # CONFIG_SCSI_QLA_ISCSI is not set | 555 | # CONFIG_SCSI_QLA_ISCSI is not set |
| @@ -505,7 +558,68 @@ CONFIG_SCSI_QLOGIC_1280=y | |||
| 505 | # CONFIG_SCSI_DC390T is not set | 558 | # CONFIG_SCSI_DC390T is not set |
| 506 | # CONFIG_SCSI_DEBUG is not set | 559 | # CONFIG_SCSI_DEBUG is not set |
| 507 | # CONFIG_SCSI_SRP is not set | 560 | # CONFIG_SCSI_SRP is not set |
| 508 | # CONFIG_ATA is not set | 561 | # CONFIG_SCSI_DH is not set |
| 562 | CONFIG_ATA=y | ||
| 563 | CONFIG_ATA_NONSTANDARD=y | ||
| 564 | CONFIG_ATA_ACPI=y | ||
| 565 | CONFIG_SATA_PMP=y | ||
| 566 | # CONFIG_SATA_AHCI is not set | ||
| 567 | # CONFIG_SATA_SIL24 is not set | ||
| 568 | CONFIG_ATA_SFF=y | ||
| 569 | # CONFIG_SATA_SVW is not set | ||
| 570 | CONFIG_ATA_PIIX=y | ||
| 571 | # CONFIG_SATA_MV is not set | ||
| 572 | # CONFIG_SATA_NV is not set | ||
| 573 | # CONFIG_PDC_ADMA is not set | ||
| 574 | # CONFIG_SATA_QSTOR is not set | ||
| 575 | # CONFIG_SATA_PROMISE is not set | ||
| 576 | # CONFIG_SATA_SX4 is not set | ||
| 577 | # CONFIG_SATA_SIL is not set | ||
| 578 | # CONFIG_SATA_SIS is not set | ||
| 579 | # CONFIG_SATA_ULI is not set | ||
| 580 | # CONFIG_SATA_VIA is not set | ||
| 581 | # CONFIG_SATA_VITESSE is not set | ||
| 582 | # CONFIG_SATA_INIC162X is not set | ||
| 583 | # CONFIG_PATA_ACPI is not set | ||
| 584 | # CONFIG_PATA_ALI is not set | ||
| 585 | # CONFIG_PATA_AMD is not set | ||
| 586 | # CONFIG_PATA_ARTOP is not set | ||
| 587 | # CONFIG_PATA_ATIIXP is not set | ||
| 588 | # CONFIG_PATA_CMD640_PCI is not set | ||
| 589 | # CONFIG_PATA_CMD64X is not set | ||
| 590 | # CONFIG_PATA_CS5520 is not set | ||
| 591 | # CONFIG_PATA_CS5530 is not set | ||
| 592 | # CONFIG_PATA_CYPRESS is not set | ||
| 593 | # CONFIG_PATA_EFAR is not set | ||
| 594 | # CONFIG_ATA_GENERIC is not set | ||
| 595 | # CONFIG_PATA_HPT366 is not set | ||
| 596 | # CONFIG_PATA_HPT37X is not set | ||
| 597 | # CONFIG_PATA_HPT3X2N is not set | ||
| 598 | # CONFIG_PATA_HPT3X3 is not set | ||
| 599 | # CONFIG_PATA_IT821X is not set | ||
| 600 | # CONFIG_PATA_IT8213 is not set | ||
| 601 | # CONFIG_PATA_JMICRON is not set | ||
| 602 | # CONFIG_PATA_TRIFLEX is not set | ||
| 603 | # CONFIG_PATA_MARVELL is not set | ||
| 604 | # CONFIG_PATA_MPIIX is not set | ||
| 605 | # CONFIG_PATA_OLDPIIX is not set | ||
| 606 | # CONFIG_PATA_NETCELL is not set | ||
| 607 | # CONFIG_PATA_NINJA32 is not set | ||
| 608 | # CONFIG_PATA_NS87410 is not set | ||
| 609 | # CONFIG_PATA_NS87415 is not set | ||
| 610 | # CONFIG_PATA_OPTI is not set | ||
| 611 | # CONFIG_PATA_OPTIDMA is not set | ||
| 612 | # CONFIG_PATA_PDC_OLD is not set | ||
| 613 | # CONFIG_PATA_RADISYS is not set | ||
| 614 | # CONFIG_PATA_RZ1000 is not set | ||
| 615 | # CONFIG_PATA_SC1200 is not set | ||
| 616 | # CONFIG_PATA_SERVERWORKS is not set | ||
| 617 | # CONFIG_PATA_PDC2027X is not set | ||
| 618 | # CONFIG_PATA_SIL680 is not set | ||
| 619 | # CONFIG_PATA_SIS is not set | ||
| 620 | # CONFIG_PATA_VIA is not set | ||
| 621 | # CONFIG_PATA_WINBOND is not set | ||
| 622 | # CONFIG_PATA_SCH is not set | ||
| 509 | CONFIG_MD=y | 623 | CONFIG_MD=y |
| 510 | CONFIG_BLK_DEV_MD=m | 624 | CONFIG_BLK_DEV_MD=m |
| 511 | CONFIG_MD_LINEAR=m | 625 | CONFIG_MD_LINEAR=m |
| @@ -522,36 +636,52 @@ CONFIG_DM_SNAPSHOT=m | |||
| 522 | CONFIG_DM_MIRROR=m | 636 | CONFIG_DM_MIRROR=m |
| 523 | CONFIG_DM_ZERO=m | 637 | CONFIG_DM_ZERO=m |
| 524 | CONFIG_DM_MULTIPATH=m | 638 | CONFIG_DM_MULTIPATH=m |
| 525 | # CONFIG_DM_MULTIPATH_EMC is not set | ||
| 526 | # CONFIG_DM_MULTIPATH_RDAC is not set | ||
| 527 | # CONFIG_DM_DELAY is not set | 639 | # CONFIG_DM_DELAY is not set |
| 528 | 640 | # CONFIG_DM_UEVENT is not set | |
| 529 | # | ||
| 530 | # Fusion MPT device support | ||
| 531 | # | ||
| 532 | CONFIG_FUSION=y | 641 | CONFIG_FUSION=y |
| 533 | CONFIG_FUSION_SPI=y | 642 | CONFIG_FUSION_SPI=y |
| 534 | CONFIG_FUSION_FC=m | 643 | CONFIG_FUSION_FC=m |
| 535 | CONFIG_FUSION_SAS=y | 644 | CONFIG_FUSION_SAS=y |
| 536 | CONFIG_FUSION_MAX_SGE=128 | 645 | CONFIG_FUSION_MAX_SGE=128 |
| 537 | # CONFIG_FUSION_CTL is not set | 646 | # CONFIG_FUSION_CTL is not set |
| 647 | # CONFIG_FUSION_LOGGING is not set | ||
| 538 | 648 | ||
| 539 | # | 649 | # |
| 540 | # IEEE 1394 (FireWire) support | 650 | # IEEE 1394 (FireWire) support |
| 541 | # | 651 | # |
| 652 | |||
| 653 | # | ||
| 654 | # Enable only one of the two stacks, unless you know what you are doing | ||
| 655 | # | ||
| 542 | # CONFIG_FIREWIRE is not set | 656 | # CONFIG_FIREWIRE is not set |
| 543 | # CONFIG_IEEE1394 is not set | 657 | # CONFIG_IEEE1394 is not set |
| 544 | # CONFIG_I2O is not set | 658 | # CONFIG_I2O is not set |
| 545 | CONFIG_NETDEVICES=y | 659 | CONFIG_NETDEVICES=y |
| 546 | # CONFIG_NETDEVICES_MULTIQUEUE is not set | ||
| 547 | CONFIG_DUMMY=m | 660 | CONFIG_DUMMY=m |
| 548 | # CONFIG_BONDING is not set | 661 | # CONFIG_BONDING is not set |
| 549 | # CONFIG_MACVLAN is not set | 662 | # CONFIG_MACVLAN is not set |
| 550 | # CONFIG_EQUALIZER is not set | 663 | # CONFIG_EQUALIZER is not set |
| 551 | # CONFIG_TUN is not set | 664 | # CONFIG_TUN is not set |
| 665 | # CONFIG_VETH is not set | ||
| 552 | # CONFIG_NET_SB1000 is not set | 666 | # CONFIG_NET_SB1000 is not set |
| 553 | # CONFIG_ARCNET is not set | 667 | # CONFIG_ARCNET is not set |
| 554 | # CONFIG_PHYLIB is not set | 668 | CONFIG_PHYLIB=y |
| 669 | |||
| 670 | # | ||
| 671 | # MII PHY device drivers | ||
| 672 | # | ||
| 673 | # CONFIG_MARVELL_PHY is not set | ||
| 674 | # CONFIG_DAVICOM_PHY is not set | ||
| 675 | # CONFIG_QSEMI_PHY is not set | ||
| 676 | # CONFIG_LXT_PHY is not set | ||
| 677 | # CONFIG_CICADA_PHY is not set | ||
| 678 | # CONFIG_VITESSE_PHY is not set | ||
| 679 | # CONFIG_SMSC_PHY is not set | ||
| 680 | # CONFIG_BROADCOM_PHY is not set | ||
| 681 | # CONFIG_ICPLUS_PHY is not set | ||
| 682 | # CONFIG_REALTEK_PHY is not set | ||
| 683 | # CONFIG_FIXED_PHY is not set | ||
| 684 | # CONFIG_MDIO_BITBANG is not set | ||
| 555 | CONFIG_NET_ETHERNET=y | 685 | CONFIG_NET_ETHERNET=y |
| 556 | CONFIG_MII=m | 686 | CONFIG_MII=m |
| 557 | # CONFIG_HAPPYMEAL is not set | 687 | # CONFIG_HAPPYMEAL is not set |
| @@ -569,13 +699,16 @@ CONFIG_TULIP=m | |||
| 569 | # CONFIG_DM9102 is not set | 699 | # CONFIG_DM9102 is not set |
| 570 | # CONFIG_ULI526X is not set | 700 | # CONFIG_ULI526X is not set |
| 571 | # CONFIG_HP100 is not set | 701 | # CONFIG_HP100 is not set |
| 702 | # CONFIG_IBM_NEW_EMAC_ZMII is not set | ||
| 703 | # CONFIG_IBM_NEW_EMAC_RGMII is not set | ||
| 704 | # CONFIG_IBM_NEW_EMAC_TAH is not set | ||
| 705 | # CONFIG_IBM_NEW_EMAC_EMAC4 is not set | ||
| 572 | CONFIG_NET_PCI=y | 706 | CONFIG_NET_PCI=y |
| 573 | # CONFIG_PCNET32 is not set | 707 | # CONFIG_PCNET32 is not set |
| 574 | # CONFIG_AMD8111_ETH is not set | 708 | # CONFIG_AMD8111_ETH is not set |
| 575 | # CONFIG_ADAPTEC_STARFIRE is not set | 709 | # CONFIG_ADAPTEC_STARFIRE is not set |
| 576 | # CONFIG_B44 is not set | 710 | # CONFIG_B44 is not set |
| 577 | # CONFIG_FORCEDETH is not set | 711 | # CONFIG_FORCEDETH is not set |
| 578 | # CONFIG_DGRS is not set | ||
| 579 | CONFIG_EEPRO100=m | 712 | CONFIG_EEPRO100=m |
| 580 | CONFIG_E100=m | 713 | CONFIG_E100=m |
| 581 | # CONFIG_FEALNX is not set | 714 | # CONFIG_FEALNX is not set |
| @@ -583,17 +716,22 @@ CONFIG_E100=m | |||
| 583 | # CONFIG_NE2K_PCI is not set | 716 | # CONFIG_NE2K_PCI is not set |
| 584 | # CONFIG_8139CP is not set | 717 | # CONFIG_8139CP is not set |
| 585 | # CONFIG_8139TOO is not set | 718 | # CONFIG_8139TOO is not set |
| 719 | # CONFIG_R6040 is not set | ||
| 586 | # CONFIG_SIS900 is not set | 720 | # CONFIG_SIS900 is not set |
| 587 | # CONFIG_EPIC100 is not set | 721 | # CONFIG_EPIC100 is not set |
| 588 | # CONFIG_SUNDANCE is not set | 722 | # CONFIG_SUNDANCE is not set |
| 723 | # CONFIG_TLAN is not set | ||
| 589 | # CONFIG_VIA_RHINE is not set | 724 | # CONFIG_VIA_RHINE is not set |
| 590 | # CONFIG_SC92031 is not set | 725 | # CONFIG_SC92031 is not set |
| 591 | CONFIG_NETDEV_1000=y | 726 | CONFIG_NETDEV_1000=y |
| 592 | # CONFIG_ACENIC is not set | 727 | # CONFIG_ACENIC is not set |
| 593 | # CONFIG_DL2K is not set | 728 | # CONFIG_DL2K is not set |
| 594 | CONFIG_E1000=y | 729 | CONFIG_E1000=y |
| 595 | # CONFIG_E1000_NAPI is not set | ||
| 596 | # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set | 730 | # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set |
| 731 | # CONFIG_E1000E is not set | ||
| 732 | # CONFIG_IP1000 is not set | ||
| 733 | CONFIG_IGB=y | ||
| 734 | # CONFIG_IGB_LRO is not set | ||
| 597 | # CONFIG_NS83820 is not set | 735 | # CONFIG_NS83820 is not set |
| 598 | # CONFIG_HAMACHI is not set | 736 | # CONFIG_HAMACHI is not set |
| 599 | # CONFIG_YELLOWFIN is not set | 737 | # CONFIG_YELLOWFIN is not set |
| @@ -606,14 +744,20 @@ CONFIG_TIGON3=y | |||
| 606 | # CONFIG_BNX2 is not set | 744 | # CONFIG_BNX2 is not set |
| 607 | # CONFIG_QLA3XXX is not set | 745 | # CONFIG_QLA3XXX is not set |
| 608 | # CONFIG_ATL1 is not set | 746 | # CONFIG_ATL1 is not set |
| 747 | # CONFIG_ATL1E is not set | ||
| 609 | CONFIG_NETDEV_10000=y | 748 | CONFIG_NETDEV_10000=y |
| 610 | # CONFIG_CHELSIO_T1 is not set | 749 | # CONFIG_CHELSIO_T1 is not set |
| 611 | # CONFIG_CHELSIO_T3 is not set | 750 | # CONFIG_CHELSIO_T3 is not set |
| 751 | # CONFIG_IXGBE is not set | ||
| 612 | # CONFIG_IXGB is not set | 752 | # CONFIG_IXGB is not set |
| 613 | # CONFIG_S2IO is not set | 753 | # CONFIG_S2IO is not set |
| 614 | # CONFIG_MYRI10GE is not set | 754 | # CONFIG_MYRI10GE is not set |
| 615 | # CONFIG_NETXEN_NIC is not set | 755 | # CONFIG_NETXEN_NIC is not set |
| 756 | # CONFIG_NIU is not set | ||
| 616 | # CONFIG_MLX4_CORE is not set | 757 | # CONFIG_MLX4_CORE is not set |
| 758 | # CONFIG_TEHUTI is not set | ||
| 759 | # CONFIG_BNX2X is not set | ||
| 760 | # CONFIG_SFC is not set | ||
| 617 | # CONFIG_TR is not set | 761 | # CONFIG_TR is not set |
| 618 | 762 | ||
| 619 | # | 763 | # |
| @@ -621,6 +765,7 @@ CONFIG_NETDEV_10000=y | |||
| 621 | # | 765 | # |
| 622 | # CONFIG_WLAN_PRE80211 is not set | 766 | # CONFIG_WLAN_PRE80211 is not set |
| 623 | # CONFIG_WLAN_80211 is not set | 767 | # CONFIG_WLAN_80211 is not set |
| 768 | # CONFIG_IWLWIFI_LEDS is not set | ||
| 624 | 769 | ||
| 625 | # | 770 | # |
| 626 | # USB Network Adapters | 771 | # USB Network Adapters |
| @@ -629,7 +774,6 @@ CONFIG_NETDEV_10000=y | |||
| 629 | # CONFIG_USB_KAWETH is not set | 774 | # CONFIG_USB_KAWETH is not set |
| 630 | # CONFIG_USB_PEGASUS is not set | 775 | # CONFIG_USB_PEGASUS is not set |
| 631 | # CONFIG_USB_RTL8150 is not set | 776 | # CONFIG_USB_RTL8150 is not set |
| 632 | # CONFIG_USB_USBNET_MII is not set | ||
| 633 | # CONFIG_USB_USBNET is not set | 777 | # CONFIG_USB_USBNET is not set |
| 634 | # CONFIG_WAN is not set | 778 | # CONFIG_WAN is not set |
| 635 | # CONFIG_FDDI is not set | 779 | # CONFIG_FDDI is not set |
| @@ -637,8 +781,8 @@ CONFIG_NETDEV_10000=y | |||
| 637 | # CONFIG_PPP is not set | 781 | # CONFIG_PPP is not set |
| 638 | # CONFIG_SLIP is not set | 782 | # CONFIG_SLIP is not set |
| 639 | # CONFIG_NET_FC is not set | 783 | # CONFIG_NET_FC is not set |
| 640 | # CONFIG_SHAPER is not set | ||
| 641 | CONFIG_NETCONSOLE=y | 784 | CONFIG_NETCONSOLE=y |
| 785 | # CONFIG_NETCONSOLE_DYNAMIC is not set | ||
| 642 | CONFIG_NETPOLL=y | 786 | CONFIG_NETPOLL=y |
| 643 | # CONFIG_NETPOLL_TRAP is not set | 787 | # CONFIG_NETPOLL_TRAP is not set |
| 644 | CONFIG_NET_POLL_CONTROLLER=y | 788 | CONFIG_NET_POLL_CONTROLLER=y |
| @@ -660,7 +804,6 @@ CONFIG_INPUT_MOUSEDEV_PSAUX=y | |||
| 660 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | 804 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 |
| 661 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | 805 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 |
| 662 | # CONFIG_INPUT_JOYDEV is not set | 806 | # CONFIG_INPUT_JOYDEV is not set |
| 663 | # CONFIG_INPUT_TSDEV is not set | ||
| 664 | # CONFIG_INPUT_EVDEV is not set | 807 | # CONFIG_INPUT_EVDEV is not set |
| 665 | # CONFIG_INPUT_EVBUG is not set | 808 | # CONFIG_INPUT_EVBUG is not set |
| 666 | 809 | ||
| @@ -709,9 +852,11 @@ CONFIG_GAMEPORT=m | |||
| 709 | # Character devices | 852 | # Character devices |
| 710 | # | 853 | # |
| 711 | CONFIG_VT=y | 854 | CONFIG_VT=y |
| 855 | CONFIG_CONSOLE_TRANSLATIONS=y | ||
| 712 | CONFIG_VT_CONSOLE=y | 856 | CONFIG_VT_CONSOLE=y |
| 713 | CONFIG_HW_CONSOLE=y | 857 | CONFIG_HW_CONSOLE=y |
| 714 | # CONFIG_VT_HW_CONSOLE_BINDING is not set | 858 | # CONFIG_VT_HW_CONSOLE_BINDING is not set |
| 859 | CONFIG_DEVKMEM=y | ||
| 715 | CONFIG_SERIAL_NONSTANDARD=y | 860 | CONFIG_SERIAL_NONSTANDARD=y |
| 716 | # CONFIG_COMPUTONE is not set | 861 | # CONFIG_COMPUTONE is not set |
| 717 | # CONFIG_ROCKETPORT is not set | 862 | # CONFIG_ROCKETPORT is not set |
| @@ -719,15 +864,16 @@ CONFIG_SERIAL_NONSTANDARD=y | |||
| 719 | # CONFIG_DIGIEPCA is not set | 864 | # CONFIG_DIGIEPCA is not set |
| 720 | # CONFIG_MOXA_INTELLIO is not set | 865 | # CONFIG_MOXA_INTELLIO is not set |
| 721 | # CONFIG_MOXA_SMARTIO is not set | 866 | # CONFIG_MOXA_SMARTIO is not set |
| 722 | # CONFIG_MOXA_SMARTIO_NEW is not set | ||
| 723 | # CONFIG_ISI is not set | 867 | # CONFIG_ISI is not set |
| 724 | # CONFIG_SYNCLINKMP is not set | 868 | # CONFIG_SYNCLINKMP is not set |
| 725 | # CONFIG_SYNCLINK_GT is not set | 869 | # CONFIG_SYNCLINK_GT is not set |
| 726 | # CONFIG_N_HDLC is not set | 870 | # CONFIG_N_HDLC is not set |
| 871 | # CONFIG_RISCOM8 is not set | ||
| 727 | # CONFIG_SPECIALIX is not set | 872 | # CONFIG_SPECIALIX is not set |
| 728 | # CONFIG_SX is not set | 873 | # CONFIG_SX is not set |
| 729 | # CONFIG_RIO is not set | 874 | # CONFIG_RIO is not set |
| 730 | # CONFIG_STALDRV is not set | 875 | # CONFIG_STALDRV is not set |
| 876 | # CONFIG_NOZOMI is not set | ||
| 731 | CONFIG_SGI_SNSC=y | 877 | CONFIG_SGI_SNSC=y |
| 732 | CONFIG_SGI_TIOCX=y | 878 | CONFIG_SGI_TIOCX=y |
| 733 | CONFIG_SGI_MBCS=m | 879 | CONFIG_SGI_MBCS=m |
| @@ -759,76 +905,100 @@ CONFIG_UNIX98_PTYS=y | |||
| 759 | CONFIG_LEGACY_PTYS=y | 905 | CONFIG_LEGACY_PTYS=y |
| 760 | CONFIG_LEGACY_PTY_COUNT=256 | 906 | CONFIG_LEGACY_PTY_COUNT=256 |
| 761 | # CONFIG_IPMI_HANDLER is not set | 907 | # CONFIG_IPMI_HANDLER is not set |
| 762 | # CONFIG_WATCHDOG is not set | ||
| 763 | # CONFIG_HW_RANDOM is not set | 908 | # CONFIG_HW_RANDOM is not set |
| 764 | CONFIG_EFI_RTC=y | 909 | CONFIG_EFI_RTC=y |
| 765 | # CONFIG_R3964 is not set | 910 | # CONFIG_R3964 is not set |
| 766 | # CONFIG_APPLICOM is not set | 911 | # CONFIG_APPLICOM is not set |
| 767 | CONFIG_AGP=m | ||
| 768 | CONFIG_AGP_I460=m | ||
| 769 | CONFIG_AGP_HP_ZX1=m | ||
| 770 | CONFIG_AGP_SGI_TIOCA=m | ||
| 771 | CONFIG_DRM=m | ||
| 772 | CONFIG_DRM_TDFX=m | ||
| 773 | CONFIG_DRM_R128=m | ||
| 774 | CONFIG_DRM_RADEON=m | ||
| 775 | CONFIG_DRM_MGA=m | ||
| 776 | CONFIG_DRM_SIS=m | ||
| 777 | # CONFIG_DRM_VIA is not set | ||
| 778 | # CONFIG_DRM_SAVAGE is not set | ||
| 779 | CONFIG_RAW_DRIVER=m | 912 | CONFIG_RAW_DRIVER=m |
| 780 | CONFIG_MAX_RAW_DEVS=256 | 913 | CONFIG_MAX_RAW_DEVS=256 |
| 781 | CONFIG_HPET=y | 914 | CONFIG_HPET=y |
| 782 | # CONFIG_HPET_RTC_IRQ is not set | ||
| 783 | CONFIG_HPET_MMAP=y | 915 | CONFIG_HPET_MMAP=y |
| 784 | # CONFIG_HANGCHECK_TIMER is not set | 916 | # CONFIG_HANGCHECK_TIMER is not set |
| 785 | CONFIG_MMTIMER=y | 917 | CONFIG_MMTIMER=y |
| 786 | # CONFIG_TCG_TPM is not set | 918 | # CONFIG_TCG_TPM is not set |
| 787 | CONFIG_DEVPORT=y | 919 | CONFIG_DEVPORT=y |
| 788 | # CONFIG_I2C is not set | 920 | # CONFIG_I2C is not set |
| 789 | |||
| 790 | # | ||
| 791 | # SPI support | ||
| 792 | # | ||
| 793 | # CONFIG_SPI is not set | 921 | # CONFIG_SPI is not set |
| 794 | # CONFIG_SPI_MASTER is not set | ||
| 795 | # CONFIG_W1 is not set | 922 | # CONFIG_W1 is not set |
| 796 | # CONFIG_POWER_SUPPLY is not set | 923 | CONFIG_POWER_SUPPLY=y |
| 924 | # CONFIG_POWER_SUPPLY_DEBUG is not set | ||
| 925 | # CONFIG_PDA_POWER is not set | ||
| 926 | # CONFIG_BATTERY_DS2760 is not set | ||
| 797 | CONFIG_HWMON=y | 927 | CONFIG_HWMON=y |
| 798 | # CONFIG_HWMON_VID is not set | 928 | # CONFIG_HWMON_VID is not set |
| 799 | # CONFIG_SENSORS_ABITUGURU is not set | 929 | # CONFIG_SENSORS_I5K_AMB is not set |
| 800 | # CONFIG_SENSORS_F71805F is not set | 930 | # CONFIG_SENSORS_F71805F is not set |
| 931 | # CONFIG_SENSORS_F71882FG is not set | ||
| 932 | # CONFIG_SENSORS_IT87 is not set | ||
| 933 | # CONFIG_SENSORS_PC87360 is not set | ||
| 801 | # CONFIG_SENSORS_PC87427 is not set | 934 | # CONFIG_SENSORS_PC87427 is not set |
| 935 | # CONFIG_SENSORS_SIS5595 is not set | ||
| 802 | # CONFIG_SENSORS_SMSC47M1 is not set | 936 | # CONFIG_SENSORS_SMSC47M1 is not set |
| 803 | # CONFIG_SENSORS_SMSC47B397 is not set | 937 | # CONFIG_SENSORS_SMSC47B397 is not set |
| 938 | # CONFIG_SENSORS_VIA686A is not set | ||
| 804 | # CONFIG_SENSORS_VT1211 is not set | 939 | # CONFIG_SENSORS_VT1211 is not set |
| 940 | # CONFIG_SENSORS_VT8231 is not set | ||
| 805 | # CONFIG_SENSORS_W83627HF is not set | 941 | # CONFIG_SENSORS_W83627HF is not set |
| 942 | # CONFIG_SENSORS_W83627EHF is not set | ||
| 806 | # CONFIG_HWMON_DEBUG_CHIP is not set | 943 | # CONFIG_HWMON_DEBUG_CHIP is not set |
| 944 | CONFIG_THERMAL=m | ||
| 945 | # CONFIG_THERMAL_HWMON is not set | ||
| 946 | # CONFIG_WATCHDOG is not set | ||
| 947 | |||
| 948 | # | ||
| 949 | # Sonics Silicon Backplane | ||
| 950 | # | ||
| 951 | CONFIG_SSB_POSSIBLE=y | ||
| 952 | # CONFIG_SSB is not set | ||
| 807 | 953 | ||
| 808 | # | 954 | # |
| 809 | # Multifunction device drivers | 955 | # Multifunction device drivers |
| 810 | # | 956 | # |
| 957 | # CONFIG_MFD_CORE is not set | ||
| 811 | # CONFIG_MFD_SM501 is not set | 958 | # CONFIG_MFD_SM501 is not set |
| 959 | # CONFIG_HTC_PASIC3 is not set | ||
| 812 | 960 | ||
| 813 | # | 961 | # |
| 814 | # Multimedia devices | 962 | # Multimedia devices |
| 815 | # | 963 | # |
| 964 | |||
| 965 | # | ||
| 966 | # Multimedia core support | ||
| 967 | # | ||
| 816 | # CONFIG_VIDEO_DEV is not set | 968 | # CONFIG_VIDEO_DEV is not set |
| 817 | # CONFIG_DVB_CORE is not set | 969 | # CONFIG_DVB_CORE is not set |
| 970 | # CONFIG_VIDEO_MEDIA is not set | ||
| 971 | |||
| 972 | # | ||
| 973 | # Multimedia drivers | ||
| 974 | # | ||
| 818 | CONFIG_DAB=y | 975 | CONFIG_DAB=y |
| 819 | # CONFIG_USB_DABUSB is not set | 976 | # CONFIG_USB_DABUSB is not set |
| 820 | 977 | ||
| 821 | # | 978 | # |
| 822 | # Graphics support | 979 | # Graphics support |
| 823 | # | 980 | # |
| 981 | CONFIG_AGP=m | ||
| 982 | CONFIG_AGP_I460=m | ||
| 983 | CONFIG_AGP_HP_ZX1=m | ||
| 984 | CONFIG_AGP_SGI_TIOCA=m | ||
| 985 | CONFIG_DRM=m | ||
| 986 | CONFIG_DRM_TDFX=m | ||
| 987 | CONFIG_DRM_R128=m | ||
| 988 | CONFIG_DRM_RADEON=m | ||
| 989 | CONFIG_DRM_MGA=m | ||
| 990 | CONFIG_DRM_SIS=m | ||
| 991 | # CONFIG_DRM_VIA is not set | ||
| 992 | # CONFIG_DRM_SAVAGE is not set | ||
| 993 | # CONFIG_VGASTATE is not set | ||
| 994 | # CONFIG_VIDEO_OUTPUT_CONTROL is not set | ||
| 995 | # CONFIG_FB is not set | ||
| 824 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | 996 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set |
| 825 | 997 | ||
| 826 | # | 998 | # |
| 827 | # Display device support | 999 | # Display device support |
| 828 | # | 1000 | # |
| 829 | # CONFIG_DISPLAY_SUPPORT is not set | 1001 | # CONFIG_DISPLAY_SUPPORT is not set |
| 830 | # CONFIG_VGASTATE is not set | ||
| 831 | # CONFIG_FB is not set | ||
| 832 | 1002 | ||
| 833 | # | 1003 | # |
| 834 | # Console display driver support | 1004 | # Console display driver support |
| @@ -836,15 +1006,7 @@ CONFIG_DAB=y | |||
| 836 | CONFIG_VGA_CONSOLE=y | 1006 | CONFIG_VGA_CONSOLE=y |
| 837 | # CONFIG_VGACON_SOFT_SCROLLBACK is not set | 1007 | # CONFIG_VGACON_SOFT_SCROLLBACK is not set |
| 838 | CONFIG_DUMMY_CONSOLE=y | 1008 | CONFIG_DUMMY_CONSOLE=y |
| 839 | |||
| 840 | # | ||
| 841 | # Sound | ||
| 842 | # | ||
| 843 | CONFIG_SOUND=m | 1009 | CONFIG_SOUND=m |
| 844 | |||
| 845 | # | ||
| 846 | # Advanced Linux Sound Architecture | ||
| 847 | # | ||
| 848 | CONFIG_SND=m | 1010 | CONFIG_SND=m |
| 849 | CONFIG_SND_TIMER=m | 1011 | CONFIG_SND_TIMER=m |
| 850 | CONFIG_SND_PCM=m | 1012 | CONFIG_SND_PCM=m |
| @@ -862,22 +1024,18 @@ CONFIG_SND_SUPPORT_OLD_API=y | |||
| 862 | CONFIG_SND_VERBOSE_PROCFS=y | 1024 | CONFIG_SND_VERBOSE_PROCFS=y |
| 863 | CONFIG_SND_VERBOSE_PRINTK=y | 1025 | CONFIG_SND_VERBOSE_PRINTK=y |
| 864 | # CONFIG_SND_DEBUG is not set | 1026 | # CONFIG_SND_DEBUG is not set |
| 865 | 1027 | CONFIG_SND_VMASTER=y | |
| 866 | # | ||
| 867 | # Generic devices | ||
| 868 | # | ||
| 869 | CONFIG_SND_MPU401_UART=m | 1028 | CONFIG_SND_MPU401_UART=m |
| 870 | CONFIG_SND_OPL3_LIB=m | 1029 | CONFIG_SND_OPL3_LIB=m |
| 871 | CONFIG_SND_AC97_CODEC=m | 1030 | CONFIG_SND_AC97_CODEC=m |
| 1031 | CONFIG_SND_DRIVERS=y | ||
| 872 | CONFIG_SND_DUMMY=m | 1032 | CONFIG_SND_DUMMY=m |
| 873 | CONFIG_SND_VIRMIDI=m | 1033 | CONFIG_SND_VIRMIDI=m |
| 874 | CONFIG_SND_MTPAV=m | 1034 | CONFIG_SND_MTPAV=m |
| 875 | CONFIG_SND_SERIAL_U16550=m | 1035 | CONFIG_SND_SERIAL_U16550=m |
| 876 | CONFIG_SND_MPU401=m | 1036 | CONFIG_SND_MPU401=m |
| 877 | 1037 | # CONFIG_SND_AC97_POWER_SAVE is not set | |
| 878 | # | 1038 | CONFIG_SND_PCI=y |
| 879 | # PCI devices | ||
| 880 | # | ||
| 881 | # CONFIG_SND_AD1889 is not set | 1039 | # CONFIG_SND_AD1889 is not set |
| 882 | # CONFIG_SND_ALS300 is not set | 1040 | # CONFIG_SND_ALS300 is not set |
| 883 | # CONFIG_SND_ALI5451 is not set | 1041 | # CONFIG_SND_ALI5451 is not set |
| @@ -886,10 +1044,12 @@ CONFIG_SND_MPU401=m | |||
| 886 | # CONFIG_SND_AU8810 is not set | 1044 | # CONFIG_SND_AU8810 is not set |
| 887 | # CONFIG_SND_AU8820 is not set | 1045 | # CONFIG_SND_AU8820 is not set |
| 888 | # CONFIG_SND_AU8830 is not set | 1046 | # CONFIG_SND_AU8830 is not set |
| 1047 | # CONFIG_SND_AW2 is not set | ||
| 889 | # CONFIG_SND_AZT3328 is not set | 1048 | # CONFIG_SND_AZT3328 is not set |
| 890 | # CONFIG_SND_BT87X is not set | 1049 | # CONFIG_SND_BT87X is not set |
| 891 | # CONFIG_SND_CA0106 is not set | 1050 | # CONFIG_SND_CA0106 is not set |
| 892 | # CONFIG_SND_CMIPCI is not set | 1051 | # CONFIG_SND_CMIPCI is not set |
| 1052 | # CONFIG_SND_OXYGEN is not set | ||
| 893 | CONFIG_SND_CS4281=m | 1053 | CONFIG_SND_CS4281=m |
| 894 | CONFIG_SND_CS46XX=m | 1054 | CONFIG_SND_CS46XX=m |
| 895 | CONFIG_SND_CS46XX_NEW_DSP=y | 1055 | CONFIG_SND_CS46XX_NEW_DSP=y |
| @@ -912,10 +1072,10 @@ CONFIG_SND_EMU10K1=m | |||
| 912 | # CONFIG_SND_ES1938 is not set | 1072 | # CONFIG_SND_ES1938 is not set |
| 913 | # CONFIG_SND_ES1968 is not set | 1073 | # CONFIG_SND_ES1968 is not set |
| 914 | CONFIG_SND_FM801=m | 1074 | CONFIG_SND_FM801=m |
| 915 | # CONFIG_SND_FM801_TEA575X_BOOL is not set | ||
| 916 | # CONFIG_SND_HDA_INTEL is not set | 1075 | # CONFIG_SND_HDA_INTEL is not set |
| 917 | # CONFIG_SND_HDSP is not set | 1076 | # CONFIG_SND_HDSP is not set |
| 918 | # CONFIG_SND_HDSPM is not set | 1077 | # CONFIG_SND_HDSPM is not set |
| 1078 | # CONFIG_SND_HIFIER is not set | ||
| 919 | # CONFIG_SND_ICE1712 is not set | 1079 | # CONFIG_SND_ICE1712 is not set |
| 920 | # CONFIG_SND_ICE1724 is not set | 1080 | # CONFIG_SND_ICE1724 is not set |
| 921 | # CONFIG_SND_INTEL8X0 is not set | 1081 | # CONFIG_SND_INTEL8X0 is not set |
| @@ -933,29 +1093,19 @@ CONFIG_SND_FM801=m | |||
| 933 | # CONFIG_SND_TRIDENT is not set | 1093 | # CONFIG_SND_TRIDENT is not set |
| 934 | # CONFIG_SND_VIA82XX is not set | 1094 | # CONFIG_SND_VIA82XX is not set |
| 935 | # CONFIG_SND_VIA82XX_MODEM is not set | 1095 | # CONFIG_SND_VIA82XX_MODEM is not set |
| 1096 | # CONFIG_SND_VIRTUOSO is not set | ||
| 936 | # CONFIG_SND_VX222 is not set | 1097 | # CONFIG_SND_VX222 is not set |
| 937 | # CONFIG_SND_YMFPCI is not set | 1098 | # CONFIG_SND_YMFPCI is not set |
| 938 | # CONFIG_SND_AC97_POWER_SAVE is not set | 1099 | CONFIG_SND_USB=y |
| 939 | |||
| 940 | # | ||
| 941 | # USB devices | ||
| 942 | # | ||
| 943 | # CONFIG_SND_USB_AUDIO is not set | 1100 | # CONFIG_SND_USB_AUDIO is not set |
| 944 | # CONFIG_SND_USB_CAIAQ is not set | 1101 | # CONFIG_SND_USB_CAIAQ is not set |
| 945 | |||
| 946 | # | ||
| 947 | # System on Chip audio support | ||
| 948 | # | ||
| 949 | # CONFIG_SND_SOC is not set | 1102 | # CONFIG_SND_SOC is not set |
| 950 | |||
| 951 | # | ||
| 952 | # Open Sound System | ||
| 953 | # | ||
| 954 | # CONFIG_SOUND_PRIME is not set | 1103 | # CONFIG_SOUND_PRIME is not set |
| 955 | CONFIG_AC97_BUS=m | 1104 | CONFIG_AC97_BUS=m |
| 956 | CONFIG_HID_SUPPORT=y | 1105 | CONFIG_HID_SUPPORT=y |
| 957 | CONFIG_HID=y | 1106 | CONFIG_HID=y |
| 958 | # CONFIG_HID_DEBUG is not set | 1107 | # CONFIG_HID_DEBUG is not set |
| 1108 | # CONFIG_HIDRAW is not set | ||
| 959 | 1109 | ||
| 960 | # | 1110 | # |
| 961 | # USB Input Devices | 1111 | # USB Input Devices |
| @@ -976,6 +1126,7 @@ CONFIG_USB_ARCH_HAS_OHCI=y | |||
| 976 | CONFIG_USB_ARCH_HAS_EHCI=y | 1126 | CONFIG_USB_ARCH_HAS_EHCI=y |
| 977 | CONFIG_USB=m | 1127 | CONFIG_USB=m |
| 978 | # CONFIG_USB_DEBUG is not set | 1128 | # CONFIG_USB_DEBUG is not set |
| 1129 | # CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set | ||
| 979 | 1130 | ||
| 980 | # | 1131 | # |
| 981 | # Miscellaneous USB options | 1132 | # Miscellaneous USB options |
| @@ -984,17 +1135,17 @@ CONFIG_USB_DEVICEFS=y | |||
| 984 | CONFIG_USB_DEVICE_CLASS=y | 1135 | CONFIG_USB_DEVICE_CLASS=y |
| 985 | # CONFIG_USB_DYNAMIC_MINORS is not set | 1136 | # CONFIG_USB_DYNAMIC_MINORS is not set |
| 986 | # CONFIG_USB_SUSPEND is not set | 1137 | # CONFIG_USB_SUSPEND is not set |
| 987 | # CONFIG_USB_PERSIST is not set | ||
| 988 | # CONFIG_USB_OTG is not set | 1138 | # CONFIG_USB_OTG is not set |
| 989 | 1139 | ||
| 990 | # | 1140 | # |
| 991 | # USB Host Controller Drivers | 1141 | # USB Host Controller Drivers |
| 992 | # | 1142 | # |
| 1143 | # CONFIG_USB_C67X00_HCD is not set | ||
| 993 | CONFIG_USB_EHCI_HCD=m | 1144 | CONFIG_USB_EHCI_HCD=m |
| 994 | # CONFIG_USB_EHCI_SPLIT_ISO is not set | ||
| 995 | # CONFIG_USB_EHCI_ROOT_HUB_TT is not set | 1145 | # CONFIG_USB_EHCI_ROOT_HUB_TT is not set |
| 996 | # CONFIG_USB_EHCI_TT_NEWSCHED is not set | 1146 | # CONFIG_USB_EHCI_TT_NEWSCHED is not set |
| 997 | # CONFIG_USB_ISP116X_HCD is not set | 1147 | # CONFIG_USB_ISP116X_HCD is not set |
| 1148 | # CONFIG_USB_ISP1760_HCD is not set | ||
| 998 | CONFIG_USB_OHCI_HCD=m | 1149 | CONFIG_USB_OHCI_HCD=m |
| 999 | # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set | 1150 | # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set |
| 1000 | # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set | 1151 | # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set |
| @@ -1008,6 +1159,7 @@ CONFIG_USB_UHCI_HCD=m | |||
| 1008 | # | 1159 | # |
| 1009 | # CONFIG_USB_ACM is not set | 1160 | # CONFIG_USB_ACM is not set |
| 1010 | # CONFIG_USB_PRINTER is not set | 1161 | # CONFIG_USB_PRINTER is not set |
| 1162 | # CONFIG_USB_WDM is not set | ||
| 1011 | 1163 | ||
| 1012 | # | 1164 | # |
| 1013 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' | 1165 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' |
| @@ -1027,7 +1179,9 @@ CONFIG_USB_STORAGE=m | |||
| 1027 | # CONFIG_USB_STORAGE_SDDR55 is not set | 1179 | # CONFIG_USB_STORAGE_SDDR55 is not set |
| 1028 | # CONFIG_USB_STORAGE_JUMPSHOT is not set | 1180 | # CONFIG_USB_STORAGE_JUMPSHOT is not set |
| 1029 | # CONFIG_USB_STORAGE_ALAUDA is not set | 1181 | # CONFIG_USB_STORAGE_ALAUDA is not set |
| 1182 | # CONFIG_USB_STORAGE_ONETOUCH is not set | ||
| 1030 | # CONFIG_USB_STORAGE_KARMA is not set | 1183 | # CONFIG_USB_STORAGE_KARMA is not set |
| 1184 | # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set | ||
| 1031 | # CONFIG_USB_LIBUSUAL is not set | 1185 | # CONFIG_USB_LIBUSUAL is not set |
| 1032 | 1186 | ||
| 1033 | # | 1187 | # |
| @@ -1040,10 +1194,6 @@ CONFIG_USB_MON=y | |||
| 1040 | # | 1194 | # |
| 1041 | # USB port drivers | 1195 | # USB port drivers |
| 1042 | # | 1196 | # |
| 1043 | |||
| 1044 | # | ||
| 1045 | # USB Serial Converter support | ||
| 1046 | # | ||
| 1047 | # CONFIG_USB_SERIAL is not set | 1197 | # CONFIG_USB_SERIAL is not set |
| 1048 | 1198 | ||
| 1049 | # | 1199 | # |
| @@ -1069,67 +1219,32 @@ CONFIG_USB_MON=y | |||
| 1069 | # CONFIG_USB_TRANCEVIBRATOR is not set | 1219 | # CONFIG_USB_TRANCEVIBRATOR is not set |
| 1070 | # CONFIG_USB_IOWARRIOR is not set | 1220 | # CONFIG_USB_IOWARRIOR is not set |
| 1071 | # CONFIG_USB_TEST is not set | 1221 | # CONFIG_USB_TEST is not set |
| 1072 | 1222 | # CONFIG_USB_ISIGHTFW is not set | |
| 1073 | # | ||
| 1074 | # USB DSL modem support | ||
| 1075 | # | ||
| 1076 | |||
| 1077 | # | ||
| 1078 | # USB Gadget Support | ||
| 1079 | # | ||
| 1080 | # CONFIG_USB_GADGET is not set | 1223 | # CONFIG_USB_GADGET is not set |
| 1081 | # CONFIG_MMC is not set | 1224 | # CONFIG_MMC is not set |
| 1082 | 1225 | # CONFIG_MEMSTICK is not set | |
| 1083 | # | ||
| 1084 | # LED devices | ||
| 1085 | # | ||
| 1086 | # CONFIG_NEW_LEDS is not set | 1226 | # CONFIG_NEW_LEDS is not set |
| 1087 | 1227 | # CONFIG_ACCESSIBILITY is not set | |
| 1088 | # | ||
| 1089 | # LED drivers | ||
| 1090 | # | ||
| 1091 | |||
| 1092 | # | ||
| 1093 | # LED Triggers | ||
| 1094 | # | ||
| 1095 | CONFIG_INFINIBAND=m | 1228 | CONFIG_INFINIBAND=m |
| 1096 | # CONFIG_INFINIBAND_USER_MAD is not set | 1229 | # CONFIG_INFINIBAND_USER_MAD is not set |
| 1097 | # CONFIG_INFINIBAND_USER_ACCESS is not set | 1230 | # CONFIG_INFINIBAND_USER_ACCESS is not set |
| 1098 | CONFIG_INFINIBAND_ADDR_TRANS=y | 1231 | CONFIG_INFINIBAND_ADDR_TRANS=y |
| 1099 | CONFIG_INFINIBAND_MTHCA=m | 1232 | CONFIG_INFINIBAND_MTHCA=m |
| 1100 | CONFIG_INFINIBAND_MTHCA_DEBUG=y | 1233 | CONFIG_INFINIBAND_MTHCA_DEBUG=y |
| 1234 | # CONFIG_INFINIBAND_IPATH is not set | ||
| 1101 | # CONFIG_INFINIBAND_AMSO1100 is not set | 1235 | # CONFIG_INFINIBAND_AMSO1100 is not set |
| 1102 | # CONFIG_MLX4_INFINIBAND is not set | 1236 | # CONFIG_MLX4_INFINIBAND is not set |
| 1237 | # CONFIG_INFINIBAND_NES is not set | ||
| 1103 | CONFIG_INFINIBAND_IPOIB=m | 1238 | CONFIG_INFINIBAND_IPOIB=m |
| 1104 | # CONFIG_INFINIBAND_IPOIB_CM is not set | 1239 | # CONFIG_INFINIBAND_IPOIB_CM is not set |
| 1105 | CONFIG_INFINIBAND_IPOIB_DEBUG=y | 1240 | CONFIG_INFINIBAND_IPOIB_DEBUG=y |
| 1106 | # CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set | 1241 | # CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set |
| 1107 | # CONFIG_INFINIBAND_SRP is not set | 1242 | # CONFIG_INFINIBAND_SRP is not set |
| 1108 | # CONFIG_INFINIBAND_ISER is not set | 1243 | # CONFIG_INFINIBAND_ISER is not set |
| 1109 | |||
| 1110 | # | ||
| 1111 | # Real Time Clock | ||
| 1112 | # | ||
| 1113 | # CONFIG_RTC_CLASS is not set | 1244 | # CONFIG_RTC_CLASS is not set |
| 1114 | 1245 | # CONFIG_DMADEVICES is not set | |
| 1115 | # | ||
| 1116 | # DMA Engine support | ||
| 1117 | # | ||
| 1118 | # CONFIG_DMA_ENGINE is not set | ||
| 1119 | |||
| 1120 | # | ||
| 1121 | # DMA Clients | ||
| 1122 | # | ||
| 1123 | |||
| 1124 | # | ||
| 1125 | # DMA Devices | ||
| 1126 | # | ||
| 1127 | |||
| 1128 | # | ||
| 1129 | # Userspace I/O | ||
| 1130 | # | ||
| 1131 | # CONFIG_UIO is not set | 1246 | # CONFIG_UIO is not set |
| 1132 | # CONFIG_MSPEC is not set | 1247 | CONFIG_MSPEC=m |
| 1133 | 1248 | ||
| 1134 | # | 1249 | # |
| 1135 | # File systems | 1250 | # File systems |
| @@ -1145,7 +1260,6 @@ CONFIG_EXT3_FS_POSIX_ACL=y | |||
| 1145 | CONFIG_EXT3_FS_SECURITY=y | 1260 | CONFIG_EXT3_FS_SECURITY=y |
| 1146 | # CONFIG_EXT4DEV_FS is not set | 1261 | # CONFIG_EXT4DEV_FS is not set |
| 1147 | CONFIG_JBD=y | 1262 | CONFIG_JBD=y |
| 1148 | # CONFIG_JBD_DEBUG is not set | ||
| 1149 | CONFIG_FS_MBCACHE=y | 1263 | CONFIG_FS_MBCACHE=y |
| 1150 | CONFIG_REISERFS_FS=y | 1264 | CONFIG_REISERFS_FS=y |
| 1151 | # CONFIG_REISERFS_CHECK is not set | 1265 | # CONFIG_REISERFS_CHECK is not set |
| @@ -1157,17 +1271,15 @@ CONFIG_REISERFS_FS_SECURITY=y | |||
| 1157 | CONFIG_FS_POSIX_ACL=y | 1271 | CONFIG_FS_POSIX_ACL=y |
| 1158 | CONFIG_XFS_FS=y | 1272 | CONFIG_XFS_FS=y |
| 1159 | # CONFIG_XFS_QUOTA is not set | 1273 | # CONFIG_XFS_QUOTA is not set |
| 1160 | # CONFIG_XFS_SECURITY is not set | ||
| 1161 | # CONFIG_XFS_POSIX_ACL is not set | 1274 | # CONFIG_XFS_POSIX_ACL is not set |
| 1162 | # CONFIG_XFS_RT is not set | 1275 | # CONFIG_XFS_RT is not set |
| 1276 | # CONFIG_XFS_DEBUG is not set | ||
| 1163 | # CONFIG_GFS2_FS is not set | 1277 | # CONFIG_GFS2_FS is not set |
| 1164 | # CONFIG_OCFS2_FS is not set | 1278 | # CONFIG_OCFS2_FS is not set |
| 1165 | # CONFIG_MINIX_FS is not set | 1279 | CONFIG_DNOTIFY=y |
| 1166 | # CONFIG_ROMFS_FS is not set | ||
| 1167 | CONFIG_INOTIFY=y | 1280 | CONFIG_INOTIFY=y |
| 1168 | CONFIG_INOTIFY_USER=y | 1281 | CONFIG_INOTIFY_USER=y |
| 1169 | # CONFIG_QUOTA is not set | 1282 | # CONFIG_QUOTA is not set |
| 1170 | CONFIG_DNOTIFY=y | ||
| 1171 | CONFIG_AUTOFS_FS=y | 1283 | CONFIG_AUTOFS_FS=y |
| 1172 | CONFIG_AUTOFS4_FS=y | 1284 | CONFIG_AUTOFS4_FS=y |
| 1173 | # CONFIG_FUSE_FS is not set | 1285 | # CONFIG_FUSE_FS is not set |
| @@ -1205,7 +1317,6 @@ CONFIG_TMPFS=y | |||
| 1205 | # CONFIG_TMPFS_POSIX_ACL is not set | 1317 | # CONFIG_TMPFS_POSIX_ACL is not set |
| 1206 | CONFIG_HUGETLBFS=y | 1318 | CONFIG_HUGETLBFS=y |
| 1207 | CONFIG_HUGETLB_PAGE=y | 1319 | CONFIG_HUGETLB_PAGE=y |
| 1208 | CONFIG_RAMFS=y | ||
| 1209 | # CONFIG_CONFIGFS_FS is not set | 1320 | # CONFIG_CONFIGFS_FS is not set |
| 1210 | 1321 | ||
| 1211 | # | 1322 | # |
| @@ -1220,32 +1331,30 @@ CONFIG_RAMFS=y | |||
| 1220 | # CONFIG_EFS_FS is not set | 1331 | # CONFIG_EFS_FS is not set |
| 1221 | # CONFIG_CRAMFS is not set | 1332 | # CONFIG_CRAMFS is not set |
| 1222 | # CONFIG_VXFS_FS is not set | 1333 | # CONFIG_VXFS_FS is not set |
| 1334 | # CONFIG_MINIX_FS is not set | ||
| 1335 | # CONFIG_OMFS_FS is not set | ||
| 1223 | # CONFIG_HPFS_FS is not set | 1336 | # CONFIG_HPFS_FS is not set |
| 1224 | # CONFIG_QNX4FS_FS is not set | 1337 | # CONFIG_QNX4FS_FS is not set |
| 1338 | # CONFIG_ROMFS_FS is not set | ||
| 1225 | # CONFIG_SYSV_FS is not set | 1339 | # CONFIG_SYSV_FS is not set |
| 1226 | # CONFIG_UFS_FS is not set | 1340 | # CONFIG_UFS_FS is not set |
| 1227 | 1341 | CONFIG_NETWORK_FILESYSTEMS=y | |
| 1228 | # | ||
| 1229 | # Network File Systems | ||
| 1230 | # | ||
| 1231 | CONFIG_NFS_FS=m | 1342 | CONFIG_NFS_FS=m |
| 1232 | CONFIG_NFS_V3=y | 1343 | CONFIG_NFS_V3=y |
| 1233 | # CONFIG_NFS_V3_ACL is not set | 1344 | # CONFIG_NFS_V3_ACL is not set |
| 1234 | CONFIG_NFS_V4=y | 1345 | CONFIG_NFS_V4=y |
| 1235 | CONFIG_NFS_DIRECTIO=y | ||
| 1236 | CONFIG_NFSD=m | 1346 | CONFIG_NFSD=m |
| 1237 | CONFIG_NFSD_V3=y | 1347 | CONFIG_NFSD_V3=y |
| 1238 | # CONFIG_NFSD_V3_ACL is not set | 1348 | # CONFIG_NFSD_V3_ACL is not set |
| 1239 | CONFIG_NFSD_V4=y | 1349 | CONFIG_NFSD_V4=y |
| 1240 | CONFIG_NFSD_TCP=y | ||
| 1241 | CONFIG_LOCKD=m | 1350 | CONFIG_LOCKD=m |
| 1242 | CONFIG_LOCKD_V4=y | 1351 | CONFIG_LOCKD_V4=y |
| 1243 | CONFIG_EXPORTFS=m | 1352 | CONFIG_EXPORTFS=m |
| 1244 | CONFIG_NFS_COMMON=y | 1353 | CONFIG_NFS_COMMON=y |
| 1245 | CONFIG_SUNRPC=m | 1354 | CONFIG_SUNRPC=m |
| 1246 | CONFIG_SUNRPC_GSS=m | 1355 | CONFIG_SUNRPC_GSS=m |
| 1247 | # CONFIG_SUNRPC_BIND34 is not set | 1356 | CONFIG_SUNRPC_XPRT_RDMA=m |
| 1248 | CONFIG_RPCSEC_GSS_KRB5=y | 1357 | CONFIG_RPCSEC_GSS_KRB5=m |
| 1249 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | 1358 | # CONFIG_RPCSEC_GSS_SPKM3 is not set |
| 1250 | CONFIG_SMB_FS=m | 1359 | CONFIG_SMB_FS=m |
| 1251 | CONFIG_SMB_NLS_DEFAULT=y | 1360 | CONFIG_SMB_NLS_DEFAULT=y |
| @@ -1281,10 +1390,6 @@ CONFIG_SGI_PARTITION=y | |||
| 1281 | # CONFIG_KARMA_PARTITION is not set | 1390 | # CONFIG_KARMA_PARTITION is not set |
| 1282 | CONFIG_EFI_PARTITION=y | 1391 | CONFIG_EFI_PARTITION=y |
| 1283 | # CONFIG_SYSV68_PARTITION is not set | 1392 | # CONFIG_SYSV68_PARTITION is not set |
| 1284 | |||
| 1285 | # | ||
| 1286 | # Native Language Support | ||
| 1287 | # | ||
| 1288 | CONFIG_NLS=y | 1393 | CONFIG_NLS=y |
| 1289 | CONFIG_NLS_DEFAULT="iso8859-1" | 1394 | CONFIG_NLS_DEFAULT="iso8859-1" |
| 1290 | CONFIG_NLS_CODEPAGE_437=y | 1395 | CONFIG_NLS_CODEPAGE_437=y |
| @@ -1325,22 +1430,24 @@ CONFIG_NLS_ISO8859_15=m | |||
| 1325 | CONFIG_NLS_KOI8_R=m | 1430 | CONFIG_NLS_KOI8_R=m |
| 1326 | CONFIG_NLS_KOI8_U=m | 1431 | CONFIG_NLS_KOI8_U=m |
| 1327 | CONFIG_NLS_UTF8=m | 1432 | CONFIG_NLS_UTF8=m |
| 1328 | |||
| 1329 | # | ||
| 1330 | # Distributed Lock Manager | ||
| 1331 | # | ||
| 1332 | # CONFIG_DLM is not set | 1433 | # CONFIG_DLM is not set |
| 1434 | CONFIG_HAVE_KVM=y | ||
| 1435 | CONFIG_VIRTUALIZATION=y | ||
| 1436 | # CONFIG_KVM is not set | ||
| 1333 | 1437 | ||
| 1334 | # | 1438 | # |
| 1335 | # Library routines | 1439 | # Library routines |
| 1336 | # | 1440 | # |
| 1337 | CONFIG_BITREVERSE=y | 1441 | CONFIG_BITREVERSE=y |
| 1442 | # CONFIG_GENERIC_FIND_FIRST_BIT is not set | ||
| 1338 | # CONFIG_CRC_CCITT is not set | 1443 | # CONFIG_CRC_CCITT is not set |
| 1339 | # CONFIG_CRC16 is not set | 1444 | # CONFIG_CRC16 is not set |
| 1340 | # CONFIG_CRC_ITU_T is not set | 1445 | CONFIG_CRC_T10DIF=y |
| 1446 | CONFIG_CRC_ITU_T=m | ||
| 1341 | CONFIG_CRC32=y | 1447 | CONFIG_CRC32=y |
| 1342 | # CONFIG_CRC7 is not set | 1448 | # CONFIG_CRC7 is not set |
| 1343 | # CONFIG_LIBCRC32C is not set | 1449 | # CONFIG_LIBCRC32C is not set |
| 1450 | CONFIG_GENERIC_ALLOCATOR=y | ||
| 1344 | CONFIG_PLIST=y | 1451 | CONFIG_PLIST=y |
| 1345 | CONFIG_HAS_IOMEM=y | 1452 | CONFIG_HAS_IOMEM=y |
| 1346 | CONFIG_HAS_IOPORT=y | 1453 | CONFIG_HAS_IOPORT=y |
| @@ -1358,16 +1465,12 @@ CONFIG_IRQ_PER_CPU=y | |||
| 1358 | # CONFIG_HP_SIMSCSI is not set | 1465 | # CONFIG_HP_SIMSCSI is not set |
| 1359 | 1466 | ||
| 1360 | # | 1467 | # |
| 1361 | # Instrumentation Support | ||
| 1362 | # | ||
| 1363 | # CONFIG_PROFILING is not set | ||
| 1364 | # CONFIG_KPROBES is not set | ||
| 1365 | |||
| 1366 | # | ||
| 1367 | # Kernel hacking | 1468 | # Kernel hacking |
| 1368 | # | 1469 | # |
| 1369 | # CONFIG_PRINTK_TIME is not set | 1470 | # CONFIG_PRINTK_TIME is not set |
| 1471 | CONFIG_ENABLE_WARN_DEPRECATED=y | ||
| 1370 | CONFIG_ENABLE_MUST_CHECK=y | 1472 | CONFIG_ENABLE_MUST_CHECK=y |
| 1473 | CONFIG_FRAME_WARN=2048 | ||
| 1371 | CONFIG_MAGIC_SYSRQ=y | 1474 | CONFIG_MAGIC_SYSRQ=y |
| 1372 | # CONFIG_UNUSED_SYMBOLS is not set | 1475 | # CONFIG_UNUSED_SYMBOLS is not set |
| 1373 | # CONFIG_DEBUG_FS is not set | 1476 | # CONFIG_DEBUG_FS is not set |
| @@ -1375,10 +1478,14 @@ CONFIG_MAGIC_SYSRQ=y | |||
| 1375 | CONFIG_DEBUG_KERNEL=y | 1478 | CONFIG_DEBUG_KERNEL=y |
| 1376 | # CONFIG_DEBUG_SHIRQ is not set | 1479 | # CONFIG_DEBUG_SHIRQ is not set |
| 1377 | CONFIG_DETECT_SOFTLOCKUP=y | 1480 | CONFIG_DETECT_SOFTLOCKUP=y |
| 1481 | # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set | ||
| 1482 | CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 | ||
| 1378 | CONFIG_SCHED_DEBUG=y | 1483 | CONFIG_SCHED_DEBUG=y |
| 1379 | # CONFIG_SCHEDSTATS is not set | 1484 | # CONFIG_SCHEDSTATS is not set |
| 1380 | # CONFIG_TIMER_STATS is not set | 1485 | # CONFIG_TIMER_STATS is not set |
| 1381 | # CONFIG_DEBUG_SLAB is not set | 1486 | # CONFIG_DEBUG_OBJECTS is not set |
| 1487 | # CONFIG_SLUB_DEBUG_ON is not set | ||
| 1488 | # CONFIG_SLUB_STATS is not set | ||
| 1382 | # CONFIG_DEBUG_RT_MUTEXES is not set | 1489 | # CONFIG_DEBUG_RT_MUTEXES is not set |
| 1383 | # CONFIG_RT_MUTEX_TESTER is not set | 1490 | # CONFIG_RT_MUTEX_TESTER is not set |
| 1384 | # CONFIG_DEBUG_SPINLOCK is not set | 1491 | # CONFIG_DEBUG_SPINLOCK is not set |
| @@ -1388,10 +1495,15 @@ CONFIG_DEBUG_MUTEXES=y | |||
| 1388 | # CONFIG_DEBUG_KOBJECT is not set | 1495 | # CONFIG_DEBUG_KOBJECT is not set |
| 1389 | # CONFIG_DEBUG_INFO is not set | 1496 | # CONFIG_DEBUG_INFO is not set |
| 1390 | # CONFIG_DEBUG_VM is not set | 1497 | # CONFIG_DEBUG_VM is not set |
| 1498 | # CONFIG_DEBUG_WRITECOUNT is not set | ||
| 1499 | CONFIG_DEBUG_MEMORY_INIT=y | ||
| 1391 | # CONFIG_DEBUG_LIST is not set | 1500 | # CONFIG_DEBUG_LIST is not set |
| 1392 | CONFIG_FORCED_INLINING=y | 1501 | # CONFIG_DEBUG_SG is not set |
| 1502 | # CONFIG_BOOT_PRINTK_DELAY is not set | ||
| 1393 | # CONFIG_RCU_TORTURE_TEST is not set | 1503 | # CONFIG_RCU_TORTURE_TEST is not set |
| 1504 | # CONFIG_BACKTRACE_SELF_TEST is not set | ||
| 1394 | # CONFIG_FAULT_INJECTION is not set | 1505 | # CONFIG_FAULT_INJECTION is not set |
| 1506 | # CONFIG_SAMPLES is not set | ||
| 1395 | CONFIG_IA64_GRANULE_16MB=y | 1507 | CONFIG_IA64_GRANULE_16MB=y |
| 1396 | # CONFIG_IA64_GRANULE_64MB is not set | 1508 | # CONFIG_IA64_GRANULE_64MB is not set |
| 1397 | # CONFIG_IA64_PRINT_HAZARDS is not set | 1509 | # CONFIG_IA64_PRINT_HAZARDS is not set |
| @@ -1405,41 +1517,85 @@ CONFIG_SYSVIPC_COMPAT=y | |||
| 1405 | # | 1517 | # |
| 1406 | # CONFIG_KEYS is not set | 1518 | # CONFIG_KEYS is not set |
| 1407 | # CONFIG_SECURITY is not set | 1519 | # CONFIG_SECURITY is not set |
| 1520 | # CONFIG_SECURITY_FILE_CAPABILITIES is not set | ||
| 1408 | CONFIG_CRYPTO=y | 1521 | CONFIG_CRYPTO=y |
| 1522 | |||
| 1523 | # | ||
| 1524 | # Crypto core or helper | ||
| 1525 | # | ||
| 1409 | CONFIG_CRYPTO_ALGAPI=y | 1526 | CONFIG_CRYPTO_ALGAPI=y |
| 1410 | CONFIG_CRYPTO_BLKCIPHER=m | 1527 | CONFIG_CRYPTO_BLKCIPHER=m |
| 1411 | CONFIG_CRYPTO_MANAGER=m | 1528 | CONFIG_CRYPTO_MANAGER=m |
| 1529 | # CONFIG_CRYPTO_GF128MUL is not set | ||
| 1530 | # CONFIG_CRYPTO_NULL is not set | ||
| 1531 | # CONFIG_CRYPTO_CRYPTD is not set | ||
| 1532 | # CONFIG_CRYPTO_AUTHENC is not set | ||
| 1533 | # CONFIG_CRYPTO_TEST is not set | ||
| 1534 | |||
| 1535 | # | ||
| 1536 | # Authenticated Encryption with Associated Data | ||
| 1537 | # | ||
| 1538 | # CONFIG_CRYPTO_CCM is not set | ||
| 1539 | # CONFIG_CRYPTO_GCM is not set | ||
| 1540 | # CONFIG_CRYPTO_SEQIV is not set | ||
| 1541 | |||
| 1542 | # | ||
| 1543 | # Block modes | ||
| 1544 | # | ||
| 1545 | CONFIG_CRYPTO_CBC=m | ||
| 1546 | # CONFIG_CRYPTO_CTR is not set | ||
| 1547 | # CONFIG_CRYPTO_CTS is not set | ||
| 1548 | CONFIG_CRYPTO_ECB=m | ||
| 1549 | # CONFIG_CRYPTO_LRW is not set | ||
| 1550 | CONFIG_CRYPTO_PCBC=m | ||
| 1551 | # CONFIG_CRYPTO_XTS is not set | ||
| 1552 | |||
| 1553 | # | ||
| 1554 | # Hash modes | ||
| 1555 | # | ||
| 1412 | # CONFIG_CRYPTO_HMAC is not set | 1556 | # CONFIG_CRYPTO_HMAC is not set |
| 1413 | # CONFIG_CRYPTO_XCBC is not set | 1557 | # CONFIG_CRYPTO_XCBC is not set |
| 1414 | # CONFIG_CRYPTO_NULL is not set | 1558 | |
| 1559 | # | ||
| 1560 | # Digest | ||
| 1561 | # | ||
| 1562 | # CONFIG_CRYPTO_CRC32C is not set | ||
| 1415 | # CONFIG_CRYPTO_MD4 is not set | 1563 | # CONFIG_CRYPTO_MD4 is not set |
| 1416 | CONFIG_CRYPTO_MD5=y | 1564 | CONFIG_CRYPTO_MD5=y |
| 1565 | # CONFIG_CRYPTO_MICHAEL_MIC is not set | ||
| 1566 | # CONFIG_CRYPTO_RMD128 is not set | ||
| 1567 | # CONFIG_CRYPTO_RMD160 is not set | ||
| 1568 | # CONFIG_CRYPTO_RMD256 is not set | ||
| 1569 | # CONFIG_CRYPTO_RMD320 is not set | ||
| 1417 | # CONFIG_CRYPTO_SHA1 is not set | 1570 | # CONFIG_CRYPTO_SHA1 is not set |
| 1418 | # CONFIG_CRYPTO_SHA256 is not set | 1571 | # CONFIG_CRYPTO_SHA256 is not set |
| 1419 | # CONFIG_CRYPTO_SHA512 is not set | 1572 | # CONFIG_CRYPTO_SHA512 is not set |
| 1420 | # CONFIG_CRYPTO_WP512 is not set | ||
| 1421 | # CONFIG_CRYPTO_TGR192 is not set | 1573 | # CONFIG_CRYPTO_TGR192 is not set |
| 1422 | # CONFIG_CRYPTO_GF128MUL is not set | 1574 | # CONFIG_CRYPTO_WP512 is not set |
| 1423 | CONFIG_CRYPTO_ECB=m | 1575 | |
| 1424 | CONFIG_CRYPTO_CBC=m | 1576 | # |
| 1425 | CONFIG_CRYPTO_PCBC=m | 1577 | # Ciphers |
| 1426 | # CONFIG_CRYPTO_LRW is not set | 1578 | # |
| 1427 | # CONFIG_CRYPTO_CRYPTD is not set | ||
| 1428 | CONFIG_CRYPTO_DES=m | ||
| 1429 | # CONFIG_CRYPTO_FCRYPT is not set | ||
| 1430 | # CONFIG_CRYPTO_BLOWFISH is not set | ||
| 1431 | # CONFIG_CRYPTO_TWOFISH is not set | ||
| 1432 | # CONFIG_CRYPTO_SERPENT is not set | ||
| 1433 | # CONFIG_CRYPTO_AES is not set | 1579 | # CONFIG_CRYPTO_AES is not set |
| 1580 | # CONFIG_CRYPTO_ANUBIS is not set | ||
| 1581 | # CONFIG_CRYPTO_ARC4 is not set | ||
| 1582 | # CONFIG_CRYPTO_BLOWFISH is not set | ||
| 1583 | # CONFIG_CRYPTO_CAMELLIA is not set | ||
| 1434 | # CONFIG_CRYPTO_CAST5 is not set | 1584 | # CONFIG_CRYPTO_CAST5 is not set |
| 1435 | # CONFIG_CRYPTO_CAST6 is not set | 1585 | # CONFIG_CRYPTO_CAST6 is not set |
| 1436 | # CONFIG_CRYPTO_TEA is not set | 1586 | CONFIG_CRYPTO_DES=m |
| 1437 | # CONFIG_CRYPTO_ARC4 is not set | 1587 | # CONFIG_CRYPTO_FCRYPT is not set |
| 1438 | # CONFIG_CRYPTO_KHAZAD is not set | 1588 | # CONFIG_CRYPTO_KHAZAD is not set |
| 1439 | # CONFIG_CRYPTO_ANUBIS is not set | 1589 | # CONFIG_CRYPTO_SALSA20 is not set |
| 1590 | # CONFIG_CRYPTO_SEED is not set | ||
| 1591 | # CONFIG_CRYPTO_SERPENT is not set | ||
| 1592 | # CONFIG_CRYPTO_TEA is not set | ||
| 1593 | # CONFIG_CRYPTO_TWOFISH is not set | ||
| 1594 | |||
| 1595 | # | ||
| 1596 | # Compression | ||
| 1597 | # | ||
| 1440 | # CONFIG_CRYPTO_DEFLATE is not set | 1598 | # CONFIG_CRYPTO_DEFLATE is not set |
| 1441 | # CONFIG_CRYPTO_MICHAEL_MIC is not set | 1599 | # CONFIG_CRYPTO_LZO is not set |
| 1442 | # CONFIG_CRYPTO_CRC32C is not set | ||
| 1443 | # CONFIG_CRYPTO_CAMELLIA is not set | ||
| 1444 | # CONFIG_CRYPTO_TEST is not set | ||
| 1445 | CONFIG_CRYPTO_HW=y | 1600 | CONFIG_CRYPTO_HW=y |
| 1601 | # CONFIG_CRYPTO_DEV_HIFN_795X is not set | ||
diff --git a/arch/ia64/kernel/.gitignore b/arch/ia64/kernel/.gitignore index 98307759a3b8..21cb0da5ded8 100644 --- a/arch/ia64/kernel/.gitignore +++ b/arch/ia64/kernel/.gitignore | |||
| @@ -1 +1,2 @@ | |||
| 1 | gate.lds | 1 | gate.lds |
| 2 | vmlinux.lds | ||
diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index c39627df3cde..416a952b19bd 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S | |||
| @@ -1243,11 +1243,11 @@ ENTRY(speculation_vector) | |||
| 1243 | 1243 | ||
| 1244 | add r17=r17,r18 // now add the offset | 1244 | add r17=r17,r18 // now add the offset |
| 1245 | ;; | 1245 | ;; |
| 1246 | MOV_FROM_IIP(r17) | 1246 | MOV_TO_IIP(r17, r19) |
| 1247 | dep r16=0,r16,41,2 // clear EI | 1247 | dep r16=0,r16,41,2 // clear EI |
| 1248 | ;; | 1248 | ;; |
| 1249 | 1249 | ||
| 1250 | MOV_FROM_IPSR(p0, r16) | 1250 | MOV_TO_IPSR(p0, r16, r19) |
| 1251 | ;; | 1251 | ;; |
| 1252 | 1252 | ||
| 1253 | RFI | 1253 | RFI |
diff --git a/include/asm-m68knommu/Kbuild b/arch/m68knommu/include/asm/Kbuild index c68e1680da01..c68e1680da01 100644 --- a/include/asm-m68knommu/Kbuild +++ b/arch/m68knommu/include/asm/Kbuild | |||
diff --git a/include/asm-m68knommu/MC68328.h b/arch/m68knommu/include/asm/MC68328.h index a337e56d09bf..a337e56d09bf 100644 --- a/include/asm-m68knommu/MC68328.h +++ b/arch/m68knommu/include/asm/MC68328.h | |||
diff --git a/include/asm-m68knommu/MC68332.h b/arch/m68knommu/include/asm/MC68332.h index 6bb8f02685a2..6bb8f02685a2 100644 --- a/include/asm-m68knommu/MC68332.h +++ b/arch/m68knommu/include/asm/MC68332.h | |||
diff --git a/include/asm-m68knommu/MC68EZ328.h b/arch/m68knommu/include/asm/MC68EZ328.h index 69b7f9139e5e..69b7f9139e5e 100644 --- a/include/asm-m68knommu/MC68EZ328.h +++ b/arch/m68knommu/include/asm/MC68EZ328.h | |||
diff --git a/include/asm-m68knommu/MC68VZ328.h b/arch/m68knommu/include/asm/MC68VZ328.h index 2b9bf626a0a5..2b9bf626a0a5 100644 --- a/include/asm-m68knommu/MC68VZ328.h +++ b/arch/m68knommu/include/asm/MC68VZ328.h | |||
diff --git a/include/asm-m68knommu/a.out.h b/arch/m68knommu/include/asm/a.out.h index ce18ef99de04..ce18ef99de04 100644 --- a/include/asm-m68knommu/a.out.h +++ b/arch/m68knommu/include/asm/a.out.h | |||
diff --git a/include/asm-m68knommu/anchor.h b/arch/m68knommu/include/asm/anchor.h index 871c0d5cfc3d..871c0d5cfc3d 100644 --- a/include/asm-m68knommu/anchor.h +++ b/arch/m68knommu/include/asm/anchor.h | |||
diff --git a/include/asm-m68knommu/atomic.h b/arch/m68knommu/include/asm/atomic.h index d5632a305dae..d5632a305dae 100644 --- a/include/asm-m68knommu/atomic.h +++ b/arch/m68knommu/include/asm/atomic.h | |||
diff --git a/include/asm-m68knommu/auxvec.h b/arch/m68knommu/include/asm/auxvec.h index 844d6d52204b..844d6d52204b 100644 --- a/include/asm-m68knommu/auxvec.h +++ b/arch/m68knommu/include/asm/auxvec.h | |||
diff --git a/include/asm-m68knommu/bitops.h b/arch/m68knommu/include/asm/bitops.h index 6f3685eab44c..6f3685eab44c 100644 --- a/include/asm-m68knommu/bitops.h +++ b/arch/m68knommu/include/asm/bitops.h | |||
diff --git a/include/asm-m68knommu/bootinfo.h b/arch/m68knommu/include/asm/bootinfo.h index c12e526f5189..c12e526f5189 100644 --- a/include/asm-m68knommu/bootinfo.h +++ b/arch/m68knommu/include/asm/bootinfo.h | |||
diff --git a/include/asm-m68knommu/bootstd.h b/arch/m68knommu/include/asm/bootstd.h index bdc1a4ac4fe9..bdc1a4ac4fe9 100644 --- a/include/asm-m68knommu/bootstd.h +++ b/arch/m68knommu/include/asm/bootstd.h | |||
diff --git a/include/asm-m68knommu/bug.h b/arch/m68knommu/include/asm/bug.h index 70e7dc0af21a..70e7dc0af21a 100644 --- a/include/asm-m68knommu/bug.h +++ b/arch/m68knommu/include/asm/bug.h | |||
diff --git a/include/asm-m68knommu/bugs.h b/arch/m68knommu/include/asm/bugs.h index 5f382dac3a60..5f382dac3a60 100644 --- a/include/asm-m68knommu/bugs.h +++ b/arch/m68knommu/include/asm/bugs.h | |||
diff --git a/include/asm-m68knommu/byteorder.h b/arch/m68knommu/include/asm/byteorder.h index 20bb4426b610..20bb4426b610 100644 --- a/include/asm-m68knommu/byteorder.h +++ b/arch/m68knommu/include/asm/byteorder.h | |||
diff --git a/include/asm-m68knommu/cache.h b/arch/m68knommu/include/asm/cache.h index 24e9eace5f8c..24e9eace5f8c 100644 --- a/include/asm-m68knommu/cache.h +++ b/arch/m68knommu/include/asm/cache.h | |||
diff --git a/include/asm-m68knommu/cachectl.h b/arch/m68knommu/include/asm/cachectl.h index bcf5a6a9dd52..bcf5a6a9dd52 100644 --- a/include/asm-m68knommu/cachectl.h +++ b/arch/m68knommu/include/asm/cachectl.h | |||
diff --git a/include/asm-m68knommu/cacheflush.h b/arch/m68knommu/include/asm/cacheflush.h index 87e5dc0413b4..87e5dc0413b4 100644 --- a/include/asm-m68knommu/cacheflush.h +++ b/arch/m68knommu/include/asm/cacheflush.h | |||
diff --git a/include/asm-m68knommu/checksum.h b/arch/m68knommu/include/asm/checksum.h index 81883482ffb1..81883482ffb1 100644 --- a/include/asm-m68knommu/checksum.h +++ b/arch/m68knommu/include/asm/checksum.h | |||
diff --git a/include/asm-m68knommu/coldfire.h b/arch/m68knommu/include/asm/coldfire.h index 83a9fa4e618a..83a9fa4e618a 100644 --- a/include/asm-m68knommu/coldfire.h +++ b/arch/m68knommu/include/asm/coldfire.h | |||
diff --git a/include/asm-m68knommu/commproc.h b/arch/m68knommu/include/asm/commproc.h index edf5eb6c08d2..edf5eb6c08d2 100644 --- a/include/asm-m68knommu/commproc.h +++ b/arch/m68knommu/include/asm/commproc.h | |||
diff --git a/include/asm-m68knommu/cputime.h b/arch/m68knommu/include/asm/cputime.h index a0c4a660878d..a0c4a660878d 100644 --- a/include/asm-m68knommu/cputime.h +++ b/arch/m68knommu/include/asm/cputime.h | |||
diff --git a/include/asm-m68knommu/current.h b/arch/m68knommu/include/asm/current.h index 53ee0f9f7cef..53ee0f9f7cef 100644 --- a/include/asm-m68knommu/current.h +++ b/arch/m68knommu/include/asm/current.h | |||
diff --git a/include/asm-m68knommu/dbg.h b/arch/m68knommu/include/asm/dbg.h index 27af3270f671..27af3270f671 100644 --- a/include/asm-m68knommu/dbg.h +++ b/arch/m68knommu/include/asm/dbg.h | |||
diff --git a/include/asm-m68knommu/delay.h b/arch/m68knommu/include/asm/delay.h index 55cbd6294ab6..55cbd6294ab6 100644 --- a/include/asm-m68knommu/delay.h +++ b/arch/m68knommu/include/asm/delay.h | |||
diff --git a/include/asm-m68knommu/device.h b/arch/m68knommu/include/asm/device.h index d8f9872b0e2d..d8f9872b0e2d 100644 --- a/include/asm-m68knommu/device.h +++ b/arch/m68knommu/include/asm/device.h | |||
diff --git a/include/asm-m68knommu/div64.h b/arch/m68knommu/include/asm/div64.h index 6cd978cefb28..6cd978cefb28 100644 --- a/include/asm-m68knommu/div64.h +++ b/arch/m68knommu/include/asm/div64.h | |||
diff --git a/include/asm-m68knommu/dma-mapping.h b/arch/m68knommu/include/asm/dma-mapping.h index 6aeab18e58bd..6aeab18e58bd 100644 --- a/include/asm-m68knommu/dma-mapping.h +++ b/arch/m68knommu/include/asm/dma-mapping.h | |||
diff --git a/include/asm-m68knommu/dma.h b/arch/m68knommu/include/asm/dma.h index 939a02056217..939a02056217 100644 --- a/include/asm-m68knommu/dma.h +++ b/arch/m68knommu/include/asm/dma.h | |||
diff --git a/include/asm-m68knommu/elf.h b/arch/m68knommu/include/asm/elf.h index 27f0ec70fba8..27f0ec70fba8 100644 --- a/include/asm-m68knommu/elf.h +++ b/arch/m68knommu/include/asm/elf.h | |||
diff --git a/include/asm-m68knommu/elia.h b/arch/m68knommu/include/asm/elia.h index e037d4e2de33..e037d4e2de33 100644 --- a/include/asm-m68knommu/elia.h +++ b/arch/m68knommu/include/asm/elia.h | |||
diff --git a/include/asm-m68knommu/emergency-restart.h b/arch/m68knommu/include/asm/emergency-restart.h index 108d8c48e42e..108d8c48e42e 100644 --- a/include/asm-m68knommu/emergency-restart.h +++ b/arch/m68knommu/include/asm/emergency-restart.h | |||
diff --git a/include/asm-m68knommu/entry.h b/arch/m68knommu/include/asm/entry.h index c2553d26273d..c2553d26273d 100644 --- a/include/asm-m68knommu/entry.h +++ b/arch/m68knommu/include/asm/entry.h | |||
diff --git a/include/asm-m68knommu/errno.h b/arch/m68knommu/include/asm/errno.h index 7e8c22b9a5e6..7e8c22b9a5e6 100644 --- a/include/asm-m68knommu/errno.h +++ b/arch/m68knommu/include/asm/errno.h | |||
diff --git a/include/asm-m68knommu/fb.h b/arch/m68knommu/include/asm/fb.h index c7df38030992..c7df38030992 100644 --- a/include/asm-m68knommu/fb.h +++ b/arch/m68knommu/include/asm/fb.h | |||
diff --git a/include/asm-m68knommu/fcntl.h b/arch/m68knommu/include/asm/fcntl.h index f6a552cda4cd..f6a552cda4cd 100644 --- a/include/asm-m68knommu/fcntl.h +++ b/arch/m68knommu/include/asm/fcntl.h | |||
diff --git a/include/asm-m68knommu/flat.h b/arch/m68knommu/include/asm/flat.h index 814b5174a8e0..814b5174a8e0 100644 --- a/include/asm-m68knommu/flat.h +++ b/arch/m68knommu/include/asm/flat.h | |||
diff --git a/include/asm-m68knommu/fpu.h b/arch/m68knommu/include/asm/fpu.h index b16b2e4fca2a..b16b2e4fca2a 100644 --- a/include/asm-m68knommu/fpu.h +++ b/arch/m68knommu/include/asm/fpu.h | |||
diff --git a/include/asm-m68knommu/futex.h b/arch/m68knommu/include/asm/futex.h index 6a332a9f099c..6a332a9f099c 100644 --- a/include/asm-m68knommu/futex.h +++ b/arch/m68knommu/include/asm/futex.h | |||
diff --git a/include/asm-m68knommu/hardirq.h b/arch/m68knommu/include/asm/hardirq.h index bfad28149a49..bfad28149a49 100644 --- a/include/asm-m68knommu/hardirq.h +++ b/arch/m68knommu/include/asm/hardirq.h | |||
diff --git a/include/asm-m68knommu/hw_irq.h b/arch/m68knommu/include/asm/hw_irq.h index f3ec9e5ae049..f3ec9e5ae049 100644 --- a/include/asm-m68knommu/hw_irq.h +++ b/arch/m68knommu/include/asm/hw_irq.h | |||
diff --git a/include/asm-m68knommu/hwtest.h b/arch/m68knommu/include/asm/hwtest.h index 700626a1b1bf..700626a1b1bf 100644 --- a/include/asm-m68knommu/hwtest.h +++ b/arch/m68knommu/include/asm/hwtest.h | |||
diff --git a/include/asm-m68knommu/io.h b/arch/m68knommu/include/asm/io.h index 6adef1ee2082..6adef1ee2082 100644 --- a/include/asm-m68knommu/io.h +++ b/arch/m68knommu/include/asm/io.h | |||
diff --git a/include/asm-m68knommu/ioctl.h b/arch/m68knommu/include/asm/ioctl.h index b279fe06dfe5..b279fe06dfe5 100644 --- a/include/asm-m68knommu/ioctl.h +++ b/arch/m68knommu/include/asm/ioctl.h | |||
diff --git a/include/asm-m68knommu/ioctls.h b/arch/m68knommu/include/asm/ioctls.h index 0b1eb4d85059..0b1eb4d85059 100644 --- a/include/asm-m68knommu/ioctls.h +++ b/arch/m68knommu/include/asm/ioctls.h | |||
diff --git a/include/asm-m68knommu/ipcbuf.h b/arch/m68knommu/include/asm/ipcbuf.h index e4a7be6dd706..e4a7be6dd706 100644 --- a/include/asm-m68knommu/ipcbuf.h +++ b/arch/m68knommu/include/asm/ipcbuf.h | |||
diff --git a/include/asm-m68knommu/irq.h b/arch/m68knommu/include/asm/irq.h index 9373c31ac87d..9373c31ac87d 100644 --- a/include/asm-m68knommu/irq.h +++ b/arch/m68knommu/include/asm/irq.h | |||
diff --git a/include/asm-m68knommu/irq_regs.h b/arch/m68knommu/include/asm/irq_regs.h index 3dd9c0b70270..3dd9c0b70270 100644 --- a/include/asm-m68knommu/irq_regs.h +++ b/arch/m68knommu/include/asm/irq_regs.h | |||
diff --git a/include/asm-m68knommu/kdebug.h b/arch/m68knommu/include/asm/kdebug.h index 6ece1b037665..6ece1b037665 100644 --- a/include/asm-m68knommu/kdebug.h +++ b/arch/m68knommu/include/asm/kdebug.h | |||
diff --git a/include/asm-m68knommu/kmap_types.h b/arch/m68knommu/include/asm/kmap_types.h index bfb6707575d1..bfb6707575d1 100644 --- a/include/asm-m68knommu/kmap_types.h +++ b/arch/m68knommu/include/asm/kmap_types.h | |||
diff --git a/include/asm-m68knommu/linkage.h b/arch/m68knommu/include/asm/linkage.h index c288a19ff489..c288a19ff489 100644 --- a/include/asm-m68knommu/linkage.h +++ b/arch/m68knommu/include/asm/linkage.h | |||
diff --git a/include/asm-m68knommu/local.h b/arch/m68knommu/include/asm/local.h index 84a39c1b86f8..84a39c1b86f8 100644 --- a/include/asm-m68knommu/local.h +++ b/arch/m68knommu/include/asm/local.h | |||
diff --git a/include/asm-m68knommu/m5206sim.h b/arch/m68knommu/include/asm/m5206sim.h index 7e3594dea88b..7e3594dea88b 100644 --- a/include/asm-m68knommu/m5206sim.h +++ b/arch/m68knommu/include/asm/m5206sim.h | |||
diff --git a/include/asm-m68knommu/m520xsim.h b/arch/m68knommu/include/asm/m520xsim.h index 49d016e6391a..49d016e6391a 100644 --- a/include/asm-m68knommu/m520xsim.h +++ b/arch/m68knommu/include/asm/m520xsim.h | |||
diff --git a/include/asm-m68knommu/m523xsim.h b/arch/m68knommu/include/asm/m523xsim.h index bf397313e93f..bf397313e93f 100644 --- a/include/asm-m68knommu/m523xsim.h +++ b/arch/m68knommu/include/asm/m523xsim.h | |||
diff --git a/include/asm-m68knommu/m5249sim.h b/arch/m68knommu/include/asm/m5249sim.h index 366eb8602d2f..366eb8602d2f 100644 --- a/include/asm-m68knommu/m5249sim.h +++ b/arch/m68knommu/include/asm/m5249sim.h | |||
diff --git a/include/asm-m68knommu/m5272sim.h b/arch/m68knommu/include/asm/m5272sim.h index 6217edc21139..6217edc21139 100644 --- a/include/asm-m68knommu/m5272sim.h +++ b/arch/m68knommu/include/asm/m5272sim.h | |||
diff --git a/include/asm-m68knommu/m527xsim.h b/arch/m68knommu/include/asm/m527xsim.h index 1f63ab3fb3e6..1f63ab3fb3e6 100644 --- a/include/asm-m68knommu/m527xsim.h +++ b/arch/m68knommu/include/asm/m527xsim.h | |||
diff --git a/include/asm-m68knommu/m528xsim.h b/arch/m68knommu/include/asm/m528xsim.h index 28bf783a5d6d..28bf783a5d6d 100644 --- a/include/asm-m68knommu/m528xsim.h +++ b/arch/m68knommu/include/asm/m528xsim.h | |||
diff --git a/include/asm-m68knommu/m5307sim.h b/arch/m68knommu/include/asm/m5307sim.h index 5886728409c0..5886728409c0 100644 --- a/include/asm-m68knommu/m5307sim.h +++ b/arch/m68knommu/include/asm/m5307sim.h | |||
diff --git a/include/asm-m68knommu/m532xsim.h b/arch/m68knommu/include/asm/m532xsim.h index 1835fd20a82c..1835fd20a82c 100644 --- a/include/asm-m68knommu/m532xsim.h +++ b/arch/m68knommu/include/asm/m532xsim.h | |||
diff --git a/include/asm-m68knommu/m5407sim.h b/arch/m68knommu/include/asm/m5407sim.h index cc22c4a53005..cc22c4a53005 100644 --- a/include/asm-m68knommu/m5407sim.h +++ b/arch/m68knommu/include/asm/m5407sim.h | |||
diff --git a/include/asm-m68knommu/m68360.h b/arch/m68knommu/include/asm/m68360.h index eb7d39ef2855..eb7d39ef2855 100644 --- a/include/asm-m68knommu/m68360.h +++ b/arch/m68knommu/include/asm/m68360.h | |||
diff --git a/include/asm-m68knommu/m68360_enet.h b/arch/m68knommu/include/asm/m68360_enet.h index c36f4d059203..c36f4d059203 100644 --- a/include/asm-m68knommu/m68360_enet.h +++ b/arch/m68knommu/include/asm/m68360_enet.h | |||
diff --git a/include/asm-m68knommu/m68360_pram.h b/arch/m68knommu/include/asm/m68360_pram.h index e6088bbce93d..e6088bbce93d 100644 --- a/include/asm-m68knommu/m68360_pram.h +++ b/arch/m68knommu/include/asm/m68360_pram.h | |||
diff --git a/include/asm-m68knommu/m68360_quicc.h b/arch/m68knommu/include/asm/m68360_quicc.h index 6d40f4d18e10..6d40f4d18e10 100644 --- a/include/asm-m68knommu/m68360_quicc.h +++ b/arch/m68knommu/include/asm/m68360_quicc.h | |||
diff --git a/include/asm-m68knommu/m68360_regs.h b/arch/m68knommu/include/asm/m68360_regs.h index d57217ca4f27..d57217ca4f27 100644 --- a/include/asm-m68knommu/m68360_regs.h +++ b/arch/m68knommu/include/asm/m68360_regs.h | |||
diff --git a/include/asm-m68knommu/machdep.h b/arch/m68knommu/include/asm/machdep.h index de9f47a51cc2..de9f47a51cc2 100644 --- a/include/asm-m68knommu/machdep.h +++ b/arch/m68knommu/include/asm/machdep.h | |||
diff --git a/include/asm-m68knommu/math-emu.h b/arch/m68knommu/include/asm/math-emu.h index 7e7090517b72..7e7090517b72 100644 --- a/include/asm-m68knommu/math-emu.h +++ b/arch/m68knommu/include/asm/math-emu.h | |||
diff --git a/include/asm-m68knommu/mc146818rtc.h b/arch/m68knommu/include/asm/mc146818rtc.h index 907a0481a140..907a0481a140 100644 --- a/include/asm-m68knommu/mc146818rtc.h +++ b/arch/m68knommu/include/asm/mc146818rtc.h | |||
diff --git a/include/asm-m68knommu/mcfcache.h b/arch/m68knommu/include/asm/mcfcache.h index c042634fadaa..c042634fadaa 100644 --- a/include/asm-m68knommu/mcfcache.h +++ b/arch/m68knommu/include/asm/mcfcache.h | |||
diff --git a/include/asm-m68knommu/mcfdma.h b/arch/m68knommu/include/asm/mcfdma.h index 705c52c79cd8..705c52c79cd8 100644 --- a/include/asm-m68knommu/mcfdma.h +++ b/arch/m68knommu/include/asm/mcfdma.h | |||
diff --git a/include/asm-m68knommu/mcfmbus.h b/arch/m68knommu/include/asm/mcfmbus.h index 319899c47a2c..319899c47a2c 100644 --- a/include/asm-m68knommu/mcfmbus.h +++ b/arch/m68knommu/include/asm/mcfmbus.h | |||
diff --git a/include/asm-m68knommu/mcfne.h b/arch/m68knommu/include/asm/mcfne.h index 431f63aadd0e..431f63aadd0e 100644 --- a/include/asm-m68knommu/mcfne.h +++ b/arch/m68knommu/include/asm/mcfne.h | |||
diff --git a/include/asm-m68knommu/mcfpci.h b/arch/m68knommu/include/asm/mcfpci.h index f1507dd06ec6..f1507dd06ec6 100644 --- a/include/asm-m68knommu/mcfpci.h +++ b/arch/m68knommu/include/asm/mcfpci.h | |||
diff --git a/include/asm-m68knommu/mcfpit.h b/arch/m68knommu/include/asm/mcfpit.h index f570cf64fd29..f570cf64fd29 100644 --- a/include/asm-m68knommu/mcfpit.h +++ b/arch/m68knommu/include/asm/mcfpit.h | |||
diff --git a/include/asm-m68knommu/mcfsim.h b/arch/m68knommu/include/asm/mcfsim.h index da3f2ceff3a4..da3f2ceff3a4 100644 --- a/include/asm-m68knommu/mcfsim.h +++ b/arch/m68knommu/include/asm/mcfsim.h | |||
diff --git a/include/asm-m68knommu/mcfsmc.h b/arch/m68knommu/include/asm/mcfsmc.h index 2d7a4dbd9683..2d7a4dbd9683 100644 --- a/include/asm-m68knommu/mcfsmc.h +++ b/arch/m68knommu/include/asm/mcfsmc.h | |||
diff --git a/include/asm-m68knommu/mcftimer.h b/arch/m68knommu/include/asm/mcftimer.h index 0f90f6d2227a..0f90f6d2227a 100644 --- a/include/asm-m68knommu/mcftimer.h +++ b/arch/m68knommu/include/asm/mcftimer.h | |||
diff --git a/include/asm-m68knommu/mcfuart.h b/arch/m68knommu/include/asm/mcfuart.h index ef2293873612..ef2293873612 100644 --- a/include/asm-m68knommu/mcfuart.h +++ b/arch/m68knommu/include/asm/mcfuart.h | |||
diff --git a/include/asm-m68knommu/mcfwdebug.h b/arch/m68knommu/include/asm/mcfwdebug.h index 27f70e45d700..27f70e45d700 100644 --- a/include/asm-m68knommu/mcfwdebug.h +++ b/arch/m68knommu/include/asm/mcfwdebug.h | |||
diff --git a/include/asm-m68knommu/md.h b/arch/m68knommu/include/asm/md.h index d810c78de5ff..d810c78de5ff 100644 --- a/include/asm-m68knommu/md.h +++ b/arch/m68knommu/include/asm/md.h | |||
diff --git a/include/asm-m68knommu/mman.h b/arch/m68knommu/include/asm/mman.h index 4846c682efed..4846c682efed 100644 --- a/include/asm-m68knommu/mman.h +++ b/arch/m68knommu/include/asm/mman.h | |||
diff --git a/include/asm-m68knommu/mmu.h b/arch/m68knommu/include/asm/mmu.h index 5fa6b68353ba..5fa6b68353ba 100644 --- a/include/asm-m68knommu/mmu.h +++ b/arch/m68knommu/include/asm/mmu.h | |||
diff --git a/include/asm-m68knommu/mmu_context.h b/arch/m68knommu/include/asm/mmu_context.h index 9ccee4278c97..9ccee4278c97 100644 --- a/include/asm-m68knommu/mmu_context.h +++ b/arch/m68knommu/include/asm/mmu_context.h | |||
diff --git a/include/asm-m68knommu/module.h b/arch/m68knommu/include/asm/module.h index 2e45ab50b232..2e45ab50b232 100644 --- a/include/asm-m68knommu/module.h +++ b/arch/m68knommu/include/asm/module.h | |||
diff --git a/include/asm-m68knommu/movs.h b/arch/m68knommu/include/asm/movs.h index 81a16779e833..81a16779e833 100644 --- a/include/asm-m68knommu/movs.h +++ b/arch/m68knommu/include/asm/movs.h | |||
diff --git a/include/asm-m68knommu/msgbuf.h b/arch/m68knommu/include/asm/msgbuf.h index bdfadec4d52d..bdfadec4d52d 100644 --- a/include/asm-m68knommu/msgbuf.h +++ b/arch/m68knommu/include/asm/msgbuf.h | |||
diff --git a/include/asm-m68knommu/mutex.h b/arch/m68knommu/include/asm/mutex.h index 458c1f7fbc18..458c1f7fbc18 100644 --- a/include/asm-m68knommu/mutex.h +++ b/arch/m68knommu/include/asm/mutex.h | |||
diff --git a/include/asm-m68knommu/nettel.h b/arch/m68knommu/include/asm/nettel.h index 0299f6a2deeb..0299f6a2deeb 100644 --- a/include/asm-m68knommu/nettel.h +++ b/arch/m68knommu/include/asm/nettel.h | |||
diff --git a/include/asm-m68knommu/openprom.h b/arch/m68knommu/include/asm/openprom.h index fdba7953ff9f..fdba7953ff9f 100644 --- a/include/asm-m68knommu/openprom.h +++ b/arch/m68knommu/include/asm/openprom.h | |||
diff --git a/include/asm-m68knommu/oplib.h b/arch/m68knommu/include/asm/oplib.h index ce079dc332d9..ce079dc332d9 100644 --- a/include/asm-m68knommu/oplib.h +++ b/arch/m68knommu/include/asm/oplib.h | |||
diff --git a/include/asm-m68knommu/page.h b/arch/m68knommu/include/asm/page.h index 3a1ede4544cb..3a1ede4544cb 100644 --- a/include/asm-m68knommu/page.h +++ b/arch/m68knommu/include/asm/page.h | |||
diff --git a/include/asm-m68knommu/page_offset.h b/arch/m68knommu/include/asm/page_offset.h index d4e73e0ba646..d4e73e0ba646 100644 --- a/include/asm-m68knommu/page_offset.h +++ b/arch/m68knommu/include/asm/page_offset.h | |||
diff --git a/include/asm-m68knommu/param.h b/arch/m68knommu/include/asm/param.h index 6044397adb64..6044397adb64 100644 --- a/include/asm-m68knommu/param.h +++ b/arch/m68knommu/include/asm/param.h | |||
diff --git a/include/asm-m68knommu/pci.h b/arch/m68knommu/include/asm/pci.h index a13f3cc87451..a13f3cc87451 100644 --- a/include/asm-m68knommu/pci.h +++ b/arch/m68knommu/include/asm/pci.h | |||
diff --git a/include/asm-m68knommu/percpu.h b/arch/m68knommu/include/asm/percpu.h index 5de72c327efd..5de72c327efd 100644 --- a/include/asm-m68knommu/percpu.h +++ b/arch/m68knommu/include/asm/percpu.h | |||
diff --git a/include/asm-m68knommu/pgalloc.h b/arch/m68knommu/include/asm/pgalloc.h index d6352f671ec0..d6352f671ec0 100644 --- a/include/asm-m68knommu/pgalloc.h +++ b/arch/m68knommu/include/asm/pgalloc.h | |||
diff --git a/include/asm-m68knommu/pgtable.h b/arch/m68knommu/include/asm/pgtable.h index 46251016e821..46251016e821 100644 --- a/include/asm-m68knommu/pgtable.h +++ b/arch/m68knommu/include/asm/pgtable.h | |||
diff --git a/include/asm-m68knommu/poll.h b/arch/m68knommu/include/asm/poll.h index ee1b6cb549ca..ee1b6cb549ca 100644 --- a/include/asm-m68knommu/poll.h +++ b/arch/m68knommu/include/asm/poll.h | |||
diff --git a/include/asm-m68knommu/posix_types.h b/arch/m68knommu/include/asm/posix_types.h index 6205fb9392a3..6205fb9392a3 100644 --- a/include/asm-m68knommu/posix_types.h +++ b/arch/m68knommu/include/asm/posix_types.h | |||
diff --git a/include/asm-m68knommu/processor.h b/arch/m68knommu/include/asm/processor.h index 91cba18acdd3..91cba18acdd3 100644 --- a/include/asm-m68knommu/processor.h +++ b/arch/m68knommu/include/asm/processor.h | |||
diff --git a/include/asm-m68knommu/ptrace.h b/arch/m68knommu/include/asm/ptrace.h index 8c9194b98548..8c9194b98548 100644 --- a/include/asm-m68knommu/ptrace.h +++ b/arch/m68knommu/include/asm/ptrace.h | |||
diff --git a/include/asm-m68knommu/quicc_simple.h b/arch/m68knommu/include/asm/quicc_simple.h index c3636932d4bc..c3636932d4bc 100644 --- a/include/asm-m68knommu/quicc_simple.h +++ b/arch/m68knommu/include/asm/quicc_simple.h | |||
diff --git a/include/asm-m68knommu/resource.h b/arch/m68knommu/include/asm/resource.h index 7fa63d5ea576..7fa63d5ea576 100644 --- a/include/asm-m68knommu/resource.h +++ b/arch/m68knommu/include/asm/resource.h | |||
diff --git a/include/asm-m68knommu/rtc.h b/arch/m68knommu/include/asm/rtc.h index eaf18ec83c8e..eaf18ec83c8e 100644 --- a/include/asm-m68knommu/rtc.h +++ b/arch/m68knommu/include/asm/rtc.h | |||
diff --git a/include/asm-m68knommu/scatterlist.h b/arch/m68knommu/include/asm/scatterlist.h index afc4788b0d2c..afc4788b0d2c 100644 --- a/include/asm-m68knommu/scatterlist.h +++ b/arch/m68knommu/include/asm/scatterlist.h | |||
diff --git a/include/asm-m68knommu/sections.h b/arch/m68knommu/include/asm/sections.h index dd0ecb98ec08..dd0ecb98ec08 100644 --- a/include/asm-m68knommu/sections.h +++ b/arch/m68knommu/include/asm/sections.h | |||
diff --git a/include/asm-m68knommu/segment.h b/arch/m68knommu/include/asm/segment.h index 42318ebec7ec..42318ebec7ec 100644 --- a/include/asm-m68knommu/segment.h +++ b/arch/m68knommu/include/asm/segment.h | |||
diff --git a/include/asm-m68knommu/sembuf.h b/arch/m68knommu/include/asm/sembuf.h index 3a634f9ecf50..3a634f9ecf50 100644 --- a/include/asm-m68knommu/sembuf.h +++ b/arch/m68knommu/include/asm/sembuf.h | |||
diff --git a/include/asm-m68knommu/setup.h b/arch/m68knommu/include/asm/setup.h index fb86bb2a6078..fb86bb2a6078 100644 --- a/include/asm-m68knommu/setup.h +++ b/arch/m68knommu/include/asm/setup.h | |||
diff --git a/include/asm-m68knommu/shm.h b/arch/m68knommu/include/asm/shm.h index cc8e522d9050..cc8e522d9050 100644 --- a/include/asm-m68knommu/shm.h +++ b/arch/m68knommu/include/asm/shm.h | |||
diff --git a/include/asm-m68knommu/shmbuf.h b/arch/m68knommu/include/asm/shmbuf.h index bc34cf8eefce..bc34cf8eefce 100644 --- a/include/asm-m68knommu/shmbuf.h +++ b/arch/m68knommu/include/asm/shmbuf.h | |||
diff --git a/include/asm-m68knommu/shmparam.h b/arch/m68knommu/include/asm/shmparam.h index d7ee69648ebf..d7ee69648ebf 100644 --- a/include/asm-m68knommu/shmparam.h +++ b/arch/m68knommu/include/asm/shmparam.h | |||
diff --git a/include/asm-m68knommu/sigcontext.h b/arch/m68knommu/include/asm/sigcontext.h index 36c293fc133d..36c293fc133d 100644 --- a/include/asm-m68knommu/sigcontext.h +++ b/arch/m68knommu/include/asm/sigcontext.h | |||
diff --git a/include/asm-m68knommu/siginfo.h b/arch/m68knommu/include/asm/siginfo.h index b18e5f4064ae..b18e5f4064ae 100644 --- a/include/asm-m68knommu/siginfo.h +++ b/arch/m68knommu/include/asm/siginfo.h | |||
diff --git a/include/asm-m68knommu/signal.h b/arch/m68knommu/include/asm/signal.h index 216c08be54a0..216c08be54a0 100644 --- a/include/asm-m68knommu/signal.h +++ b/arch/m68knommu/include/asm/signal.h | |||
diff --git a/include/asm-m68knommu/smp.h b/arch/m68knommu/include/asm/smp.h index 9e9bd7e58922..9e9bd7e58922 100644 --- a/include/asm-m68knommu/smp.h +++ b/arch/m68knommu/include/asm/smp.h | |||
diff --git a/include/asm-m68knommu/socket.h b/arch/m68knommu/include/asm/socket.h index ac5478bf6371..ac5478bf6371 100644 --- a/include/asm-m68knommu/socket.h +++ b/arch/m68knommu/include/asm/socket.h | |||
diff --git a/include/asm-m68knommu/sockios.h b/arch/m68knommu/include/asm/sockios.h index dcc6a8900ce2..dcc6a8900ce2 100644 --- a/include/asm-m68knommu/sockios.h +++ b/arch/m68knommu/include/asm/sockios.h | |||
diff --git a/include/asm-m68knommu/spinlock.h b/arch/m68knommu/include/asm/spinlock.h index 6bb1f06c4781..6bb1f06c4781 100644 --- a/include/asm-m68knommu/spinlock.h +++ b/arch/m68knommu/include/asm/spinlock.h | |||
diff --git a/include/asm-m68knommu/stat.h b/arch/m68knommu/include/asm/stat.h index 3d4b260e7c03..3d4b260e7c03 100644 --- a/include/asm-m68knommu/stat.h +++ b/arch/m68knommu/include/asm/stat.h | |||
diff --git a/include/asm-m68knommu/statfs.h b/arch/m68knommu/include/asm/statfs.h index 2ce99eaf0970..2ce99eaf0970 100644 --- a/include/asm-m68knommu/statfs.h +++ b/arch/m68knommu/include/asm/statfs.h | |||
diff --git a/include/asm-m68knommu/string.h b/arch/m68knommu/include/asm/string.h index af09e17000fc..af09e17000fc 100644 --- a/include/asm-m68knommu/string.h +++ b/arch/m68knommu/include/asm/string.h | |||
diff --git a/include/asm-m68knommu/system.h b/arch/m68knommu/include/asm/system.h index 40f49de69821..40f49de69821 100644 --- a/include/asm-m68knommu/system.h +++ b/arch/m68knommu/include/asm/system.h | |||
diff --git a/include/asm-m68knommu/termbits.h b/arch/m68knommu/include/asm/termbits.h index 05dd6bc27285..05dd6bc27285 100644 --- a/include/asm-m68knommu/termbits.h +++ b/arch/m68knommu/include/asm/termbits.h | |||
diff --git a/include/asm-m68knommu/termios.h b/arch/m68knommu/include/asm/termios.h index e7337881a985..e7337881a985 100644 --- a/include/asm-m68knommu/termios.h +++ b/arch/m68knommu/include/asm/termios.h | |||
diff --git a/include/asm-m68knommu/thread_info.h b/arch/m68knommu/include/asm/thread_info.h index 0c9bc095f3f0..0c9bc095f3f0 100644 --- a/include/asm-m68knommu/thread_info.h +++ b/arch/m68knommu/include/asm/thread_info.h | |||
diff --git a/include/asm-m68knommu/timex.h b/arch/m68knommu/include/asm/timex.h index 109050f3fe91..109050f3fe91 100644 --- a/include/asm-m68knommu/timex.h +++ b/arch/m68knommu/include/asm/timex.h | |||
diff --git a/include/asm-m68knommu/tlb.h b/arch/m68knommu/include/asm/tlb.h index 77a7c51ca299..77a7c51ca299 100644 --- a/include/asm-m68knommu/tlb.h +++ b/arch/m68knommu/include/asm/tlb.h | |||
diff --git a/include/asm-m68knommu/tlbflush.h b/arch/m68knommu/include/asm/tlbflush.h index a470cfb803eb..a470cfb803eb 100644 --- a/include/asm-m68knommu/tlbflush.h +++ b/arch/m68knommu/include/asm/tlbflush.h | |||
diff --git a/include/asm-m68knommu/topology.h b/arch/m68knommu/include/asm/topology.h index ca173e9f26ff..ca173e9f26ff 100644 --- a/include/asm-m68knommu/topology.h +++ b/arch/m68knommu/include/asm/topology.h | |||
diff --git a/include/asm-m68knommu/traps.h b/arch/m68knommu/include/asm/traps.h index d0671e5f8e29..d0671e5f8e29 100644 --- a/include/asm-m68knommu/traps.h +++ b/arch/m68knommu/include/asm/traps.h | |||
diff --git a/include/asm-m68knommu/types.h b/arch/m68knommu/include/asm/types.h index 031238c2d180..031238c2d180 100644 --- a/include/asm-m68knommu/types.h +++ b/arch/m68knommu/include/asm/types.h | |||
diff --git a/include/asm-m68knommu/uaccess.h b/arch/m68knommu/include/asm/uaccess.h index 68bbe9b312f1..68bbe9b312f1 100644 --- a/include/asm-m68knommu/uaccess.h +++ b/arch/m68knommu/include/asm/uaccess.h | |||
diff --git a/include/asm-m68knommu/ucontext.h b/arch/m68knommu/include/asm/ucontext.h index 713a27f901cd..713a27f901cd 100644 --- a/include/asm-m68knommu/ucontext.h +++ b/arch/m68knommu/include/asm/ucontext.h | |||
diff --git a/include/asm-m68knommu/unaligned.h b/arch/m68knommu/include/asm/unaligned.h index eb1ea4cb9a59..eb1ea4cb9a59 100644 --- a/include/asm-m68knommu/unaligned.h +++ b/arch/m68knommu/include/asm/unaligned.h | |||
diff --git a/include/asm-m68knommu/unistd.h b/arch/m68knommu/include/asm/unistd.h index 4ba98b9c5d79..4ba98b9c5d79 100644 --- a/include/asm-m68knommu/unistd.h +++ b/arch/m68knommu/include/asm/unistd.h | |||
diff --git a/include/asm-m68knommu/user.h b/arch/m68knommu/include/asm/user.h index a5a555b761c4..a5a555b761c4 100644 --- a/include/asm-m68knommu/user.h +++ b/arch/m68knommu/include/asm/user.h | |||
diff --git a/arch/powerpc/platforms/iseries/Kconfig b/arch/powerpc/platforms/iseries/Kconfig index ea3e541ac74f..45ffd8e542f4 100644 --- a/arch/powerpc/platforms/iseries/Kconfig +++ b/arch/powerpc/platforms/iseries/Kconfig | |||
| @@ -7,15 +7,6 @@ config PPC_ISERIES | |||
| 7 | menu "iSeries device drivers" | 7 | menu "iSeries device drivers" |
| 8 | depends on PPC_ISERIES | 8 | depends on PPC_ISERIES |
| 9 | 9 | ||
| 10 | config VIOCONS | ||
| 11 | bool "iSeries Virtual Console Support (Obsolete)" | ||
| 12 | depends on !HVC_ISERIES | ||
| 13 | default n | ||
| 14 | help | ||
| 15 | This is the old virtual console driver for legacy iSeries. | ||
| 16 | You should use the iSeries Hypervisor Virtual Console | ||
| 17 | support instead. | ||
| 18 | |||
| 19 | config VIODASD | 10 | config VIODASD |
| 20 | tristate "iSeries Virtual I/O disk support" | 11 | tristate "iSeries Virtual I/O disk support" |
| 21 | help | 12 | help |
| @@ -38,5 +29,5 @@ endmenu | |||
| 38 | 29 | ||
| 39 | config VIOPATH | 30 | config VIOPATH |
| 40 | bool | 31 | bool |
| 41 | depends on VIOCONS || VIODASD || VIOCD || VIOTAPE || ISERIES_VETH | 32 | depends on VIODASD || VIOCD || VIOTAPE || ISERIES_VETH |
| 42 | default y | 33 | default y |
diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c index 65974c6d3d7a..c029d3eb9ef0 100644 --- a/crypto/async_tx/async_xor.c +++ b/crypto/async_tx/async_xor.c | |||
| @@ -263,11 +263,12 @@ async_xor_zero_sum(struct page *dest, struct page **src_list, | |||
| 263 | if (unlikely(!tx)) { | 263 | if (unlikely(!tx)) { |
| 264 | async_tx_quiesce(&depend_tx); | 264 | async_tx_quiesce(&depend_tx); |
| 265 | 265 | ||
| 266 | while (!tx) | 266 | while (!tx) { |
| 267 | dma_async_issue_pending(chan); | 267 | dma_async_issue_pending(chan); |
| 268 | tx = device->device_prep_dma_zero_sum(chan, | 268 | tx = device->device_prep_dma_zero_sum(chan, |
| 269 | dma_src, src_cnt, len, result, | 269 | dma_src, src_cnt, len, result, |
| 270 | dma_prep_flags); | 270 | dma_prep_flags); |
| 271 | } | ||
| 271 | } | 272 | } |
| 272 | 273 | ||
| 273 | async_tx_submit(chan, tx, flags, depend_tx, cb_fn, cb_param); | 274 | async_tx_submit(chan, tx, flags, depend_tx, cb_fn, cb_param); |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 0ce0c279aabf..b73116ef9236 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
| @@ -159,7 +159,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, | |||
| 159 | static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); | 159 | static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); |
| 160 | 160 | ||
| 161 | static int cciss_revalidate(struct gendisk *disk); | 161 | static int cciss_revalidate(struct gendisk *disk); |
| 162 | static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk); | 162 | static int rebuild_lun_table(ctlr_info_t *h, int first_time); |
| 163 | static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, | 163 | static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, |
| 164 | int clear_all); | 164 | int clear_all); |
| 165 | 165 | ||
| @@ -171,7 +171,6 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, | |||
| 171 | int withirq, sector_t total_size, | 171 | int withirq, sector_t total_size, |
| 172 | unsigned int block_size, InquiryData_struct *inq_buff, | 172 | unsigned int block_size, InquiryData_struct *inq_buff, |
| 173 | drive_info_struct *drv); | 173 | drive_info_struct *drv); |
| 174 | static void cciss_getgeometry(int cntl_num); | ||
| 175 | static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *, | 174 | static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *, |
| 176 | __u32); | 175 | __u32); |
| 177 | static void start_io(ctlr_info_t *h); | 176 | static void start_io(ctlr_info_t *h); |
| @@ -929,8 +928,10 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, | |||
| 929 | return 0; | 928 | return 0; |
| 930 | } | 929 | } |
| 931 | 930 | ||
| 931 | case CCISS_DEREGDISK: | ||
| 932 | case CCISS_REGNEWD: | ||
| 932 | case CCISS_REVALIDVOLS: | 933 | case CCISS_REVALIDVOLS: |
| 933 | return rebuild_lun_table(host, NULL); | 934 | return rebuild_lun_table(host, 0); |
| 934 | 935 | ||
| 935 | case CCISS_GETLUNINFO:{ | 936 | case CCISS_GETLUNINFO:{ |
| 936 | LogvolInfo_struct luninfo; | 937 | LogvolInfo_struct luninfo; |
| @@ -943,12 +944,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, | |||
| 943 | return -EFAULT; | 944 | return -EFAULT; |
| 944 | return 0; | 945 | return 0; |
| 945 | } | 946 | } |
| 946 | case CCISS_DEREGDISK: | ||
| 947 | return rebuild_lun_table(host, disk); | ||
| 948 | |||
| 949 | case CCISS_REGNEWD: | ||
| 950 | return rebuild_lun_table(host, NULL); | ||
| 951 | |||
| 952 | case CCISS_PASSTHRU: | 947 | case CCISS_PASSTHRU: |
| 953 | { | 948 | { |
| 954 | IOCTL_Command_struct iocommand; | 949 | IOCTL_Command_struct iocommand; |
| @@ -1134,7 +1129,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, | |||
| 1134 | if (ioc->Request.Type.Direction == XFER_WRITE) { | 1129 | if (ioc->Request.Type.Direction == XFER_WRITE) { |
| 1135 | if (copy_from_user | 1130 | if (copy_from_user |
| 1136 | (buff[sg_used], data_ptr, sz)) { | 1131 | (buff[sg_used], data_ptr, sz)) { |
| 1137 | status = -ENOMEM; | 1132 | status = -EFAULT; |
| 1138 | goto cleanup1; | 1133 | goto cleanup1; |
| 1139 | } | 1134 | } |
| 1140 | } else { | 1135 | } else { |
| @@ -1330,15 +1325,84 @@ static void cciss_softirq_done(struct request *rq) | |||
| 1330 | spin_unlock_irqrestore(&h->lock, flags); | 1325 | spin_unlock_irqrestore(&h->lock, flags); |
| 1331 | } | 1326 | } |
| 1332 | 1327 | ||
| 1328 | /* This function gets the serial number of a logical drive via | ||
| 1329 | * inquiry page 0x83. Serial no. is 16 bytes. If the serial | ||
| 1330 | * number cannot be had, for whatever reason, 16 bytes of 0xff | ||
| 1331 | * are returned instead. | ||
| 1332 | */ | ||
| 1333 | static void cciss_get_serial_no(int ctlr, int logvol, int withirq, | ||
| 1334 | unsigned char *serial_no, int buflen) | ||
| 1335 | { | ||
| 1336 | #define PAGE_83_INQ_BYTES 64 | ||
| 1337 | int rc; | ||
| 1338 | unsigned char *buf; | ||
| 1339 | |||
| 1340 | if (buflen > 16) | ||
| 1341 | buflen = 16; | ||
| 1342 | memset(serial_no, 0xff, buflen); | ||
| 1343 | buf = kzalloc(PAGE_83_INQ_BYTES, GFP_KERNEL); | ||
| 1344 | if (!buf) | ||
| 1345 | return; | ||
| 1346 | memset(serial_no, 0, buflen); | ||
| 1347 | if (withirq) | ||
| 1348 | rc = sendcmd_withirq(CISS_INQUIRY, ctlr, buf, | ||
| 1349 | PAGE_83_INQ_BYTES, 1, logvol, 0x83, TYPE_CMD); | ||
| 1350 | else | ||
| 1351 | rc = sendcmd(CISS_INQUIRY, ctlr, buf, | ||
| 1352 | PAGE_83_INQ_BYTES, 1, logvol, 0x83, NULL, TYPE_CMD); | ||
| 1353 | if (rc == IO_OK) | ||
| 1354 | memcpy(serial_no, &buf[8], buflen); | ||
| 1355 | kfree(buf); | ||
| 1356 | return; | ||
| 1357 | } | ||
| 1358 | |||
| 1359 | static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, | ||
| 1360 | int drv_index) | ||
| 1361 | { | ||
| 1362 | disk->queue = blk_init_queue(do_cciss_request, &h->lock); | ||
| 1363 | sprintf(disk->disk_name, "cciss/c%dd%d", h->ctlr, drv_index); | ||
| 1364 | disk->major = h->major; | ||
| 1365 | disk->first_minor = drv_index << NWD_SHIFT; | ||
| 1366 | disk->fops = &cciss_fops; | ||
| 1367 | disk->private_data = &h->drv[drv_index]; | ||
| 1368 | |||
| 1369 | /* Set up queue information */ | ||
| 1370 | blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask); | ||
| 1371 | |||
| 1372 | /* This is a hardware imposed limit. */ | ||
| 1373 | blk_queue_max_hw_segments(disk->queue, MAXSGENTRIES); | ||
| 1374 | |||
| 1375 | /* This is a limit in the driver and could be eliminated. */ | ||
| 1376 | blk_queue_max_phys_segments(disk->queue, MAXSGENTRIES); | ||
| 1377 | |||
| 1378 | blk_queue_max_sectors(disk->queue, h->cciss_max_sectors); | ||
| 1379 | |||
| 1380 | blk_queue_softirq_done(disk->queue, cciss_softirq_done); | ||
| 1381 | |||
| 1382 | disk->queue->queuedata = h; | ||
| 1383 | |||
| 1384 | blk_queue_hardsect_size(disk->queue, | ||
| 1385 | h->drv[drv_index].block_size); | ||
| 1386 | |||
| 1387 | /* Make sure all queue data is written out before */ | ||
| 1388 | /* setting h->drv[drv_index].queue, as setting this */ | ||
| 1389 | /* allows the interrupt handler to start the queue */ | ||
| 1390 | wmb(); | ||
| 1391 | h->drv[drv_index].queue = disk->queue; | ||
| 1392 | add_disk(disk); | ||
| 1393 | } | ||
| 1394 | |||
| 1333 | /* This function will check the usage_count of the drive to be updated/added. | 1395 | /* This function will check the usage_count of the drive to be updated/added. |
| 1334 | * If the usage_count is zero then the drive information will be updated and | 1396 | * If the usage_count is zero and it is a heretofore unknown drive, or, |
| 1335 | * the disk will be re-registered with the kernel. If not then it will be | 1397 | * the drive's capacity, geometry, or serial number has changed, |
| 1336 | * left alone for the next reboot. The exception to this is disk 0 which | 1398 | * then the drive information will be updated and the disk will be |
| 1337 | * will always be left registered with the kernel since it is also the | 1399 | * re-registered with the kernel. If these conditions don't hold, |
| 1338 | * controller node. Any changes to disk 0 will show up on the next | 1400 | * then it will be left alone for the next reboot. The exception to this |
| 1339 | * reboot. | 1401 | * is disk 0 which will always be left registered with the kernel since it |
| 1402 | * is also the controller node. Any changes to disk 0 will show up on | ||
| 1403 | * the next reboot. | ||
| 1340 | */ | 1404 | */ |
| 1341 | static void cciss_update_drive_info(int ctlr, int drv_index) | 1405 | static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) |
| 1342 | { | 1406 | { |
| 1343 | ctlr_info_t *h = hba[ctlr]; | 1407 | ctlr_info_t *h = hba[ctlr]; |
| 1344 | struct gendisk *disk; | 1408 | struct gendisk *disk; |
| @@ -1347,16 +1411,81 @@ static void cciss_update_drive_info(int ctlr, int drv_index) | |||
| 1347 | sector_t total_size; | 1411 | sector_t total_size; |
| 1348 | unsigned long flags = 0; | 1412 | unsigned long flags = 0; |
| 1349 | int ret = 0; | 1413 | int ret = 0; |
| 1414 | drive_info_struct *drvinfo; | ||
| 1415 | int was_only_controller_node; | ||
| 1416 | |||
| 1417 | /* Get information about the disk and modify the driver structure */ | ||
| 1418 | inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); | ||
| 1419 | drvinfo = kmalloc(sizeof(*drvinfo), GFP_KERNEL); | ||
| 1420 | if (inq_buff == NULL || drvinfo == NULL) | ||
| 1421 | goto mem_msg; | ||
| 1422 | |||
| 1423 | /* See if we're trying to update the "controller node" | ||
| 1424 | * this will happen the when the first logical drive gets | ||
| 1425 | * created by ACU. | ||
| 1426 | */ | ||
| 1427 | was_only_controller_node = (drv_index == 0 && | ||
| 1428 | h->drv[0].raid_level == -1); | ||
| 1350 | 1429 | ||
| 1351 | /* if the disk already exists then deregister it before proceeding */ | 1430 | /* testing to see if 16-byte CDBs are already being used */ |
| 1352 | if (h->drv[drv_index].raid_level != -1) { | 1431 | if (h->cciss_read == CCISS_READ_16) { |
| 1432 | cciss_read_capacity_16(h->ctlr, drv_index, 1, | ||
| 1433 | &total_size, &block_size); | ||
| 1434 | |||
| 1435 | } else { | ||
| 1436 | cciss_read_capacity(ctlr, drv_index, 1, | ||
| 1437 | &total_size, &block_size); | ||
| 1438 | |||
| 1439 | /* if read_capacity returns all F's this volume is >2TB */ | ||
| 1440 | /* in size so we switch to 16-byte CDB's for all */ | ||
| 1441 | /* read/write ops */ | ||
| 1442 | if (total_size == 0xFFFFFFFFULL) { | ||
| 1443 | cciss_read_capacity_16(ctlr, drv_index, 1, | ||
| 1444 | &total_size, &block_size); | ||
| 1445 | h->cciss_read = CCISS_READ_16; | ||
| 1446 | h->cciss_write = CCISS_WRITE_16; | ||
| 1447 | } else { | ||
| 1448 | h->cciss_read = CCISS_READ_10; | ||
| 1449 | h->cciss_write = CCISS_WRITE_10; | ||
| 1450 | } | ||
| 1451 | } | ||
| 1452 | |||
| 1453 | cciss_geometry_inquiry(ctlr, drv_index, 1, total_size, block_size, | ||
| 1454 | inq_buff, drvinfo); | ||
| 1455 | drvinfo->block_size = block_size; | ||
| 1456 | drvinfo->nr_blocks = total_size + 1; | ||
| 1457 | |||
| 1458 | cciss_get_serial_no(ctlr, drv_index, 1, drvinfo->serial_no, | ||
| 1459 | sizeof(drvinfo->serial_no)); | ||
| 1460 | |||
| 1461 | /* Is it the same disk we already know, and nothing's changed? */ | ||
| 1462 | if (h->drv[drv_index].raid_level != -1 && | ||
| 1463 | ((memcmp(drvinfo->serial_no, | ||
| 1464 | h->drv[drv_index].serial_no, 16) == 0) && | ||
| 1465 | drvinfo->block_size == h->drv[drv_index].block_size && | ||
| 1466 | drvinfo->nr_blocks == h->drv[drv_index].nr_blocks && | ||
| 1467 | drvinfo->heads == h->drv[drv_index].heads && | ||
| 1468 | drvinfo->sectors == h->drv[drv_index].sectors && | ||
| 1469 | drvinfo->cylinders == h->drv[drv_index].cylinders)) | ||
| 1470 | /* The disk is unchanged, nothing to update */ | ||
| 1471 | goto freeret; | ||
| 1472 | |||
| 1473 | /* If we get here it's not the same disk, or something's changed, | ||
| 1474 | * so we need to * deregister it, and re-register it, if it's not | ||
| 1475 | * in use. | ||
| 1476 | * If the disk already exists then deregister it before proceeding | ||
| 1477 | * (unless it's the first disk (for the controller node). | ||
| 1478 | */ | ||
| 1479 | if (h->drv[drv_index].raid_level != -1 && drv_index != 0) { | ||
| 1480 | printk(KERN_WARNING "disk %d has changed.\n", drv_index); | ||
| 1353 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 1481 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); |
| 1354 | h->drv[drv_index].busy_configuring = 1; | 1482 | h->drv[drv_index].busy_configuring = 1; |
| 1355 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 1483 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); |
| 1356 | 1484 | ||
| 1357 | /* deregister_disk sets h->drv[drv_index].queue = NULL */ | 1485 | /* deregister_disk sets h->drv[drv_index].queue = NULL |
| 1358 | /* which keeps the interrupt handler from starting */ | 1486 | * which keeps the interrupt handler from starting |
| 1359 | /* the queue. */ | 1487 | * the queue. |
| 1488 | */ | ||
| 1360 | ret = deregister_disk(h->gendisk[drv_index], | 1489 | ret = deregister_disk(h->gendisk[drv_index], |
| 1361 | &h->drv[drv_index], 0); | 1490 | &h->drv[drv_index], 0); |
| 1362 | h->drv[drv_index].busy_configuring = 0; | 1491 | h->drv[drv_index].busy_configuring = 0; |
| @@ -1364,81 +1493,37 @@ static void cciss_update_drive_info(int ctlr, int drv_index) | |||
| 1364 | 1493 | ||
| 1365 | /* If the disk is in use return */ | 1494 | /* If the disk is in use return */ |
| 1366 | if (ret) | 1495 | if (ret) |
| 1367 | return; | 1496 | goto freeret; |
| 1368 | 1497 | ||
| 1369 | /* Get information about the disk and modify the driver structure */ | 1498 | /* Save the new information from cciss_geometry_inquiry |
| 1370 | inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); | 1499 | * and serial number inquiry. |
| 1371 | if (inq_buff == NULL) | 1500 | */ |
| 1372 | goto mem_msg; | 1501 | h->drv[drv_index].block_size = drvinfo->block_size; |
| 1373 | 1502 | h->drv[drv_index].nr_blocks = drvinfo->nr_blocks; | |
| 1374 | /* testing to see if 16-byte CDBs are already being used */ | 1503 | h->drv[drv_index].heads = drvinfo->heads; |
| 1375 | if (h->cciss_read == CCISS_READ_16) { | 1504 | h->drv[drv_index].sectors = drvinfo->sectors; |
| 1376 | cciss_read_capacity_16(h->ctlr, drv_index, 1, | 1505 | h->drv[drv_index].cylinders = drvinfo->cylinders; |
| 1377 | &total_size, &block_size); | 1506 | h->drv[drv_index].raid_level = drvinfo->raid_level; |
| 1378 | goto geo_inq; | 1507 | memcpy(h->drv[drv_index].serial_no, drvinfo->serial_no, 16); |
| 1379 | } | ||
| 1380 | |||
| 1381 | cciss_read_capacity(ctlr, drv_index, 1, | ||
| 1382 | &total_size, &block_size); | ||
| 1383 | |||
| 1384 | /* if read_capacity returns all F's this volume is >2TB in size */ | ||
| 1385 | /* so we switch to 16-byte CDB's for all read/write ops */ | ||
| 1386 | if (total_size == 0xFFFFFFFFULL) { | ||
| 1387 | cciss_read_capacity_16(ctlr, drv_index, 1, | ||
| 1388 | &total_size, &block_size); | ||
| 1389 | h->cciss_read = CCISS_READ_16; | ||
| 1390 | h->cciss_write = CCISS_WRITE_16; | ||
| 1391 | } else { | ||
| 1392 | h->cciss_read = CCISS_READ_10; | ||
| 1393 | h->cciss_write = CCISS_WRITE_10; | ||
| 1394 | } | ||
| 1395 | geo_inq: | ||
| 1396 | cciss_geometry_inquiry(ctlr, drv_index, 1, total_size, block_size, | ||
| 1397 | inq_buff, &h->drv[drv_index]); | ||
| 1398 | 1508 | ||
| 1399 | ++h->num_luns; | 1509 | ++h->num_luns; |
| 1400 | disk = h->gendisk[drv_index]; | 1510 | disk = h->gendisk[drv_index]; |
| 1401 | set_capacity(disk, h->drv[drv_index].nr_blocks); | 1511 | set_capacity(disk, h->drv[drv_index].nr_blocks); |
| 1402 | 1512 | ||
| 1403 | /* if it's the controller it's already added */ | 1513 | /* If it's not disk 0 (drv_index != 0) |
| 1404 | if (drv_index) { | 1514 | * or if it was disk 0, but there was previously |
| 1405 | disk->queue = blk_init_queue(do_cciss_request, &h->lock); | 1515 | * no actual corresponding configured logical drive |
| 1406 | sprintf(disk->disk_name, "cciss/c%dd%d", ctlr, drv_index); | 1516 | * (raid_leve == -1) then we want to update the |
| 1407 | disk->major = h->major; | 1517 | * logical drive's information. |
| 1408 | disk->first_minor = drv_index << NWD_SHIFT; | 1518 | */ |
| 1409 | disk->fops = &cciss_fops; | 1519 | if (drv_index || first_time) |
| 1410 | disk->private_data = &h->drv[drv_index]; | 1520 | cciss_add_disk(h, disk, drv_index); |
| 1411 | |||
| 1412 | /* Set up queue information */ | ||
| 1413 | blk_queue_bounce_limit(disk->queue, hba[ctlr]->pdev->dma_mask); | ||
| 1414 | |||
| 1415 | /* This is a hardware imposed limit. */ | ||
| 1416 | blk_queue_max_hw_segments(disk->queue, MAXSGENTRIES); | ||
| 1417 | |||
| 1418 | /* This is a limit in the driver and could be eliminated. */ | ||
| 1419 | blk_queue_max_phys_segments(disk->queue, MAXSGENTRIES); | ||
| 1420 | |||
| 1421 | blk_queue_max_sectors(disk->queue, h->cciss_max_sectors); | ||
| 1422 | |||
| 1423 | blk_queue_softirq_done(disk->queue, cciss_softirq_done); | ||
| 1424 | |||
| 1425 | disk->queue->queuedata = hba[ctlr]; | ||
| 1426 | |||
| 1427 | blk_queue_hardsect_size(disk->queue, | ||
| 1428 | hba[ctlr]->drv[drv_index].block_size); | ||
| 1429 | |||
| 1430 | /* Make sure all queue data is written out before */ | ||
| 1431 | /* setting h->drv[drv_index].queue, as setting this */ | ||
| 1432 | /* allows the interrupt handler to start the queue */ | ||
| 1433 | wmb(); | ||
| 1434 | h->drv[drv_index].queue = disk->queue; | ||
| 1435 | add_disk(disk); | ||
| 1436 | } | ||
| 1437 | 1521 | ||
| 1438 | freeret: | 1522 | freeret: |
| 1439 | kfree(inq_buff); | 1523 | kfree(inq_buff); |
| 1524 | kfree(drvinfo); | ||
| 1440 | return; | 1525 | return; |
| 1441 | mem_msg: | 1526 | mem_msg: |
| 1442 | printk(KERN_ERR "cciss: out of memory\n"); | 1527 | printk(KERN_ERR "cciss: out of memory\n"); |
| 1443 | goto freeret; | 1528 | goto freeret; |
| 1444 | } | 1529 | } |
| @@ -1448,21 +1533,91 @@ geo_inq: | |||
| 1448 | * where new drives will be added. If the index to be returned is greater | 1533 | * where new drives will be added. If the index to be returned is greater |
| 1449 | * than the highest_lun index for the controller then highest_lun is set | 1534 | * than the highest_lun index for the controller then highest_lun is set |
| 1450 | * to this new index. If there are no available indexes then -1 is returned. | 1535 | * to this new index. If there are no available indexes then -1 is returned. |
| 1536 | * "controller_node" is used to know if this is a real logical drive, or just | ||
| 1537 | * the controller node, which determines if this counts towards highest_lun. | ||
| 1451 | */ | 1538 | */ |
| 1452 | static int cciss_find_free_drive_index(int ctlr) | 1539 | static int cciss_find_free_drive_index(int ctlr, int controller_node) |
| 1453 | { | 1540 | { |
| 1454 | int i; | 1541 | int i; |
| 1455 | 1542 | ||
| 1456 | for (i = 0; i < CISS_MAX_LUN; i++) { | 1543 | for (i = 0; i < CISS_MAX_LUN; i++) { |
| 1457 | if (hba[ctlr]->drv[i].raid_level == -1) { | 1544 | if (hba[ctlr]->drv[i].raid_level == -1) { |
| 1458 | if (i > hba[ctlr]->highest_lun) | 1545 | if (i > hba[ctlr]->highest_lun) |
| 1459 | hba[ctlr]->highest_lun = i; | 1546 | if (!controller_node) |
| 1547 | hba[ctlr]->highest_lun = i; | ||
| 1460 | return i; | 1548 | return i; |
| 1461 | } | 1549 | } |
| 1462 | } | 1550 | } |
| 1463 | return -1; | 1551 | return -1; |
| 1464 | } | 1552 | } |
| 1465 | 1553 | ||
| 1554 | /* cciss_add_gendisk finds a free hba[]->drv structure | ||
| 1555 | * and allocates a gendisk if needed, and sets the lunid | ||
| 1556 | * in the drvinfo structure. It returns the index into | ||
| 1557 | * the ->drv[] array, or -1 if none are free. | ||
| 1558 | * is_controller_node indicates whether highest_lun should | ||
| 1559 | * count this disk, or if it's only being added to provide | ||
| 1560 | * a means to talk to the controller in case no logical | ||
| 1561 | * drives have yet been configured. | ||
| 1562 | */ | ||
| 1563 | static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node) | ||
| 1564 | { | ||
| 1565 | int drv_index; | ||
| 1566 | |||
| 1567 | drv_index = cciss_find_free_drive_index(h->ctlr, controller_node); | ||
| 1568 | if (drv_index == -1) | ||
| 1569 | return -1; | ||
| 1570 | /*Check if the gendisk needs to be allocated */ | ||
| 1571 | if (!h->gendisk[drv_index]) { | ||
| 1572 | h->gendisk[drv_index] = | ||
| 1573 | alloc_disk(1 << NWD_SHIFT); | ||
| 1574 | if (!h->gendisk[drv_index]) { | ||
| 1575 | printk(KERN_ERR "cciss%d: could not " | ||
| 1576 | "allocate a new disk %d\n", | ||
| 1577 | h->ctlr, drv_index); | ||
| 1578 | return -1; | ||
| 1579 | } | ||
| 1580 | } | ||
| 1581 | h->drv[drv_index].LunID = lunid; | ||
| 1582 | |||
| 1583 | /* Don't need to mark this busy because nobody */ | ||
| 1584 | /* else knows about this disk yet to contend */ | ||
| 1585 | /* for access to it. */ | ||
| 1586 | h->drv[drv_index].busy_configuring = 0; | ||
| 1587 | wmb(); | ||
| 1588 | return drv_index; | ||
| 1589 | } | ||
| 1590 | |||
| 1591 | /* This is for the special case of a controller which | ||
| 1592 | * has no logical drives. In this case, we still need | ||
| 1593 | * to register a disk so the controller can be accessed | ||
| 1594 | * by the Array Config Utility. | ||
| 1595 | */ | ||
| 1596 | static void cciss_add_controller_node(ctlr_info_t *h) | ||
| 1597 | { | ||
| 1598 | struct gendisk *disk; | ||
| 1599 | int drv_index; | ||
| 1600 | |||
| 1601 | if (h->gendisk[0] != NULL) /* already did this? Then bail. */ | ||
| 1602 | return; | ||
| 1603 | |||
| 1604 | drv_index = cciss_add_gendisk(h, 0, 1); | ||
| 1605 | if (drv_index == -1) { | ||
| 1606 | printk(KERN_WARNING "cciss%d: could not " | ||
| 1607 | "add disk 0.\n", h->ctlr); | ||
| 1608 | return; | ||
| 1609 | } | ||
| 1610 | h->drv[drv_index].block_size = 512; | ||
| 1611 | h->drv[drv_index].nr_blocks = 0; | ||
| 1612 | h->drv[drv_index].heads = 0; | ||
| 1613 | h->drv[drv_index].sectors = 0; | ||
| 1614 | h->drv[drv_index].cylinders = 0; | ||
| 1615 | h->drv[drv_index].raid_level = -1; | ||
| 1616 | memset(h->drv[drv_index].serial_no, 0, 16); | ||
| 1617 | disk = h->gendisk[drv_index]; | ||
| 1618 | cciss_add_disk(h, disk, drv_index); | ||
| 1619 | } | ||
| 1620 | |||
| 1466 | /* This function will add and remove logical drives from the Logical | 1621 | /* This function will add and remove logical drives from the Logical |
| 1467 | * drive array of the controller and maintain persistency of ordering | 1622 | * drive array of the controller and maintain persistency of ordering |
| 1468 | * so that mount points are preserved until the next reboot. This allows | 1623 | * so that mount points are preserved until the next reboot. This allows |
| @@ -1470,15 +1625,12 @@ static int cciss_find_free_drive_index(int ctlr) | |||
| 1470 | * without a re-ordering of those drives. | 1625 | * without a re-ordering of those drives. |
| 1471 | * INPUT | 1626 | * INPUT |
| 1472 | * h = The controller to perform the operations on | 1627 | * h = The controller to perform the operations on |
| 1473 | * del_disk = The disk to remove if specified. If the value given | ||
| 1474 | * is NULL then no disk is removed. | ||
| 1475 | */ | 1628 | */ |
| 1476 | static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | 1629 | static int rebuild_lun_table(ctlr_info_t *h, int first_time) |
| 1477 | { | 1630 | { |
| 1478 | int ctlr = h->ctlr; | 1631 | int ctlr = h->ctlr; |
| 1479 | int num_luns; | 1632 | int num_luns; |
| 1480 | ReportLunData_struct *ld_buff = NULL; | 1633 | ReportLunData_struct *ld_buff = NULL; |
| 1481 | drive_info_struct *drv = NULL; | ||
| 1482 | int return_code; | 1634 | int return_code; |
| 1483 | int listlength = 0; | 1635 | int listlength = 0; |
| 1484 | int i; | 1636 | int i; |
| @@ -1487,6 +1639,9 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | |||
| 1487 | __u32 lunid = 0; | 1639 | __u32 lunid = 0; |
| 1488 | unsigned long flags; | 1640 | unsigned long flags; |
| 1489 | 1641 | ||
| 1642 | if (!capable(CAP_SYS_RAWIO)) | ||
| 1643 | return -EPERM; | ||
| 1644 | |||
| 1490 | /* Set busy_configuring flag for this operation */ | 1645 | /* Set busy_configuring flag for this operation */ |
| 1491 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 1646 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); |
| 1492 | if (h->busy_configuring) { | 1647 | if (h->busy_configuring) { |
| @@ -1494,100 +1649,100 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | |||
| 1494 | return -EBUSY; | 1649 | return -EBUSY; |
| 1495 | } | 1650 | } |
| 1496 | h->busy_configuring = 1; | 1651 | h->busy_configuring = 1; |
| 1652 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
| 1497 | 1653 | ||
| 1498 | /* if del_disk is NULL then we are being called to add a new disk | 1654 | ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); |
| 1499 | * and update the logical drive table. If it is not NULL then | 1655 | if (ld_buff == NULL) |
| 1500 | * we will check if the disk is in use or not. | 1656 | goto mem_msg; |
| 1501 | */ | ||
| 1502 | if (del_disk != NULL) { | ||
| 1503 | drv = get_drv(del_disk); | ||
| 1504 | drv->busy_configuring = 1; | ||
| 1505 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
| 1506 | return_code = deregister_disk(del_disk, drv, 1); | ||
| 1507 | drv->busy_configuring = 0; | ||
| 1508 | h->busy_configuring = 0; | ||
| 1509 | return return_code; | ||
| 1510 | } else { | ||
| 1511 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
| 1512 | if (!capable(CAP_SYS_RAWIO)) | ||
| 1513 | return -EPERM; | ||
| 1514 | 1657 | ||
| 1515 | ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); | 1658 | return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff, |
| 1516 | if (ld_buff == NULL) | 1659 | sizeof(ReportLunData_struct), 0, |
| 1517 | goto mem_msg; | 1660 | 0, 0, TYPE_CMD); |
| 1518 | |||
| 1519 | return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff, | ||
| 1520 | sizeof(ReportLunData_struct), 0, | ||
| 1521 | 0, 0, TYPE_CMD); | ||
| 1522 | |||
| 1523 | if (return_code == IO_OK) { | ||
| 1524 | listlength = | ||
| 1525 | be32_to_cpu(*(__be32 *) ld_buff->LUNListLength); | ||
| 1526 | } else { /* reading number of logical volumes failed */ | ||
| 1527 | printk(KERN_WARNING "cciss: report logical volume" | ||
| 1528 | " command failed\n"); | ||
| 1529 | listlength = 0; | ||
| 1530 | goto freeret; | ||
| 1531 | } | ||
| 1532 | 1661 | ||
| 1533 | num_luns = listlength / 8; /* 8 bytes per entry */ | 1662 | if (return_code == IO_OK) |
| 1534 | if (num_luns > CISS_MAX_LUN) { | 1663 | listlength = be32_to_cpu(*(__be32 *) ld_buff->LUNListLength); |
| 1535 | num_luns = CISS_MAX_LUN; | 1664 | else { /* reading number of logical volumes failed */ |
| 1536 | printk(KERN_WARNING "cciss: more luns configured" | 1665 | printk(KERN_WARNING "cciss: report logical volume" |
| 1537 | " on controller than can be handled by" | 1666 | " command failed\n"); |
| 1538 | " this driver.\n"); | 1667 | listlength = 0; |
| 1668 | goto freeret; | ||
| 1669 | } | ||
| 1670 | |||
| 1671 | num_luns = listlength / 8; /* 8 bytes per entry */ | ||
| 1672 | if (num_luns > CISS_MAX_LUN) { | ||
| 1673 | num_luns = CISS_MAX_LUN; | ||
| 1674 | printk(KERN_WARNING "cciss: more luns configured" | ||
| 1675 | " on controller than can be handled by" | ||
| 1676 | " this driver.\n"); | ||
| 1677 | } | ||
| 1678 | |||
| 1679 | if (num_luns == 0) | ||
| 1680 | cciss_add_controller_node(h); | ||
| 1681 | |||
| 1682 | /* Compare controller drive array to driver's drive array | ||
| 1683 | * to see if any drives are missing on the controller due | ||
| 1684 | * to action of Array Config Utility (user deletes drive) | ||
| 1685 | * and deregister logical drives which have disappeared. | ||
| 1686 | */ | ||
| 1687 | for (i = 0; i <= h->highest_lun; i++) { | ||
| 1688 | int j; | ||
| 1689 | drv_found = 0; | ||
| 1690 | for (j = 0; j < num_luns; j++) { | ||
| 1691 | memcpy(&lunid, &ld_buff->LUN[j][0], 4); | ||
| 1692 | lunid = le32_to_cpu(lunid); | ||
| 1693 | if (h->drv[i].LunID == lunid) { | ||
| 1694 | drv_found = 1; | ||
| 1695 | break; | ||
| 1696 | } | ||
| 1539 | } | 1697 | } |
| 1698 | if (!drv_found) { | ||
| 1699 | /* Deregister it from the OS, it's gone. */ | ||
| 1700 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | ||
| 1701 | h->drv[i].busy_configuring = 1; | ||
| 1702 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
| 1703 | return_code = deregister_disk(h->gendisk[i], | ||
| 1704 | &h->drv[i], 1); | ||
| 1705 | h->drv[i].busy_configuring = 0; | ||
| 1706 | } | ||
| 1707 | } | ||
| 1708 | |||
| 1709 | /* Compare controller drive array to driver's drive array. | ||
| 1710 | * Check for updates in the drive information and any new drives | ||
| 1711 | * on the controller due to ACU adding logical drives, or changing | ||
| 1712 | * a logical drive's size, etc. Reregister any new/changed drives | ||
| 1713 | */ | ||
| 1714 | for (i = 0; i < num_luns; i++) { | ||
| 1715 | int j; | ||
| 1540 | 1716 | ||
| 1541 | /* Compare controller drive array to drivers drive array. | 1717 | drv_found = 0; |
| 1542 | * Check for updates in the drive information and any new drives | 1718 | |
| 1543 | * on the controller. | 1719 | memcpy(&lunid, &ld_buff->LUN[i][0], 4); |
| 1720 | lunid = le32_to_cpu(lunid); | ||
| 1721 | |||
| 1722 | /* Find if the LUN is already in the drive array | ||
| 1723 | * of the driver. If so then update its info | ||
| 1724 | * if not in use. If it does not exist then find | ||
| 1725 | * the first free index and add it. | ||
| 1544 | */ | 1726 | */ |
| 1545 | for (i = 0; i < num_luns; i++) { | 1727 | for (j = 0; j <= h->highest_lun; j++) { |
| 1546 | int j; | 1728 | if (h->drv[j].raid_level != -1 && |
| 1547 | 1729 | h->drv[j].LunID == lunid) { | |
| 1548 | drv_found = 0; | 1730 | drv_index = j; |
| 1549 | 1731 | drv_found = 1; | |
| 1550 | lunid = (0xff & | 1732 | break; |
| 1551 | (unsigned int)(ld_buff->LUN[i][3])) << 24; | ||
| 1552 | lunid |= (0xff & | ||
| 1553 | (unsigned int)(ld_buff->LUN[i][2])) << 16; | ||
| 1554 | lunid |= (0xff & | ||
| 1555 | (unsigned int)(ld_buff->LUN[i][1])) << 8; | ||
| 1556 | lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]); | ||
| 1557 | |||
| 1558 | /* Find if the LUN is already in the drive array | ||
| 1559 | * of the controller. If so then update its info | ||
| 1560 | * if not is use. If it does not exist then find | ||
| 1561 | * the first free index and add it. | ||
| 1562 | */ | ||
| 1563 | for (j = 0; j <= h->highest_lun; j++) { | ||
| 1564 | if (h->drv[j].LunID == lunid) { | ||
| 1565 | drv_index = j; | ||
| 1566 | drv_found = 1; | ||
| 1567 | } | ||
| 1568 | } | 1733 | } |
| 1734 | } | ||
| 1569 | 1735 | ||
| 1570 | /* check if the drive was found already in the array */ | 1736 | /* check if the drive was found already in the array */ |
| 1571 | if (!drv_found) { | 1737 | if (!drv_found) { |
| 1572 | drv_index = cciss_find_free_drive_index(ctlr); | 1738 | drv_index = cciss_add_gendisk(h, lunid, 0); |
| 1573 | if (drv_index == -1) | 1739 | if (drv_index == -1) |
| 1574 | goto freeret; | 1740 | goto freeret; |
| 1575 | 1741 | } | |
| 1576 | /*Check if the gendisk needs to be allocated */ | 1742 | cciss_update_drive_info(ctlr, drv_index, first_time); |
| 1577 | if (!h->gendisk[drv_index]){ | 1743 | } /* end for */ |
| 1578 | h->gendisk[drv_index] = alloc_disk(1 << NWD_SHIFT); | ||
| 1579 | if (!h->gendisk[drv_index]){ | ||
| 1580 | printk(KERN_ERR "cciss: could not allocate new disk %d\n", drv_index); | ||
| 1581 | goto mem_msg; | ||
| 1582 | } | ||
| 1583 | } | ||
| 1584 | } | ||
| 1585 | h->drv[drv_index].LunID = lunid; | ||
| 1586 | cciss_update_drive_info(ctlr, drv_index); | ||
| 1587 | } /* end for */ | ||
| 1588 | } /* end else */ | ||
| 1589 | 1744 | ||
| 1590 | freeret: | 1745 | freeret: |
| 1591 | kfree(ld_buff); | 1746 | kfree(ld_buff); |
| 1592 | h->busy_configuring = 0; | 1747 | h->busy_configuring = 0; |
| 1593 | /* We return -1 here to tell the ACU that we have registered/updated | 1748 | /* We return -1 here to tell the ACU that we have registered/updated |
| @@ -1595,8 +1750,9 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | |||
| 1595 | * additional times. | 1750 | * additional times. |
| 1596 | */ | 1751 | */ |
| 1597 | return -1; | 1752 | return -1; |
| 1598 | mem_msg: | 1753 | mem_msg: |
| 1599 | printk(KERN_ERR "cciss: out of memory\n"); | 1754 | printk(KERN_ERR "cciss: out of memory\n"); |
| 1755 | h->busy_configuring = 0; | ||
| 1600 | goto freeret; | 1756 | goto freeret; |
| 1601 | } | 1757 | } |
| 1602 | 1758 | ||
| @@ -1652,15 +1808,15 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, | |||
| 1652 | * other than disk 0 we will call put_disk. We do not | 1808 | * other than disk 0 we will call put_disk. We do not |
| 1653 | * do this for disk 0 as we need it to be able to | 1809 | * do this for disk 0 as we need it to be able to |
| 1654 | * configure the controller. | 1810 | * configure the controller. |
| 1655 | */ | 1811 | */ |
| 1656 | if (clear_all){ | 1812 | if (clear_all){ |
| 1657 | /* This isn't pretty, but we need to find the | 1813 | /* This isn't pretty, but we need to find the |
| 1658 | * disk in our array and NULL our the pointer. | 1814 | * disk in our array and NULL our the pointer. |
| 1659 | * This is so that we will call alloc_disk if | 1815 | * This is so that we will call alloc_disk if |
| 1660 | * this index is used again later. | 1816 | * this index is used again later. |
| 1661 | */ | 1817 | */ |
| 1662 | for (i=0; i < CISS_MAX_LUN; i++){ | 1818 | for (i=0; i < CISS_MAX_LUN; i++){ |
| 1663 | if(h->gendisk[i] == disk){ | 1819 | if (h->gendisk[i] == disk) { |
| 1664 | h->gendisk[i] = NULL; | 1820 | h->gendisk[i] = NULL; |
| 1665 | break; | 1821 | break; |
| 1666 | } | 1822 | } |
| @@ -1688,7 +1844,7 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, | |||
| 1688 | if (drv == h->drv + h->highest_lun) { | 1844 | if (drv == h->drv + h->highest_lun) { |
| 1689 | /* if so, find the new hightest lun */ | 1845 | /* if so, find the new hightest lun */ |
| 1690 | int i, newhighest = -1; | 1846 | int i, newhighest = -1; |
| 1691 | for (i = 0; i < h->highest_lun; i++) { | 1847 | for (i = 0; i <= h->highest_lun; i++) { |
| 1692 | /* if the disk has size > 0, it is available */ | 1848 | /* if the disk has size > 0, it is available */ |
| 1693 | if (h->drv[i].heads) | 1849 | if (h->drv[i].heads) |
| 1694 | newhighest = i; | 1850 | newhighest = i; |
| @@ -3199,136 +3355,9 @@ err_out_free_res: | |||
| 3199 | return err; | 3355 | return err; |
| 3200 | } | 3356 | } |
| 3201 | 3357 | ||
| 3202 | /* | 3358 | /* Function to find the first free pointer into our hba[] array |
| 3203 | * Gets information about the local volumes attached to the controller. | 3359 | * Returns -1 if no free entries are left. |
| 3204 | */ | 3360 | */ |
| 3205 | static void cciss_getgeometry(int cntl_num) | ||
| 3206 | { | ||
| 3207 | ReportLunData_struct *ld_buff; | ||
| 3208 | InquiryData_struct *inq_buff; | ||
| 3209 | int return_code; | ||
| 3210 | int i; | ||
| 3211 | int listlength = 0; | ||
| 3212 | __u32 lunid = 0; | ||
| 3213 | unsigned block_size; | ||
| 3214 | sector_t total_size; | ||
| 3215 | |||
| 3216 | ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); | ||
| 3217 | if (ld_buff == NULL) { | ||
| 3218 | printk(KERN_ERR "cciss: out of memory\n"); | ||
| 3219 | return; | ||
| 3220 | } | ||
| 3221 | inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); | ||
| 3222 | if (inq_buff == NULL) { | ||
| 3223 | printk(KERN_ERR "cciss: out of memory\n"); | ||
| 3224 | kfree(ld_buff); | ||
| 3225 | return; | ||
| 3226 | } | ||
| 3227 | /* Get the firmware version */ | ||
| 3228 | return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff, | ||
| 3229 | sizeof(InquiryData_struct), 0, 0, 0, NULL, | ||
| 3230 | TYPE_CMD); | ||
| 3231 | if (return_code == IO_OK) { | ||
| 3232 | hba[cntl_num]->firm_ver[0] = inq_buff->data_byte[32]; | ||
| 3233 | hba[cntl_num]->firm_ver[1] = inq_buff->data_byte[33]; | ||
| 3234 | hba[cntl_num]->firm_ver[2] = inq_buff->data_byte[34]; | ||
| 3235 | hba[cntl_num]->firm_ver[3] = inq_buff->data_byte[35]; | ||
| 3236 | } else { /* send command failed */ | ||
| 3237 | |||
| 3238 | printk(KERN_WARNING "cciss: unable to determine firmware" | ||
| 3239 | " version of controller\n"); | ||
| 3240 | } | ||
| 3241 | /* Get the number of logical volumes */ | ||
| 3242 | return_code = sendcmd(CISS_REPORT_LOG, cntl_num, ld_buff, | ||
| 3243 | sizeof(ReportLunData_struct), 0, 0, 0, NULL, | ||
| 3244 | TYPE_CMD); | ||
| 3245 | |||
| 3246 | if (return_code == IO_OK) { | ||
| 3247 | #ifdef CCISS_DEBUG | ||
| 3248 | printk("LUN Data\n--------------------------\n"); | ||
| 3249 | #endif /* CCISS_DEBUG */ | ||
| 3250 | |||
| 3251 | listlength |= | ||
| 3252 | (0xff & (unsigned int)(ld_buff->LUNListLength[0])) << 24; | ||
| 3253 | listlength |= | ||
| 3254 | (0xff & (unsigned int)(ld_buff->LUNListLength[1])) << 16; | ||
| 3255 | listlength |= | ||
| 3256 | (0xff & (unsigned int)(ld_buff->LUNListLength[2])) << 8; | ||
| 3257 | listlength |= 0xff & (unsigned int)(ld_buff->LUNListLength[3]); | ||
| 3258 | } else { /* reading number of logical volumes failed */ | ||
| 3259 | |||
| 3260 | printk(KERN_WARNING "cciss: report logical volume" | ||
| 3261 | " command failed\n"); | ||
| 3262 | listlength = 0; | ||
| 3263 | } | ||
| 3264 | hba[cntl_num]->num_luns = listlength / 8; // 8 bytes pre entry | ||
| 3265 | if (hba[cntl_num]->num_luns > CISS_MAX_LUN) { | ||
| 3266 | printk(KERN_ERR | ||
| 3267 | "ciss: only %d number of logical volumes supported\n", | ||
| 3268 | CISS_MAX_LUN); | ||
| 3269 | hba[cntl_num]->num_luns = CISS_MAX_LUN; | ||
| 3270 | } | ||
| 3271 | #ifdef CCISS_DEBUG | ||
| 3272 | printk(KERN_DEBUG "Length = %x %x %x %x = %d\n", | ||
| 3273 | ld_buff->LUNListLength[0], ld_buff->LUNListLength[1], | ||
| 3274 | ld_buff->LUNListLength[2], ld_buff->LUNListLength[3], | ||
| 3275 | hba[cntl_num]->num_luns); | ||
| 3276 | #endif /* CCISS_DEBUG */ | ||
| 3277 | |||
| 3278 | hba[cntl_num]->highest_lun = hba[cntl_num]->num_luns - 1; | ||
| 3279 | for (i = 0; i < CISS_MAX_LUN; i++) { | ||
| 3280 | if (i < hba[cntl_num]->num_luns) { | ||
| 3281 | lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3])) | ||
| 3282 | << 24; | ||
| 3283 | lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][2])) | ||
| 3284 | << 16; | ||
| 3285 | lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][1])) | ||
| 3286 | << 8; | ||
| 3287 | lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]); | ||
| 3288 | |||
| 3289 | hba[cntl_num]->drv[i].LunID = lunid; | ||
| 3290 | |||
| 3291 | #ifdef CCISS_DEBUG | ||
| 3292 | printk(KERN_DEBUG "LUN[%d]: %x %x %x %x = %x\n", i, | ||
| 3293 | ld_buff->LUN[i][0], ld_buff->LUN[i][1], | ||
| 3294 | ld_buff->LUN[i][2], ld_buff->LUN[i][3], | ||
| 3295 | hba[cntl_num]->drv[i].LunID); | ||
| 3296 | #endif /* CCISS_DEBUG */ | ||
| 3297 | |||
| 3298 | /* testing to see if 16-byte CDBs are already being used */ | ||
| 3299 | if(hba[cntl_num]->cciss_read == CCISS_READ_16) { | ||
| 3300 | cciss_read_capacity_16(cntl_num, i, 0, | ||
| 3301 | &total_size, &block_size); | ||
| 3302 | goto geo_inq; | ||
| 3303 | } | ||
| 3304 | cciss_read_capacity(cntl_num, i, 0, &total_size, &block_size); | ||
| 3305 | |||
| 3306 | /* If read_capacity returns all F's the logical is >2TB */ | ||
| 3307 | /* so we switch to 16-byte CDBs for all read/write ops */ | ||
| 3308 | if(total_size == 0xFFFFFFFFULL) { | ||
| 3309 | cciss_read_capacity_16(cntl_num, i, 0, | ||
| 3310 | &total_size, &block_size); | ||
| 3311 | hba[cntl_num]->cciss_read = CCISS_READ_16; | ||
| 3312 | hba[cntl_num]->cciss_write = CCISS_WRITE_16; | ||
| 3313 | } else { | ||
| 3314 | hba[cntl_num]->cciss_read = CCISS_READ_10; | ||
| 3315 | hba[cntl_num]->cciss_write = CCISS_WRITE_10; | ||
| 3316 | } | ||
| 3317 | geo_inq: | ||
| 3318 | cciss_geometry_inquiry(cntl_num, i, 0, total_size, | ||
| 3319 | block_size, inq_buff, | ||
| 3320 | &hba[cntl_num]->drv[i]); | ||
| 3321 | } else { | ||
| 3322 | /* initialize raid_level to indicate a free space */ | ||
| 3323 | hba[cntl_num]->drv[i].raid_level = -1; | ||
| 3324 | } | ||
| 3325 | } | ||
| 3326 | kfree(ld_buff); | ||
| 3327 | kfree(inq_buff); | ||
| 3328 | } | ||
| 3329 | |||
| 3330 | /* Function to find the first free pointer into our hba[] array */ | ||
| 3331 | /* Returns -1 if no free entries are left. */ | ||
| 3332 | static int alloc_cciss_hba(void) | 3361 | static int alloc_cciss_hba(void) |
| 3333 | { | 3362 | { |
| 3334 | int i; | 3363 | int i; |
| @@ -3340,11 +3369,6 @@ static int alloc_cciss_hba(void) | |||
| 3340 | p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL); | 3369 | p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL); |
| 3341 | if (!p) | 3370 | if (!p) |
| 3342 | goto Enomem; | 3371 | goto Enomem; |
| 3343 | p->gendisk[0] = alloc_disk(1 << NWD_SHIFT); | ||
| 3344 | if (!p->gendisk[0]) { | ||
| 3345 | kfree(p); | ||
| 3346 | goto Enomem; | ||
| 3347 | } | ||
| 3348 | hba[i] = p; | 3372 | hba[i] = p; |
| 3349 | return i; | 3373 | return i; |
| 3350 | } | 3374 | } |
| @@ -3472,11 +3496,13 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
| 3472 | ((hba[i]->nr_cmds + BITS_PER_LONG - | 3496 | ((hba[i]->nr_cmds + BITS_PER_LONG - |
| 3473 | 1) / BITS_PER_LONG) * sizeof(unsigned long)); | 3497 | 1) / BITS_PER_LONG) * sizeof(unsigned long)); |
| 3474 | 3498 | ||
| 3475 | #ifdef CCISS_DEBUG | 3499 | hba[i]->num_luns = 0; |
| 3476 | printk(KERN_DEBUG "Scanning for drives on controller cciss%d\n", i); | 3500 | hba[i]->highest_lun = -1; |
| 3477 | #endif /* CCISS_DEBUG */ | 3501 | for (j = 0; j < CISS_MAX_LUN; j++) { |
| 3478 | 3502 | hba[i]->drv[j].raid_level = -1; | |
| 3479 | cciss_getgeometry(i); | 3503 | hba[i]->drv[j].queue = NULL; |
| 3504 | hba[i]->gendisk[j] = NULL; | ||
| 3505 | } | ||
| 3480 | 3506 | ||
| 3481 | cciss_scsi_setup(i); | 3507 | cciss_scsi_setup(i); |
| 3482 | 3508 | ||
| @@ -3489,76 +3515,10 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
| 3489 | 3515 | ||
| 3490 | hba[i]->busy_initializing = 0; | 3516 | hba[i]->busy_initializing = 0; |
| 3491 | 3517 | ||
| 3492 | do { | 3518 | rebuild_lun_table(hba[i], 1); |
| 3493 | drive_info_struct *drv = &(hba[i]->drv[j]); | ||
| 3494 | struct gendisk *disk = hba[i]->gendisk[j]; | ||
| 3495 | struct request_queue *q; | ||
| 3496 | |||
| 3497 | /* Check if the disk was allocated already */ | ||
| 3498 | if (!disk){ | ||
| 3499 | hba[i]->gendisk[j] = alloc_disk(1 << NWD_SHIFT); | ||
| 3500 | disk = hba[i]->gendisk[j]; | ||
| 3501 | } | ||
| 3502 | |||
| 3503 | /* Check that the disk was able to be allocated */ | ||
| 3504 | if (!disk) { | ||
| 3505 | printk(KERN_ERR "cciss: unable to allocate memory for disk %d\n", j); | ||
| 3506 | goto clean4; | ||
| 3507 | } | ||
| 3508 | |||
| 3509 | q = blk_init_queue(do_cciss_request, &hba[i]->lock); | ||
| 3510 | if (!q) { | ||
| 3511 | printk(KERN_ERR | ||
| 3512 | "cciss: unable to allocate queue for disk %d\n", | ||
| 3513 | j); | ||
| 3514 | goto clean4; | ||
| 3515 | } | ||
| 3516 | drv->queue = q; | ||
| 3517 | |||
| 3518 | blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); | ||
| 3519 | |||
| 3520 | /* This is a hardware imposed limit. */ | ||
| 3521 | blk_queue_max_hw_segments(q, MAXSGENTRIES); | ||
| 3522 | |||
| 3523 | /* This is a limit in the driver and could be eliminated. */ | ||
| 3524 | blk_queue_max_phys_segments(q, MAXSGENTRIES); | ||
| 3525 | |||
| 3526 | blk_queue_max_sectors(q, hba[i]->cciss_max_sectors); | ||
| 3527 | |||
| 3528 | blk_queue_softirq_done(q, cciss_softirq_done); | ||
| 3529 | |||
| 3530 | q->queuedata = hba[i]; | ||
| 3531 | sprintf(disk->disk_name, "cciss/c%dd%d", i, j); | ||
| 3532 | disk->major = hba[i]->major; | ||
| 3533 | disk->first_minor = j << NWD_SHIFT; | ||
| 3534 | disk->fops = &cciss_fops; | ||
| 3535 | disk->queue = q; | ||
| 3536 | disk->private_data = drv; | ||
| 3537 | disk->driverfs_dev = &pdev->dev; | ||
| 3538 | /* we must register the controller even if no disks exist */ | ||
| 3539 | /* this is for the online array utilities */ | ||
| 3540 | if (!drv->heads && j) | ||
| 3541 | continue; | ||
| 3542 | blk_queue_hardsect_size(q, drv->block_size); | ||
| 3543 | set_capacity(disk, drv->nr_blocks); | ||
| 3544 | j++; | ||
| 3545 | } while (j <= hba[i]->highest_lun); | ||
| 3546 | |||
| 3547 | /* Make sure all queue data is written out before */ | ||
| 3548 | /* interrupt handler, triggered by add_disk, */ | ||
| 3549 | /* is allowed to start them. */ | ||
| 3550 | wmb(); | ||
| 3551 | |||
| 3552 | for (j = 0; j <= hba[i]->highest_lun; j++) | ||
| 3553 | add_disk(hba[i]->gendisk[j]); | ||
| 3554 | |||
| 3555 | /* we must register the controller even if no disks exist */ | ||
| 3556 | if (hba[i]->highest_lun == -1) | ||
| 3557 | add_disk(hba[i]->gendisk[0]); | ||
| 3558 | |||
| 3559 | return 1; | 3519 | return 1; |
| 3560 | 3520 | ||
| 3561 | clean4: | 3521 | clean4: |
| 3562 | #ifdef CONFIG_CISS_SCSI_TAPE | 3522 | #ifdef CONFIG_CISS_SCSI_TAPE |
| 3563 | kfree(hba[i]->scsi_rejects.complete); | 3523 | kfree(hba[i]->scsi_rejects.complete); |
| 3564 | #endif | 3524 | #endif |
| @@ -3573,9 +3533,9 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
| 3573 | hba[i]->errinfo_pool, | 3533 | hba[i]->errinfo_pool, |
| 3574 | hba[i]->errinfo_pool_dhandle); | 3534 | hba[i]->errinfo_pool_dhandle); |
| 3575 | free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]); | 3535 | free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]); |
| 3576 | clean2: | 3536 | clean2: |
| 3577 | unregister_blkdev(hba[i]->major, hba[i]->devname); | 3537 | unregister_blkdev(hba[i]->major, hba[i]->devname); |
| 3578 | clean1: | 3538 | clean1: |
| 3579 | hba[i]->busy_initializing = 0; | 3539 | hba[i]->busy_initializing = 0; |
| 3580 | /* cleanup any queues that may have been initialized */ | 3540 | /* cleanup any queues that may have been initialized */ |
| 3581 | for (j=0; j <= hba[i]->highest_lun; j++){ | 3541 | for (j=0; j <= hba[i]->highest_lun; j++){ |
| @@ -3654,7 +3614,9 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) | |||
| 3654 | } | 3614 | } |
| 3655 | } | 3615 | } |
| 3656 | 3616 | ||
| 3617 | #ifdef CONFIG_CISS_SCSI_TAPE | ||
| 3657 | cciss_unregister_scsi(i); /* unhook from SCSI subsystem */ | 3618 | cciss_unregister_scsi(i); /* unhook from SCSI subsystem */ |
| 3619 | #endif | ||
| 3658 | 3620 | ||
| 3659 | cciss_shutdown(pdev); | 3621 | cciss_shutdown(pdev); |
| 3660 | 3622 | ||
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index b70988dd33ec..24a7efa993ab 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h | |||
| @@ -39,6 +39,8 @@ typedef struct _drive_info_struct | |||
| 39 | *to prevent it from being opened or it's queue | 39 | *to prevent it from being opened or it's queue |
| 40 | *from being started. | 40 | *from being started. |
| 41 | */ | 41 | */ |
| 42 | __u8 serial_no[16]; /* from inquiry page 0x83, */ | ||
| 43 | /* not necc. null terminated. */ | ||
| 42 | } drive_info_struct; | 44 | } drive_info_struct; |
| 43 | 45 | ||
| 44 | #ifdef CONFIG_CISS_SCSI_TAPE | 46 | #ifdef CONFIG_CISS_SCSI_TAPE |
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index e4bf9a11ca0d..e1233aabda77 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c | |||
| @@ -358,23 +358,68 @@ find_bus_target_lun(int ctlr, int *bus, int *target, int *lun) | |||
| 358 | } | 358 | } |
| 359 | return (!found); | 359 | return (!found); |
| 360 | } | 360 | } |
| 361 | struct scsi2map { | ||
| 362 | char scsi3addr[8]; | ||
| 363 | int bus, target, lun; | ||
| 364 | }; | ||
| 361 | 365 | ||
| 362 | static int | 366 | static int |
| 363 | cciss_scsi_add_entry(int ctlr, int hostno, | 367 | cciss_scsi_add_entry(int ctlr, int hostno, |
| 364 | unsigned char *scsi3addr, int devtype) | 368 | unsigned char *scsi3addr, int devtype, |
| 369 | struct scsi2map *added, int *nadded) | ||
| 365 | { | 370 | { |
| 366 | /* assumes hba[ctlr]->scsi_ctlr->lock is held */ | 371 | /* assumes hba[ctlr]->scsi_ctlr->lock is held */ |
| 367 | int n = ccissscsi[ctlr].ndevices; | 372 | int n = ccissscsi[ctlr].ndevices; |
| 368 | struct cciss_scsi_dev_t *sd; | 373 | struct cciss_scsi_dev_t *sd; |
| 374 | int i, bus, target, lun; | ||
| 375 | unsigned char addr1[8], addr2[8]; | ||
| 369 | 376 | ||
| 370 | if (n >= CCISS_MAX_SCSI_DEVS_PER_HBA) { | 377 | if (n >= CCISS_MAX_SCSI_DEVS_PER_HBA) { |
| 371 | printk("cciss%d: Too many devices, " | 378 | printk("cciss%d: Too many devices, " |
| 372 | "some will be inaccessible.\n", ctlr); | 379 | "some will be inaccessible.\n", ctlr); |
| 373 | return -1; | 380 | return -1; |
| 374 | } | 381 | } |
| 382 | |||
| 383 | bus = target = -1; | ||
| 384 | lun = 0; | ||
| 385 | /* Is this device a non-zero lun of a multi-lun device */ | ||
| 386 | /* byte 4 of the 8-byte LUN addr will contain the logical unit no. */ | ||
| 387 | if (scsi3addr[4] != 0) { | ||
| 388 | /* Search through our list and find the device which */ | ||
| 389 | /* has the same 8 byte LUN address, excepting byte 4. */ | ||
| 390 | /* Assign the same bus and target for this new LUN. */ | ||
| 391 | /* Use the logical unit number from the firmware. */ | ||
| 392 | memcpy(addr1, scsi3addr, 8); | ||
| 393 | addr1[4] = 0; | ||
| 394 | for (i = 0; i < n; i++) { | ||
| 395 | sd = &ccissscsi[ctlr].dev[i]; | ||
| 396 | memcpy(addr2, sd->scsi3addr, 8); | ||
| 397 | addr2[4] = 0; | ||
| 398 | /* differ only in byte 4? */ | ||
| 399 | if (memcmp(addr1, addr2, 8) == 0) { | ||
| 400 | bus = sd->bus; | ||
| 401 | target = sd->target; | ||
| 402 | lun = scsi3addr[4]; | ||
| 403 | break; | ||
| 404 | } | ||
| 405 | } | ||
| 406 | } | ||
| 407 | |||
| 375 | sd = &ccissscsi[ctlr].dev[n]; | 408 | sd = &ccissscsi[ctlr].dev[n]; |
| 376 | if (find_bus_target_lun(ctlr, &sd->bus, &sd->target, &sd->lun) != 0) | 409 | if (lun == 0) { |
| 377 | return -1; | 410 | if (find_bus_target_lun(ctlr, |
| 411 | &sd->bus, &sd->target, &sd->lun) != 0) | ||
| 412 | return -1; | ||
| 413 | } else { | ||
| 414 | sd->bus = bus; | ||
| 415 | sd->target = target; | ||
| 416 | sd->lun = lun; | ||
| 417 | } | ||
| 418 | added[*nadded].bus = sd->bus; | ||
| 419 | added[*nadded].target = sd->target; | ||
| 420 | added[*nadded].lun = sd->lun; | ||
| 421 | (*nadded)++; | ||
| 422 | |||
| 378 | memcpy(&sd->scsi3addr[0], scsi3addr, 8); | 423 | memcpy(&sd->scsi3addr[0], scsi3addr, 8); |
| 379 | sd->devtype = devtype; | 424 | sd->devtype = devtype; |
| 380 | ccissscsi[ctlr].ndevices++; | 425 | ccissscsi[ctlr].ndevices++; |
| @@ -390,7 +435,8 @@ cciss_scsi_add_entry(int ctlr, int hostno, | |||
| 390 | } | 435 | } |
| 391 | 436 | ||
| 392 | static void | 437 | static void |
| 393 | cciss_scsi_remove_entry(int ctlr, int hostno, int entry) | 438 | cciss_scsi_remove_entry(int ctlr, int hostno, int entry, |
| 439 | struct scsi2map *removed, int *nremoved) | ||
| 394 | { | 440 | { |
| 395 | /* assumes hba[ctlr]->scsi_ctlr->lock is held */ | 441 | /* assumes hba[ctlr]->scsi_ctlr->lock is held */ |
| 396 | int i; | 442 | int i; |
| @@ -398,6 +444,10 @@ cciss_scsi_remove_entry(int ctlr, int hostno, int entry) | |||
| 398 | 444 | ||
| 399 | if (entry < 0 || entry >= CCISS_MAX_SCSI_DEVS_PER_HBA) return; | 445 | if (entry < 0 || entry >= CCISS_MAX_SCSI_DEVS_PER_HBA) return; |
| 400 | sd = ccissscsi[ctlr].dev[entry]; | 446 | sd = ccissscsi[ctlr].dev[entry]; |
| 447 | removed[*nremoved].bus = sd.bus; | ||
| 448 | removed[*nremoved].target = sd.target; | ||
| 449 | removed[*nremoved].lun = sd.lun; | ||
| 450 | (*nremoved)++; | ||
| 401 | for (i=entry;i<ccissscsi[ctlr].ndevices-1;i++) | 451 | for (i=entry;i<ccissscsi[ctlr].ndevices-1;i++) |
| 402 | ccissscsi[ctlr].dev[i] = ccissscsi[ctlr].dev[i+1]; | 452 | ccissscsi[ctlr].dev[i] = ccissscsi[ctlr].dev[i+1]; |
| 403 | ccissscsi[ctlr].ndevices--; | 453 | ccissscsi[ctlr].ndevices--; |
| @@ -417,6 +467,26 @@ cciss_scsi_remove_entry(int ctlr, int hostno, int entry) | |||
| 417 | (a)[1] == (b)[1] && \ | 467 | (a)[1] == (b)[1] && \ |
| 418 | (a)[0] == (b)[0]) | 468 | (a)[0] == (b)[0]) |
| 419 | 469 | ||
| 470 | static void fixup_botched_add(int ctlr, char *scsi3addr) | ||
| 471 | { | ||
| 472 | /* called when scsi_add_device fails in order to re-adjust */ | ||
| 473 | /* ccissscsi[] to match the mid layer's view. */ | ||
| 474 | unsigned long flags; | ||
| 475 | int i, j; | ||
| 476 | CPQ_TAPE_LOCK(ctlr, flags); | ||
| 477 | for (i = 0; i < ccissscsi[ctlr].ndevices; i++) { | ||
| 478 | if (memcmp(scsi3addr, | ||
| 479 | ccissscsi[ctlr].dev[i].scsi3addr, 8) == 0) { | ||
| 480 | for (j = i; j < ccissscsi[ctlr].ndevices-1; j++) | ||
| 481 | ccissscsi[ctlr].dev[j] = | ||
| 482 | ccissscsi[ctlr].dev[j+1]; | ||
| 483 | ccissscsi[ctlr].ndevices--; | ||
| 484 | break; | ||
| 485 | } | ||
| 486 | } | ||
| 487 | CPQ_TAPE_UNLOCK(ctlr, flags); | ||
| 488 | } | ||
| 489 | |||
| 420 | static int | 490 | static int |
| 421 | adjust_cciss_scsi_table(int ctlr, int hostno, | 491 | adjust_cciss_scsi_table(int ctlr, int hostno, |
| 422 | struct cciss_scsi_dev_t sd[], int nsds) | 492 | struct cciss_scsi_dev_t sd[], int nsds) |
| @@ -429,13 +499,33 @@ adjust_cciss_scsi_table(int ctlr, int hostno, | |||
| 429 | int i,j, found, changes=0; | 499 | int i,j, found, changes=0; |
| 430 | struct cciss_scsi_dev_t *csd; | 500 | struct cciss_scsi_dev_t *csd; |
| 431 | unsigned long flags; | 501 | unsigned long flags; |
| 502 | struct scsi2map *added, *removed; | ||
| 503 | int nadded, nremoved; | ||
| 504 | struct Scsi_Host *sh = NULL; | ||
| 505 | |||
| 506 | added = kzalloc(sizeof(*added) * CCISS_MAX_SCSI_DEVS_PER_HBA, | ||
| 507 | GFP_KERNEL); | ||
| 508 | removed = kzalloc(sizeof(*removed) * CCISS_MAX_SCSI_DEVS_PER_HBA, | ||
| 509 | GFP_KERNEL); | ||
| 510 | |||
| 511 | if (!added || !removed) { | ||
| 512 | printk(KERN_WARNING "cciss%d: Out of memory in " | ||
| 513 | "adjust_cciss_scsi_table\n", ctlr); | ||
| 514 | goto free_and_out; | ||
| 515 | } | ||
| 432 | 516 | ||
| 433 | CPQ_TAPE_LOCK(ctlr, flags); | 517 | CPQ_TAPE_LOCK(ctlr, flags); |
| 434 | 518 | ||
| 519 | if (hostno != -1) /* if it's not the first time... */ | ||
| 520 | sh = ((struct cciss_scsi_adapter_data_t *) | ||
| 521 | hba[ctlr]->scsi_ctlr)->scsi_host; | ||
| 522 | |||
| 435 | /* find any devices in ccissscsi[] that are not in | 523 | /* find any devices in ccissscsi[] that are not in |
| 436 | sd[] and remove them from ccissscsi[] */ | 524 | sd[] and remove them from ccissscsi[] */ |
| 437 | 525 | ||
| 438 | i = 0; | 526 | i = 0; |
| 527 | nremoved = 0; | ||
| 528 | nadded = 0; | ||
| 439 | while(i<ccissscsi[ctlr].ndevices) { | 529 | while(i<ccissscsi[ctlr].ndevices) { |
| 440 | csd = &ccissscsi[ctlr].dev[i]; | 530 | csd = &ccissscsi[ctlr].dev[i]; |
| 441 | found=0; | 531 | found=0; |
| @@ -455,8 +545,9 @@ adjust_cciss_scsi_table(int ctlr, int hostno, | |||
| 455 | /* printk("cciss%d: %s device c%db%dt%dl%d removed.\n", | 545 | /* printk("cciss%d: %s device c%db%dt%dl%d removed.\n", |
| 456 | ctlr, scsi_device_type(csd->devtype), hostno, | 546 | ctlr, scsi_device_type(csd->devtype), hostno, |
| 457 | csd->bus, csd->target, csd->lun); */ | 547 | csd->bus, csd->target, csd->lun); */ |
| 458 | cciss_scsi_remove_entry(ctlr, hostno, i); | 548 | cciss_scsi_remove_entry(ctlr, hostno, i, |
| 459 | /* note, i not incremented */ | 549 | removed, &nremoved); |
| 550 | /* remove ^^^, hence i not incremented */ | ||
| 460 | } | 551 | } |
| 461 | else if (found == 1) { /* device is different kind */ | 552 | else if (found == 1) { /* device is different kind */ |
| 462 | changes++; | 553 | changes++; |
| @@ -464,8 +555,15 @@ adjust_cciss_scsi_table(int ctlr, int hostno, | |||
| 464 | "(device type now %s).\n", | 555 | "(device type now %s).\n", |
| 465 | ctlr, hostno, csd->bus, csd->target, csd->lun, | 556 | ctlr, hostno, csd->bus, csd->target, csd->lun, |
| 466 | scsi_device_type(csd->devtype)); | 557 | scsi_device_type(csd->devtype)); |
| 558 | cciss_scsi_remove_entry(ctlr, hostno, i, | ||
| 559 | removed, &nremoved); | ||
| 560 | /* remove ^^^, hence i not incremented */ | ||
| 561 | if (cciss_scsi_add_entry(ctlr, hostno, | ||
| 562 | &sd[j].scsi3addr[0], sd[j].devtype, | ||
| 563 | added, &nadded) != 0) | ||
| 564 | /* we just removed one, so add can't fail. */ | ||
| 565 | BUG(); | ||
| 467 | csd->devtype = sd[j].devtype; | 566 | csd->devtype = sd[j].devtype; |
| 468 | i++; /* so just move along. */ | ||
| 469 | } else /* device is same as it ever was, */ | 567 | } else /* device is same as it ever was, */ |
| 470 | i++; /* so just move along. */ | 568 | i++; /* so just move along. */ |
| 471 | } | 569 | } |
| @@ -489,7 +587,9 @@ adjust_cciss_scsi_table(int ctlr, int hostno, | |||
| 489 | if (!found) { | 587 | if (!found) { |
| 490 | changes++; | 588 | changes++; |
| 491 | if (cciss_scsi_add_entry(ctlr, hostno, | 589 | if (cciss_scsi_add_entry(ctlr, hostno, |
| 492 | &sd[i].scsi3addr[0], sd[i].devtype) != 0) | 590 | |
| 591 | &sd[i].scsi3addr[0], sd[i].devtype, | ||
| 592 | added, &nadded) != 0) | ||
| 493 | break; | 593 | break; |
| 494 | } else if (found == 1) { | 594 | } else if (found == 1) { |
| 495 | /* should never happen... */ | 595 | /* should never happen... */ |
| @@ -501,9 +601,50 @@ adjust_cciss_scsi_table(int ctlr, int hostno, | |||
| 501 | } | 601 | } |
| 502 | CPQ_TAPE_UNLOCK(ctlr, flags); | 602 | CPQ_TAPE_UNLOCK(ctlr, flags); |
| 503 | 603 | ||
| 504 | if (!changes) | 604 | /* Don't notify scsi mid layer of any changes the first time through */ |
| 505 | printk("cciss%d: No device changes detected.\n", ctlr); | 605 | /* (or if there are no changes) scsi_scan_host will do it later the */ |
| 606 | /* first time through. */ | ||
| 607 | if (hostno == -1 || !changes) | ||
| 608 | goto free_and_out; | ||
| 609 | |||
| 610 | /* Notify scsi mid layer of any removed devices */ | ||
| 611 | for (i = 0; i < nremoved; i++) { | ||
| 612 | struct scsi_device *sdev = | ||
| 613 | scsi_device_lookup(sh, removed[i].bus, | ||
| 614 | removed[i].target, removed[i].lun); | ||
| 615 | if (sdev != NULL) { | ||
| 616 | scsi_remove_device(sdev); | ||
| 617 | scsi_device_put(sdev); | ||
| 618 | } else { | ||
| 619 | /* We don't expect to get here. */ | ||
| 620 | /* future cmds to this device will get selection */ | ||
| 621 | /* timeout as if the device was gone. */ | ||
| 622 | printk(KERN_WARNING "cciss%d: didn't find " | ||
| 623 | "c%db%dt%dl%d\n for removal.", | ||
| 624 | ctlr, hostno, removed[i].bus, | ||
| 625 | removed[i].target, removed[i].lun); | ||
| 626 | } | ||
| 627 | } | ||
| 628 | |||
| 629 | /* Notify scsi mid layer of any added devices */ | ||
| 630 | for (i = 0; i < nadded; i++) { | ||
| 631 | int rc; | ||
| 632 | rc = scsi_add_device(sh, added[i].bus, | ||
| 633 | added[i].target, added[i].lun); | ||
| 634 | if (rc == 0) | ||
| 635 | continue; | ||
| 636 | printk(KERN_WARNING "cciss%d: scsi_add_device " | ||
| 637 | "c%db%dt%dl%d failed, device not added.\n", | ||
| 638 | ctlr, hostno, | ||
| 639 | added[i].bus, added[i].target, added[i].lun); | ||
| 640 | /* now we have to remove it from ccissscsi, */ | ||
| 641 | /* since it didn't get added to scsi mid layer */ | ||
| 642 | fixup_botched_add(ctlr, added[i].scsi3addr); | ||
| 643 | } | ||
| 506 | 644 | ||
| 645 | free_and_out: | ||
| 646 | kfree(added); | ||
| 647 | kfree(removed); | ||
| 507 | return 0; | 648 | return 0; |
| 508 | } | 649 | } |
| 509 | 650 | ||
| @@ -1355,32 +1496,6 @@ cciss_unregister_scsi(int ctlr) | |||
| 1355 | } | 1496 | } |
| 1356 | 1497 | ||
| 1357 | static int | 1498 | static int |
| 1358 | cciss_register_scsi(int ctlr) | ||
| 1359 | { | ||
| 1360 | unsigned long flags; | ||
| 1361 | |||
| 1362 | CPQ_TAPE_LOCK(ctlr, flags); | ||
| 1363 | |||
| 1364 | /* Since this is really a block driver, the SCSI core may not be | ||
| 1365 | initialized at init time, in which case, calling scsi_register_host | ||
| 1366 | would hang. Instead, we do it later, via /proc filesystem | ||
| 1367 | and rc scripts, when we know SCSI core is good to go. */ | ||
| 1368 | |||
| 1369 | /* Only register if SCSI devices are detected. */ | ||
| 1370 | if (ccissscsi[ctlr].ndevices != 0) { | ||
| 1371 | ((struct cciss_scsi_adapter_data_t *) | ||
| 1372 | hba[ctlr]->scsi_ctlr)->registered = 1; | ||
| 1373 | CPQ_TAPE_UNLOCK(ctlr, flags); | ||
| 1374 | return cciss_scsi_detect(ctlr); | ||
| 1375 | } | ||
| 1376 | CPQ_TAPE_UNLOCK(ctlr, flags); | ||
| 1377 | printk(KERN_INFO | ||
| 1378 | "cciss%d: No appropriate SCSI device detected, " | ||
| 1379 | "SCSI subsystem not engaged.\n", ctlr); | ||
| 1380 | return 0; | ||
| 1381 | } | ||
| 1382 | |||
| 1383 | static int | ||
| 1384 | cciss_engage_scsi(int ctlr) | 1499 | cciss_engage_scsi(int ctlr) |
| 1385 | { | 1500 | { |
| 1386 | struct cciss_scsi_adapter_data_t *sa; | 1501 | struct cciss_scsi_adapter_data_t *sa; |
| @@ -1391,15 +1506,15 @@ cciss_engage_scsi(int ctlr) | |||
| 1391 | sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr; | 1506 | sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr; |
| 1392 | stk = &sa->cmd_stack; | 1507 | stk = &sa->cmd_stack; |
| 1393 | 1508 | ||
| 1394 | if (((struct cciss_scsi_adapter_data_t *) | 1509 | if (sa->registered) { |
| 1395 | hba[ctlr]->scsi_ctlr)->registered) { | ||
| 1396 | printk("cciss%d: SCSI subsystem already engaged.\n", ctlr); | 1510 | printk("cciss%d: SCSI subsystem already engaged.\n", ctlr); |
| 1397 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | 1511 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); |
| 1398 | return ENXIO; | 1512 | return ENXIO; |
| 1399 | } | 1513 | } |
| 1514 | sa->registered = 1; | ||
| 1400 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | 1515 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); |
| 1401 | cciss_update_non_disk_devices(ctlr, -1); | 1516 | cciss_update_non_disk_devices(ctlr, -1); |
| 1402 | cciss_register_scsi(ctlr); | 1517 | cciss_scsi_detect(ctlr); |
| 1403 | return 0; | 1518 | return 0; |
| 1404 | } | 1519 | } |
| 1405 | 1520 | ||
| @@ -1493,7 +1608,5 @@ static int cciss_eh_abort_handler(struct scsi_cmnd *scsicmd) | |||
| 1493 | /* If no tape support, then these become defined out of existence */ | 1608 | /* If no tape support, then these become defined out of existence */ |
| 1494 | 1609 | ||
| 1495 | #define cciss_scsi_setup(cntl_num) | 1610 | #define cciss_scsi_setup(cntl_num) |
| 1496 | #define cciss_unregister_scsi(ctlr) | ||
| 1497 | #define cciss_register_scsi(ctlr) | ||
| 1498 | 1611 | ||
| 1499 | #endif /* CONFIG_CISS_SCSI_TAPE */ | 1612 | #endif /* CONFIG_CISS_SCSI_TAPE */ |
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 9ae05c584234..3ca643cafccd 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
| @@ -154,8 +154,8 @@ static int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg) | |||
| 154 | return 0; | 154 | return 0; |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | int blkif_ioctl(struct inode *inode, struct file *filep, | 157 | static int blkif_ioctl(struct inode *inode, struct file *filep, |
| 158 | unsigned command, unsigned long argument) | 158 | unsigned command, unsigned long argument) |
| 159 | { | 159 | { |
| 160 | struct blkfront_info *info = | 160 | struct blkfront_info *info = |
| 161 | inode->i_bdev->bd_disk->private_data; | 161 | inode->i_bdev->bd_disk->private_data; |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index d0ac944e1696..caff85149b9d 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
| @@ -8,7 +8,7 @@ config VT | |||
| 8 | bool "Virtual terminal" if EMBEDDED | 8 | bool "Virtual terminal" if EMBEDDED |
| 9 | depends on !S390 | 9 | depends on !S390 |
| 10 | select INPUT | 10 | select INPUT |
| 11 | default y if !VIOCONS | 11 | default y |
| 12 | ---help--- | 12 | ---help--- |
| 13 | If you say Y here, you will get support for terminal devices with | 13 | If you say Y here, you will get support for terminal devices with |
| 14 | display and keyboard devices. These are called "virtual" because you | 14 | display and keyboard devices. These are called "virtual" because you |
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 8a161c30e1dc..6850f6da7576 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
| @@ -55,7 +55,6 @@ obj-$(CONFIG_RAW_DRIVER) += raw.o | |||
| 55 | obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o | 55 | obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o |
| 56 | obj-$(CONFIG_MSPEC) += mspec.o | 56 | obj-$(CONFIG_MSPEC) += mspec.o |
| 57 | obj-$(CONFIG_MMTIMER) += mmtimer.o | 57 | obj-$(CONFIG_MMTIMER) += mmtimer.o |
| 58 | obj-$(CONFIG_VIOCONS) += viocons.o | ||
| 59 | obj-$(CONFIG_VIOTAPE) += viotape.o | 58 | obj-$(CONFIG_VIOTAPE) += viotape.o |
| 60 | obj-$(CONFIG_HVCS) += hvcs.o | 59 | obj-$(CONFIG_HVCS) += hvcs.o |
| 61 | obj-$(CONFIG_IBM_BSR) += bsr.o | 60 | obj-$(CONFIG_IBM_BSR) += bsr.o |
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index 3530ff417a51..6e763e3f5a81 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c | |||
| @@ -1254,7 +1254,7 @@ static int rs_break(struct tty_struct *tty, int break_state) | |||
| 1254 | unsigned long flags; | 1254 | unsigned long flags; |
| 1255 | 1255 | ||
| 1256 | if (serial_paranoia_check(info, tty->name, "rs_break")) | 1256 | if (serial_paranoia_check(info, tty->name, "rs_break")) |
| 1257 | return; | 1257 | return -EINVAL; |
| 1258 | 1258 | ||
| 1259 | local_irq_save(flags); | 1259 | local_irq_save(flags); |
| 1260 | if (break_state == -1) | 1260 | if (break_state == -1) |
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c deleted file mode 100644 index 65fb848e1cce..000000000000 --- a/drivers/char/viocons.c +++ /dev/null | |||
| @@ -1,1171 +0,0 @@ | |||
| 1 | /* -*- linux-c -*- | ||
| 2 | * | ||
| 3 | * drivers/char/viocons.c | ||
| 4 | * | ||
| 5 | * iSeries Virtual Terminal | ||
| 6 | * | ||
| 7 | * Authors: Dave Boutcher <boutcher@us.ibm.com> | ||
| 8 | * Ryan Arnold <ryanarn@us.ibm.com> | ||
| 9 | * Colin Devilbiss <devilbis@us.ibm.com> | ||
| 10 | * Stephen Rothwell | ||
| 11 | * | ||
| 12 | * (C) Copyright 2000, 2001, 2002, 2003, 2004 IBM Corporation | ||
| 13 | * | ||
| 14 | * This program is free software; you can redistribute it and/or | ||
| 15 | * modify it under the terms of the GNU General Public License as | ||
| 16 | * published by the Free Software Foundation; either version 2 of the | ||
| 17 | * License, or (at your option) anyu later version. | ||
| 18 | * | ||
| 19 | * This program is distributed in the hope that it will be useful, but | ||
| 20 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 22 | * General Public License for more details. | ||
| 23 | * | ||
| 24 | * You should have received a copy of the GNU General Public License | ||
| 25 | * along with this program; if not, write to the Free Software Foundation, | ||
| 26 | * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 27 | */ | ||
| 28 | #include <linux/kernel.h> | ||
| 29 | #include <linux/proc_fs.h> | ||
| 30 | #include <linux/errno.h> | ||
| 31 | #include <linux/vmalloc.h> | ||
| 32 | #include <linux/mm.h> | ||
| 33 | #include <linux/console.h> | ||
| 34 | #include <linux/module.h> | ||
| 35 | #include <asm/uaccess.h> | ||
| 36 | #include <linux/init.h> | ||
| 37 | #include <linux/wait.h> | ||
| 38 | #include <linux/spinlock.h> | ||
| 39 | #include <asm/ioctls.h> | ||
| 40 | #include <linux/kd.h> | ||
| 41 | #include <linux/tty.h> | ||
| 42 | #include <linux/tty_flip.h> | ||
| 43 | #include <linux/sysrq.h> | ||
| 44 | |||
| 45 | #include <asm/firmware.h> | ||
| 46 | #include <asm/iseries/vio.h> | ||
| 47 | #include <asm/iseries/hv_lp_event.h> | ||
| 48 | #include <asm/iseries/hv_call_event.h> | ||
| 49 | #include <asm/iseries/hv_lp_config.h> | ||
| 50 | #include <asm/iseries/hv_call.h> | ||
| 51 | |||
| 52 | #ifdef CONFIG_VT | ||
| 53 | #error You must turn off CONFIG_VT to use CONFIG_VIOCONS | ||
| 54 | #endif | ||
| 55 | |||
| 56 | #define VIOTTY_MAGIC (0x0DCB) | ||
| 57 | #define VTTY_PORTS 10 | ||
| 58 | |||
| 59 | #define VIOCONS_KERN_WARN KERN_WARNING "viocons: " | ||
| 60 | #define VIOCONS_KERN_INFO KERN_INFO "viocons: " | ||
| 61 | |||
| 62 | static DEFINE_SPINLOCK(consolelock); | ||
| 63 | static DEFINE_SPINLOCK(consoleloglock); | ||
| 64 | |||
| 65 | static int vio_sysrq_pressed; | ||
| 66 | |||
| 67 | #define VIOCHAR_NUM_BUF 16 | ||
| 68 | |||
| 69 | /* | ||
| 70 | * Our port information. We store a pointer to one entry in the | ||
| 71 | * tty_driver_data | ||
| 72 | */ | ||
| 73 | static struct port_info { | ||
| 74 | int magic; | ||
| 75 | struct tty_struct *tty; | ||
| 76 | HvLpIndex lp; | ||
| 77 | u8 vcons; | ||
| 78 | u64 seq; /* sequence number of last HV send */ | ||
| 79 | u64 ack; /* last ack from HV */ | ||
| 80 | /* | ||
| 81 | * When we get writes faster than we can send it to the partition, | ||
| 82 | * buffer the data here. Note that used is a bit map of used buffers. | ||
| 83 | * It had better have enough bits to hold VIOCHAR_NUM_BUF the bitops assume | ||
| 84 | * it is a multiple of unsigned long | ||
| 85 | */ | ||
| 86 | unsigned long used; | ||
| 87 | u8 *buffer[VIOCHAR_NUM_BUF]; | ||
| 88 | int bufferBytes[VIOCHAR_NUM_BUF]; | ||
| 89 | int curbuf; | ||
| 90 | int bufferOverflow; | ||
| 91 | int overflowMessage; | ||
| 92 | } port_info[VTTY_PORTS]; | ||
| 93 | |||
| 94 | #define viochar_is_console(pi) ((pi) == &port_info[0]) | ||
| 95 | #define viochar_port(pi) ((pi) - &port_info[0]) | ||
| 96 | |||
| 97 | static void initDataEvent(struct viocharlpevent *viochar, HvLpIndex lp); | ||
| 98 | |||
| 99 | static struct tty_driver *viotty_driver; | ||
| 100 | |||
| 101 | static void hvlog(char *fmt, ...) | ||
| 102 | { | ||
| 103 | int i; | ||
| 104 | unsigned long flags; | ||
| 105 | va_list args; | ||
| 106 | static char buf[256]; | ||
| 107 | |||
| 108 | spin_lock_irqsave(&consoleloglock, flags); | ||
| 109 | va_start(args, fmt); | ||
| 110 | i = vscnprintf(buf, sizeof(buf) - 1, fmt, args); | ||
| 111 | va_end(args); | ||
| 112 | buf[i++] = '\r'; | ||
| 113 | HvCall_writeLogBuffer(buf, i); | ||
| 114 | spin_unlock_irqrestore(&consoleloglock, flags); | ||
| 115 | } | ||
| 116 | |||
| 117 | static void hvlogOutput(const char *buf, int count) | ||
| 118 | { | ||
| 119 | unsigned long flags; | ||
| 120 | int begin; | ||
| 121 | int index; | ||
| 122 | static const char cr = '\r'; | ||
| 123 | |||
| 124 | begin = 0; | ||
| 125 | spin_lock_irqsave(&consoleloglock, flags); | ||
| 126 | for (index = 0; index < count; index++) { | ||
| 127 | if (buf[index] == '\n') { | ||
| 128 | /* | ||
| 129 | * Start right after the last '\n' or at the zeroth | ||
| 130 | * array position and output the number of characters | ||
| 131 | * including the newline. | ||
| 132 | */ | ||
| 133 | HvCall_writeLogBuffer(&buf[begin], index - begin + 1); | ||
| 134 | begin = index + 1; | ||
| 135 | HvCall_writeLogBuffer(&cr, 1); | ||
| 136 | } | ||
| 137 | } | ||
| 138 | if ((index - begin) > 0) | ||
| 139 | HvCall_writeLogBuffer(&buf[begin], index - begin); | ||
| 140 | spin_unlock_irqrestore(&consoleloglock, flags); | ||
| 141 | } | ||
| 142 | |||
| 143 | /* | ||
| 144 | * Make sure we're pointing to a valid port_info structure. Shamelessly | ||
| 145 | * plagerized from serial.c | ||
| 146 | */ | ||
| 147 | static inline int viotty_paranoia_check(struct port_info *pi, | ||
| 148 | char *name, const char *routine) | ||
| 149 | { | ||
| 150 | static const char *bad_pi_addr = VIOCONS_KERN_WARN | ||
| 151 | "warning: bad address for port_info struct (%s) in %s\n"; | ||
| 152 | static const char *badmagic = VIOCONS_KERN_WARN | ||
| 153 | "warning: bad magic number for port_info struct (%s) in %s\n"; | ||
| 154 | |||
| 155 | if ((pi < &port_info[0]) || (viochar_port(pi) > VTTY_PORTS)) { | ||
| 156 | printk(bad_pi_addr, name, routine); | ||
| 157 | return 1; | ||
| 158 | } | ||
| 159 | if (pi->magic != VIOTTY_MAGIC) { | ||
| 160 | printk(badmagic, name, routine); | ||
| 161 | return 1; | ||
| 162 | } | ||
| 163 | return 0; | ||
| 164 | } | ||
| 165 | |||
| 166 | /* | ||
| 167 | * Add data to our pending-send buffers. | ||
| 168 | * | ||
| 169 | * NOTE: Don't use printk in here because it gets nastily recursive. | ||
| 170 | * hvlog can be used to log to the hypervisor buffer | ||
| 171 | */ | ||
| 172 | static int buffer_add(struct port_info *pi, const char *buf, size_t len) | ||
| 173 | { | ||
| 174 | size_t bleft; | ||
| 175 | size_t curlen; | ||
| 176 | const char *curbuf; | ||
| 177 | int nextbuf; | ||
| 178 | |||
| 179 | curbuf = buf; | ||
| 180 | bleft = len; | ||
| 181 | while (bleft > 0) { | ||
| 182 | /* | ||
| 183 | * If there is no space left in the current buffer, we have | ||
| 184 | * filled everything up, so return. If we filled the previous | ||
| 185 | * buffer we would already have moved to the next one. | ||
| 186 | */ | ||
| 187 | if (pi->bufferBytes[pi->curbuf] == VIOCHAR_MAX_DATA) { | ||
| 188 | hvlog ("\n\rviocons: No overflow buffer available for memcpy().\n"); | ||
| 189 | pi->bufferOverflow++; | ||
| 190 | pi->overflowMessage = 1; | ||
| 191 | break; | ||
| 192 | } | ||
| 193 | |||
| 194 | /* | ||
| 195 | * Turn on the "used" bit for this buffer. If it's already on, | ||
| 196 | * that's fine. | ||
| 197 | */ | ||
| 198 | set_bit(pi->curbuf, &pi->used); | ||
| 199 | |||
| 200 | /* | ||
| 201 | * See if this buffer has been allocated. If not, allocate it. | ||
| 202 | */ | ||
| 203 | if (pi->buffer[pi->curbuf] == NULL) { | ||
| 204 | pi->buffer[pi->curbuf] = | ||
| 205 | kmalloc(VIOCHAR_MAX_DATA, GFP_ATOMIC); | ||
| 206 | if (pi->buffer[pi->curbuf] == NULL) { | ||
| 207 | hvlog("\n\rviocons: kmalloc failed allocating spaces for buffer %d.", | ||
| 208 | pi->curbuf); | ||
| 209 | break; | ||
| 210 | } | ||
| 211 | } | ||
| 212 | |||
| 213 | /* Figure out how much we can copy into this buffer. */ | ||
| 214 | if (bleft < (VIOCHAR_MAX_DATA - pi->bufferBytes[pi->curbuf])) | ||
| 215 | curlen = bleft; | ||
| 216 | else | ||
| 217 | curlen = VIOCHAR_MAX_DATA - pi->bufferBytes[pi->curbuf]; | ||
| 218 | |||
| 219 | /* Copy the data into the buffer. */ | ||
| 220 | memcpy(pi->buffer[pi->curbuf] + pi->bufferBytes[pi->curbuf], | ||
| 221 | curbuf, curlen); | ||
| 222 | |||
| 223 | pi->bufferBytes[pi->curbuf] += curlen; | ||
| 224 | curbuf += curlen; | ||
| 225 | bleft -= curlen; | ||
| 226 | |||
| 227 | /* | ||
| 228 | * Now see if we've filled this buffer. If not then | ||
| 229 | * we'll try to use it again later. If we've filled it | ||
| 230 | * up then we'll advance the curbuf to the next in the | ||
| 231 | * circular queue. | ||
| 232 | */ | ||
| 233 | if (pi->bufferBytes[pi->curbuf] == VIOCHAR_MAX_DATA) { | ||
| 234 | nextbuf = (pi->curbuf + 1) % VIOCHAR_NUM_BUF; | ||
| 235 | /* | ||
| 236 | * Move to the next buffer if it hasn't been used yet | ||
| 237 | */ | ||
| 238 | if (test_bit(nextbuf, &pi->used) == 0) | ||
| 239 | pi->curbuf = nextbuf; | ||
| 240 | } | ||
| 241 | } | ||
| 242 | return len - bleft; | ||
| 243 | } | ||
| 244 | |||
| 245 | /* | ||
| 246 | * Send pending data | ||
| 247 | * | ||
| 248 | * NOTE: Don't use printk in here because it gets nastily recursive. | ||
| 249 | * hvlog can be used to log to the hypervisor buffer | ||
| 250 | */ | ||
| 251 | static void send_buffers(struct port_info *pi) | ||
| 252 | { | ||
| 253 | HvLpEvent_Rc hvrc; | ||
| 254 | int nextbuf; | ||
| 255 | struct viocharlpevent *viochar; | ||
| 256 | unsigned long flags; | ||
| 257 | |||
| 258 | spin_lock_irqsave(&consolelock, flags); | ||
| 259 | |||
| 260 | viochar = (struct viocharlpevent *) | ||
| 261 | vio_get_event_buffer(viomajorsubtype_chario); | ||
| 262 | |||
| 263 | /* Make sure we got a buffer */ | ||
| 264 | if (viochar == NULL) { | ||
| 265 | hvlog("\n\rviocons: Can't get viochar buffer in sendBuffers()."); | ||
| 266 | spin_unlock_irqrestore(&consolelock, flags); | ||
| 267 | return; | ||
| 268 | } | ||
| 269 | |||
| 270 | if (pi->used == 0) { | ||
| 271 | hvlog("\n\rviocons: in sendbuffers(), but no buffers used.\n"); | ||
| 272 | vio_free_event_buffer(viomajorsubtype_chario, viochar); | ||
| 273 | spin_unlock_irqrestore(&consolelock, flags); | ||
| 274 | return; | ||
| 275 | } | ||
| 276 | |||
| 277 | /* | ||
| 278 | * curbuf points to the buffer we're filling. We want to | ||
| 279 | * start sending AFTER this one. | ||
| 280 | */ | ||
| 281 | nextbuf = (pi->curbuf + 1) % VIOCHAR_NUM_BUF; | ||
| 282 | |||
| 283 | /* | ||
| 284 | * Loop until we find a buffer with the used bit on | ||
| 285 | */ | ||
| 286 | while (test_bit(nextbuf, &pi->used) == 0) | ||
| 287 | nextbuf = (nextbuf + 1) % VIOCHAR_NUM_BUF; | ||
| 288 | |||
| 289 | initDataEvent(viochar, pi->lp); | ||
| 290 | |||
| 291 | /* | ||
| 292 | * While we have buffers with data, and our send window | ||
| 293 | * is open, send them | ||
| 294 | */ | ||
| 295 | while ((test_bit(nextbuf, &pi->used)) && | ||
| 296 | ((pi->seq - pi->ack) < VIOCHAR_WINDOW)) { | ||
| 297 | viochar->len = pi->bufferBytes[nextbuf]; | ||
| 298 | viochar->event.xCorrelationToken = pi->seq++; | ||
| 299 | viochar->event.xSizeMinus1 = | ||
| 300 | offsetof(struct viocharlpevent, data) + viochar->len; | ||
| 301 | |||
| 302 | memcpy(viochar->data, pi->buffer[nextbuf], viochar->len); | ||
| 303 | |||
| 304 | hvrc = HvCallEvent_signalLpEvent(&viochar->event); | ||
| 305 | if (hvrc) { | ||
| 306 | /* | ||
| 307 | * MUST unlock the spinlock before doing a printk | ||
| 308 | */ | ||
| 309 | vio_free_event_buffer(viomajorsubtype_chario, viochar); | ||
| 310 | spin_unlock_irqrestore(&consolelock, flags); | ||
| 311 | |||
| 312 | printk(VIOCONS_KERN_WARN | ||
| 313 | "error sending event! return code %d\n", | ||
| 314 | (int)hvrc); | ||
| 315 | return; | ||
| 316 | } | ||
| 317 | |||
| 318 | /* | ||
| 319 | * clear the used bit, zero the number of bytes in | ||
| 320 | * this buffer, and move to the next buffer | ||
| 321 | */ | ||
| 322 | clear_bit(nextbuf, &pi->used); | ||
| 323 | pi->bufferBytes[nextbuf] = 0; | ||
| 324 | nextbuf = (nextbuf + 1) % VIOCHAR_NUM_BUF; | ||
| 325 | } | ||
| 326 | |||
| 327 | /* | ||
| 328 | * If we have emptied all the buffers, start at 0 again. | ||
| 329 | * this will re-use any allocated buffers | ||
| 330 | */ | ||
| 331 | if (pi->used == 0) { | ||
| 332 | pi->curbuf = 0; | ||
| 333 | |||
| 334 | if (pi->overflowMessage) | ||
| 335 | pi->overflowMessage = 0; | ||
| 336 | |||
| 337 | if (pi->tty) { | ||
| 338 | tty_wakeup(pi->tty); | ||
| 339 | } | ||
| 340 | } | ||
| 341 | |||
| 342 | vio_free_event_buffer(viomajorsubtype_chario, viochar); | ||
| 343 | spin_unlock_irqrestore(&consolelock, flags); | ||
| 344 | } | ||
| 345 | |||
| 346 | /* | ||
| 347 | * Our internal writer. Gets called both from the console device and | ||
| 348 | * the tty device. the tty pointer will be NULL if called from the console. | ||
| 349 | * Return total number of bytes "written". | ||
| 350 | * | ||
| 351 | * NOTE: Don't use printk in here because it gets nastily recursive. hvlog | ||
| 352 | * can be used to log to the hypervisor buffer | ||
| 353 | */ | ||
| 354 | static int internal_write(struct port_info *pi, const char *buf, size_t len) | ||
| 355 | { | ||
| 356 | HvLpEvent_Rc hvrc; | ||
| 357 | size_t bleft; | ||
| 358 | size_t curlen; | ||
| 359 | const char *curbuf; | ||
| 360 | unsigned long flags; | ||
| 361 | struct viocharlpevent *viochar; | ||
| 362 | |||
| 363 | /* | ||
| 364 | * Write to the hvlog of inbound data are now done prior to | ||
| 365 | * calling internal_write() since internal_write() is only called in | ||
| 366 | * the event that an lp event path is active, which isn't the case for | ||
| 367 | * logging attempts prior to console initialization. | ||
| 368 | * | ||
| 369 | * If there is already data queued for this port, send it prior to | ||
| 370 | * attempting to send any new data. | ||
| 371 | */ | ||
| 372 | if (pi->used) | ||
| 373 | send_buffers(pi); | ||
| 374 | |||
| 375 | spin_lock_irqsave(&consolelock, flags); | ||
| 376 | |||
| 377 | viochar = vio_get_event_buffer(viomajorsubtype_chario); | ||
| 378 | if (viochar == NULL) { | ||
| 379 | spin_unlock_irqrestore(&consolelock, flags); | ||
| 380 | hvlog("\n\rviocons: Can't get vio buffer in internal_write()."); | ||
| 381 | return -EAGAIN; | ||
| 382 | } | ||
| 383 | initDataEvent(viochar, pi->lp); | ||
| 384 | |||
| 385 | curbuf = buf; | ||
| 386 | bleft = len; | ||
| 387 | |||
| 388 | while ((bleft > 0) && (pi->used == 0) && | ||
| 389 | ((pi->seq - pi->ack) < VIOCHAR_WINDOW)) { | ||
| 390 | if (bleft > VIOCHAR_MAX_DATA) | ||
| 391 | curlen = VIOCHAR_MAX_DATA; | ||
| 392 | else | ||
| 393 | curlen = bleft; | ||
| 394 | |||
| 395 | viochar->event.xCorrelationToken = pi->seq++; | ||
| 396 | memcpy(viochar->data, curbuf, curlen); | ||
| 397 | viochar->len = curlen; | ||
| 398 | viochar->event.xSizeMinus1 = | ||
| 399 | offsetof(struct viocharlpevent, data) + curlen; | ||
| 400 | |||
| 401 | hvrc = HvCallEvent_signalLpEvent(&viochar->event); | ||
| 402 | if (hvrc) { | ||
| 403 | hvlog("viocons: error sending event! %d\n", (int)hvrc); | ||
| 404 | goto out; | ||
| 405 | } | ||
| 406 | curbuf += curlen; | ||
| 407 | bleft -= curlen; | ||
| 408 | } | ||
| 409 | |||
| 410 | /* If we didn't send it all, buffer as much of it as we can. */ | ||
| 411 | if (bleft > 0) | ||
| 412 | bleft -= buffer_add(pi, curbuf, bleft); | ||
| 413 | out: | ||
| 414 | vio_free_event_buffer(viomajorsubtype_chario, viochar); | ||
| 415 | spin_unlock_irqrestore(&consolelock, flags); | ||
| 416 | return len - bleft; | ||
| 417 | } | ||
| 418 | |||
| 419 | static struct port_info *get_port_data(struct tty_struct *tty) | ||
| 420 | { | ||
| 421 | unsigned long flags; | ||
| 422 | struct port_info *pi; | ||
| 423 | |||
| 424 | spin_lock_irqsave(&consolelock, flags); | ||
| 425 | if (tty) { | ||
| 426 | pi = (struct port_info *)tty->driver_data; | ||
| 427 | if (!pi || viotty_paranoia_check(pi, tty->name, | ||
| 428 | "get_port_data")) { | ||
| 429 | pi = NULL; | ||
| 430 | } | ||
| 431 | } else | ||
| 432 | /* | ||
| 433 | * If this is the console device, use the lp from | ||
| 434 | * the first port entry | ||
| 435 | */ | ||
| 436 | pi = &port_info[0]; | ||
| 437 | spin_unlock_irqrestore(&consolelock, flags); | ||
| 438 | return pi; | ||
| 439 | } | ||
| 440 | |||
| 441 | /* | ||
| 442 | * Initialize the common fields in a charLpEvent | ||
| 443 | */ | ||
| 444 | static void initDataEvent(struct viocharlpevent *viochar, HvLpIndex lp) | ||
| 445 | { | ||
| 446 | struct HvLpEvent *hev = &viochar->event; | ||
| 447 | |||
| 448 | memset(viochar, 0, sizeof(struct viocharlpevent)); | ||
| 449 | |||
| 450 | hev->flags = HV_LP_EVENT_VALID | HV_LP_EVENT_DEFERRED_ACK | | ||
| 451 | HV_LP_EVENT_INT; | ||
| 452 | hev->xType = HvLpEvent_Type_VirtualIo; | ||
| 453 | hev->xSubtype = viomajorsubtype_chario | viochardata; | ||
| 454 | hev->xSourceLp = HvLpConfig_getLpIndex(); | ||
| 455 | hev->xTargetLp = lp; | ||
| 456 | hev->xSizeMinus1 = sizeof(struct viocharlpevent); | ||
| 457 | hev->xSourceInstanceId = viopath_sourceinst(lp); | ||
| 458 | hev->xTargetInstanceId = viopath_targetinst(lp); | ||
| 459 | } | ||
| 460 | |||
| 461 | /* | ||
| 462 | * early console device write | ||
| 463 | */ | ||
| 464 | static void viocons_write_early(struct console *co, const char *s, unsigned count) | ||
| 465 | { | ||
| 466 | hvlogOutput(s, count); | ||
| 467 | } | ||
| 468 | |||
| 469 | /* | ||
| 470 | * console device write | ||
| 471 | */ | ||
| 472 | static void viocons_write(struct console *co, const char *s, unsigned count) | ||
| 473 | { | ||
| 474 | int index; | ||
| 475 | int begin; | ||
| 476 | struct port_info *pi; | ||
| 477 | |||
| 478 | static const char cr = '\r'; | ||
| 479 | |||
| 480 | /* | ||
| 481 | * Check port data first because the target LP might be valid but | ||
| 482 | * simply not active, in which case we want to hvlog the output. | ||
| 483 | */ | ||
| 484 | pi = get_port_data(NULL); | ||
| 485 | if (pi == NULL) { | ||
| 486 | hvlog("\n\rviocons_write: unable to get port data."); | ||
| 487 | return; | ||
| 488 | } | ||
| 489 | |||
| 490 | hvlogOutput(s, count); | ||
| 491 | |||
| 492 | if (!viopath_isactive(pi->lp)) | ||
| 493 | return; | ||
| 494 | |||
| 495 | /* | ||
| 496 | * Any newline character found will cause a | ||
| 497 | * carriage return character to be emitted as well. | ||
| 498 | */ | ||
| 499 | begin = 0; | ||
| 500 | for (index = 0; index < count; index++) { | ||
| 501 | if (s[index] == '\n') { | ||
| 502 | /* | ||
| 503 | * Newline found. Print everything up to and | ||
| 504 | * including the newline | ||
| 505 | */ | ||
| 506 | internal_write(pi, &s[begin], index - begin + 1); | ||
| 507 | begin = index + 1; | ||
| 508 | /* Emit a carriage return as well */ | ||
| 509 | internal_write(pi, &cr, 1); | ||
| 510 | } | ||
| 511 | } | ||
| 512 | |||
| 513 | /* If any characters left to write, write them now */ | ||
| 514 | if ((index - begin) > 0) | ||
| 515 | internal_write(pi, &s[begin], index - begin); | ||
| 516 | } | ||
| 517 | |||
| 518 | /* | ||
| 519 | * Work out the device associate with this console | ||
| 520 | */ | ||
| 521 | static struct tty_driver *viocons_device(struct console *c, int *index) | ||
| 522 | { | ||
| 523 | *index = c->index; | ||
| 524 | return viotty_driver; | ||
| 525 | } | ||
| 526 | |||
| 527 | /* | ||
| 528 | * console device I/O methods | ||
| 529 | */ | ||
| 530 | static struct console viocons_early = { | ||
| 531 | .name = "viocons", | ||
| 532 | .write = viocons_write_early, | ||
| 533 | .flags = CON_PRINTBUFFER, | ||
| 534 | .index = -1, | ||
| 535 | }; | ||
| 536 | |||
| 537 | static struct console viocons = { | ||
| 538 | .name = "viocons", | ||
| 539 | .write = viocons_write, | ||
| 540 | .device = viocons_device, | ||
| 541 | .flags = CON_PRINTBUFFER, | ||
| 542 | .index = -1, | ||
| 543 | }; | ||
| 544 | |||
| 545 | /* | ||
| 546 | * TTY Open method | ||
| 547 | */ | ||
| 548 | static int viotty_open(struct tty_struct *tty, struct file *filp) | ||
| 549 | { | ||
| 550 | int port; | ||
| 551 | unsigned long flags; | ||
| 552 | struct port_info *pi; | ||
| 553 | |||
| 554 | port = tty->index; | ||
| 555 | |||
| 556 | if ((port < 0) || (port >= VTTY_PORTS)) | ||
| 557 | return -ENODEV; | ||
| 558 | |||
| 559 | spin_lock_irqsave(&consolelock, flags); | ||
| 560 | |||
| 561 | pi = &port_info[port]; | ||
| 562 | /* If some other TTY is already connected here, reject the open */ | ||
| 563 | if ((pi->tty) && (pi->tty != tty)) { | ||
| 564 | spin_unlock_irqrestore(&consolelock, flags); | ||
| 565 | printk(VIOCONS_KERN_WARN | ||
| 566 | "attempt to open device twice from different ttys\n"); | ||
| 567 | return -EBUSY; | ||
| 568 | } | ||
| 569 | tty->driver_data = pi; | ||
| 570 | pi->tty = tty; | ||
| 571 | spin_unlock_irqrestore(&consolelock, flags); | ||
| 572 | |||
| 573 | return 0; | ||
| 574 | } | ||
| 575 | |||
| 576 | /* | ||
| 577 | * TTY Close method | ||
| 578 | */ | ||
| 579 | static void viotty_close(struct tty_struct *tty, struct file *filp) | ||
| 580 | { | ||
| 581 | unsigned long flags; | ||
| 582 | struct port_info *pi; | ||
| 583 | |||
| 584 | spin_lock_irqsave(&consolelock, flags); | ||
| 585 | pi = (struct port_info *)tty->driver_data; | ||
| 586 | |||
| 587 | if (!pi || viotty_paranoia_check(pi, tty->name, "viotty_close")) { | ||
| 588 | spin_unlock_irqrestore(&consolelock, flags); | ||
| 589 | return; | ||
| 590 | } | ||
| 591 | if (tty->count == 1) | ||
| 592 | pi->tty = NULL; | ||
| 593 | spin_unlock_irqrestore(&consolelock, flags); | ||
| 594 | } | ||
| 595 | |||
| 596 | /* | ||
| 597 | * TTY Write method | ||
| 598 | */ | ||
| 599 | static int viotty_write(struct tty_struct *tty, const unsigned char *buf, | ||
| 600 | int count) | ||
| 601 | { | ||
| 602 | struct port_info *pi; | ||
| 603 | |||
| 604 | pi = get_port_data(tty); | ||
| 605 | if (pi == NULL) { | ||
| 606 | hvlog("\n\rviotty_write: no port data."); | ||
| 607 | return -ENODEV; | ||
| 608 | } | ||
| 609 | |||
| 610 | if (viochar_is_console(pi)) | ||
| 611 | hvlogOutput(buf, count); | ||
| 612 | |||
| 613 | /* | ||
| 614 | * If the path to this LP is closed, don't bother doing anything more. | ||
| 615 | * just dump the data on the floor and return count. For some reason | ||
| 616 | * some user level programs will attempt to probe available tty's and | ||
| 617 | * they'll attempt a viotty_write on an invalid port which maps to an | ||
| 618 | * invalid target lp. If this is the case then ignore the | ||
| 619 | * viotty_write call and, since the viopath isn't active to this | ||
| 620 | * partition, return count. | ||
| 621 | */ | ||
| 622 | if (!viopath_isactive(pi->lp)) | ||
| 623 | return count; | ||
| 624 | |||
| 625 | return internal_write(pi, buf, count); | ||
| 626 | } | ||
| 627 | |||
| 628 | /* | ||
| 629 | * TTY put_char method | ||
| 630 | */ | ||
| 631 | static int viotty_put_char(struct tty_struct *tty, unsigned char ch) | ||
| 632 | { | ||
| 633 | struct port_info *pi; | ||
| 634 | |||
| 635 | pi = get_port_data(tty); | ||
| 636 | if (pi == NULL) | ||
| 637 | return 0; | ||
| 638 | |||
| 639 | /* This will append '\r' as well if the char is '\n' */ | ||
| 640 | if (viochar_is_console(pi)) | ||
| 641 | hvlogOutput(&ch, 1); | ||
| 642 | |||
| 643 | if (viopath_isactive(pi->lp)) | ||
| 644 | internal_write(pi, &ch, 1); | ||
| 645 | return 1; | ||
| 646 | } | ||
| 647 | |||
| 648 | /* | ||
| 649 | * TTY write_room method | ||
| 650 | */ | ||
| 651 | static int viotty_write_room(struct tty_struct *tty) | ||
| 652 | { | ||
| 653 | int i; | ||
| 654 | int room = 0; | ||
| 655 | struct port_info *pi; | ||
| 656 | unsigned long flags; | ||
| 657 | |||
| 658 | spin_lock_irqsave(&consolelock, flags); | ||
| 659 | pi = (struct port_info *)tty->driver_data; | ||
| 660 | if (!pi || viotty_paranoia_check(pi, tty->name, "viotty_write_room")) { | ||
| 661 | spin_unlock_irqrestore(&consolelock, flags); | ||
| 662 | return 0; | ||
| 663 | } | ||
| 664 | |||
| 665 | /* If no buffers are used, return the max size. */ | ||
| 666 | if (pi->used == 0) { | ||
| 667 | spin_unlock_irqrestore(&consolelock, flags); | ||
| 668 | return VIOCHAR_MAX_DATA * VIOCHAR_NUM_BUF; | ||
| 669 | } | ||
| 670 | |||
| 671 | /* | ||
| 672 | * We retain the spinlock because we want to get an accurate | ||
| 673 | * count and it can change on us between each operation if we | ||
| 674 | * don't hold the spinlock. | ||
| 675 | */ | ||
| 676 | for (i = 0; ((i < VIOCHAR_NUM_BUF) && (room < VIOCHAR_MAX_DATA)); i++) | ||
| 677 | room += (VIOCHAR_MAX_DATA - pi->bufferBytes[i]); | ||
| 678 | spin_unlock_irqrestore(&consolelock, flags); | ||
| 679 | |||
| 680 | if (room > VIOCHAR_MAX_DATA) | ||
| 681 | room = VIOCHAR_MAX_DATA; | ||
| 682 | return room; | ||
| 683 | } | ||
| 684 | |||
| 685 | /* | ||
| 686 | * TTY chars_in_buffer method | ||
| 687 | */ | ||
| 688 | static int viotty_chars_in_buffer(struct tty_struct *tty) | ||
| 689 | { | ||
| 690 | return 0; | ||
| 691 | } | ||
| 692 | |||
| 693 | static int viotty_ioctl(struct tty_struct *tty, struct file *file, | ||
| 694 | unsigned int cmd, unsigned long arg) | ||
| 695 | { | ||
| 696 | switch (cmd) { | ||
| 697 | /* | ||
| 698 | * the ioctls below read/set the flags usually shown in the leds | ||
| 699 | * don't use them - they will go away without warning | ||
| 700 | */ | ||
| 701 | case KDGETLED: | ||
| 702 | case KDGKBLED: | ||
| 703 | return put_user(0, (char *)arg); | ||
| 704 | |||
| 705 | case KDSKBLED: | ||
| 706 | return 0; | ||
| 707 | } | ||
| 708 | /* FIXME: WTF is this being called for ??? */ | ||
| 709 | lock_kernel(); | ||
| 710 | ret = n_tty_ioctl(tty, file, cmd, arg); | ||
| 711 | unlock_kernel(); | ||
| 712 | return ret; | ||
| 713 | } | ||
| 714 | |||
| 715 | /* | ||
| 716 | * Handle an open charLpEvent. Could be either interrupt or ack | ||
| 717 | */ | ||
| 718 | static void vioHandleOpenEvent(struct HvLpEvent *event) | ||
| 719 | { | ||
| 720 | unsigned long flags; | ||
| 721 | struct viocharlpevent *cevent = (struct viocharlpevent *)event; | ||
| 722 | u8 port = cevent->virtual_device; | ||
| 723 | struct port_info *pi; | ||
| 724 | int reject = 0; | ||
| 725 | |||
| 726 | if (hvlpevent_is_ack(event)) { | ||
| 727 | if (port >= VTTY_PORTS) | ||
| 728 | return; | ||
| 729 | |||
| 730 | spin_lock_irqsave(&consolelock, flags); | ||
| 731 | /* Got the lock, don't cause console output */ | ||
| 732 | |||
| 733 | pi = &port_info[port]; | ||
| 734 | if (event->xRc == HvLpEvent_Rc_Good) { | ||
| 735 | pi->seq = pi->ack = 0; | ||
| 736 | /* | ||
| 737 | * This line allows connections from the primary | ||
| 738 | * partition but once one is connected from the | ||
| 739 | * primary partition nothing short of a reboot | ||
| 740 | * of linux will allow access from the hosting | ||
| 741 | * partition again without a required iSeries fix. | ||
| 742 | */ | ||
| 743 | pi->lp = event->xTargetLp; | ||
| 744 | } | ||
| 745 | |||
| 746 | spin_unlock_irqrestore(&consolelock, flags); | ||
| 747 | if (event->xRc != HvLpEvent_Rc_Good) | ||
| 748 | printk(VIOCONS_KERN_WARN | ||
| 749 | "handle_open_event: event->xRc == (%d).\n", | ||
| 750 | event->xRc); | ||
| 751 | |||
| 752 | if (event->xCorrelationToken != 0) { | ||
| 753 | atomic_t *aptr= (atomic_t *)event->xCorrelationToken; | ||
| 754 | atomic_set(aptr, 1); | ||
| 755 | } else | ||
| 756 | printk(VIOCONS_KERN_WARN | ||
| 757 | "weird...got open ack without atomic\n"); | ||
| 758 | return; | ||
| 759 | } | ||
| 760 | |||
| 761 | /* This had better require an ack, otherwise complain */ | ||
| 762 | if (!hvlpevent_need_ack(event)) { | ||
| 763 | printk(VIOCONS_KERN_WARN "viocharopen without ack bit!\n"); | ||
| 764 | return; | ||
| 765 | } | ||
| 766 | |||
| 767 | spin_lock_irqsave(&consolelock, flags); | ||
| 768 | /* Got the lock, don't cause console output */ | ||
| 769 | |||
| 770 | /* Make sure this is a good virtual tty */ | ||
| 771 | if (port >= VTTY_PORTS) { | ||
| 772 | event->xRc = HvLpEvent_Rc_SubtypeError; | ||
| 773 | cevent->subtype_result_code = viorc_openRejected; | ||
| 774 | /* | ||
| 775 | * Flag state here since we can't printk while holding | ||
| 776 | * a spinlock. | ||
| 777 | */ | ||
| 778 | reject = 1; | ||
| 779 | } else { | ||
| 780 | pi = &port_info[port]; | ||
| 781 | if ((pi->lp != HvLpIndexInvalid) && | ||
| 782 | (pi->lp != event->xSourceLp)) { | ||
| 783 | /* | ||
| 784 | * If this is tty is already connected to a different | ||
| 785 | * partition, fail. | ||
| 786 | */ | ||
| 787 | event->xRc = HvLpEvent_Rc_SubtypeError; | ||
| 788 | cevent->subtype_result_code = viorc_openRejected; | ||
| 789 | reject = 2; | ||
| 790 | } else { | ||
| 791 | pi->lp = event->xSourceLp; | ||
| 792 | event->xRc = HvLpEvent_Rc_Good; | ||
| 793 | cevent->subtype_result_code = viorc_good; | ||
| 794 | pi->seq = pi->ack = 0; | ||
| 795 | reject = 0; | ||
| 796 | } | ||
| 797 | } | ||
| 798 | |||
| 799 | spin_unlock_irqrestore(&consolelock, flags); | ||
| 800 | |||
| 801 | if (reject == 1) | ||
| 802 | printk(VIOCONS_KERN_WARN "open rejected: bad virtual tty.\n"); | ||
| 803 | else if (reject == 2) | ||
| 804 | printk(VIOCONS_KERN_WARN | ||
| 805 | "open rejected: console in exclusive use by another partition.\n"); | ||
| 806 | |||
| 807 | /* Return the acknowledgement */ | ||
| 808 | HvCallEvent_ackLpEvent(event); | ||
| 809 | } | ||
| 810 | |||
| 811 | /* | ||
| 812 | * Handle a close charLpEvent. This should ONLY be an Interrupt because the | ||
| 813 | * virtual console should never actually issue a close event to the hypervisor | ||
| 814 | * because the virtual console never goes away. A close event coming from the | ||
| 815 | * hypervisor simply means that there are no client consoles connected to the | ||
| 816 | * virtual console. | ||
| 817 | * | ||
| 818 | * Regardless of the number of connections masqueraded on the other side of | ||
| 819 | * the hypervisor ONLY ONE close event should be called to accompany the ONE | ||
| 820 | * open event that is called. The close event should ONLY be called when NO | ||
| 821 | * MORE connections (masqueraded or not) exist on the other side of the | ||
| 822 | * hypervisor. | ||
| 823 | */ | ||
| 824 | static void vioHandleCloseEvent(struct HvLpEvent *event) | ||
| 825 | { | ||
| 826 | unsigned long flags; | ||
| 827 | struct viocharlpevent *cevent = (struct viocharlpevent *)event; | ||
| 828 | u8 port = cevent->virtual_device; | ||
| 829 | |||
| 830 | if (hvlpevent_is_int(event)) { | ||
| 831 | if (port >= VTTY_PORTS) { | ||
| 832 | printk(VIOCONS_KERN_WARN | ||
| 833 | "close message from invalid virtual device.\n"); | ||
| 834 | return; | ||
| 835 | } | ||
| 836 | |||
| 837 | /* For closes, just mark the console partition invalid */ | ||
| 838 | spin_lock_irqsave(&consolelock, flags); | ||
| 839 | /* Got the lock, don't cause console output */ | ||
| 840 | |||
| 841 | if (port_info[port].lp == event->xSourceLp) | ||
| 842 | port_info[port].lp = HvLpIndexInvalid; | ||
| 843 | |||
| 844 | spin_unlock_irqrestore(&consolelock, flags); | ||
| 845 | printk(VIOCONS_KERN_INFO "close from %d\n", event->xSourceLp); | ||
| 846 | } else | ||
| 847 | printk(VIOCONS_KERN_WARN | ||
| 848 | "got unexpected close acknowlegement\n"); | ||
| 849 | } | ||
| 850 | |||
| 851 | /* | ||
| 852 | * Handle a config charLpEvent. Could be either interrupt or ack | ||
| 853 | */ | ||
| 854 | static void vioHandleConfig(struct HvLpEvent *event) | ||
| 855 | { | ||
| 856 | struct viocharlpevent *cevent = (struct viocharlpevent *)event; | ||
| 857 | |||
| 858 | HvCall_writeLogBuffer(cevent->data, cevent->len); | ||
| 859 | |||
| 860 | if (cevent->data[0] == 0x01) | ||
| 861 | printk(VIOCONS_KERN_INFO "window resized to %d: %d: %d: %d\n", | ||
| 862 | cevent->data[1], cevent->data[2], | ||
| 863 | cevent->data[3], cevent->data[4]); | ||
| 864 | else | ||
| 865 | printk(VIOCONS_KERN_WARN "unknown config event\n"); | ||
| 866 | } | ||
| 867 | |||
| 868 | /* | ||
| 869 | * Handle a data charLpEvent. | ||
| 870 | */ | ||
| 871 | static void vioHandleData(struct HvLpEvent *event) | ||
| 872 | { | ||
| 873 | struct tty_struct *tty; | ||
| 874 | unsigned long flags; | ||
| 875 | struct viocharlpevent *cevent = (struct viocharlpevent *)event; | ||
| 876 | struct port_info *pi; | ||
| 877 | int index; | ||
| 878 | int num_pushed; | ||
| 879 | u8 port = cevent->virtual_device; | ||
| 880 | |||
| 881 | if (port >= VTTY_PORTS) { | ||
| 882 | printk(VIOCONS_KERN_WARN "data on invalid virtual device %d\n", | ||
| 883 | port); | ||
| 884 | return; | ||
| 885 | } | ||
| 886 | |||
| 887 | /* | ||
| 888 | * Hold the spinlock so that we don't take an interrupt that | ||
| 889 | * changes tty between the time we fetch the port_info | ||
| 890 | * pointer and the time we paranoia check. | ||
| 891 | */ | ||
| 892 | spin_lock_irqsave(&consolelock, flags); | ||
| 893 | pi = &port_info[port]; | ||
| 894 | |||
| 895 | /* | ||
| 896 | * Change 05/01/2003 - Ryan Arnold: If a partition other than | ||
| 897 | * the current exclusive partition tries to send us data | ||
| 898 | * events then just drop them on the floor because we don't | ||
| 899 | * want his stinking data. He isn't authorized to receive | ||
| 900 | * data because he wasn't the first one to get the console, | ||
| 901 | * therefore he shouldn't be allowed to send data either. | ||
| 902 | * This will work without an iSeries fix. | ||
| 903 | */ | ||
| 904 | if (pi->lp != event->xSourceLp) { | ||
| 905 | spin_unlock_irqrestore(&consolelock, flags); | ||
| 906 | return; | ||
| 907 | } | ||
| 908 | |||
| 909 | tty = pi->tty; | ||
| 910 | if (tty == NULL) { | ||
| 911 | spin_unlock_irqrestore(&consolelock, flags); | ||
| 912 | printk(VIOCONS_KERN_WARN "no tty for virtual device %d\n", | ||
| 913 | port); | ||
| 914 | return; | ||
| 915 | } | ||
| 916 | |||
| 917 | if (tty->magic != TTY_MAGIC) { | ||
| 918 | spin_unlock_irqrestore(&consolelock, flags); | ||
| 919 | printk(VIOCONS_KERN_WARN "tty bad magic\n"); | ||
| 920 | return; | ||
| 921 | } | ||
| 922 | |||
| 923 | /* | ||
| 924 | * Just to be paranoid, make sure the tty points back to this port | ||
| 925 | */ | ||
| 926 | pi = (struct port_info *)tty->driver_data; | ||
| 927 | if (!pi || viotty_paranoia_check(pi, tty->name, "vioHandleData")) { | ||
| 928 | spin_unlock_irqrestore(&consolelock, flags); | ||
| 929 | return; | ||
| 930 | } | ||
| 931 | spin_unlock_irqrestore(&consolelock, flags); | ||
| 932 | |||
| 933 | /* | ||
| 934 | * Change 07/21/2003 - Ryan Arnold: functionality added to | ||
| 935 | * support sysrq utilizing ^O as the sysrq key. The sysrq | ||
| 936 | * functionality will only work if built into the kernel and | ||
| 937 | * then only if sysrq is enabled through the proc filesystem. | ||
| 938 | */ | ||
| 939 | num_pushed = 0; | ||
| 940 | for (index = 0; index < cevent->len; index++) { | ||
| 941 | /* | ||
| 942 | * Will be optimized away if !CONFIG_MAGIC_SYSRQ: | ||
| 943 | */ | ||
| 944 | if (sysrq_on()) { | ||
| 945 | /* 0x0f is the ascii character for ^O */ | ||
| 946 | if (cevent->data[index] == '\x0f') { | ||
| 947 | vio_sysrq_pressed = 1; | ||
| 948 | /* | ||
| 949 | * continue because we don't want to add | ||
| 950 | * the sysrq key into the data string. | ||
| 951 | */ | ||
| 952 | continue; | ||
| 953 | } else if (vio_sysrq_pressed) { | ||
| 954 | handle_sysrq(cevent->data[index], tty); | ||
| 955 | vio_sysrq_pressed = 0; | ||
| 956 | /* | ||
| 957 | * continue because we don't want to add | ||
| 958 | * the sysrq sequence into the data string. | ||
| 959 | */ | ||
| 960 | continue; | ||
| 961 | } | ||
| 962 | } | ||
| 963 | /* | ||
| 964 | * The sysrq sequence isn't included in this check if | ||
| 965 | * sysrq is enabled and compiled into the kernel because | ||
| 966 | * the sequence will never get inserted into the buffer. | ||
| 967 | * Don't attempt to copy more data into the buffer than we | ||
| 968 | * have room for because it would fail without indication. | ||
| 969 | */ | ||
| 970 | if(tty_insert_flip_char(tty, cevent->data[index], TTY_NORMAL) == 0) { | ||
| 971 | printk(VIOCONS_KERN_WARN "input buffer overflow!\n"); | ||
| 972 | break; | ||
| 973 | } | ||
| 974 | num_pushed++; | ||
| 975 | } | ||
| 976 | |||
| 977 | if (num_pushed) | ||
| 978 | tty_flip_buffer_push(tty); | ||
| 979 | } | ||
| 980 | |||
| 981 | /* | ||
| 982 | * Handle an ack charLpEvent. | ||
| 983 | */ | ||
| 984 | static void vioHandleAck(struct HvLpEvent *event) | ||
| 985 | { | ||
| 986 | struct viocharlpevent *cevent = (struct viocharlpevent *)event; | ||
| 987 | unsigned long flags; | ||
| 988 | u8 port = cevent->virtual_device; | ||
| 989 | |||
| 990 | if (port >= VTTY_PORTS) { | ||
| 991 | printk(VIOCONS_KERN_WARN "data on invalid virtual device\n"); | ||
| 992 | return; | ||
| 993 | } | ||
| 994 | |||
| 995 | spin_lock_irqsave(&consolelock, flags); | ||
| 996 | port_info[port].ack = event->xCorrelationToken; | ||
| 997 | spin_unlock_irqrestore(&consolelock, flags); | ||
| 998 | |||
| 999 | if (port_info[port].used) | ||
| 1000 | send_buffers(&port_info[port]); | ||
| 1001 | } | ||
| 1002 | |||
| 1003 | /* | ||
| 1004 | * Handle charLpEvents and route to the appropriate routine | ||
| 1005 | */ | ||
| 1006 | static void vioHandleCharEvent(struct HvLpEvent *event) | ||
| 1007 | { | ||
| 1008 | int charminor; | ||
| 1009 | |||
| 1010 | if (event == NULL) | ||
| 1011 | return; | ||
| 1012 | |||
| 1013 | charminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK; | ||
| 1014 | switch (charminor) { | ||
| 1015 | case viocharopen: | ||
| 1016 | vioHandleOpenEvent(event); | ||
| 1017 | break; | ||
| 1018 | case viocharclose: | ||
| 1019 | vioHandleCloseEvent(event); | ||
| 1020 | break; | ||
| 1021 | case viochardata: | ||
| 1022 | vioHandleData(event); | ||
| 1023 | break; | ||
| 1024 | case viocharack: | ||
| 1025 | vioHandleAck(event); | ||
| 1026 | break; | ||
| 1027 | case viocharconfig: | ||
| 1028 | vioHandleConfig(event); | ||
| 1029 | break; | ||
| 1030 | default: | ||
| 1031 | if (hvlpevent_is_int(event) && hvlpevent_need_ack(event)) { | ||
| 1032 | event->xRc = HvLpEvent_Rc_InvalidSubtype; | ||
| 1033 | HvCallEvent_ackLpEvent(event); | ||
| 1034 | } | ||
| 1035 | } | ||
| 1036 | } | ||
| 1037 | |||
| 1038 | /* | ||
| 1039 | * Send an open event | ||
| 1040 | */ | ||
| 1041 | static int send_open(HvLpIndex remoteLp, void *sem) | ||
| 1042 | { | ||
| 1043 | return HvCallEvent_signalLpEventFast(remoteLp, | ||
| 1044 | HvLpEvent_Type_VirtualIo, | ||
| 1045 | viomajorsubtype_chario | viocharopen, | ||
| 1046 | HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck, | ||
| 1047 | viopath_sourceinst(remoteLp), | ||
| 1048 | viopath_targetinst(remoteLp), | ||
| 1049 | (u64)(unsigned long)sem, VIOVERSION << 16, | ||
| 1050 | 0, 0, 0, 0); | ||
| 1051 | } | ||
| 1052 | |||
| 1053 | static const struct tty_operations serial_ops = { | ||
| 1054 | .open = viotty_open, | ||
| 1055 | .close = viotty_close, | ||
| 1056 | .write = viotty_write, | ||
| 1057 | .put_char = viotty_put_char, | ||
| 1058 | .write_room = viotty_write_room, | ||
| 1059 | .chars_in_buffer = viotty_chars_in_buffer, | ||
| 1060 | .ioctl = viotty_ioctl, | ||
| 1061 | }; | ||
| 1062 | |||
| 1063 | static int __init viocons_init2(void) | ||
| 1064 | { | ||
| 1065 | atomic_t wait_flag; | ||
| 1066 | int rc; | ||
| 1067 | |||
| 1068 | if (!firmware_has_feature(FW_FEATURE_ISERIES)) | ||
| 1069 | return -ENODEV; | ||
| 1070 | |||
| 1071 | /* +2 for fudge */ | ||
| 1072 | rc = viopath_open(HvLpConfig_getPrimaryLpIndex(), | ||
| 1073 | viomajorsubtype_chario, VIOCHAR_WINDOW + 2); | ||
| 1074 | if (rc) | ||
| 1075 | printk(VIOCONS_KERN_WARN "error opening to primary %d\n", rc); | ||
| 1076 | |||
| 1077 | if (viopath_hostLp == HvLpIndexInvalid) | ||
| 1078 | vio_set_hostlp(); | ||
| 1079 | |||
| 1080 | /* | ||
| 1081 | * And if the primary is not the same as the hosting LP, open to the | ||
| 1082 | * hosting lp | ||
| 1083 | */ | ||
| 1084 | if ((viopath_hostLp != HvLpIndexInvalid) && | ||
| 1085 | (viopath_hostLp != HvLpConfig_getPrimaryLpIndex())) { | ||
| 1086 | printk(VIOCONS_KERN_INFO "open path to hosting (%d)\n", | ||
| 1087 | viopath_hostLp); | ||
| 1088 | rc = viopath_open(viopath_hostLp, viomajorsubtype_chario, | ||
| 1089 | VIOCHAR_WINDOW + 2); /* +2 for fudge */ | ||
| 1090 | if (rc) | ||
| 1091 | printk(VIOCONS_KERN_WARN | ||
| 1092 | "error opening to partition %d: %d\n", | ||
| 1093 | viopath_hostLp, rc); | ||
| 1094 | } | ||
| 1095 | |||
| 1096 | if (vio_setHandler(viomajorsubtype_chario, vioHandleCharEvent) < 0) | ||
| 1097 | printk(VIOCONS_KERN_WARN | ||
| 1098 | "error seting handler for console events!\n"); | ||
| 1099 | |||
| 1100 | /* | ||
| 1101 | * First, try to open the console to the hosting lp. | ||
| 1102 | * Wait on a semaphore for the response. | ||
| 1103 | */ | ||
| 1104 | atomic_set(&wait_flag, 0); | ||
| 1105 | if ((viopath_isactive(viopath_hostLp)) && | ||
| 1106 | (send_open(viopath_hostLp, (void *)&wait_flag) == 0)) { | ||
| 1107 | printk(VIOCONS_KERN_INFO "hosting partition %d\n", | ||
| 1108 | viopath_hostLp); | ||
| 1109 | while (atomic_read(&wait_flag) == 0) | ||
| 1110 | mb(); | ||
| 1111 | atomic_set(&wait_flag, 0); | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | /* | ||
| 1115 | * If we don't have an active console, try the primary | ||
| 1116 | */ | ||
| 1117 | if ((!viopath_isactive(port_info[0].lp)) && | ||
| 1118 | (viopath_isactive(HvLpConfig_getPrimaryLpIndex())) && | ||
| 1119 | (send_open(HvLpConfig_getPrimaryLpIndex(), (void *)&wait_flag) | ||
| 1120 | == 0)) { | ||
| 1121 | printk(VIOCONS_KERN_INFO "opening console to primary partition\n"); | ||
| 1122 | while (atomic_read(&wait_flag) == 0) | ||
| 1123 | mb(); | ||
| 1124 | } | ||
| 1125 | |||
| 1126 | /* Initialize the tty_driver structure */ | ||
| 1127 | viotty_driver = alloc_tty_driver(VTTY_PORTS); | ||
| 1128 | viotty_driver->owner = THIS_MODULE; | ||
| 1129 | viotty_driver->driver_name = "vioconsole"; | ||
| 1130 | viotty_driver->name = "tty"; | ||
| 1131 | viotty_driver->name_base = 1; | ||
| 1132 | viotty_driver->major = TTY_MAJOR; | ||
| 1133 | viotty_driver->minor_start = 1; | ||
| 1134 | viotty_driver->type = TTY_DRIVER_TYPE_CONSOLE; | ||
| 1135 | viotty_driver->subtype = 1; | ||
| 1136 | viotty_driver->init_termios = tty_std_termios; | ||
| 1137 | viotty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS; | ||
| 1138 | tty_set_operations(viotty_driver, &serial_ops); | ||
| 1139 | |||
| 1140 | if (tty_register_driver(viotty_driver)) { | ||
| 1141 | printk(VIOCONS_KERN_WARN "couldn't register console driver\n"); | ||
| 1142 | put_tty_driver(viotty_driver); | ||
| 1143 | viotty_driver = NULL; | ||
| 1144 | } | ||
| 1145 | |||
| 1146 | unregister_console(&viocons_early); | ||
| 1147 | register_console(&viocons); | ||
| 1148 | |||
| 1149 | return 0; | ||
| 1150 | } | ||
| 1151 | |||
| 1152 | static int __init viocons_init(void) | ||
| 1153 | { | ||
| 1154 | int i; | ||
| 1155 | |||
| 1156 | if (!firmware_has_feature(FW_FEATURE_ISERIES)) | ||
| 1157 | return -ENODEV; | ||
| 1158 | |||
| 1159 | printk(VIOCONS_KERN_INFO "registering console\n"); | ||
| 1160 | for (i = 0; i < VTTY_PORTS; i++) { | ||
| 1161 | port_info[i].lp = HvLpIndexInvalid; | ||
| 1162 | port_info[i].magic = VIOTTY_MAGIC; | ||
| 1163 | } | ||
| 1164 | HvCall_setLogBufferFormatAndCodepage(HvCall_LogBuffer_ASCII, 437); | ||
| 1165 | add_preferred_console("viocons", 0, NULL); | ||
| 1166 | register_console(&viocons_early); | ||
| 1167 | return 0; | ||
| 1168 | } | ||
| 1169 | |||
| 1170 | console_initcall(viocons_init); | ||
| 1171 | module_init(viocons_init2); | ||
diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c index bc81d6fcd2fd..2e6d5848d217 100644 --- a/drivers/firewire/fw-cdev.c +++ b/drivers/firewire/fw-cdev.c | |||
| @@ -369,22 +369,33 @@ complete_transaction(struct fw_card *card, int rcode, | |||
| 369 | struct response *response = data; | 369 | struct response *response = data; |
| 370 | struct client *client = response->client; | 370 | struct client *client = response->client; |
| 371 | unsigned long flags; | 371 | unsigned long flags; |
| 372 | struct fw_cdev_event_response *r = &response->response; | ||
| 372 | 373 | ||
| 373 | if (length < response->response.length) | 374 | if (length < r->length) |
| 374 | response->response.length = length; | 375 | r->length = length; |
| 375 | if (rcode == RCODE_COMPLETE) | 376 | if (rcode == RCODE_COMPLETE) |
| 376 | memcpy(response->response.data, payload, | 377 | memcpy(r->data, payload, r->length); |
| 377 | response->response.length); | ||
| 378 | 378 | ||
| 379 | spin_lock_irqsave(&client->lock, flags); | 379 | spin_lock_irqsave(&client->lock, flags); |
| 380 | list_del(&response->resource.link); | 380 | list_del(&response->resource.link); |
| 381 | spin_unlock_irqrestore(&client->lock, flags); | 381 | spin_unlock_irqrestore(&client->lock, flags); |
| 382 | 382 | ||
| 383 | response->response.type = FW_CDEV_EVENT_RESPONSE; | 383 | r->type = FW_CDEV_EVENT_RESPONSE; |
| 384 | response->response.rcode = rcode; | 384 | r->rcode = rcode; |
| 385 | queue_event(client, &response->event, &response->response, | 385 | |
| 386 | sizeof(response->response) + response->response.length, | 386 | /* |
| 387 | NULL, 0); | 387 | * In the case that sizeof(*r) doesn't align with the position of the |
| 388 | * data, and the read is short, preserve an extra copy of the data | ||
| 389 | * to stay compatible with a pre-2.6.27 bug. Since the bug is harmless | ||
| 390 | * for short reads and some apps depended on it, this is both safe | ||
| 391 | * and prudent for compatibility. | ||
| 392 | */ | ||
| 393 | if (r->length <= sizeof(*r) - offsetof(typeof(*r), data)) | ||
| 394 | queue_event(client, &response->event, r, sizeof(*r), | ||
| 395 | r->data, r->length); | ||
| 396 | else | ||
| 397 | queue_event(client, &response->event, r, sizeof(*r) + r->length, | ||
| 398 | NULL, 0); | ||
| 388 | } | 399 | } |
| 389 | 400 | ||
| 390 | static int ioctl_send_request(struct client *client, void *buffer) | 401 | static int ioctl_send_request(struct client *client, void *buffer) |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index c882fd05cf29..bf4ebfb86fa5 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
| @@ -57,6 +57,16 @@ config SENSORS_ABITUGURU3 | |||
| 57 | This driver can also be built as a module. If so, the module | 57 | This driver can also be built as a module. If so, the module |
| 58 | will be called abituguru3. | 58 | will be called abituguru3. |
| 59 | 59 | ||
| 60 | config SENSORS_AD7414 | ||
| 61 | tristate "Analog Devices AD7414" | ||
| 62 | depends on I2C && EXPERIMENTAL | ||
| 63 | help | ||
| 64 | If you say yes here you get support for the Analog Devices | ||
| 65 | AD7414 temperature monitoring chip. | ||
| 66 | |||
| 67 | This driver can also be built as a module. If so, the module | ||
| 68 | will be called ad7414. | ||
| 69 | |||
| 60 | config SENSORS_AD7418 | 70 | config SENSORS_AD7418 |
| 61 | tristate "Analog Devices AD7416, AD7417 and AD7418" | 71 | tristate "Analog Devices AD7416, AD7417 and AD7418" |
| 62 | depends on I2C && EXPERIMENTAL | 72 | depends on I2C && EXPERIMENTAL |
| @@ -124,7 +134,7 @@ config SENSORS_ADM1031 | |||
| 124 | 134 | ||
| 125 | config SENSORS_ADM9240 | 135 | config SENSORS_ADM9240 |
| 126 | tristate "Analog Devices ADM9240 and compatibles" | 136 | tristate "Analog Devices ADM9240 and compatibles" |
| 127 | depends on I2C && EXPERIMENTAL | 137 | depends on I2C |
| 128 | select HWMON_VID | 138 | select HWMON_VID |
| 129 | help | 139 | help |
| 130 | If you say yes here you get support for Analog Devices ADM9240, | 140 | If you say yes here you get support for Analog Devices ADM9240, |
| @@ -575,8 +585,8 @@ config SENSORS_DME1737 | |||
| 575 | select HWMON_VID | 585 | select HWMON_VID |
| 576 | help | 586 | help |
| 577 | If you say yes here you get support for the hardware monitoring | 587 | If you say yes here you get support for the hardware monitoring |
| 578 | and fan control features of the SMSC DME1737 (and compatibles | 588 | and fan control features of the SMSC DME1737, SCH311x, SCH5027, and |
| 579 | like the Asus A8000) and SCH311x Super-I/O chips. | 589 | Asus A8000 Super-I/O chips. |
| 580 | 590 | ||
| 581 | This driver can also be built as a module. If so, the module | 591 | This driver can also be built as a module. If so, the module |
| 582 | will be called dme1737. | 592 | will be called dme1737. |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index d098677e08de..7943e5cefb06 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
| @@ -15,6 +15,7 @@ obj-$(CONFIG_SENSORS_W83791D) += w83791d.o | |||
| 15 | 15 | ||
| 16 | obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o | 16 | obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o |
| 17 | obj-$(CONFIG_SENSORS_ABITUGURU3)+= abituguru3.o | 17 | obj-$(CONFIG_SENSORS_ABITUGURU3)+= abituguru3.o |
| 18 | obj-$(CONFIG_SENSORS_AD7414) += ad7414.o | ||
| 18 | obj-$(CONFIG_SENSORS_AD7418) += ad7418.o | 19 | obj-$(CONFIG_SENSORS_AD7418) += ad7418.o |
| 19 | obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o | 20 | obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o |
| 20 | obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o | 21 | obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o |
diff --git a/drivers/hwmon/ad7414.c b/drivers/hwmon/ad7414.c new file mode 100644 index 000000000000..ce8d94fbfd7e --- /dev/null +++ b/drivers/hwmon/ad7414.c | |||
| @@ -0,0 +1,268 @@ | |||
| 1 | /* | ||
| 2 | * An hwmon driver for the Analog Devices AD7414 | ||
| 3 | * | ||
| 4 | * Copyright 2006 Stefan Roese <sr at denx.de>, DENX Software Engineering | ||
| 5 | * | ||
| 6 | * Copyright (c) 2008 PIKA Technologies | ||
| 7 | * Sean MacLennan <smaclennan@pikatech.com> | ||
| 8 | * | ||
| 9 | * Copyright (c) 2008 Spansion Inc. | ||
| 10 | * Frank Edelhaeuser <frank.edelhaeuser at spansion.com> | ||
| 11 | * (converted to "new style" I2C driver model, removed checkpatch.pl warnings) | ||
| 12 | * | ||
| 13 | * Based on ad7418.c | ||
| 14 | * Copyright 2006 Tower Technologies, Alessandro Zummo <a.zummo at towertech.it> | ||
| 15 | * | ||
| 16 | * This program is free software; you can redistribute it and/or modify | ||
| 17 | * it under the terms of the GNU General Public License as published by | ||
| 18 | * the Free Software Foundation; either version 2 of the License, or | ||
| 19 | * (at your option) any later version. | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <linux/module.h> | ||
| 23 | #include <linux/jiffies.h> | ||
| 24 | #include <linux/i2c.h> | ||
| 25 | #include <linux/hwmon.h> | ||
| 26 | #include <linux/hwmon-sysfs.h> | ||
| 27 | #include <linux/err.h> | ||
| 28 | #include <linux/mutex.h> | ||
| 29 | #include <linux/sysfs.h> | ||
| 30 | |||
| 31 | |||
| 32 | /* AD7414 registers */ | ||
| 33 | #define AD7414_REG_TEMP 0x00 | ||
| 34 | #define AD7414_REG_CONF 0x01 | ||
| 35 | #define AD7414_REG_T_HIGH 0x02 | ||
| 36 | #define AD7414_REG_T_LOW 0x03 | ||
| 37 | |||
| 38 | static u8 AD7414_REG_LIMIT[] = { AD7414_REG_T_HIGH, AD7414_REG_T_LOW }; | ||
| 39 | |||
| 40 | struct ad7414_data { | ||
| 41 | struct device *hwmon_dev; | ||
| 42 | struct mutex lock; /* atomic read data updates */ | ||
| 43 | char valid; /* !=0 if following fields are valid */ | ||
| 44 | unsigned long next_update; /* In jiffies */ | ||
| 45 | s16 temp_input; /* Register values */ | ||
| 46 | s8 temps[ARRAY_SIZE(AD7414_REG_LIMIT)]; | ||
| 47 | }; | ||
| 48 | |||
| 49 | /* REG: (0.25C/bit, two's complement) << 6 */ | ||
| 50 | static inline int ad7414_temp_from_reg(s16 reg) | ||
| 51 | { | ||
| 52 | /* use integer division instead of equivalent right shift to | ||
| 53 | * guarantee arithmetic shift and preserve the sign | ||
| 54 | */ | ||
| 55 | return ((int)reg / 64) * 250; | ||
| 56 | } | ||
| 57 | |||
| 58 | static inline int ad7414_read(struct i2c_client *client, u8 reg) | ||
| 59 | { | ||
| 60 | if (reg == AD7414_REG_TEMP) { | ||
| 61 | int value = i2c_smbus_read_word_data(client, reg); | ||
| 62 | return (value < 0) ? value : swab16(value); | ||
| 63 | } else | ||
| 64 | return i2c_smbus_read_byte_data(client, reg); | ||
| 65 | } | ||
| 66 | |||
| 67 | static inline int ad7414_write(struct i2c_client *client, u8 reg, u8 value) | ||
| 68 | { | ||
| 69 | return i2c_smbus_write_byte_data(client, reg, value); | ||
| 70 | } | ||
| 71 | |||
| 72 | struct ad7414_data *ad7414_update_device(struct device *dev) | ||
| 73 | { | ||
| 74 | struct i2c_client *client = to_i2c_client(dev); | ||
| 75 | struct ad7414_data *data = i2c_get_clientdata(client); | ||
| 76 | |||
| 77 | mutex_lock(&data->lock); | ||
| 78 | |||
| 79 | if (time_after(jiffies, data->next_update) || !data->valid) { | ||
| 80 | int value, i; | ||
| 81 | |||
| 82 | dev_dbg(&client->dev, "starting ad7414 update\n"); | ||
| 83 | |||
| 84 | value = ad7414_read(client, AD7414_REG_TEMP); | ||
| 85 | if (value < 0) | ||
| 86 | dev_dbg(&client->dev, "AD7414_REG_TEMP err %d\n", | ||
| 87 | value); | ||
| 88 | else | ||
| 89 | data->temp_input = value; | ||
| 90 | |||
| 91 | for (i = 0; i < ARRAY_SIZE(AD7414_REG_LIMIT); ++i) { | ||
| 92 | value = ad7414_read(client, AD7414_REG_LIMIT[i]); | ||
| 93 | if (value < 0) | ||
| 94 | dev_dbg(&client->dev, "AD7414 reg %d err %d\n", | ||
| 95 | AD7414_REG_LIMIT[i], value); | ||
| 96 | else | ||
| 97 | data->temps[i] = value; | ||
| 98 | } | ||
| 99 | |||
| 100 | data->next_update = jiffies + HZ + HZ / 2; | ||
| 101 | data->valid = 1; | ||
| 102 | } | ||
| 103 | |||
| 104 | mutex_unlock(&data->lock); | ||
| 105 | |||
| 106 | return data; | ||
| 107 | } | ||
| 108 | |||
| 109 | static ssize_t show_temp_input(struct device *dev, | ||
| 110 | struct device_attribute *attr, char *buf) | ||
| 111 | { | ||
| 112 | struct ad7414_data *data = ad7414_update_device(dev); | ||
| 113 | return sprintf(buf, "%d\n", ad7414_temp_from_reg(data->temp_input)); | ||
| 114 | } | ||
| 115 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL, 0); | ||
| 116 | |||
| 117 | static ssize_t show_max_min(struct device *dev, struct device_attribute *attr, | ||
| 118 | char *buf) | ||
| 119 | { | ||
| 120 | int index = to_sensor_dev_attr(attr)->index; | ||
| 121 | struct ad7414_data *data = ad7414_update_device(dev); | ||
| 122 | return sprintf(buf, "%d\n", data->temps[index] * 1000); | ||
| 123 | } | ||
| 124 | |||
| 125 | static ssize_t set_max_min(struct device *dev, | ||
| 126 | struct device_attribute *attr, | ||
| 127 | const char *buf, size_t count) | ||
| 128 | { | ||
| 129 | struct i2c_client *client = to_i2c_client(dev); | ||
| 130 | struct ad7414_data *data = i2c_get_clientdata(client); | ||
| 131 | int index = to_sensor_dev_attr(attr)->index; | ||
| 132 | u8 reg = AD7414_REG_LIMIT[index]; | ||
| 133 | long temp = simple_strtol(buf, NULL, 10); | ||
| 134 | |||
| 135 | temp = SENSORS_LIMIT(temp, -40000, 85000); | ||
| 136 | temp = (temp + (temp < 0 ? -500 : 500)) / 1000; | ||
| 137 | |||
| 138 | mutex_lock(&data->lock); | ||
| 139 | data->temps[index] = temp; | ||
| 140 | ad7414_write(client, reg, temp); | ||
| 141 | mutex_unlock(&data->lock); | ||
| 142 | return count; | ||
| 143 | } | ||
| 144 | |||
| 145 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, | ||
| 146 | show_max_min, set_max_min, 0); | ||
| 147 | static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, | ||
| 148 | show_max_min, set_max_min, 1); | ||
| 149 | |||
| 150 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | ||
| 151 | char *buf) | ||
| 152 | { | ||
| 153 | int bitnr = to_sensor_dev_attr(attr)->index; | ||
| 154 | struct ad7414_data *data = ad7414_update_device(dev); | ||
| 155 | int value = (data->temp_input >> bitnr) & 1; | ||
| 156 | return sprintf(buf, "%d\n", value); | ||
| 157 | } | ||
| 158 | |||
| 159 | static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 3); | ||
| 160 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 4); | ||
| 161 | |||
| 162 | static struct attribute *ad7414_attributes[] = { | ||
| 163 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
| 164 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
| 165 | &sensor_dev_attr_temp1_min.dev_attr.attr, | ||
| 166 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | ||
| 167 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, | ||
| 168 | NULL | ||
| 169 | }; | ||
| 170 | |||
| 171 | static const struct attribute_group ad7414_group = { | ||
| 172 | .attrs = ad7414_attributes, | ||
| 173 | }; | ||
| 174 | |||
| 175 | static int ad7414_probe(struct i2c_client *client, | ||
| 176 | const struct i2c_device_id *dev_id) | ||
| 177 | { | ||
| 178 | struct ad7414_data *data; | ||
| 179 | int conf; | ||
| 180 | int err = 0; | ||
| 181 | |||
| 182 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | | ||
| 183 | I2C_FUNC_SMBUS_READ_WORD_DATA)) | ||
| 184 | goto exit; | ||
| 185 | |||
| 186 | data = kzalloc(sizeof(struct ad7414_data), GFP_KERNEL); | ||
| 187 | if (!data) { | ||
| 188 | err = -ENOMEM; | ||
| 189 | goto exit; | ||
| 190 | } | ||
| 191 | |||
| 192 | i2c_set_clientdata(client, data); | ||
| 193 | mutex_init(&data->lock); | ||
| 194 | |||
| 195 | dev_info(&client->dev, "chip found\n"); | ||
| 196 | |||
| 197 | /* Make sure the chip is powered up. */ | ||
| 198 | conf = i2c_smbus_read_byte_data(client, AD7414_REG_CONF); | ||
| 199 | if (conf < 0) | ||
| 200 | dev_warn(&client->dev, | ||
| 201 | "ad7414_probe unable to read config register.\n"); | ||
| 202 | else { | ||
| 203 | conf &= ~(1 << 7); | ||
| 204 | i2c_smbus_write_byte_data(client, AD7414_REG_CONF, conf); | ||
| 205 | } | ||
| 206 | |||
| 207 | /* Register sysfs hooks */ | ||
| 208 | err = sysfs_create_group(&client->dev.kobj, &ad7414_group); | ||
| 209 | if (err) | ||
| 210 | goto exit_free; | ||
| 211 | |||
| 212 | data->hwmon_dev = hwmon_device_register(&client->dev); | ||
| 213 | if (IS_ERR(data->hwmon_dev)) { | ||
| 214 | err = PTR_ERR(data->hwmon_dev); | ||
| 215 | goto exit_remove; | ||
| 216 | } | ||
| 217 | |||
| 218 | return 0; | ||
| 219 | |||
| 220 | exit_remove: | ||
| 221 | sysfs_remove_group(&client->dev.kobj, &ad7414_group); | ||
| 222 | exit_free: | ||
| 223 | kfree(data); | ||
| 224 | exit: | ||
| 225 | return err; | ||
| 226 | } | ||
| 227 | |||
| 228 | static int __devexit ad7414_remove(struct i2c_client *client) | ||
| 229 | { | ||
| 230 | struct ad7414_data *data = i2c_get_clientdata(client); | ||
| 231 | |||
| 232 | hwmon_device_unregister(data->hwmon_dev); | ||
| 233 | sysfs_remove_group(&client->dev.kobj, &ad7414_group); | ||
| 234 | kfree(data); | ||
| 235 | return 0; | ||
| 236 | } | ||
| 237 | |||
| 238 | static const struct i2c_device_id ad7414_id[] = { | ||
| 239 | { "ad7414", 0 }, | ||
| 240 | {} | ||
| 241 | }; | ||
| 242 | |||
| 243 | static struct i2c_driver ad7414_driver = { | ||
| 244 | .driver = { | ||
| 245 | .name = "ad7414", | ||
| 246 | }, | ||
| 247 | .probe = ad7414_probe, | ||
| 248 | .remove = __devexit_p(ad7414_remove), | ||
| 249 | .id_table = ad7414_id, | ||
| 250 | }; | ||
| 251 | |||
| 252 | static int __init ad7414_init(void) | ||
| 253 | { | ||
| 254 | return i2c_add_driver(&ad7414_driver); | ||
| 255 | } | ||
| 256 | module_init(ad7414_init); | ||
| 257 | |||
| 258 | static void __exit ad7414_exit(void) | ||
| 259 | { | ||
| 260 | i2c_del_driver(&ad7414_driver); | ||
| 261 | } | ||
| 262 | module_exit(ad7414_exit); | ||
| 263 | |||
| 264 | MODULE_AUTHOR("Stefan Roese <sr at denx.de>, " | ||
| 265 | "Frank Edelhaeuser <frank.edelhaeuser at spansion.com>"); | ||
| 266 | |||
| 267 | MODULE_DESCRIPTION("AD7414 driver"); | ||
| 268 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c index 5e2cf0aef480..cdb8311e4ef7 100644 --- a/drivers/hwmon/dme1737.c +++ b/drivers/hwmon/dme1737.c | |||
| @@ -1,11 +1,11 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * dme1737.c - Driver for the SMSC DME1737, Asus A8000, and SMSC SCH311x | 2 | * dme1737.c - Driver for the SMSC DME1737, Asus A8000, SMSC SCH311x and |
| 3 | * Super-I/O chips integrated hardware monitoring features. | 3 | * SCH5027 Super-I/O chips integrated hardware monitoring features. |
| 4 | * Copyright (c) 2007 Juerg Haefliger <juergh@gmail.com> | 4 | * Copyright (c) 2007, 2008 Juerg Haefliger <juergh@gmail.com> |
| 5 | * | 5 | * |
| 6 | * This driver is an I2C/ISA hybrid, meaning that it uses the I2C bus to access | 6 | * This driver is an I2C/ISA hybrid, meaning that it uses the I2C bus to access |
| 7 | * the chip registers if a DME1737 (or A8000) is found and the ISA bus if a | 7 | * the chip registers if a DME1737, A8000, or SCH5027 is found and the ISA bus |
| 8 | * SCH311x chip is found. Both types of chips have very similar hardware | 8 | * if a SCH311x chip is found. Both types of chips have very similar hardware |
| 9 | * monitoring capabilities but differ in the way they can be accessed. | 9 | * monitoring capabilities but differ in the way they can be accessed. |
| 10 | * | 10 | * |
| 11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
| @@ -57,7 +57,10 @@ MODULE_PARM_DESC(probe_all_addr, "Include probing of non-standard LPC " | |||
| 57 | static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; | 57 | static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; |
| 58 | 58 | ||
| 59 | /* Insmod parameters */ | 59 | /* Insmod parameters */ |
| 60 | I2C_CLIENT_INSMOD_1(dme1737); | 60 | I2C_CLIENT_INSMOD_2(dme1737, sch5027); |
| 61 | |||
| 62 | /* ISA chip types */ | ||
| 63 | enum isa_chips { sch311x = sch5027 + 1 }; | ||
| 61 | 64 | ||
| 62 | /* --------------------------------------------------------------------- | 65 | /* --------------------------------------------------------------------- |
| 63 | * Registers | 66 | * Registers |
| @@ -163,6 +166,7 @@ static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23}; | |||
| 163 | #define DME1737_VERSTEP 0x88 | 166 | #define DME1737_VERSTEP 0x88 |
| 164 | #define DME1737_VERSTEP_MASK 0xf8 | 167 | #define DME1737_VERSTEP_MASK 0xf8 |
| 165 | #define SCH311X_DEVICE 0x8c | 168 | #define SCH311X_DEVICE 0x8c |
| 169 | #define SCH5027_VERSTEP 0x69 | ||
| 166 | 170 | ||
| 167 | /* Length of ISA address segment */ | 171 | /* Length of ISA address segment */ |
| 168 | #define DME1737_EXTENT 2 | 172 | #define DME1737_EXTENT 2 |
| @@ -182,6 +186,7 @@ struct dme1737_data { | |||
| 182 | unsigned long last_update; /* in jiffies */ | 186 | unsigned long last_update; /* in jiffies */ |
| 183 | unsigned long last_vbat; /* in jiffies */ | 187 | unsigned long last_vbat; /* in jiffies */ |
| 184 | enum chips type; | 188 | enum chips type; |
| 189 | const int *in_nominal; /* pointer to IN_NOMINAL array */ | ||
| 185 | 190 | ||
| 186 | u8 vid; | 191 | u8 vid; |
| 187 | u8 pwm_rr_en; | 192 | u8 pwm_rr_en; |
| @@ -220,23 +225,23 @@ static const int IN_NOMINAL_DME1737[] = {5000, 2250, 3300, 5000, 12000, 3300, | |||
| 220 | 3300}; | 225 | 3300}; |
| 221 | static const int IN_NOMINAL_SCH311x[] = {2500, 1500, 3300, 5000, 12000, 3300, | 226 | static const int IN_NOMINAL_SCH311x[] = {2500, 1500, 3300, 5000, 12000, 3300, |
| 222 | 3300}; | 227 | 3300}; |
| 223 | #define IN_NOMINAL(ix, type) (((type) == dme1737) ? \ | 228 | static const int IN_NOMINAL_SCH5027[] = {5000, 2250, 3300, 1125, 1125, 3300, |
| 224 | IN_NOMINAL_DME1737[(ix)] : \ | 229 | 3300}; |
| 225 | IN_NOMINAL_SCH311x[(ix)]) | 230 | #define IN_NOMINAL(type) ((type) == sch311x ? IN_NOMINAL_SCH311x : \ |
| 231 | (type) == sch5027 ? IN_NOMINAL_SCH5027 : \ | ||
| 232 | IN_NOMINAL_DME1737) | ||
| 226 | 233 | ||
| 227 | /* Voltage input | 234 | /* Voltage input |
| 228 | * Voltage inputs have 16 bits resolution, limit values have 8 bits | 235 | * Voltage inputs have 16 bits resolution, limit values have 8 bits |
| 229 | * resolution. */ | 236 | * resolution. */ |
| 230 | static inline int IN_FROM_REG(int reg, int ix, int res, int type) | 237 | static inline int IN_FROM_REG(int reg, int nominal, int res) |
| 231 | { | 238 | { |
| 232 | return (reg * IN_NOMINAL(ix, type) + (3 << (res - 3))) / | 239 | return (reg * nominal + (3 << (res - 3))) / (3 << (res - 2)); |
| 233 | (3 << (res - 2)); | ||
| 234 | } | 240 | } |
| 235 | 241 | ||
| 236 | static inline int IN_TO_REG(int val, int ix, int type) | 242 | static inline int IN_TO_REG(int val, int nominal) |
| 237 | { | 243 | { |
| 238 | return SENSORS_LIMIT((val * 192 + IN_NOMINAL(ix, type) / 2) / | 244 | return SENSORS_LIMIT((val * 192 + nominal / 2) / nominal, 0, 255); |
| 239 | IN_NOMINAL(ix, type), 0, 255); | ||
| 240 | } | 245 | } |
| 241 | 246 | ||
| 242 | /* Temperature input | 247 | /* Temperature input |
| @@ -565,7 +570,10 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
| 565 | 570 | ||
| 566 | /* Sample register contents every 1 sec */ | 571 | /* Sample register contents every 1 sec */ |
| 567 | if (time_after(jiffies, data->last_update + HZ) || !data->valid) { | 572 | if (time_after(jiffies, data->last_update + HZ) || !data->valid) { |
| 568 | data->vid = dme1737_read(client, DME1737_REG_VID) & 0x3f; | 573 | if (data->type != sch5027) { |
| 574 | data->vid = dme1737_read(client, DME1737_REG_VID) & | ||
| 575 | 0x3f; | ||
| 576 | } | ||
| 569 | 577 | ||
| 570 | /* In (voltage) registers */ | 578 | /* In (voltage) registers */ |
| 571 | for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) { | 579 | for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) { |
| @@ -593,8 +601,10 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
| 593 | DME1737_REG_TEMP_MIN(ix)); | 601 | DME1737_REG_TEMP_MIN(ix)); |
| 594 | data->temp_max[ix] = dme1737_read(client, | 602 | data->temp_max[ix] = dme1737_read(client, |
| 595 | DME1737_REG_TEMP_MAX(ix)); | 603 | DME1737_REG_TEMP_MAX(ix)); |
| 596 | data->temp_offset[ix] = dme1737_read(client, | 604 | if (data->type != sch5027) { |
| 597 | DME1737_REG_TEMP_OFFSET(ix)); | 605 | data->temp_offset[ix] = dme1737_read(client, |
| 606 | DME1737_REG_TEMP_OFFSET(ix)); | ||
| 607 | } | ||
| 598 | } | 608 | } |
| 599 | 609 | ||
| 600 | /* In and temp LSB registers | 610 | /* In and temp LSB registers |
| @@ -669,9 +679,11 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
| 669 | data->zone_abs[ix] = dme1737_read(client, | 679 | data->zone_abs[ix] = dme1737_read(client, |
| 670 | DME1737_REG_ZONE_ABS(ix)); | 680 | DME1737_REG_ZONE_ABS(ix)); |
| 671 | } | 681 | } |
| 672 | for (ix = 0; ix < ARRAY_SIZE(data->zone_hyst); ix++) { | 682 | if (data->type != sch5027) { |
| 673 | data->zone_hyst[ix] = dme1737_read(client, | 683 | for (ix = 0; ix < ARRAY_SIZE(data->zone_hyst); ix++) { |
| 684 | data->zone_hyst[ix] = dme1737_read(client, | ||
| 674 | DME1737_REG_ZONE_HYST(ix)); | 685 | DME1737_REG_ZONE_HYST(ix)); |
| 686 | } | ||
| 675 | } | 687 | } |
| 676 | 688 | ||
| 677 | /* Alarm registers */ | 689 | /* Alarm registers */ |
| @@ -735,13 +747,13 @@ static ssize_t show_in(struct device *dev, struct device_attribute *attr, | |||
| 735 | 747 | ||
| 736 | switch (fn) { | 748 | switch (fn) { |
| 737 | case SYS_IN_INPUT: | 749 | case SYS_IN_INPUT: |
| 738 | res = IN_FROM_REG(data->in[ix], ix, 16, data->type); | 750 | res = IN_FROM_REG(data->in[ix], data->in_nominal[ix], 16); |
| 739 | break; | 751 | break; |
| 740 | case SYS_IN_MIN: | 752 | case SYS_IN_MIN: |
| 741 | res = IN_FROM_REG(data->in_min[ix], ix, 8, data->type); | 753 | res = IN_FROM_REG(data->in_min[ix], data->in_nominal[ix], 8); |
| 742 | break; | 754 | break; |
| 743 | case SYS_IN_MAX: | 755 | case SYS_IN_MAX: |
| 744 | res = IN_FROM_REG(data->in_max[ix], ix, 8, data->type); | 756 | res = IN_FROM_REG(data->in_max[ix], data->in_nominal[ix], 8); |
| 745 | break; | 757 | break; |
| 746 | case SYS_IN_ALARM: | 758 | case SYS_IN_ALARM: |
| 747 | res = (data->alarms >> DME1737_BIT_ALARM_IN[ix]) & 0x01; | 759 | res = (data->alarms >> DME1737_BIT_ALARM_IN[ix]) & 0x01; |
| @@ -768,12 +780,12 @@ static ssize_t set_in(struct device *dev, struct device_attribute *attr, | |||
| 768 | mutex_lock(&data->update_lock); | 780 | mutex_lock(&data->update_lock); |
| 769 | switch (fn) { | 781 | switch (fn) { |
| 770 | case SYS_IN_MIN: | 782 | case SYS_IN_MIN: |
| 771 | data->in_min[ix] = IN_TO_REG(val, ix, data->type); | 783 | data->in_min[ix] = IN_TO_REG(val, data->in_nominal[ix]); |
| 772 | dme1737_write(client, DME1737_REG_IN_MIN(ix), | 784 | dme1737_write(client, DME1737_REG_IN_MIN(ix), |
| 773 | data->in_min[ix]); | 785 | data->in_min[ix]); |
| 774 | break; | 786 | break; |
| 775 | case SYS_IN_MAX: | 787 | case SYS_IN_MAX: |
| 776 | data->in_max[ix] = IN_TO_REG(val, ix, data->type); | 788 | data->in_max[ix] = IN_TO_REG(val, data->in_nominal[ix]); |
| 777 | dme1737_write(client, DME1737_REG_IN_MAX(ix), | 789 | dme1737_write(client, DME1737_REG_IN_MAX(ix), |
| 778 | data->in_max[ix]); | 790 | data->in_max[ix]); |
| 779 | break; | 791 | break; |
| @@ -1166,7 +1178,7 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, | |||
| 1166 | return sprintf(buf, "%d\n", res); | 1178 | return sprintf(buf, "%d\n", res); |
| 1167 | } | 1179 | } |
| 1168 | 1180 | ||
| 1169 | static struct attribute *dme1737_attr_pwm[]; | 1181 | static struct attribute *dme1737_pwm_chmod_attr[]; |
| 1170 | static void dme1737_chmod_file(struct device*, struct attribute*, mode_t); | 1182 | static void dme1737_chmod_file(struct device*, struct attribute*, mode_t); |
| 1171 | 1183 | ||
| 1172 | static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | 1184 | static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, |
| @@ -1230,7 +1242,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
| 1230 | switch (val) { | 1242 | switch (val) { |
| 1231 | case 0: | 1243 | case 0: |
| 1232 | /* Change permissions of pwm[ix] to read-only */ | 1244 | /* Change permissions of pwm[ix] to read-only */ |
| 1233 | dme1737_chmod_file(dev, dme1737_attr_pwm[ix], | 1245 | dme1737_chmod_file(dev, dme1737_pwm_chmod_attr[ix], |
| 1234 | S_IRUGO); | 1246 | S_IRUGO); |
| 1235 | /* Turn fan fully on */ | 1247 | /* Turn fan fully on */ |
| 1236 | data->pwm_config[ix] = PWM_EN_TO_REG(0, | 1248 | data->pwm_config[ix] = PWM_EN_TO_REG(0, |
| @@ -1245,12 +1257,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
| 1245 | dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), | 1257 | dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), |
| 1246 | data->pwm_config[ix]); | 1258 | data->pwm_config[ix]); |
| 1247 | /* Change permissions of pwm[ix] to read-writeable */ | 1259 | /* Change permissions of pwm[ix] to read-writeable */ |
| 1248 | dme1737_chmod_file(dev, dme1737_attr_pwm[ix], | 1260 | dme1737_chmod_file(dev, dme1737_pwm_chmod_attr[ix], |
| 1249 | S_IRUGO | S_IWUSR); | 1261 | S_IRUGO | S_IWUSR); |
| 1250 | break; | 1262 | break; |
| 1251 | case 2: | 1263 | case 2: |
| 1252 | /* Change permissions of pwm[ix] to read-only */ | 1264 | /* Change permissions of pwm[ix] to read-only */ |
| 1253 | dme1737_chmod_file(dev, dme1737_attr_pwm[ix], | 1265 | dme1737_chmod_file(dev, dme1737_pwm_chmod_attr[ix], |
| 1254 | S_IRUGO); | 1266 | S_IRUGO); |
| 1255 | /* Turn on auto mode using the saved zone channel | 1267 | /* Turn on auto mode using the saved zone channel |
| 1256 | * assignment */ | 1268 | * assignment */ |
| @@ -1570,88 +1582,98 @@ static struct attribute *dme1737_attr[] ={ | |||
| 1570 | &sensor_dev_attr_temp1_max.dev_attr.attr, | 1582 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
| 1571 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, | 1583 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, |
| 1572 | &sensor_dev_attr_temp1_fault.dev_attr.attr, | 1584 | &sensor_dev_attr_temp1_fault.dev_attr.attr, |
| 1573 | &sensor_dev_attr_temp1_offset.dev_attr.attr, | ||
| 1574 | &sensor_dev_attr_temp2_input.dev_attr.attr, | 1585 | &sensor_dev_attr_temp2_input.dev_attr.attr, |
| 1575 | &sensor_dev_attr_temp2_min.dev_attr.attr, | 1586 | &sensor_dev_attr_temp2_min.dev_attr.attr, |
| 1576 | &sensor_dev_attr_temp2_max.dev_attr.attr, | 1587 | &sensor_dev_attr_temp2_max.dev_attr.attr, |
| 1577 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, | 1588 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, |
| 1578 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | 1589 | &sensor_dev_attr_temp2_fault.dev_attr.attr, |
| 1579 | &sensor_dev_attr_temp2_offset.dev_attr.attr, | ||
| 1580 | &sensor_dev_attr_temp3_input.dev_attr.attr, | 1590 | &sensor_dev_attr_temp3_input.dev_attr.attr, |
| 1581 | &sensor_dev_attr_temp3_min.dev_attr.attr, | 1591 | &sensor_dev_attr_temp3_min.dev_attr.attr, |
| 1582 | &sensor_dev_attr_temp3_max.dev_attr.attr, | 1592 | &sensor_dev_attr_temp3_max.dev_attr.attr, |
| 1583 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, | 1593 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, |
| 1584 | &sensor_dev_attr_temp3_fault.dev_attr.attr, | 1594 | &sensor_dev_attr_temp3_fault.dev_attr.attr, |
| 1585 | &sensor_dev_attr_temp3_offset.dev_attr.attr, | ||
| 1586 | /* Zones */ | 1595 | /* Zones */ |
| 1587 | &sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr, | ||
| 1588 | &sensor_dev_attr_zone1_auto_point1_temp.dev_attr.attr, | 1596 | &sensor_dev_attr_zone1_auto_point1_temp.dev_attr.attr, |
| 1589 | &sensor_dev_attr_zone1_auto_point2_temp.dev_attr.attr, | 1597 | &sensor_dev_attr_zone1_auto_point2_temp.dev_attr.attr, |
| 1590 | &sensor_dev_attr_zone1_auto_point3_temp.dev_attr.attr, | 1598 | &sensor_dev_attr_zone1_auto_point3_temp.dev_attr.attr, |
| 1591 | &sensor_dev_attr_zone1_auto_channels_temp.dev_attr.attr, | 1599 | &sensor_dev_attr_zone1_auto_channels_temp.dev_attr.attr, |
| 1592 | &sensor_dev_attr_zone2_auto_point1_temp_hyst.dev_attr.attr, | ||
| 1593 | &sensor_dev_attr_zone2_auto_point1_temp.dev_attr.attr, | 1600 | &sensor_dev_attr_zone2_auto_point1_temp.dev_attr.attr, |
| 1594 | &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr, | 1601 | &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr, |
| 1595 | &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr, | 1602 | &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr, |
| 1596 | &sensor_dev_attr_zone2_auto_channels_temp.dev_attr.attr, | 1603 | &sensor_dev_attr_zone2_auto_channels_temp.dev_attr.attr, |
| 1597 | &sensor_dev_attr_zone3_auto_point1_temp_hyst.dev_attr.attr, | ||
| 1598 | &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, | 1604 | &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, |
| 1599 | &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, | 1605 | &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, |
| 1600 | &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr, | 1606 | &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr, |
| 1601 | &sensor_dev_attr_zone3_auto_channels_temp.dev_attr.attr, | 1607 | &sensor_dev_attr_zone3_auto_channels_temp.dev_attr.attr, |
| 1608 | NULL | ||
| 1609 | }; | ||
| 1610 | |||
| 1611 | static const struct attribute_group dme1737_group = { | ||
| 1612 | .attrs = dme1737_attr, | ||
| 1613 | }; | ||
| 1614 | |||
| 1615 | /* The following struct holds misc attributes, which are not available in all | ||
| 1616 | * chips. Their creation depends on the chip type which is determined during | ||
| 1617 | * module load. */ | ||
| 1618 | static struct attribute *dme1737_misc_attr[] = { | ||
| 1619 | /* Temperatures */ | ||
| 1620 | &sensor_dev_attr_temp1_offset.dev_attr.attr, | ||
| 1621 | &sensor_dev_attr_temp2_offset.dev_attr.attr, | ||
| 1622 | &sensor_dev_attr_temp3_offset.dev_attr.attr, | ||
| 1623 | /* Zones */ | ||
| 1624 | &sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr, | ||
| 1625 | &sensor_dev_attr_zone2_auto_point1_temp_hyst.dev_attr.attr, | ||
| 1626 | &sensor_dev_attr_zone3_auto_point1_temp_hyst.dev_attr.attr, | ||
| 1602 | /* Misc */ | 1627 | /* Misc */ |
| 1603 | &dev_attr_vrm.attr, | 1628 | &dev_attr_vrm.attr, |
| 1604 | &dev_attr_cpu0_vid.attr, | 1629 | &dev_attr_cpu0_vid.attr, |
| 1605 | NULL | 1630 | NULL |
| 1606 | }; | 1631 | }; |
| 1607 | 1632 | ||
| 1608 | static const struct attribute_group dme1737_group = { | 1633 | static const struct attribute_group dme1737_misc_group = { |
| 1609 | .attrs = dme1737_attr, | 1634 | .attrs = dme1737_misc_attr, |
| 1610 | }; | 1635 | }; |
| 1611 | 1636 | ||
| 1612 | /* The following structs hold the PWM attributes, some of which are optional. | 1637 | /* The following structs hold the PWM attributes, some of which are optional. |
| 1613 | * Their creation depends on the chip configuration which is determined during | 1638 | * Their creation depends on the chip configuration which is determined during |
| 1614 | * module load. */ | 1639 | * module load. */ |
| 1615 | static struct attribute *dme1737_attr_pwm1[] = { | 1640 | static struct attribute *dme1737_pwm1_attr[] = { |
| 1616 | &sensor_dev_attr_pwm1.dev_attr.attr, | 1641 | &sensor_dev_attr_pwm1.dev_attr.attr, |
| 1617 | &sensor_dev_attr_pwm1_freq.dev_attr.attr, | 1642 | &sensor_dev_attr_pwm1_freq.dev_attr.attr, |
| 1618 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | 1643 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, |
| 1619 | &sensor_dev_attr_pwm1_ramp_rate.dev_attr.attr, | 1644 | &sensor_dev_attr_pwm1_ramp_rate.dev_attr.attr, |
| 1620 | &sensor_dev_attr_pwm1_auto_channels_zone.dev_attr.attr, | 1645 | &sensor_dev_attr_pwm1_auto_channels_zone.dev_attr.attr, |
| 1621 | &sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr, | ||
| 1622 | &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, | 1646 | &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, |
| 1623 | &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, | 1647 | &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, |
| 1624 | NULL | 1648 | NULL |
| 1625 | }; | 1649 | }; |
| 1626 | static struct attribute *dme1737_attr_pwm2[] = { | 1650 | static struct attribute *dme1737_pwm2_attr[] = { |
| 1627 | &sensor_dev_attr_pwm2.dev_attr.attr, | 1651 | &sensor_dev_attr_pwm2.dev_attr.attr, |
| 1628 | &sensor_dev_attr_pwm2_freq.dev_attr.attr, | 1652 | &sensor_dev_attr_pwm2_freq.dev_attr.attr, |
| 1629 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, | 1653 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, |
| 1630 | &sensor_dev_attr_pwm2_ramp_rate.dev_attr.attr, | 1654 | &sensor_dev_attr_pwm2_ramp_rate.dev_attr.attr, |
| 1631 | &sensor_dev_attr_pwm2_auto_channels_zone.dev_attr.attr, | 1655 | &sensor_dev_attr_pwm2_auto_channels_zone.dev_attr.attr, |
| 1632 | &sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr, | ||
| 1633 | &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr, | 1656 | &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr, |
| 1634 | &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr, | 1657 | &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr, |
| 1635 | NULL | 1658 | NULL |
| 1636 | }; | 1659 | }; |
| 1637 | static struct attribute *dme1737_attr_pwm3[] = { | 1660 | static struct attribute *dme1737_pwm3_attr[] = { |
| 1638 | &sensor_dev_attr_pwm3.dev_attr.attr, | 1661 | &sensor_dev_attr_pwm3.dev_attr.attr, |
| 1639 | &sensor_dev_attr_pwm3_freq.dev_attr.attr, | 1662 | &sensor_dev_attr_pwm3_freq.dev_attr.attr, |
| 1640 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, | 1663 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, |
| 1641 | &sensor_dev_attr_pwm3_ramp_rate.dev_attr.attr, | 1664 | &sensor_dev_attr_pwm3_ramp_rate.dev_attr.attr, |
| 1642 | &sensor_dev_attr_pwm3_auto_channels_zone.dev_attr.attr, | 1665 | &sensor_dev_attr_pwm3_auto_channels_zone.dev_attr.attr, |
| 1643 | &sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr, | ||
| 1644 | &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr, | 1666 | &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr, |
| 1645 | &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr, | 1667 | &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr, |
| 1646 | NULL | 1668 | NULL |
| 1647 | }; | 1669 | }; |
| 1648 | static struct attribute *dme1737_attr_pwm5[] = { | 1670 | static struct attribute *dme1737_pwm5_attr[] = { |
| 1649 | &sensor_dev_attr_pwm5.dev_attr.attr, | 1671 | &sensor_dev_attr_pwm5.dev_attr.attr, |
| 1650 | &sensor_dev_attr_pwm5_freq.dev_attr.attr, | 1672 | &sensor_dev_attr_pwm5_freq.dev_attr.attr, |
| 1651 | &sensor_dev_attr_pwm5_enable.dev_attr.attr, | 1673 | &sensor_dev_attr_pwm5_enable.dev_attr.attr, |
| 1652 | NULL | 1674 | NULL |
| 1653 | }; | 1675 | }; |
| 1654 | static struct attribute *dme1737_attr_pwm6[] = { | 1676 | static struct attribute *dme1737_pwm6_attr[] = { |
| 1655 | &sensor_dev_attr_pwm6.dev_attr.attr, | 1677 | &sensor_dev_attr_pwm6.dev_attr.attr, |
| 1656 | &sensor_dev_attr_pwm6_freq.dev_attr.attr, | 1678 | &sensor_dev_attr_pwm6_freq.dev_attr.attr, |
| 1657 | &sensor_dev_attr_pwm6_enable.dev_attr.attr, | 1679 | &sensor_dev_attr_pwm6_enable.dev_attr.attr, |
| @@ -1659,53 +1681,62 @@ static struct attribute *dme1737_attr_pwm6[] = { | |||
| 1659 | }; | 1681 | }; |
| 1660 | 1682 | ||
| 1661 | static const struct attribute_group dme1737_pwm_group[] = { | 1683 | static const struct attribute_group dme1737_pwm_group[] = { |
| 1662 | { .attrs = dme1737_attr_pwm1 }, | 1684 | { .attrs = dme1737_pwm1_attr }, |
| 1663 | { .attrs = dme1737_attr_pwm2 }, | 1685 | { .attrs = dme1737_pwm2_attr }, |
| 1664 | { .attrs = dme1737_attr_pwm3 }, | 1686 | { .attrs = dme1737_pwm3_attr }, |
| 1665 | { .attrs = NULL }, | 1687 | { .attrs = NULL }, |
| 1666 | { .attrs = dme1737_attr_pwm5 }, | 1688 | { .attrs = dme1737_pwm5_attr }, |
| 1667 | { .attrs = dme1737_attr_pwm6 }, | 1689 | { .attrs = dme1737_pwm6_attr }, |
| 1690 | }; | ||
| 1691 | |||
| 1692 | /* The following struct holds misc PWM attributes, which are not available in | ||
| 1693 | * all chips. Their creation depends on the chip type which is determined | ||
| 1694 | * during module load. */ | ||
| 1695 | static struct attribute *dme1737_pwm_misc_attr[] = { | ||
| 1696 | &sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr, | ||
| 1697 | &sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr, | ||
| 1698 | &sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr, | ||
| 1668 | }; | 1699 | }; |
| 1669 | 1700 | ||
| 1670 | /* The following structs hold the fan attributes, some of which are optional. | 1701 | /* The following structs hold the fan attributes, some of which are optional. |
| 1671 | * Their creation depends on the chip configuration which is determined during | 1702 | * Their creation depends on the chip configuration which is determined during |
| 1672 | * module load. */ | 1703 | * module load. */ |
| 1673 | static struct attribute *dme1737_attr_fan1[] = { | 1704 | static struct attribute *dme1737_fan1_attr[] = { |
| 1674 | &sensor_dev_attr_fan1_input.dev_attr.attr, | 1705 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
| 1675 | &sensor_dev_attr_fan1_min.dev_attr.attr, | 1706 | &sensor_dev_attr_fan1_min.dev_attr.attr, |
| 1676 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, | 1707 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, |
| 1677 | &sensor_dev_attr_fan1_type.dev_attr.attr, | 1708 | &sensor_dev_attr_fan1_type.dev_attr.attr, |
| 1678 | NULL | 1709 | NULL |
| 1679 | }; | 1710 | }; |
| 1680 | static struct attribute *dme1737_attr_fan2[] = { | 1711 | static struct attribute *dme1737_fan2_attr[] = { |
| 1681 | &sensor_dev_attr_fan2_input.dev_attr.attr, | 1712 | &sensor_dev_attr_fan2_input.dev_attr.attr, |
| 1682 | &sensor_dev_attr_fan2_min.dev_attr.attr, | 1713 | &sensor_dev_attr_fan2_min.dev_attr.attr, |
| 1683 | &sensor_dev_attr_fan2_alarm.dev_attr.attr, | 1714 | &sensor_dev_attr_fan2_alarm.dev_attr.attr, |
| 1684 | &sensor_dev_attr_fan2_type.dev_attr.attr, | 1715 | &sensor_dev_attr_fan2_type.dev_attr.attr, |
| 1685 | NULL | 1716 | NULL |
| 1686 | }; | 1717 | }; |
| 1687 | static struct attribute *dme1737_attr_fan3[] = { | 1718 | static struct attribute *dme1737_fan3_attr[] = { |
| 1688 | &sensor_dev_attr_fan3_input.dev_attr.attr, | 1719 | &sensor_dev_attr_fan3_input.dev_attr.attr, |
| 1689 | &sensor_dev_attr_fan3_min.dev_attr.attr, | 1720 | &sensor_dev_attr_fan3_min.dev_attr.attr, |
| 1690 | &sensor_dev_attr_fan3_alarm.dev_attr.attr, | 1721 | &sensor_dev_attr_fan3_alarm.dev_attr.attr, |
| 1691 | &sensor_dev_attr_fan3_type.dev_attr.attr, | 1722 | &sensor_dev_attr_fan3_type.dev_attr.attr, |
| 1692 | NULL | 1723 | NULL |
| 1693 | }; | 1724 | }; |
| 1694 | static struct attribute *dme1737_attr_fan4[] = { | 1725 | static struct attribute *dme1737_fan4_attr[] = { |
| 1695 | &sensor_dev_attr_fan4_input.dev_attr.attr, | 1726 | &sensor_dev_attr_fan4_input.dev_attr.attr, |
| 1696 | &sensor_dev_attr_fan4_min.dev_attr.attr, | 1727 | &sensor_dev_attr_fan4_min.dev_attr.attr, |
| 1697 | &sensor_dev_attr_fan4_alarm.dev_attr.attr, | 1728 | &sensor_dev_attr_fan4_alarm.dev_attr.attr, |
| 1698 | &sensor_dev_attr_fan4_type.dev_attr.attr, | 1729 | &sensor_dev_attr_fan4_type.dev_attr.attr, |
| 1699 | NULL | 1730 | NULL |
| 1700 | }; | 1731 | }; |
| 1701 | static struct attribute *dme1737_attr_fan5[] = { | 1732 | static struct attribute *dme1737_fan5_attr[] = { |
| 1702 | &sensor_dev_attr_fan5_input.dev_attr.attr, | 1733 | &sensor_dev_attr_fan5_input.dev_attr.attr, |
| 1703 | &sensor_dev_attr_fan5_min.dev_attr.attr, | 1734 | &sensor_dev_attr_fan5_min.dev_attr.attr, |
| 1704 | &sensor_dev_attr_fan5_alarm.dev_attr.attr, | 1735 | &sensor_dev_attr_fan5_alarm.dev_attr.attr, |
| 1705 | &sensor_dev_attr_fan5_max.dev_attr.attr, | 1736 | &sensor_dev_attr_fan5_max.dev_attr.attr, |
| 1706 | NULL | 1737 | NULL |
| 1707 | }; | 1738 | }; |
| 1708 | static struct attribute *dme1737_attr_fan6[] = { | 1739 | static struct attribute *dme1737_fan6_attr[] = { |
| 1709 | &sensor_dev_attr_fan6_input.dev_attr.attr, | 1740 | &sensor_dev_attr_fan6_input.dev_attr.attr, |
| 1710 | &sensor_dev_attr_fan6_min.dev_attr.attr, | 1741 | &sensor_dev_attr_fan6_min.dev_attr.attr, |
| 1711 | &sensor_dev_attr_fan6_alarm.dev_attr.attr, | 1742 | &sensor_dev_attr_fan6_alarm.dev_attr.attr, |
| @@ -1714,94 +1745,83 @@ static struct attribute *dme1737_attr_fan6[] = { | |||
| 1714 | }; | 1745 | }; |
| 1715 | 1746 | ||
| 1716 | static const struct attribute_group dme1737_fan_group[] = { | 1747 | static const struct attribute_group dme1737_fan_group[] = { |
| 1717 | { .attrs = dme1737_attr_fan1 }, | 1748 | { .attrs = dme1737_fan1_attr }, |
| 1718 | { .attrs = dme1737_attr_fan2 }, | 1749 | { .attrs = dme1737_fan2_attr }, |
| 1719 | { .attrs = dme1737_attr_fan3 }, | 1750 | { .attrs = dme1737_fan3_attr }, |
| 1720 | { .attrs = dme1737_attr_fan4 }, | 1751 | { .attrs = dme1737_fan4_attr }, |
| 1721 | { .attrs = dme1737_attr_fan5 }, | 1752 | { .attrs = dme1737_fan5_attr }, |
| 1722 | { .attrs = dme1737_attr_fan6 }, | 1753 | { .attrs = dme1737_fan6_attr }, |
| 1723 | }; | 1754 | }; |
| 1724 | 1755 | ||
| 1725 | /* The permissions of all of the following attributes are changed to read- | 1756 | /* The permissions of the following zone attributes are changed to read- |
| 1726 | * writeable if the chip is *not* locked. Otherwise they stay read-only. */ | 1757 | * writeable if the chip is *not* locked. Otherwise they stay read-only. */ |
| 1727 | static struct attribute *dme1737_attr_lock[] = { | 1758 | static struct attribute *dme1737_zone_chmod_attr[] = { |
| 1728 | /* Temperatures */ | ||
| 1729 | &sensor_dev_attr_temp1_offset.dev_attr.attr, | ||
| 1730 | &sensor_dev_attr_temp2_offset.dev_attr.attr, | ||
| 1731 | &sensor_dev_attr_temp3_offset.dev_attr.attr, | ||
| 1732 | /* Zones */ | ||
| 1733 | &sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr, | ||
| 1734 | &sensor_dev_attr_zone1_auto_point1_temp.dev_attr.attr, | 1759 | &sensor_dev_attr_zone1_auto_point1_temp.dev_attr.attr, |
| 1735 | &sensor_dev_attr_zone1_auto_point2_temp.dev_attr.attr, | 1760 | &sensor_dev_attr_zone1_auto_point2_temp.dev_attr.attr, |
| 1736 | &sensor_dev_attr_zone1_auto_point3_temp.dev_attr.attr, | 1761 | &sensor_dev_attr_zone1_auto_point3_temp.dev_attr.attr, |
| 1737 | &sensor_dev_attr_zone2_auto_point1_temp_hyst.dev_attr.attr, | ||
| 1738 | &sensor_dev_attr_zone2_auto_point1_temp.dev_attr.attr, | 1762 | &sensor_dev_attr_zone2_auto_point1_temp.dev_attr.attr, |
| 1739 | &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr, | 1763 | &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr, |
| 1740 | &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr, | 1764 | &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr, |
| 1741 | &sensor_dev_attr_zone3_auto_point1_temp_hyst.dev_attr.attr, | ||
| 1742 | &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, | 1765 | &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, |
| 1743 | &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, | 1766 | &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, |
| 1744 | &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr, | 1767 | &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr, |
| 1745 | NULL | 1768 | NULL |
| 1746 | }; | 1769 | }; |
| 1747 | 1770 | ||
| 1748 | static const struct attribute_group dme1737_lock_group = { | 1771 | static const struct attribute_group dme1737_zone_chmod_group = { |
| 1749 | .attrs = dme1737_attr_lock, | 1772 | .attrs = dme1737_zone_chmod_attr, |
| 1750 | }; | 1773 | }; |
| 1751 | 1774 | ||
| 1752 | /* The permissions of the following PWM attributes are changed to read- | 1775 | /* The permissions of the following PWM attributes are changed to read- |
| 1753 | * writeable if the chip is *not* locked and the respective PWM is available. | 1776 | * writeable if the chip is *not* locked and the respective PWM is available. |
| 1754 | * Otherwise they stay read-only. */ | 1777 | * Otherwise they stay read-only. */ |
| 1755 | static struct attribute *dme1737_attr_pwm1_lock[] = { | 1778 | static struct attribute *dme1737_pwm1_chmod_attr[] = { |
| 1756 | &sensor_dev_attr_pwm1_freq.dev_attr.attr, | 1779 | &sensor_dev_attr_pwm1_freq.dev_attr.attr, |
| 1757 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | 1780 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, |
| 1758 | &sensor_dev_attr_pwm1_ramp_rate.dev_attr.attr, | 1781 | &sensor_dev_attr_pwm1_ramp_rate.dev_attr.attr, |
| 1759 | &sensor_dev_attr_pwm1_auto_channels_zone.dev_attr.attr, | 1782 | &sensor_dev_attr_pwm1_auto_channels_zone.dev_attr.attr, |
| 1760 | &sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr, | ||
| 1761 | &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, | 1783 | &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, |
| 1762 | NULL | 1784 | NULL |
| 1763 | }; | 1785 | }; |
| 1764 | static struct attribute *dme1737_attr_pwm2_lock[] = { | 1786 | static struct attribute *dme1737_pwm2_chmod_attr[] = { |
| 1765 | &sensor_dev_attr_pwm2_freq.dev_attr.attr, | 1787 | &sensor_dev_attr_pwm2_freq.dev_attr.attr, |
| 1766 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, | 1788 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, |
| 1767 | &sensor_dev_attr_pwm2_ramp_rate.dev_attr.attr, | 1789 | &sensor_dev_attr_pwm2_ramp_rate.dev_attr.attr, |
| 1768 | &sensor_dev_attr_pwm2_auto_channels_zone.dev_attr.attr, | 1790 | &sensor_dev_attr_pwm2_auto_channels_zone.dev_attr.attr, |
| 1769 | &sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr, | ||
| 1770 | &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr, | 1791 | &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr, |
| 1771 | NULL | 1792 | NULL |
| 1772 | }; | 1793 | }; |
| 1773 | static struct attribute *dme1737_attr_pwm3_lock[] = { | 1794 | static struct attribute *dme1737_pwm3_chmod_attr[] = { |
| 1774 | &sensor_dev_attr_pwm3_freq.dev_attr.attr, | 1795 | &sensor_dev_attr_pwm3_freq.dev_attr.attr, |
| 1775 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, | 1796 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, |
| 1776 | &sensor_dev_attr_pwm3_ramp_rate.dev_attr.attr, | 1797 | &sensor_dev_attr_pwm3_ramp_rate.dev_attr.attr, |
| 1777 | &sensor_dev_attr_pwm3_auto_channels_zone.dev_attr.attr, | 1798 | &sensor_dev_attr_pwm3_auto_channels_zone.dev_attr.attr, |
| 1778 | &sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr, | ||
| 1779 | &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr, | 1799 | &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr, |
| 1780 | NULL | 1800 | NULL |
| 1781 | }; | 1801 | }; |
| 1782 | static struct attribute *dme1737_attr_pwm5_lock[] = { | 1802 | static struct attribute *dme1737_pwm5_chmod_attr[] = { |
| 1783 | &sensor_dev_attr_pwm5.dev_attr.attr, | 1803 | &sensor_dev_attr_pwm5.dev_attr.attr, |
| 1784 | &sensor_dev_attr_pwm5_freq.dev_attr.attr, | 1804 | &sensor_dev_attr_pwm5_freq.dev_attr.attr, |
| 1785 | NULL | 1805 | NULL |
| 1786 | }; | 1806 | }; |
| 1787 | static struct attribute *dme1737_attr_pwm6_lock[] = { | 1807 | static struct attribute *dme1737_pwm6_chmod_attr[] = { |
| 1788 | &sensor_dev_attr_pwm6.dev_attr.attr, | 1808 | &sensor_dev_attr_pwm6.dev_attr.attr, |
| 1789 | &sensor_dev_attr_pwm6_freq.dev_attr.attr, | 1809 | &sensor_dev_attr_pwm6_freq.dev_attr.attr, |
| 1790 | NULL | 1810 | NULL |
| 1791 | }; | 1811 | }; |
| 1792 | 1812 | ||
| 1793 | static const struct attribute_group dme1737_pwm_lock_group[] = { | 1813 | static const struct attribute_group dme1737_pwm_chmod_group[] = { |
| 1794 | { .attrs = dme1737_attr_pwm1_lock }, | 1814 | { .attrs = dme1737_pwm1_chmod_attr }, |
| 1795 | { .attrs = dme1737_attr_pwm2_lock }, | 1815 | { .attrs = dme1737_pwm2_chmod_attr }, |
| 1796 | { .attrs = dme1737_attr_pwm3_lock }, | 1816 | { .attrs = dme1737_pwm3_chmod_attr }, |
| 1797 | { .attrs = NULL }, | 1817 | { .attrs = NULL }, |
| 1798 | { .attrs = dme1737_attr_pwm5_lock }, | 1818 | { .attrs = dme1737_pwm5_chmod_attr }, |
| 1799 | { .attrs = dme1737_attr_pwm6_lock }, | 1819 | { .attrs = dme1737_pwm6_chmod_attr }, |
| 1800 | }; | 1820 | }; |
| 1801 | 1821 | ||
| 1802 | /* Pwm[1-3] are read-writeable if the associated pwm is in manual mode and the | 1822 | /* Pwm[1-3] are read-writeable if the associated pwm is in manual mode and the |
| 1803 | * chip is not locked. Otherwise they are read-only. */ | 1823 | * chip is not locked. Otherwise they are read-only. */ |
| 1804 | static struct attribute *dme1737_attr_pwm[] = { | 1824 | static struct attribute *dme1737_pwm_chmod_attr[] = { |
| 1805 | &sensor_dev_attr_pwm1.dev_attr.attr, | 1825 | &sensor_dev_attr_pwm1.dev_attr.attr, |
| 1806 | &sensor_dev_attr_pwm2.dev_attr.attr, | 1826 | &sensor_dev_attr_pwm2.dev_attr.attr, |
| 1807 | &sensor_dev_attr_pwm3.dev_attr.attr, | 1827 | &sensor_dev_attr_pwm3.dev_attr.attr, |
| @@ -1875,9 +1895,17 @@ static void dme1737_remove_files(struct device *dev) | |||
| 1875 | if (data->has_pwm & (1 << ix)) { | 1895 | if (data->has_pwm & (1 << ix)) { |
| 1876 | sysfs_remove_group(&dev->kobj, | 1896 | sysfs_remove_group(&dev->kobj, |
| 1877 | &dme1737_pwm_group[ix]); | 1897 | &dme1737_pwm_group[ix]); |
| 1898 | if (data->type != sch5027 && ix < 3) { | ||
| 1899 | sysfs_remove_file(&dev->kobj, | ||
| 1900 | dme1737_pwm_misc_attr[ix]); | ||
| 1901 | } | ||
| 1878 | } | 1902 | } |
| 1879 | } | 1903 | } |
| 1880 | 1904 | ||
| 1905 | if (data->type != sch5027) { | ||
| 1906 | sysfs_remove_group(&dev->kobj, &dme1737_misc_group); | ||
| 1907 | } | ||
| 1908 | |||
| 1881 | sysfs_remove_group(&dev->kobj, &dme1737_group); | 1909 | sysfs_remove_group(&dev->kobj, &dme1737_group); |
| 1882 | 1910 | ||
| 1883 | if (!data->client.driver) { | 1911 | if (!data->client.driver) { |
| @@ -1901,6 +1929,13 @@ static int dme1737_create_files(struct device *dev) | |||
| 1901 | goto exit_remove; | 1929 | goto exit_remove; |
| 1902 | } | 1930 | } |
| 1903 | 1931 | ||
| 1932 | /* Create misc sysfs attributes */ | ||
| 1933 | if ((data->type != sch5027) && | ||
| 1934 | (err = sysfs_create_group(&dev->kobj, | ||
| 1935 | &dme1737_misc_group))) { | ||
| 1936 | goto exit_remove; | ||
| 1937 | } | ||
| 1938 | |||
| 1904 | /* Create fan sysfs attributes */ | 1939 | /* Create fan sysfs attributes */ |
| 1905 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { | 1940 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { |
| 1906 | if (data->has_fan & (1 << ix)) { | 1941 | if (data->has_fan & (1 << ix)) { |
| @@ -1918,6 +1953,11 @@ static int dme1737_create_files(struct device *dev) | |||
| 1918 | &dme1737_pwm_group[ix]))) { | 1953 | &dme1737_pwm_group[ix]))) { |
| 1919 | goto exit_remove; | 1954 | goto exit_remove; |
| 1920 | } | 1955 | } |
| 1956 | if (data->type != sch5027 && ix < 3 && | ||
| 1957 | (err = sysfs_create_file(&dev->kobj, | ||
| 1958 | dme1737_pwm_misc_attr[ix]))) { | ||
| 1959 | goto exit_remove; | ||
| 1960 | } | ||
| 1921 | } | 1961 | } |
| 1922 | } | 1962 | } |
| 1923 | 1963 | ||
| @@ -1927,16 +1967,27 @@ static int dme1737_create_files(struct device *dev) | |||
| 1927 | dev_info(dev, "Device is locked. Some attributes " | 1967 | dev_info(dev, "Device is locked. Some attributes " |
| 1928 | "will be read-only.\n"); | 1968 | "will be read-only.\n"); |
| 1929 | } else { | 1969 | } else { |
| 1930 | /* Change permissions of standard attributes */ | 1970 | /* Change permissions of zone sysfs attributes */ |
| 1931 | dme1737_chmod_group(dev, &dme1737_lock_group, | 1971 | dme1737_chmod_group(dev, &dme1737_zone_chmod_group, |
| 1932 | S_IRUGO | S_IWUSR); | 1972 | S_IRUGO | S_IWUSR); |
| 1933 | 1973 | ||
| 1934 | /* Change permissions of PWM attributes */ | 1974 | /* Change permissions of misc sysfs attributes */ |
| 1935 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_lock_group); ix++) { | 1975 | if (data->type != sch5027) { |
| 1976 | dme1737_chmod_group(dev, &dme1737_misc_group, | ||
| 1977 | S_IRUGO | S_IWUSR); | ||
| 1978 | } | ||
| 1979 | |||
| 1980 | /* Change permissions of PWM sysfs attributes */ | ||
| 1981 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_chmod_group); ix++) { | ||
| 1936 | if (data->has_pwm & (1 << ix)) { | 1982 | if (data->has_pwm & (1 << ix)) { |
| 1937 | dme1737_chmod_group(dev, | 1983 | dme1737_chmod_group(dev, |
| 1938 | &dme1737_pwm_lock_group[ix], | 1984 | &dme1737_pwm_chmod_group[ix], |
| 1985 | S_IRUGO | S_IWUSR); | ||
| 1986 | if (data->type != sch5027 && ix < 3) { | ||
| 1987 | dme1737_chmod_file(dev, | ||
| 1988 | dme1737_pwm_misc_attr[ix], | ||
| 1939 | S_IRUGO | S_IWUSR); | 1989 | S_IRUGO | S_IWUSR); |
| 1990 | } | ||
| 1940 | } | 1991 | } |
| 1941 | } | 1992 | } |
| 1942 | 1993 | ||
| @@ -1945,7 +1996,7 @@ static int dme1737_create_files(struct device *dev) | |||
| 1945 | if ((data->has_pwm & (1 << ix)) && | 1996 | if ((data->has_pwm & (1 << ix)) && |
| 1946 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == 1)) { | 1997 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == 1)) { |
| 1947 | dme1737_chmod_file(dev, | 1998 | dme1737_chmod_file(dev, |
| 1948 | dme1737_attr_pwm[ix], | 1999 | dme1737_pwm_chmod_attr[ix], |
| 1949 | S_IRUGO | S_IWUSR); | 2000 | S_IRUGO | S_IWUSR); |
| 1950 | } | 2001 | } |
| 1951 | } | 2002 | } |
| @@ -1966,6 +2017,9 @@ static int dme1737_init_device(struct device *dev) | |||
| 1966 | int ix; | 2017 | int ix; |
| 1967 | u8 reg; | 2018 | u8 reg; |
| 1968 | 2019 | ||
| 2020 | /* Point to the right nominal voltages array */ | ||
| 2021 | data->in_nominal = IN_NOMINAL(data->type); | ||
| 2022 | |||
| 1969 | data->config = dme1737_read(client, DME1737_REG_CONFIG); | 2023 | data->config = dme1737_read(client, DME1737_REG_CONFIG); |
| 1970 | /* Inform if part is not monitoring/started */ | 2024 | /* Inform if part is not monitoring/started */ |
| 1971 | if (!(data->config & 0x01)) { | 2025 | if (!(data->config & 0x01)) { |
| @@ -2076,7 +2130,9 @@ static int dme1737_init_device(struct device *dev) | |||
| 2076 | data->pwm_acz[2] = 4; /* pwm3 -> zone3 */ | 2130 | data->pwm_acz[2] = 4; /* pwm3 -> zone3 */ |
| 2077 | 2131 | ||
| 2078 | /* Set VRM */ | 2132 | /* Set VRM */ |
| 2079 | data->vrm = vid_which_vrm(); | 2133 | if (data->type != sch5027) { |
| 2134 | data->vrm = vid_which_vrm(); | ||
| 2135 | } | ||
| 2080 | 2136 | ||
| 2081 | return 0; | 2137 | return 0; |
| 2082 | } | 2138 | } |
| @@ -2095,9 +2151,10 @@ static int dme1737_i2c_get_features(int sio_cip, struct dme1737_data *data) | |||
| 2095 | dme1737_sio_enter(sio_cip); | 2151 | dme1737_sio_enter(sio_cip); |
| 2096 | 2152 | ||
| 2097 | /* Check device ID | 2153 | /* Check device ID |
| 2098 | * The DME1737 can return either 0x78 or 0x77 as its device ID. */ | 2154 | * The DME1737 can return either 0x78 or 0x77 as its device ID. |
| 2155 | * The SCH5027 returns 0x89 as its device ID. */ | ||
| 2099 | reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20); | 2156 | reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20); |
| 2100 | if (!(reg == 0x77 || reg == 0x78)) { | 2157 | if (!(reg == 0x77 || reg == 0x78 || reg == 0x89)) { |
| 2101 | err = -ENODEV; | 2158 | err = -ENODEV; |
| 2102 | goto exit; | 2159 | goto exit; |
| 2103 | } | 2160 | } |
| @@ -2166,15 +2223,24 @@ static int dme1737_i2c_detect(struct i2c_adapter *adapter, int address, | |||
| 2166 | company = dme1737_read(client, DME1737_REG_COMPANY); | 2223 | company = dme1737_read(client, DME1737_REG_COMPANY); |
| 2167 | verstep = dme1737_read(client, DME1737_REG_VERSTEP); | 2224 | verstep = dme1737_read(client, DME1737_REG_VERSTEP); |
| 2168 | 2225 | ||
| 2169 | if (!((company == DME1737_COMPANY_SMSC) && | 2226 | if (company == DME1737_COMPANY_SMSC && |
| 2170 | ((verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP))) { | 2227 | (verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP) { |
| 2228 | kind = dme1737; | ||
| 2229 | } else if (company == DME1737_COMPANY_SMSC && | ||
| 2230 | verstep == SCH5027_VERSTEP) { | ||
| 2231 | kind = sch5027; | ||
| 2232 | } else { | ||
| 2171 | err = -ENODEV; | 2233 | err = -ENODEV; |
| 2172 | goto exit_kfree; | 2234 | goto exit_kfree; |
| 2173 | } | 2235 | } |
| 2174 | } | 2236 | } |
| 2175 | 2237 | ||
| 2176 | kind = dme1737; | 2238 | if (kind == sch5027) { |
| 2177 | name = "dme1737"; | 2239 | name = "sch5027"; |
| 2240 | } else { | ||
| 2241 | kind = dme1737; | ||
| 2242 | name = "dme1737"; | ||
| 2243 | } | ||
| 2178 | data->type = kind; | 2244 | data->type = kind; |
| 2179 | 2245 | ||
| 2180 | /* Fill in the remaining client fields and put it into the global | 2246 | /* Fill in the remaining client fields and put it into the global |
| @@ -2187,8 +2253,9 @@ static int dme1737_i2c_detect(struct i2c_adapter *adapter, int address, | |||
| 2187 | goto exit_kfree; | 2253 | goto exit_kfree; |
| 2188 | } | 2254 | } |
| 2189 | 2255 | ||
| 2190 | dev_info(dev, "Found a DME1737 chip at 0x%02x (rev 0x%02x).\n", | 2256 | dev_info(dev, "Found a %s chip at 0x%02x (rev 0x%02x).\n", |
| 2191 | client->addr, verstep); | 2257 | kind == sch5027 ? "SCH5027" : "DME1737", client->addr, |
| 2258 | verstep); | ||
| 2192 | 2259 | ||
| 2193 | /* Initialize the DME1737 chip */ | 2260 | /* Initialize the DME1737 chip */ |
| 2194 | if ((err = dme1737_init_device(dev))) { | 2261 | if ((err = dme1737_init_device(dev))) { |
| @@ -2360,15 +2427,18 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev) | |||
| 2360 | client->addr = res->start; | 2427 | client->addr = res->start; |
| 2361 | platform_set_drvdata(pdev, data); | 2428 | platform_set_drvdata(pdev, data); |
| 2362 | 2429 | ||
| 2363 | company = dme1737_read(client, DME1737_REG_COMPANY); | 2430 | /* Skip chip detection if module is loaded with force_id parameter */ |
| 2364 | device = dme1737_read(client, DME1737_REG_DEVICE); | 2431 | if (!force_id) { |
| 2432 | company = dme1737_read(client, DME1737_REG_COMPANY); | ||
| 2433 | device = dme1737_read(client, DME1737_REG_DEVICE); | ||
| 2365 | 2434 | ||
| 2366 | if (!((company == DME1737_COMPANY_SMSC) && | 2435 | if (!((company == DME1737_COMPANY_SMSC) && |
| 2367 | (device == SCH311X_DEVICE))) { | 2436 | (device == SCH311X_DEVICE))) { |
| 2368 | err = -ENODEV; | 2437 | err = -ENODEV; |
| 2369 | goto exit_kfree; | 2438 | goto exit_kfree; |
| 2439 | } | ||
| 2370 | } | 2440 | } |
| 2371 | data->type = -1; | 2441 | data->type = sch311x; |
| 2372 | 2442 | ||
| 2373 | /* Fill in the remaining client fields and initialize the mutex */ | 2443 | /* Fill in the remaining client fields and initialize the mutex */ |
| 2374 | strlcpy(client->name, "sch311x", I2C_NAME_SIZE); | 2444 | strlcpy(client->name, "sch311x", I2C_NAME_SIZE); |
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index cbeb4984b5c7..67067e9a323e 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c | |||
| @@ -87,8 +87,6 @@ static inline void superio_enter(int base); | |||
| 87 | static inline void superio_select(int base, int ld); | 87 | static inline void superio_select(int base, int ld); |
| 88 | static inline void superio_exit(int base); | 88 | static inline void superio_exit(int base); |
| 89 | 89 | ||
| 90 | static inline u16 fan_from_reg ( u16 reg ); | ||
| 91 | |||
| 92 | struct f71882fg_data { | 90 | struct f71882fg_data { |
| 93 | unsigned short addr; | 91 | unsigned short addr; |
| 94 | struct device *hwmon_dev; | 92 | struct device *hwmon_dev; |
| @@ -116,10 +114,6 @@ struct f71882fg_data { | |||
| 116 | u8 temp_diode_open; | 114 | u8 temp_diode_open; |
| 117 | }; | 115 | }; |
| 118 | 116 | ||
| 119 | static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg); | ||
| 120 | static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg); | ||
| 121 | static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val); | ||
| 122 | |||
| 123 | /* Sysfs in*/ | 117 | /* Sysfs in*/ |
| 124 | static ssize_t show_in(struct device *dev, struct device_attribute *devattr, | 118 | static ssize_t show_in(struct device *dev, struct device_attribute *devattr, |
| 125 | char *buf); | 119 | char *buf); |
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c index 3330667280b9..7b0a32c4dcfb 100644 --- a/drivers/hwmon/hwmon-vid.c +++ b/drivers/hwmon/hwmon-vid.c | |||
| @@ -1,76 +1,74 @@ | |||
| 1 | /* | 1 | /* |
| 2 | hwmon-vid.c - VID/VRM/VRD voltage conversions | 2 | * hwmon-vid.c - VID/VRM/VRD voltage conversions |
| 3 | 3 | * | |
| 4 | Copyright (c) 2004 Rudolf Marek <r.marek@assembler.cz> | 4 | * Copyright (c) 2004 Rudolf Marek <r.marek@assembler.cz> |
| 5 | 5 | * | |
| 6 | Partly imported from i2c-vid.h of the lm_sensors project | 6 | * Partly imported from i2c-vid.h of the lm_sensors project |
| 7 | Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> | 7 | * Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> |
| 8 | With assistance from Trent Piepho <xyzzy@speakeasy.org> | 8 | * With assistance from Trent Piepho <xyzzy@speakeasy.org> |
| 9 | 9 | * | |
| 10 | This program is free software; you can redistribute it and/or modify | 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 | 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 | 12 | * the Free Software Foundation; either version 2 of the License, or |
| 13 | (at your option) any later version. | 13 | * (at your option) any later version. |
| 14 | 14 | * | |
| 15 | This program is distributed in the hope that it will be useful, | 15 | * This program is distributed in the hope that it will be useful, |
| 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 18 | GNU General Public License for more details. | 18 | * GNU General Public License for more details. |
| 19 | 19 | * | |
| 20 | You should have received a copy of the GNU General Public License | 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 | 21 | * along with this program; if not, write to the Free Software |
| 22 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 23 | */ | 23 | */ |
| 24 | 24 | ||
| 25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
| 26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
| 27 | #include <linux/hwmon-vid.h> | 27 | #include <linux/hwmon-vid.h> |
| 28 | 28 | ||
| 29 | /* | 29 | /* |
| 30 | Common code for decoding VID pins. | 30 | * Common code for decoding VID pins. |
| 31 | 31 | * | |
| 32 | References: | 32 | * References: |
| 33 | 33 | * | |
| 34 | For VRM 8.4 to 9.1, "VRM x.y DC-DC Converter Design Guidelines", | 34 | * For VRM 8.4 to 9.1, "VRM x.y DC-DC Converter Design Guidelines", |
| 35 | available at http://developer.intel.com/. | 35 | * available at http://developer.intel.com/. |
| 36 | 36 | * | |
| 37 | For VRD 10.0 and up, "VRD x.y Design Guide", | 37 | * For VRD 10.0 and up, "VRD x.y Design Guide", |
| 38 | available at http://developer.intel.com/. | 38 | * available at http://developer.intel.com/. |
| 39 | 39 | * | |
| 40 | AMD Opteron processors don't follow the Intel specifications. | 40 | * AMD NPT 0Fh (Athlon64 & Opteron), AMD Publication 32559, |
| 41 | I'm going to "make up" 2.4 as the spec number for the Opterons. | 41 | * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/32559.pdf |
| 42 | No good reason just a mnemonic for the 24x Opteron processor | 42 | * Table 71. VID Code Voltages |
| 43 | series. | 43 | * AMD Opteron processors don't follow the Intel specifications. |
| 44 | 44 | * I'm going to "make up" 2.4 as the spec number for the Opterons. | |
| 45 | Opteron VID encoding is: | 45 | * No good reason just a mnemonic for the 24x Opteron processor |
| 46 | 00000 = 1.550 V | 46 | * series. |
| 47 | 00001 = 1.525 V | 47 | * |
| 48 | . . . . | 48 | * The 17 specification is in fact Intel Mobile Voltage Positioning - |
| 49 | 11110 = 0.800 V | 49 | * (IMVP-II). You can find more information in the datasheet of Max1718 |
| 50 | 11111 = 0.000 V (off) | 50 | * http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2452 |
| 51 | 51 | * | |
| 52 | The 17 specification is in fact Intel Mobile Voltage Positioning - | 52 | * The 13 specification corresponds to the Intel Pentium M series. There |
| 53 | (IMVP-II). You can find more information in the datasheet of Max1718 | 53 | * doesn't seem to be any named specification for these. The conversion |
| 54 | http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2452 | 54 | * tables are detailed directly in the various Pentium M datasheets: |
| 55 | 55 | * http://www.intel.com/design/intarch/pentiumm/docs_pentiumm.htm | |
| 56 | The 13 specification corresponds to the Intel Pentium M series. There | 56 | * |
| 57 | doesn't seem to be any named specification for these. The conversion | 57 | * The 14 specification corresponds to Intel Core series. There |
| 58 | tables are detailed directly in the various Pentium M datasheets: | 58 | * doesn't seem to be any named specification for these. The conversion |
| 59 | http://www.intel.com/design/intarch/pentiumm/docs_pentiumm.htm | 59 | * tables are detailed directly in the various Pentium Core datasheets: |
| 60 | 60 | * http://www.intel.com/design/mobile/datashts/309221.htm | |
| 61 | The 14 specification corresponds to Intel Core series. There | 61 | * |
| 62 | doesn't seem to be any named specification for these. The conversion | 62 | * The 110 (VRM 11) specification corresponds to Intel Conroe based series. |
| 63 | tables are detailed directly in the various Pentium Core datasheets: | 63 | * http://www.intel.com/design/processor/applnots/313214.htm |
| 64 | http://www.intel.com/design/mobile/datashts/309221.htm | 64 | */ |
| 65 | 65 | ||
| 66 | The 110 (VRM 11) specification corresponds to Intel Conroe based series. | 66 | /* |
| 67 | http://www.intel.com/design/processor/applnots/313214.htm | 67 | * vrm is the VRM/VRD document version multiplied by 10. |
| 68 | */ | 68 | * val is the 4-bit or more VID code. |
| 69 | 69 | * Returned value is in mV to avoid floating point in the kernel. | |
| 70 | /* vrm is the VRM/VRD document version multiplied by 10. | 70 | * Some VID have some bits in uV scale, this is rounded to mV. |
| 71 | val is the 4-bit or more VID code. | 71 | */ |
| 72 | Returned value is in mV to avoid floating point in the kernel. | ||
| 73 | Some VID have some bits in uV scale, this is rounded to mV */ | ||
| 74 | int vid_from_reg(int val, u8 vrm) | 72 | int vid_from_reg(int val, u8 vrm) |
| 75 | { | 73 | { |
| 76 | int vid; | 74 | int vid; |
| @@ -96,9 +94,11 @@ int vid_from_reg(int val, u8 vrm) | |||
| 96 | if (val < 0x02 || val > 0xb2) | 94 | if (val < 0x02 || val > 0xb2) |
| 97 | return 0; | 95 | return 0; |
| 98 | return((1600000 - (val - 2) * 6250 + 500) / 1000); | 96 | return((1600000 - (val - 2) * 6250 + 500) / 1000); |
| 99 | case 24: /* Opteron processor */ | 97 | |
| 100 | val &= 0x1f; | 98 | case 24: /* AMD NPT 0Fh (Athlon64 & Opteron) */ |
| 101 | return(val == 0x1f ? 0 : 1550 - val * 25); | 99 | val &= 0x3f; |
| 100 | return (val < 32) ? 1550 - 25 * val | ||
| 101 | : 775 - (25 * (val - 31)) / 2; | ||
| 102 | 102 | ||
| 103 | case 91: /* VRM 9.1 */ | 103 | case 91: /* VRM 9.1 */ |
| 104 | case 90: /* VRM 9.0 */ | 104 | case 90: /* VRM 9.0 */ |
| @@ -141,9 +141,9 @@ int vid_from_reg(int val, u8 vrm) | |||
| 141 | 141 | ||
| 142 | 142 | ||
| 143 | /* | 143 | /* |
| 144 | After this point is the code to automatically determine which | 144 | * After this point is the code to automatically determine which |
| 145 | VRM/VRD specification should be used depending on the CPU. | 145 | * VRM/VRD specification should be used depending on the CPU. |
| 146 | */ | 146 | */ |
| 147 | 147 | ||
| 148 | struct vrm_model { | 148 | struct vrm_model { |
| 149 | u8 vendor; | 149 | u8 vendor; |
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index e12c132ff83a..30cdb0956779 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
| @@ -151,9 +151,9 @@ static int fix_pwm_polarity; | |||
| 151 | /* The IT8718F has the VID value in a different register, in Super-I/O | 151 | /* The IT8718F has the VID value in a different register, in Super-I/O |
| 152 | configuration space. */ | 152 | configuration space. */ |
| 153 | #define IT87_REG_VID 0x0a | 153 | #define IT87_REG_VID 0x0a |
| 154 | /* Warning: register 0x0b is used for something completely different in | 154 | /* The IT8705F and IT8712F earlier than revision 0x08 use register 0x0b |
| 155 | new chips/revisions. I suspect only 16-bit tachometer mode will work | 155 | for fan divisors. Later IT8712F revisions must use 16-bit tachometer |
| 156 | for these. */ | 156 | mode. */ |
| 157 | #define IT87_REG_FAN_DIV 0x0b | 157 | #define IT87_REG_FAN_DIV 0x0b |
| 158 | #define IT87_REG_FAN_16BIT 0x0c | 158 | #define IT87_REG_FAN_16BIT 0x0c |
| 159 | 159 | ||
| @@ -234,6 +234,7 @@ static const unsigned int pwm_freq[8] = { | |||
| 234 | struct it87_sio_data { | 234 | struct it87_sio_data { |
| 235 | enum chips type; | 235 | enum chips type; |
| 236 | /* Values read from Super-I/O config space */ | 236 | /* Values read from Super-I/O config space */ |
| 237 | u8 revision; | ||
| 237 | u8 vid_value; | 238 | u8 vid_value; |
| 238 | }; | 239 | }; |
| 239 | 240 | ||
| @@ -242,6 +243,7 @@ struct it87_sio_data { | |||
| 242 | struct it87_data { | 243 | struct it87_data { |
| 243 | struct device *hwmon_dev; | 244 | struct device *hwmon_dev; |
| 244 | enum chips type; | 245 | enum chips type; |
| 246 | u8 revision; | ||
| 245 | 247 | ||
| 246 | unsigned short addr; | 248 | unsigned short addr; |
| 247 | const char *name; | 249 | const char *name; |
| @@ -268,6 +270,16 @@ struct it87_data { | |||
| 268 | u8 manual_pwm_ctl[3]; /* manual PWM value set by user */ | 270 | u8 manual_pwm_ctl[3]; /* manual PWM value set by user */ |
| 269 | }; | 271 | }; |
| 270 | 272 | ||
| 273 | static inline int has_16bit_fans(const struct it87_data *data) | ||
| 274 | { | ||
| 275 | /* IT8705F Datasheet 0.4.1, 3h == Version G. | ||
| 276 | IT8712F Datasheet 0.9.1, section 8.3.5 indicates 7h == Version I. | ||
| 277 | These are the first revisions with 16bit tachometer support. */ | ||
| 278 | return (data->type == it87 && data->revision >= 0x03) | ||
| 279 | || (data->type == it8712 && data->revision >= 0x07) | ||
| 280 | || data->type == it8716 | ||
| 281 | || data->type == it8718; | ||
| 282 | } | ||
| 271 | 283 | ||
| 272 | static int it87_probe(struct platform_device *pdev); | 284 | static int it87_probe(struct platform_device *pdev); |
| 273 | static int __devexit it87_remove(struct platform_device *pdev); | 285 | static int __devexit it87_remove(struct platform_device *pdev); |
| @@ -991,8 +1003,9 @@ static int __init it87_find(unsigned short *address, | |||
| 991 | } | 1003 | } |
| 992 | 1004 | ||
| 993 | err = 0; | 1005 | err = 0; |
| 1006 | sio_data->revision = superio_inb(DEVREV) & 0x0f; | ||
| 994 | pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n", | 1007 | pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n", |
| 995 | chip_type, *address, superio_inb(DEVREV) & 0x0f); | 1008 | chip_type, *address, sio_data->revision); |
| 996 | 1009 | ||
| 997 | /* Read GPIO config and VID value from LDN 7 (GPIO) */ | 1010 | /* Read GPIO config and VID value from LDN 7 (GPIO) */ |
| 998 | if (chip_type != IT8705F_DEVID) { | 1011 | if (chip_type != IT8705F_DEVID) { |
| @@ -1045,6 +1058,7 @@ static int __devinit it87_probe(struct platform_device *pdev) | |||
| 1045 | 1058 | ||
| 1046 | data->addr = res->start; | 1059 | data->addr = res->start; |
| 1047 | data->type = sio_data->type; | 1060 | data->type = sio_data->type; |
| 1061 | data->revision = sio_data->revision; | ||
| 1048 | data->name = names[sio_data->type]; | 1062 | data->name = names[sio_data->type]; |
| 1049 | 1063 | ||
| 1050 | /* Now, we do the remaining detection. */ | 1064 | /* Now, we do the remaining detection. */ |
| @@ -1069,7 +1083,7 @@ static int __devinit it87_probe(struct platform_device *pdev) | |||
| 1069 | goto ERROR2; | 1083 | goto ERROR2; |
| 1070 | 1084 | ||
| 1071 | /* Do not create fan files for disabled fans */ | 1085 | /* Do not create fan files for disabled fans */ |
| 1072 | if (data->type == it8716 || data->type == it8718) { | 1086 | if (has_16bit_fans(data)) { |
| 1073 | /* 16-bit tachometers */ | 1087 | /* 16-bit tachometers */ |
| 1074 | if (data->has_fan & (1 << 0)) { | 1088 | if (data->has_fan & (1 << 0)) { |
| 1075 | if ((err = device_create_file(dev, | 1089 | if ((err = device_create_file(dev, |
| @@ -1350,7 +1364,7 @@ static void __devinit it87_init_device(struct platform_device *pdev) | |||
| 1350 | data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; | 1364 | data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; |
| 1351 | 1365 | ||
| 1352 | /* Set tachometers to 16-bit mode if needed */ | 1366 | /* Set tachometers to 16-bit mode if needed */ |
| 1353 | if (data->type == it8716 || data->type == it8718) { | 1367 | if (has_16bit_fans(data)) { |
| 1354 | tmp = it87_read_value(data, IT87_REG_FAN_16BIT); | 1368 | tmp = it87_read_value(data, IT87_REG_FAN_16BIT); |
| 1355 | if (~tmp & 0x07 & data->has_fan) { | 1369 | if (~tmp & 0x07 & data->has_fan) { |
| 1356 | dev_dbg(&pdev->dev, | 1370 | dev_dbg(&pdev->dev, |
| @@ -1358,10 +1372,13 @@ static void __devinit it87_init_device(struct platform_device *pdev) | |||
| 1358 | it87_write_value(data, IT87_REG_FAN_16BIT, | 1372 | it87_write_value(data, IT87_REG_FAN_16BIT, |
| 1359 | tmp | 0x07); | 1373 | tmp | 0x07); |
| 1360 | } | 1374 | } |
| 1361 | if (tmp & (1 << 4)) | 1375 | /* IT8705F only supports three fans. */ |
| 1362 | data->has_fan |= (1 << 3); /* fan4 enabled */ | 1376 | if (data->type != it87) { |
| 1363 | if (tmp & (1 << 5)) | 1377 | if (tmp & (1 << 4)) |
| 1364 | data->has_fan |= (1 << 4); /* fan5 enabled */ | 1378 | data->has_fan |= (1 << 3); /* fan4 enabled */ |
| 1379 | if (tmp & (1 << 5)) | ||
| 1380 | data->has_fan |= (1 << 4); /* fan5 enabled */ | ||
| 1381 | } | ||
| 1365 | } | 1382 | } |
| 1366 | 1383 | ||
| 1367 | /* Set current fan mode registers and the default settings for the | 1384 | /* Set current fan mode registers and the default settings for the |
| @@ -1426,7 +1443,7 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
| 1426 | data->fan[i] = it87_read_value(data, | 1443 | data->fan[i] = it87_read_value(data, |
| 1427 | IT87_REG_FAN[i]); | 1444 | IT87_REG_FAN[i]); |
| 1428 | /* Add high byte if in 16-bit mode */ | 1445 | /* Add high byte if in 16-bit mode */ |
| 1429 | if (data->type == it8716 || data->type == it8718) { | 1446 | if (has_16bit_fans(data)) { |
| 1430 | data->fan[i] |= it87_read_value(data, | 1447 | data->fan[i] |= it87_read_value(data, |
| 1431 | IT87_REG_FANX[i]) << 8; | 1448 | IT87_REG_FANX[i]) << 8; |
| 1432 | data->fan_min[i] |= it87_read_value(data, | 1449 | data->fan_min[i] |= it87_read_value(data, |
| @@ -1443,8 +1460,7 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
| 1443 | } | 1460 | } |
| 1444 | 1461 | ||
| 1445 | /* Newer chips don't have clock dividers */ | 1462 | /* Newer chips don't have clock dividers */ |
| 1446 | if ((data->has_fan & 0x07) && data->type != it8716 | 1463 | if ((data->has_fan & 0x07) && !has_16bit_fans(data)) { |
| 1447 | && data->type != it8718) { | ||
| 1448 | i = it87_read_value(data, IT87_REG_FAN_DIV); | 1464 | i = it87_read_value(data, IT87_REG_FAN_DIV); |
| 1449 | data->fan_div[0] = i & 0x07; | 1465 | data->fan_div[0] = i & 0x07; |
| 1450 | data->fan_div[1] = (i >> 3) & 0x07; | 1466 | data->fan_div[1] = (i >> 3) & 0x07; |
| @@ -1460,7 +1476,8 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
| 1460 | data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL); | 1476 | data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL); |
| 1461 | 1477 | ||
| 1462 | data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); | 1478 | data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); |
| 1463 | /* The 8705 does not have VID capability */ | 1479 | /* The 8705 does not have VID capability. |
| 1480 | The 8718 does not use IT87_REG_VID for the same purpose. */ | ||
| 1464 | if (data->type == it8712 || data->type == it8716) { | 1481 | if (data->type == it8712 || data->type == it8716) { |
| 1465 | data->vid = it87_read_value(data, IT87_REG_VID); | 1482 | data->vid = it87_read_value(data, IT87_REG_VID); |
| 1466 | /* The older IT8712F revisions had only 5 VID pins, | 1483 | /* The older IT8712F revisions had only 5 VID pins, |
diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c index 3b01001108c1..7d97431e132f 100644 --- a/drivers/hwmon/thmc50.c +++ b/drivers/hwmon/thmc50.c | |||
| @@ -55,8 +55,11 @@ I2C_CLIENT_MODULE_PARM(adm1022_temp3, "List of adapter,address pairs " | |||
| 55 | static const u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 }; | 55 | static const u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 }; |
| 56 | static const u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C }; | 56 | static const u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C }; |
| 57 | static const u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B }; | 57 | static const u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B }; |
| 58 | static const u8 THMC50_REG_TEMP_CRITICAL[] = { 0x13, 0x14, 0x14 }; | ||
| 59 | static const u8 THMC50_REG_TEMP_DEFAULT[] = { 0x17, 0x18, 0x18 }; | ||
| 58 | 60 | ||
| 59 | #define THMC50_REG_CONF_nFANOFF 0x20 | 61 | #define THMC50_REG_CONF_nFANOFF 0x20 |
| 62 | #define THMC50_REG_CONF_PROGRAMMED 0x08 | ||
| 60 | 63 | ||
| 61 | /* Each client has this additional data */ | 64 | /* Each client has this additional data */ |
| 62 | struct thmc50_data { | 65 | struct thmc50_data { |
| @@ -72,6 +75,7 @@ struct thmc50_data { | |||
| 72 | s8 temp_input[3]; | 75 | s8 temp_input[3]; |
| 73 | s8 temp_max[3]; | 76 | s8 temp_max[3]; |
| 74 | s8 temp_min[3]; | 77 | s8 temp_min[3]; |
| 78 | s8 temp_critical[3]; | ||
| 75 | u8 analog_out; | 79 | u8 analog_out; |
| 76 | u8 alarms; | 80 | u8 alarms; |
| 77 | }; | 81 | }; |
| @@ -199,6 +203,15 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | |||
| 199 | return count; | 203 | return count; |
| 200 | } | 204 | } |
| 201 | 205 | ||
| 206 | static ssize_t show_temp_critical(struct device *dev, | ||
| 207 | struct device_attribute *attr, | ||
| 208 | char *buf) | ||
| 209 | { | ||
| 210 | int nr = to_sensor_dev_attr(attr)->index; | ||
| 211 | struct thmc50_data *data = thmc50_update_device(dev); | ||
| 212 | return sprintf(buf, "%d\n", data->temp_critical[nr] * 1000); | ||
| 213 | } | ||
| 214 | |||
| 202 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | 215 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, |
| 203 | char *buf) | 216 | char *buf) |
| 204 | { | 217 | { |
| @@ -214,7 +227,9 @@ static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp, \ | |||
| 214 | static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ | 227 | static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ |
| 215 | show_temp_min, set_temp_min, offset - 1); \ | 228 | show_temp_min, set_temp_min, offset - 1); \ |
| 216 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ | 229 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ |
| 217 | show_temp_max, set_temp_max, offset - 1); | 230 | show_temp_max, set_temp_max, offset - 1); \ |
| 231 | static SENSOR_DEVICE_ATTR(temp##offset##_crit, S_IRUGO, \ | ||
| 232 | show_temp_critical, NULL, offset - 1); | ||
| 218 | 233 | ||
| 219 | temp_reg(1); | 234 | temp_reg(1); |
| 220 | temp_reg(2); | 235 | temp_reg(2); |
| @@ -234,10 +249,12 @@ static struct attribute *thmc50_attributes[] = { | |||
| 234 | &sensor_dev_attr_temp1_max.dev_attr.attr, | 249 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
| 235 | &sensor_dev_attr_temp1_min.dev_attr.attr, | 250 | &sensor_dev_attr_temp1_min.dev_attr.attr, |
| 236 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 251 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
| 252 | &sensor_dev_attr_temp1_crit.dev_attr.attr, | ||
| 237 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, | 253 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, |
| 238 | &sensor_dev_attr_temp2_max.dev_attr.attr, | 254 | &sensor_dev_attr_temp2_max.dev_attr.attr, |
| 239 | &sensor_dev_attr_temp2_min.dev_attr.attr, | 255 | &sensor_dev_attr_temp2_min.dev_attr.attr, |
| 240 | &sensor_dev_attr_temp2_input.dev_attr.attr, | 256 | &sensor_dev_attr_temp2_input.dev_attr.attr, |
| 257 | &sensor_dev_attr_temp2_crit.dev_attr.attr, | ||
| 241 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, | 258 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, |
| 242 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | 259 | &sensor_dev_attr_temp2_fault.dev_attr.attr, |
| 243 | &sensor_dev_attr_pwm1.dev_attr.attr, | 260 | &sensor_dev_attr_pwm1.dev_attr.attr, |
| @@ -254,6 +271,7 @@ static struct attribute *temp3_attributes[] = { | |||
| 254 | &sensor_dev_attr_temp3_max.dev_attr.attr, | 271 | &sensor_dev_attr_temp3_max.dev_attr.attr, |
| 255 | &sensor_dev_attr_temp3_min.dev_attr.attr, | 272 | &sensor_dev_attr_temp3_min.dev_attr.attr, |
| 256 | &sensor_dev_attr_temp3_input.dev_attr.attr, | 273 | &sensor_dev_attr_temp3_input.dev_attr.attr, |
| 274 | &sensor_dev_attr_temp3_crit.dev_attr.attr, | ||
| 257 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, | 275 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, |
| 258 | &sensor_dev_attr_temp3_fault.dev_attr.attr, | 276 | &sensor_dev_attr_temp3_fault.dev_attr.attr, |
| 259 | NULL | 277 | NULL |
| @@ -429,6 +447,10 @@ static struct thmc50_data *thmc50_update_device(struct device *dev) | |||
| 429 | 447 | ||
| 430 | int temps = data->has_temp3 ? 3 : 2; | 448 | int temps = data->has_temp3 ? 3 : 2; |
| 431 | int i; | 449 | int i; |
| 450 | int prog = i2c_smbus_read_byte_data(client, THMC50_REG_CONF); | ||
| 451 | |||
| 452 | prog &= THMC50_REG_CONF_PROGRAMMED; | ||
| 453 | |||
| 432 | for (i = 0; i < temps; i++) { | 454 | for (i = 0; i < temps; i++) { |
| 433 | data->temp_input[i] = i2c_smbus_read_byte_data(client, | 455 | data->temp_input[i] = i2c_smbus_read_byte_data(client, |
| 434 | THMC50_REG_TEMP[i]); | 456 | THMC50_REG_TEMP[i]); |
| @@ -436,6 +458,10 @@ static struct thmc50_data *thmc50_update_device(struct device *dev) | |||
| 436 | THMC50_REG_TEMP_MAX[i]); | 458 | THMC50_REG_TEMP_MAX[i]); |
| 437 | data->temp_min[i] = i2c_smbus_read_byte_data(client, | 459 | data->temp_min[i] = i2c_smbus_read_byte_data(client, |
| 438 | THMC50_REG_TEMP_MIN[i]); | 460 | THMC50_REG_TEMP_MIN[i]); |
| 461 | data->temp_critical[i] = | ||
| 462 | i2c_smbus_read_byte_data(client, | ||
| 463 | prog ? THMC50_REG_TEMP_CRITICAL[i] | ||
| 464 | : THMC50_REG_TEMP_DEFAULT[i]); | ||
| 439 | } | 465 | } |
| 440 | data->analog_out = | 466 | data->analog_out = |
| 441 | i2c_smbus_read_byte_data(client, THMC50_REG_ANALOG_OUT); | 467 | i2c_smbus_read_byte_data(client, THMC50_REG_ANALOG_OUT); |
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 9564fb069957..b30e5796cb26 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c | |||
| @@ -67,10 +67,6 @@ module_param(force_i2c, byte, 0); | |||
| 67 | MODULE_PARM_DESC(force_i2c, | 67 | MODULE_PARM_DESC(force_i2c, |
| 68 | "Initialize the i2c address of the sensors"); | 68 | "Initialize the i2c address of the sensors"); |
| 69 | 69 | ||
| 70 | static int reset; | ||
| 71 | module_param(reset, bool, 0); | ||
| 72 | MODULE_PARM_DESC(reset, "Set to one to reset chip on load"); | ||
| 73 | |||
| 74 | static int init = 1; | 70 | static int init = 1; |
| 75 | module_param(init, bool, 0); | 71 | module_param(init, bool, 0); |
| 76 | MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); | 72 | MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); |
| @@ -209,6 +205,13 @@ static const u16 w83627hf_reg_temp_over[] = { 0x39, 0x155, 0x255 }; | |||
| 209 | #define W83627HF_REG_PWM1 0x5A | 205 | #define W83627HF_REG_PWM1 0x5A |
| 210 | #define W83627HF_REG_PWM2 0x5B | 206 | #define W83627HF_REG_PWM2 0x5B |
| 211 | 207 | ||
| 208 | static const u8 W83627THF_REG_PWM_ENABLE[] = { | ||
| 209 | 0x04, /* FAN 1 mode */ | ||
| 210 | 0x04, /* FAN 2 mode */ | ||
| 211 | 0x12, /* FAN AUX mode */ | ||
| 212 | }; | ||
| 213 | static const u8 W83627THF_PWM_ENABLE_SHIFT[] = { 2, 4, 1 }; | ||
| 214 | |||
| 212 | #define W83627THF_REG_PWM1 0x01 /* 697HF/637HF/687THF too */ | 215 | #define W83627THF_REG_PWM1 0x01 /* 697HF/637HF/687THF too */ |
| 213 | #define W83627THF_REG_PWM2 0x03 /* 697HF/637HF/687THF too */ | 216 | #define W83627THF_REG_PWM2 0x03 /* 697HF/637HF/687THF too */ |
| 214 | #define W83627THF_REG_PWM3 0x11 /* 637HF/687THF too */ | 217 | #define W83627THF_REG_PWM3 0x11 /* 637HF/687THF too */ |
| @@ -366,6 +369,9 @@ struct w83627hf_data { | |||
| 366 | u32 alarms; /* Register encoding, combined */ | 369 | u32 alarms; /* Register encoding, combined */ |
| 367 | u32 beep_mask; /* Register encoding, combined */ | 370 | u32 beep_mask; /* Register encoding, combined */ |
| 368 | u8 pwm[3]; /* Register value */ | 371 | u8 pwm[3]; /* Register value */ |
| 372 | u8 pwm_enable[3]; /* 1 = manual | ||
| 373 | 2 = thermal cruise (also called SmartFan I) | ||
| 374 | 3 = fan speed cruise */ | ||
| 369 | u8 pwm_freq[3]; /* Register value */ | 375 | u8 pwm_freq[3]; /* Register value */ |
| 370 | u16 sens[3]; /* 1 = pentium diode; 2 = 3904 diode; | 376 | u16 sens[3]; /* 1 = pentium diode; 2 = 3904 diode; |
| 371 | 4 = thermistor */ | 377 | 4 = thermistor */ |
| @@ -957,6 +963,42 @@ static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 1); | |||
| 957 | static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 2); | 963 | static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 2); |
| 958 | 964 | ||
| 959 | static ssize_t | 965 | static ssize_t |
| 966 | show_pwm_enable(struct device *dev, struct device_attribute *devattr, char *buf) | ||
| 967 | { | ||
| 968 | int nr = to_sensor_dev_attr(devattr)->index; | ||
| 969 | struct w83627hf_data *data = w83627hf_update_device(dev); | ||
| 970 | return sprintf(buf, "%d\n", data->pwm_enable[nr]); | ||
| 971 | } | ||
| 972 | |||
| 973 | static ssize_t | ||
| 974 | store_pwm_enable(struct device *dev, struct device_attribute *devattr, | ||
| 975 | const char *buf, size_t count) | ||
| 976 | { | ||
| 977 | int nr = to_sensor_dev_attr(devattr)->index; | ||
| 978 | struct w83627hf_data *data = dev_get_drvdata(dev); | ||
| 979 | unsigned long val = simple_strtoul(buf, NULL, 10); | ||
| 980 | u8 reg; | ||
| 981 | |||
| 982 | if (!val || (val > 3)) /* modes 1, 2 and 3 are supported */ | ||
| 983 | return -EINVAL; | ||
| 984 | mutex_lock(&data->update_lock); | ||
| 985 | data->pwm_enable[nr] = val; | ||
| 986 | reg = w83627hf_read_value(data, W83627THF_REG_PWM_ENABLE[nr]); | ||
| 987 | reg &= ~(0x03 << W83627THF_PWM_ENABLE_SHIFT[nr]); | ||
| 988 | reg |= (val - 1) << W83627THF_PWM_ENABLE_SHIFT[nr]; | ||
| 989 | w83627hf_write_value(data, W83627THF_REG_PWM_ENABLE[nr], reg); | ||
| 990 | mutex_unlock(&data->update_lock); | ||
| 991 | return count; | ||
| 992 | } | ||
| 993 | |||
| 994 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO|S_IWUSR, show_pwm_enable, | ||
| 995 | store_pwm_enable, 0); | ||
| 996 | static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO|S_IWUSR, show_pwm_enable, | ||
| 997 | store_pwm_enable, 1); | ||
| 998 | static SENSOR_DEVICE_ATTR(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable, | ||
| 999 | store_pwm_enable, 2); | ||
| 1000 | |||
| 1001 | static ssize_t | ||
| 960 | show_pwm_freq(struct device *dev, struct device_attribute *devattr, char *buf) | 1002 | show_pwm_freq(struct device *dev, struct device_attribute *devattr, char *buf) |
| 961 | { | 1003 | { |
| 962 | int nr = to_sensor_dev_attr(devattr)->index; | 1004 | int nr = to_sensor_dev_attr(devattr)->index; |
| @@ -1223,6 +1265,11 @@ static struct attribute *w83627hf_attributes_opt[] = { | |||
| 1223 | &sensor_dev_attr_pwm1_freq.dev_attr.attr, | 1265 | &sensor_dev_attr_pwm1_freq.dev_attr.attr, |
| 1224 | &sensor_dev_attr_pwm2_freq.dev_attr.attr, | 1266 | &sensor_dev_attr_pwm2_freq.dev_attr.attr, |
| 1225 | &sensor_dev_attr_pwm3_freq.dev_attr.attr, | 1267 | &sensor_dev_attr_pwm3_freq.dev_attr.attr, |
| 1268 | |||
| 1269 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | ||
| 1270 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, | ||
| 1271 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, | ||
| 1272 | |||
| 1226 | NULL | 1273 | NULL |
| 1227 | }; | 1274 | }; |
| 1228 | 1275 | ||
| @@ -1366,6 +1413,19 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) | |||
| 1366 | &sensor_dev_attr_pwm3_freq.dev_attr))) | 1413 | &sensor_dev_attr_pwm3_freq.dev_attr))) |
| 1367 | goto ERROR4; | 1414 | goto ERROR4; |
| 1368 | 1415 | ||
| 1416 | if (data->type != w83627hf) | ||
| 1417 | if ((err = device_create_file(dev, | ||
| 1418 | &sensor_dev_attr_pwm1_enable.dev_attr)) | ||
| 1419 | || (err = device_create_file(dev, | ||
| 1420 | &sensor_dev_attr_pwm2_enable.dev_attr))) | ||
| 1421 | goto ERROR4; | ||
| 1422 | |||
| 1423 | if (data->type == w83627thf || data->type == w83637hf | ||
| 1424 | || data->type == w83687thf) | ||
| 1425 | if ((err = device_create_file(dev, | ||
| 1426 | &sensor_dev_attr_pwm3_enable.dev_attr))) | ||
| 1427 | goto ERROR4; | ||
| 1428 | |||
| 1369 | data->hwmon_dev = hwmon_device_register(dev); | 1429 | data->hwmon_dev = hwmon_device_register(dev); |
| 1370 | if (IS_ERR(data->hwmon_dev)) { | 1430 | if (IS_ERR(data->hwmon_dev)) { |
| 1371 | err = PTR_ERR(data->hwmon_dev); | 1431 | err = PTR_ERR(data->hwmon_dev); |
| @@ -1536,29 +1596,6 @@ static void __devinit w83627hf_init_device(struct platform_device *pdev) | |||
| 1536 | enum chips type = data->type; | 1596 | enum chips type = data->type; |
| 1537 | u8 tmp; | 1597 | u8 tmp; |
| 1538 | 1598 | ||
| 1539 | if (reset) { | ||
| 1540 | /* Resetting the chip has been the default for a long time, | ||
| 1541 | but repeatedly caused problems (fans going to full | ||
| 1542 | speed...) so it is now optional. It might even go away if | ||
| 1543 | nobody reports it as being useful, as I see very little | ||
| 1544 | reason why this would be needed at all. */ | ||
| 1545 | dev_info(&pdev->dev, "If reset=1 solved a problem you were " | ||
| 1546 | "having, please report!\n"); | ||
| 1547 | |||
| 1548 | /* save this register */ | ||
| 1549 | i = w83627hf_read_value(data, W83781D_REG_BEEP_CONFIG); | ||
| 1550 | /* Reset all except Watchdog values and last conversion values | ||
| 1551 | This sets fan-divs to 2, among others */ | ||
| 1552 | w83627hf_write_value(data, W83781D_REG_CONFIG, 0x80); | ||
| 1553 | /* Restore the register and disable power-on abnormal beep. | ||
| 1554 | This saves FAN 1/2/3 input/output values set by BIOS. */ | ||
| 1555 | w83627hf_write_value(data, W83781D_REG_BEEP_CONFIG, i | 0x80); | ||
| 1556 | /* Disable master beep-enable (reset turns it on). | ||
| 1557 | Individual beeps should be reset to off but for some reason | ||
| 1558 | disabling this bit helps some people not get beeped */ | ||
| 1559 | w83627hf_write_value(data, W83781D_REG_BEEP_INTS2, 0); | ||
| 1560 | } | ||
| 1561 | |||
| 1562 | /* Minimize conflicts with other winbond i2c-only clients... */ | 1599 | /* Minimize conflicts with other winbond i2c-only clients... */ |
| 1563 | /* disable i2c subclients... how to disable main i2c client?? */ | 1600 | /* disable i2c subclients... how to disable main i2c client?? */ |
| 1564 | /* force i2c address to relatively uncommon address */ | 1601 | /* force i2c address to relatively uncommon address */ |
| @@ -1655,6 +1692,7 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev) | |||
| 1655 | { | 1692 | { |
| 1656 | struct w83627hf_data *data = dev_get_drvdata(dev); | 1693 | struct w83627hf_data *data = dev_get_drvdata(dev); |
| 1657 | int i, num_temps = (data->type == w83697hf) ? 2 : 3; | 1694 | int i, num_temps = (data->type == w83697hf) ? 2 : 3; |
| 1695 | int num_pwms = (data->type == w83697hf) ? 2 : 3; | ||
| 1658 | 1696 | ||
| 1659 | mutex_lock(&data->update_lock); | 1697 | mutex_lock(&data->update_lock); |
| 1660 | 1698 | ||
| @@ -1707,6 +1745,15 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev) | |||
| 1707 | break; | 1745 | break; |
| 1708 | } | 1746 | } |
| 1709 | } | 1747 | } |
| 1748 | if (data->type != w83627hf) { | ||
| 1749 | for (i = 0; i < num_pwms; i++) { | ||
| 1750 | u8 tmp = w83627hf_read_value(data, | ||
| 1751 | W83627THF_REG_PWM_ENABLE[i]); | ||
| 1752 | data->pwm_enable[i] = | ||
| 1753 | ((tmp >> W83627THF_PWM_ENABLE_SHIFT[i]) | ||
| 1754 | & 0x03) + 1; | ||
| 1755 | } | ||
| 1756 | } | ||
| 1710 | for (i = 0; i < num_temps; i++) { | 1757 | for (i = 0; i < num_temps; i++) { |
| 1711 | data->temp[i] = w83627hf_read_value( | 1758 | data->temp[i] = w83627hf_read_value( |
| 1712 | data, w83627hf_reg_temp[i]); | 1759 | data, w83627hf_reg_temp[i]); |
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index e4e91c9d480a..daa7d121483b 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c | |||
| @@ -233,11 +233,9 @@ static u8 fan_to_reg(long rpm, int div) | |||
| 233 | static u8 div_to_reg(int nr, long val) | 233 | static u8 div_to_reg(int nr, long val) |
| 234 | { | 234 | { |
| 235 | int i; | 235 | int i; |
| 236 | int max; | ||
| 237 | 236 | ||
| 238 | /* first three fan's divisor max out at 8, rest max out at 128 */ | 237 | /* fan divisors max out at 128 */ |
| 239 | max = (nr < 3) ? 8 : 128; | 238 | val = SENSORS_LIMIT(val, 1, 128) >> 1; |
| 240 | val = SENSORS_LIMIT(val, 1, max) >> 1; | ||
| 241 | for (i = 0; i < 7; i++) { | 239 | for (i = 0; i < 7; i++) { |
| 242 | if (val == 0) | 240 | if (val == 0) |
| 243 | break; | 241 | break; |
| @@ -530,6 +528,7 @@ static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr, | |||
| 530 | unsigned long min; | 528 | unsigned long min; |
| 531 | u8 tmp_fan_div; | 529 | u8 tmp_fan_div; |
| 532 | u8 fan_div_reg; | 530 | u8 fan_div_reg; |
| 531 | u8 vbat_reg; | ||
| 533 | int indx = 0; | 532 | int indx = 0; |
| 534 | u8 keep_mask = 0; | 533 | u8 keep_mask = 0; |
| 535 | u8 new_shift = 0; | 534 | u8 new_shift = 0; |
| @@ -581,6 +580,16 @@ static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr, | |||
| 581 | w83791d_write(client, W83791D_REG_FAN_DIV[indx], | 580 | w83791d_write(client, W83791D_REG_FAN_DIV[indx], |
| 582 | fan_div_reg | tmp_fan_div); | 581 | fan_div_reg | tmp_fan_div); |
| 583 | 582 | ||
| 583 | /* Bit 2 of fans 0-2 is stored in the vbat register (bits 5-7) */ | ||
| 584 | if (nr < 3) { | ||
| 585 | keep_mask = ~(1 << (nr + 5)); | ||
| 586 | vbat_reg = w83791d_read(client, W83791D_REG_VBAT) | ||
| 587 | & keep_mask; | ||
| 588 | tmp_fan_div = (data->fan_div[nr] << (3 + nr)) & ~keep_mask; | ||
| 589 | w83791d_write(client, W83791D_REG_VBAT, | ||
| 590 | vbat_reg | tmp_fan_div); | ||
| 591 | } | ||
| 592 | |||
| 584 | /* Restore fan_min */ | 593 | /* Restore fan_min */ |
| 585 | data->fan_min[nr] = fan_to_reg(min, DIV_FROM_REG(data->fan_div[nr])); | 594 | data->fan_min[nr] = fan_to_reg(min, DIV_FROM_REG(data->fan_div[nr])); |
| 586 | w83791d_write(client, W83791D_REG_FAN_MIN[nr], data->fan_min[nr]); | 595 | w83791d_write(client, W83791D_REG_FAN_MIN[nr], data->fan_min[nr]); |
| @@ -1182,6 +1191,7 @@ static struct w83791d_data *w83791d_update_device(struct device *dev) | |||
| 1182 | struct w83791d_data *data = i2c_get_clientdata(client); | 1191 | struct w83791d_data *data = i2c_get_clientdata(client); |
| 1183 | int i, j; | 1192 | int i, j; |
| 1184 | u8 reg_array_tmp[3]; | 1193 | u8 reg_array_tmp[3]; |
| 1194 | u8 vbat_reg; | ||
| 1185 | 1195 | ||
| 1186 | mutex_lock(&data->update_lock); | 1196 | mutex_lock(&data->update_lock); |
| 1187 | 1197 | ||
| @@ -1219,6 +1229,12 @@ static struct w83791d_data *w83791d_update_device(struct device *dev) | |||
| 1219 | data->fan_div[3] = reg_array_tmp[2] & 0x07; | 1229 | data->fan_div[3] = reg_array_tmp[2] & 0x07; |
| 1220 | data->fan_div[4] = (reg_array_tmp[2] >> 4) & 0x07; | 1230 | data->fan_div[4] = (reg_array_tmp[2] >> 4) & 0x07; |
| 1221 | 1231 | ||
| 1232 | /* The fan divisor for fans 0-2 get bit 2 from | ||
| 1233 | bits 5-7 respectively of vbat register */ | ||
| 1234 | vbat_reg = w83791d_read(client, W83791D_REG_VBAT); | ||
| 1235 | for (i = 0; i < 3; i++) | ||
| 1236 | data->fan_div[i] |= (vbat_reg >> (3 + i)) & 0x04; | ||
| 1237 | |||
| 1222 | /* Update the first temperature sensor */ | 1238 | /* Update the first temperature sensor */ |
| 1223 | for (i = 0; i < 3; i++) { | 1239 | for (i = 0; i < 3; i++) { |
| 1224 | data->temp1[i] = w83791d_read(client, | 1240 | data->temp1[i] = w83791d_read(client, |
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index e980ff3335db..d951896ff7fc 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
| @@ -155,9 +155,7 @@ struct cma_multicast { | |||
| 155 | } multicast; | 155 | } multicast; |
| 156 | struct list_head list; | 156 | struct list_head list; |
| 157 | void *context; | 157 | void *context; |
| 158 | struct sockaddr addr; | 158 | struct sockaddr_storage addr; |
| 159 | u8 pad[sizeof(struct sockaddr_in6) - | ||
| 160 | sizeof(struct sockaddr)]; | ||
| 161 | }; | 159 | }; |
| 162 | 160 | ||
| 163 | struct cma_work { | 161 | struct cma_work { |
| @@ -786,8 +784,8 @@ static void cma_cancel_operation(struct rdma_id_private *id_priv, | |||
| 786 | cma_cancel_route(id_priv); | 784 | cma_cancel_route(id_priv); |
| 787 | break; | 785 | break; |
| 788 | case CMA_LISTEN: | 786 | case CMA_LISTEN: |
| 789 | if (cma_any_addr(&id_priv->id.route.addr.src_addr) && | 787 | if (cma_any_addr((struct sockaddr *) &id_priv->id.route.addr.src_addr) |
| 790 | !id_priv->cma_dev) | 788 | && !id_priv->cma_dev) |
| 791 | cma_cancel_listens(id_priv); | 789 | cma_cancel_listens(id_priv); |
| 792 | break; | 790 | break; |
| 793 | default: | 791 | default: |
| @@ -1026,7 +1024,7 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id, | |||
| 1026 | rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path; | 1024 | rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path; |
| 1027 | 1025 | ||
| 1028 | ib_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid); | 1026 | ib_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid); |
| 1029 | ret = rdma_translate_ip(&id->route.addr.src_addr, | 1027 | ret = rdma_translate_ip((struct sockaddr *) &id->route.addr.src_addr, |
| 1030 | &id->route.addr.dev_addr); | 1028 | &id->route.addr.dev_addr); |
| 1031 | if (ret) | 1029 | if (ret) |
| 1032 | goto destroy_id; | 1030 | goto destroy_id; |
| @@ -1064,7 +1062,7 @@ static struct rdma_id_private *cma_new_udp_id(struct rdma_cm_id *listen_id, | |||
| 1064 | cma_save_net_info(&id->route.addr, &listen_id->route.addr, | 1062 | cma_save_net_info(&id->route.addr, &listen_id->route.addr, |
| 1065 | ip_ver, port, src, dst); | 1063 | ip_ver, port, src, dst); |
| 1066 | 1064 | ||
| 1067 | ret = rdma_translate_ip(&id->route.addr.src_addr, | 1065 | ret = rdma_translate_ip((struct sockaddr *) &id->route.addr.src_addr, |
| 1068 | &id->route.addr.dev_addr); | 1066 | &id->route.addr.dev_addr); |
| 1069 | if (ret) | 1067 | if (ret) |
| 1070 | goto err; | 1068 | goto err; |
| @@ -1377,7 +1375,7 @@ static int cma_ib_listen(struct rdma_id_private *id_priv) | |||
| 1377 | if (IS_ERR(id_priv->cm_id.ib)) | 1375 | if (IS_ERR(id_priv->cm_id.ib)) |
| 1378 | return PTR_ERR(id_priv->cm_id.ib); | 1376 | return PTR_ERR(id_priv->cm_id.ib); |
| 1379 | 1377 | ||
| 1380 | addr = &id_priv->id.route.addr.src_addr; | 1378 | addr = (struct sockaddr *) &id_priv->id.route.addr.src_addr; |
| 1381 | svc_id = cma_get_service_id(id_priv->id.ps, addr); | 1379 | svc_id = cma_get_service_id(id_priv->id.ps, addr); |
| 1382 | if (cma_any_addr(addr)) | 1380 | if (cma_any_addr(addr)) |
| 1383 | ret = ib_cm_listen(id_priv->cm_id.ib, svc_id, 0, NULL); | 1381 | ret = ib_cm_listen(id_priv->cm_id.ib, svc_id, 0, NULL); |
| @@ -1443,7 +1441,7 @@ static void cma_listen_on_dev(struct rdma_id_private *id_priv, | |||
| 1443 | 1441 | ||
| 1444 | dev_id_priv->state = CMA_ADDR_BOUND; | 1442 | dev_id_priv->state = CMA_ADDR_BOUND; |
| 1445 | memcpy(&id->route.addr.src_addr, &id_priv->id.route.addr.src_addr, | 1443 | memcpy(&id->route.addr.src_addr, &id_priv->id.route.addr.src_addr, |
| 1446 | ip_addr_size(&id_priv->id.route.addr.src_addr)); | 1444 | ip_addr_size((struct sockaddr *) &id_priv->id.route.addr.src_addr)); |
| 1447 | 1445 | ||
| 1448 | cma_attach_to_dev(dev_id_priv, cma_dev); | 1446 | cma_attach_to_dev(dev_id_priv, cma_dev); |
| 1449 | list_add_tail(&dev_id_priv->listen_list, &id_priv->listen_list); | 1447 | list_add_tail(&dev_id_priv->listen_list, &id_priv->listen_list); |
| @@ -1563,13 +1561,14 @@ static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms, | |||
| 1563 | path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(&addr->dev_addr)); | 1561 | path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(&addr->dev_addr)); |
| 1564 | path_rec.numb_path = 1; | 1562 | path_rec.numb_path = 1; |
| 1565 | path_rec.reversible = 1; | 1563 | path_rec.reversible = 1; |
| 1566 | path_rec.service_id = cma_get_service_id(id_priv->id.ps, &addr->dst_addr); | 1564 | path_rec.service_id = cma_get_service_id(id_priv->id.ps, |
| 1565 | (struct sockaddr *) &addr->dst_addr); | ||
| 1567 | 1566 | ||
| 1568 | comp_mask = IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID | | 1567 | comp_mask = IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID | |
| 1569 | IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH | | 1568 | IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH | |
| 1570 | IB_SA_PATH_REC_REVERSIBLE | IB_SA_PATH_REC_SERVICE_ID; | 1569 | IB_SA_PATH_REC_REVERSIBLE | IB_SA_PATH_REC_SERVICE_ID; |
| 1571 | 1570 | ||
| 1572 | if (addr->src_addr.sa_family == AF_INET) { | 1571 | if (addr->src_addr.ss_family == AF_INET) { |
| 1573 | path_rec.qos_class = cpu_to_be16((u16) id_priv->tos); | 1572 | path_rec.qos_class = cpu_to_be16((u16) id_priv->tos); |
| 1574 | comp_mask |= IB_SA_PATH_REC_QOS_CLASS; | 1573 | comp_mask |= IB_SA_PATH_REC_QOS_CLASS; |
| 1575 | } else { | 1574 | } else { |
| @@ -1848,7 +1847,7 @@ static int cma_resolve_loopback(struct rdma_id_private *id_priv) | |||
| 1848 | ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid); | 1847 | ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid); |
| 1849 | ib_addr_set_dgid(&id_priv->id.route.addr.dev_addr, &gid); | 1848 | ib_addr_set_dgid(&id_priv->id.route.addr.dev_addr, &gid); |
| 1850 | 1849 | ||
| 1851 | if (cma_zero_addr(&id_priv->id.route.addr.src_addr)) { | 1850 | if (cma_zero_addr((struct sockaddr *) &id_priv->id.route.addr.src_addr)) { |
| 1852 | src_in = (struct sockaddr_in *)&id_priv->id.route.addr.src_addr; | 1851 | src_in = (struct sockaddr_in *)&id_priv->id.route.addr.src_addr; |
| 1853 | dst_in = (struct sockaddr_in *)&id_priv->id.route.addr.dst_addr; | 1852 | dst_in = (struct sockaddr_in *)&id_priv->id.route.addr.dst_addr; |
| 1854 | src_in->sin_family = dst_in->sin_family; | 1853 | src_in->sin_family = dst_in->sin_family; |
| @@ -1897,7 +1896,7 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, | |||
| 1897 | if (cma_any_addr(dst_addr)) | 1896 | if (cma_any_addr(dst_addr)) |
| 1898 | ret = cma_resolve_loopback(id_priv); | 1897 | ret = cma_resolve_loopback(id_priv); |
| 1899 | else | 1898 | else |
| 1900 | ret = rdma_resolve_ip(&addr_client, &id->route.addr.src_addr, | 1899 | ret = rdma_resolve_ip(&addr_client, (struct sockaddr *) &id->route.addr.src_addr, |
| 1901 | dst_addr, &id->route.addr.dev_addr, | 1900 | dst_addr, &id->route.addr.dev_addr, |
| 1902 | timeout_ms, addr_handler, id_priv); | 1901 | timeout_ms, addr_handler, id_priv); |
| 1903 | if (ret) | 1902 | if (ret) |
| @@ -2021,11 +2020,11 @@ static int cma_use_port(struct idr *ps, struct rdma_id_private *id_priv) | |||
| 2021 | * We don't support binding to any address if anyone is bound to | 2020 | * We don't support binding to any address if anyone is bound to |
| 2022 | * a specific address on the same port. | 2021 | * a specific address on the same port. |
| 2023 | */ | 2022 | */ |
| 2024 | if (cma_any_addr(&id_priv->id.route.addr.src_addr)) | 2023 | if (cma_any_addr((struct sockaddr *) &id_priv->id.route.addr.src_addr)) |
| 2025 | return -EADDRNOTAVAIL; | 2024 | return -EADDRNOTAVAIL; |
| 2026 | 2025 | ||
| 2027 | hlist_for_each_entry(cur_id, node, &bind_list->owners, node) { | 2026 | hlist_for_each_entry(cur_id, node, &bind_list->owners, node) { |
| 2028 | if (cma_any_addr(&cur_id->id.route.addr.src_addr)) | 2027 | if (cma_any_addr((struct sockaddr *) &cur_id->id.route.addr.src_addr)) |
| 2029 | return -EADDRNOTAVAIL; | 2028 | return -EADDRNOTAVAIL; |
| 2030 | 2029 | ||
| 2031 | cur_sin = (struct sockaddr_in *) &cur_id->id.route.addr.src_addr; | 2030 | cur_sin = (struct sockaddr_in *) &cur_id->id.route.addr.src_addr; |
| @@ -2060,7 +2059,7 @@ static int cma_get_port(struct rdma_id_private *id_priv) | |||
| 2060 | } | 2059 | } |
| 2061 | 2060 | ||
| 2062 | mutex_lock(&lock); | 2061 | mutex_lock(&lock); |
| 2063 | if (cma_any_port(&id_priv->id.route.addr.src_addr)) | 2062 | if (cma_any_port((struct sockaddr *) &id_priv->id.route.addr.src_addr)) |
| 2064 | ret = cma_alloc_any_port(ps, id_priv); | 2063 | ret = cma_alloc_any_port(ps, id_priv); |
| 2065 | else | 2064 | else |
| 2066 | ret = cma_use_port(ps, id_priv); | 2065 | ret = cma_use_port(ps, id_priv); |
| @@ -2232,7 +2231,7 @@ static int cma_resolve_ib_udp(struct rdma_id_private *id_priv, | |||
| 2232 | 2231 | ||
| 2233 | req.path = route->path_rec; | 2232 | req.path = route->path_rec; |
| 2234 | req.service_id = cma_get_service_id(id_priv->id.ps, | 2233 | req.service_id = cma_get_service_id(id_priv->id.ps, |
| 2235 | &route->addr.dst_addr); | 2234 | (struct sockaddr *) &route->addr.dst_addr); |
| 2236 | req.timeout_ms = 1 << (CMA_CM_RESPONSE_TIMEOUT - 8); | 2235 | req.timeout_ms = 1 << (CMA_CM_RESPONSE_TIMEOUT - 8); |
| 2237 | req.max_cm_retries = CMA_MAX_CM_RETRIES; | 2236 | req.max_cm_retries = CMA_MAX_CM_RETRIES; |
| 2238 | 2237 | ||
| @@ -2283,7 +2282,7 @@ static int cma_connect_ib(struct rdma_id_private *id_priv, | |||
| 2283 | req.alternate_path = &route->path_rec[1]; | 2282 | req.alternate_path = &route->path_rec[1]; |
| 2284 | 2283 | ||
| 2285 | req.service_id = cma_get_service_id(id_priv->id.ps, | 2284 | req.service_id = cma_get_service_id(id_priv->id.ps, |
| 2286 | &route->addr.dst_addr); | 2285 | (struct sockaddr *) &route->addr.dst_addr); |
| 2287 | req.qp_num = id_priv->qp_num; | 2286 | req.qp_num = id_priv->qp_num; |
| 2288 | req.qp_type = IB_QPT_RC; | 2287 | req.qp_type = IB_QPT_RC; |
| 2289 | req.starting_psn = id_priv->seq_num; | 2288 | req.starting_psn = id_priv->seq_num; |
| @@ -2667,7 +2666,7 @@ static int cma_join_ib_multicast(struct rdma_id_private *id_priv, | |||
| 2667 | if (ret) | 2666 | if (ret) |
| 2668 | return ret; | 2667 | return ret; |
| 2669 | 2668 | ||
| 2670 | cma_set_mgid(id_priv, &mc->addr, &rec.mgid); | 2669 | cma_set_mgid(id_priv, (struct sockaddr *) &mc->addr, &rec.mgid); |
| 2671 | if (id_priv->id.ps == RDMA_PS_UDP) | 2670 | if (id_priv->id.ps == RDMA_PS_UDP) |
| 2672 | rec.qkey = cpu_to_be32(RDMA_UDP_QKEY); | 2671 | rec.qkey = cpu_to_be32(RDMA_UDP_QKEY); |
| 2673 | ib_addr_get_sgid(dev_addr, &rec.port_gid); | 2672 | ib_addr_get_sgid(dev_addr, &rec.port_gid); |
diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c index d0ef7d61c037..3af2b84cd838 100644 --- a/drivers/infiniband/core/mad_rmpp.c +++ b/drivers/infiniband/core/mad_rmpp.c | |||
| @@ -133,7 +133,7 @@ static void ack_recv(struct mad_rmpp_recv *rmpp_recv, | |||
| 133 | msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp, | 133 | msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp, |
| 134 | recv_wc->wc->pkey_index, 1, hdr_len, | 134 | recv_wc->wc->pkey_index, 1, hdr_len, |
| 135 | 0, GFP_KERNEL); | 135 | 0, GFP_KERNEL); |
| 136 | if (!msg) | 136 | if (IS_ERR(msg)) |
| 137 | return; | 137 | return; |
| 138 | 138 | ||
| 139 | format_ack(msg, (struct ib_rmpp_mad *) recv_wc->recv_buf.mad, rmpp_recv); | 139 | format_ack(msg, (struct ib_rmpp_mad *) recv_wc->recv_buf.mad, rmpp_recv); |
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index b41dd26bbfa1..3ddacf39b7ba 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c | |||
| @@ -81,9 +81,7 @@ struct ucma_multicast { | |||
| 81 | 81 | ||
| 82 | u64 uid; | 82 | u64 uid; |
| 83 | struct list_head list; | 83 | struct list_head list; |
| 84 | struct sockaddr addr; | 84 | struct sockaddr_storage addr; |
| 85 | u8 pad[sizeof(struct sockaddr_in6) - | ||
| 86 | sizeof(struct sockaddr)]; | ||
| 87 | }; | 85 | }; |
| 88 | 86 | ||
| 89 | struct ucma_event { | 87 | struct ucma_event { |
| @@ -603,11 +601,11 @@ static ssize_t ucma_query_route(struct ucma_file *file, | |||
| 603 | return PTR_ERR(ctx); | 601 | return PTR_ERR(ctx); |
| 604 | 602 | ||
| 605 | memset(&resp, 0, sizeof resp); | 603 | memset(&resp, 0, sizeof resp); |
| 606 | addr = &ctx->cm_id->route.addr.src_addr; | 604 | addr = (struct sockaddr *) &ctx->cm_id->route.addr.src_addr; |
| 607 | memcpy(&resp.src_addr, addr, addr->sa_family == AF_INET ? | 605 | memcpy(&resp.src_addr, addr, addr->sa_family == AF_INET ? |
| 608 | sizeof(struct sockaddr_in) : | 606 | sizeof(struct sockaddr_in) : |
| 609 | sizeof(struct sockaddr_in6)); | 607 | sizeof(struct sockaddr_in6)); |
| 610 | addr = &ctx->cm_id->route.addr.dst_addr; | 608 | addr = (struct sockaddr *) &ctx->cm_id->route.addr.dst_addr; |
| 611 | memcpy(&resp.dst_addr, addr, addr->sa_family == AF_INET ? | 609 | memcpy(&resp.dst_addr, addr, addr->sa_family == AF_INET ? |
| 612 | sizeof(struct sockaddr_in) : | 610 | sizeof(struct sockaddr_in) : |
| 613 | sizeof(struct sockaddr_in6)); | 611 | sizeof(struct sockaddr_in6)); |
| @@ -913,7 +911,7 @@ static ssize_t ucma_join_multicast(struct ucma_file *file, | |||
| 913 | 911 | ||
| 914 | mc->uid = cmd.uid; | 912 | mc->uid = cmd.uid; |
| 915 | memcpy(&mc->addr, &cmd.addr, sizeof cmd.addr); | 913 | memcpy(&mc->addr, &cmd.addr, sizeof cmd.addr); |
| 916 | ret = rdma_join_multicast(ctx->cm_id, &mc->addr, mc); | 914 | ret = rdma_join_multicast(ctx->cm_id, (struct sockaddr *) &mc->addr, mc); |
| 917 | if (ret) | 915 | if (ret) |
| 918 | goto err2; | 916 | goto err2; |
| 919 | 917 | ||
| @@ -929,7 +927,7 @@ static ssize_t ucma_join_multicast(struct ucma_file *file, | |||
| 929 | return 0; | 927 | return 0; |
| 930 | 928 | ||
| 931 | err3: | 929 | err3: |
| 932 | rdma_leave_multicast(ctx->cm_id, &mc->addr); | 930 | rdma_leave_multicast(ctx->cm_id, (struct sockaddr *) &mc->addr); |
| 933 | ucma_cleanup_mc_events(mc); | 931 | ucma_cleanup_mc_events(mc); |
| 934 | err2: | 932 | err2: |
| 935 | mutex_lock(&mut); | 933 | mutex_lock(&mut); |
| @@ -975,7 +973,7 @@ static ssize_t ucma_leave_multicast(struct ucma_file *file, | |||
| 975 | goto out; | 973 | goto out; |
| 976 | } | 974 | } |
| 977 | 975 | ||
| 978 | rdma_leave_multicast(mc->ctx->cm_id, &mc->addr); | 976 | rdma_leave_multicast(mc->ctx->cm_id, (struct sockaddr *) &mc->addr); |
| 979 | mutex_lock(&mc->ctx->file->mut); | 977 | mutex_lock(&mc->ctx->file->mut); |
| 980 | ucma_cleanup_mc_events(mc); | 978 | ucma_cleanup_mc_events(mc); |
| 981 | list_del(&mc->list); | 979 | list_del(&mc->list); |
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c index f6d5747153a5..4dcf08b3fd83 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.c +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c | |||
| @@ -725,9 +725,9 @@ static int __cxio_tpt_op(struct cxio_rdev *rdev_p, u32 reset_tpt_entry, | |||
| 725 | V_TPT_STAG_TYPE(type) | V_TPT_PDID(pdid)); | 725 | V_TPT_STAG_TYPE(type) | V_TPT_PDID(pdid)); |
| 726 | BUG_ON(page_size >= 28); | 726 | BUG_ON(page_size >= 28); |
| 727 | tpt.flags_pagesize_qpid = cpu_to_be32(V_TPT_PERM(perm) | | 727 | tpt.flags_pagesize_qpid = cpu_to_be32(V_TPT_PERM(perm) | |
| 728 | F_TPT_MW_BIND_ENABLE | | 728 | ((perm & TPT_MW_BIND) ? F_TPT_MW_BIND_ENABLE : 0) | |
| 729 | V_TPT_ADDR_TYPE((zbva ? TPT_ZBTO : TPT_VATO)) | | 729 | V_TPT_ADDR_TYPE((zbva ? TPT_ZBTO : TPT_VATO)) | |
| 730 | V_TPT_PAGE_SIZE(page_size)); | 730 | V_TPT_PAGE_SIZE(page_size)); |
| 731 | tpt.rsvd_pbl_addr = reset_tpt_entry ? 0 : | 731 | tpt.rsvd_pbl_addr = reset_tpt_entry ? 0 : |
| 732 | cpu_to_be32(V_TPT_PBL_ADDR(PBL_OFF(rdev_p, pbl_addr)>>3)); | 732 | cpu_to_be32(V_TPT_PBL_ADDR(PBL_OFF(rdev_p, pbl_addr)>>3)); |
| 733 | tpt.len = cpu_to_be32(len); | 733 | tpt.len = cpu_to_be32(len); |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index b89640aa6e10..eb778bfd6f66 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c | |||
| @@ -1187,28 +1187,6 @@ static ssize_t show_rev(struct device *dev, struct device_attribute *attr, | |||
| 1187 | return sprintf(buf, "%d\n", iwch_dev->rdev.t3cdev_p->type); | 1187 | return sprintf(buf, "%d\n", iwch_dev->rdev.t3cdev_p->type); |
| 1188 | } | 1188 | } |
| 1189 | 1189 | ||
| 1190 | static int fw_supports_fastreg(struct iwch_dev *iwch_dev) | ||
| 1191 | { | ||
| 1192 | struct ethtool_drvinfo info; | ||
| 1193 | struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev; | ||
| 1194 | char *cp, *next; | ||
| 1195 | unsigned fw_maj, fw_min; | ||
| 1196 | |||
| 1197 | rtnl_lock(); | ||
| 1198 | lldev->ethtool_ops->get_drvinfo(lldev, &info); | ||
| 1199 | rtnl_unlock(); | ||
| 1200 | |||
| 1201 | next = info.fw_version+1; | ||
| 1202 | cp = strsep(&next, "."); | ||
| 1203 | sscanf(cp, "%i", &fw_maj); | ||
| 1204 | cp = strsep(&next, "."); | ||
| 1205 | sscanf(cp, "%i", &fw_min); | ||
| 1206 | |||
| 1207 | PDBG("%s maj %u min %u\n", __func__, fw_maj, fw_min); | ||
| 1208 | |||
| 1209 | return fw_maj > 6 || (fw_maj == 6 && fw_min > 0); | ||
| 1210 | } | ||
| 1211 | |||
| 1212 | static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr, char *buf) | 1190 | static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr, char *buf) |
| 1213 | { | 1191 | { |
| 1214 | struct iwch_dev *iwch_dev = container_of(dev, struct iwch_dev, | 1192 | struct iwch_dev *iwch_dev = container_of(dev, struct iwch_dev, |
| @@ -1325,12 +1303,12 @@ int iwch_register_device(struct iwch_dev *dev) | |||
| 1325 | memset(&dev->ibdev.node_guid, 0, sizeof(dev->ibdev.node_guid)); | 1303 | memset(&dev->ibdev.node_guid, 0, sizeof(dev->ibdev.node_guid)); |
| 1326 | memcpy(&dev->ibdev.node_guid, dev->rdev.t3cdev_p->lldev->dev_addr, 6); | 1304 | memcpy(&dev->ibdev.node_guid, dev->rdev.t3cdev_p->lldev->dev_addr, 6); |
| 1327 | dev->ibdev.owner = THIS_MODULE; | 1305 | dev->ibdev.owner = THIS_MODULE; |
| 1328 | dev->device_cap_flags = IB_DEVICE_LOCAL_DMA_LKEY | IB_DEVICE_MEM_WINDOW; | 1306 | dev->device_cap_flags = IB_DEVICE_LOCAL_DMA_LKEY | |
| 1307 | IB_DEVICE_MEM_WINDOW | | ||
| 1308 | IB_DEVICE_MEM_MGT_EXTENSIONS; | ||
| 1329 | 1309 | ||
| 1330 | /* cxgb3 supports STag 0. */ | 1310 | /* cxgb3 supports STag 0. */ |
| 1331 | dev->ibdev.local_dma_lkey = 0; | 1311 | dev->ibdev.local_dma_lkey = 0; |
| 1332 | if (fw_supports_fastreg(dev)) | ||
| 1333 | dev->device_cap_flags |= IB_DEVICE_MEM_MGT_EXTENSIONS; | ||
| 1334 | 1312 | ||
| 1335 | dev->ibdev.uverbs_cmd_mask = | 1313 | dev->ibdev.uverbs_cmd_mask = |
| 1336 | (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) | | 1314 | (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) | |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.h b/drivers/infiniband/hw/cxgb3/iwch_provider.h index f5ceca05c435..a237d49bdcc9 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.h +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.h | |||
| @@ -293,9 +293,16 @@ static inline u32 iwch_ib_to_tpt_access(int acc) | |||
| 293 | return (acc & IB_ACCESS_REMOTE_WRITE ? TPT_REMOTE_WRITE : 0) | | 293 | return (acc & IB_ACCESS_REMOTE_WRITE ? TPT_REMOTE_WRITE : 0) | |
| 294 | (acc & IB_ACCESS_REMOTE_READ ? TPT_REMOTE_READ : 0) | | 294 | (acc & IB_ACCESS_REMOTE_READ ? TPT_REMOTE_READ : 0) | |
| 295 | (acc & IB_ACCESS_LOCAL_WRITE ? TPT_LOCAL_WRITE : 0) | | 295 | (acc & IB_ACCESS_LOCAL_WRITE ? TPT_LOCAL_WRITE : 0) | |
| 296 | (acc & IB_ACCESS_MW_BIND ? TPT_MW_BIND : 0) | | ||
| 296 | TPT_LOCAL_READ; | 297 | TPT_LOCAL_READ; |
| 297 | } | 298 | } |
| 298 | 299 | ||
| 300 | static inline u32 iwch_ib_to_tpt_bind_access(int acc) | ||
| 301 | { | ||
| 302 | return (acc & IB_ACCESS_REMOTE_WRITE ? TPT_REMOTE_WRITE : 0) | | ||
| 303 | (acc & IB_ACCESS_REMOTE_READ ? TPT_REMOTE_READ : 0); | ||
| 304 | } | ||
| 305 | |||
| 299 | enum iwch_mmid_state { | 306 | enum iwch_mmid_state { |
| 300 | IWCH_STAG_STATE_VALID, | 307 | IWCH_STAG_STATE_VALID, |
| 301 | IWCH_STAG_STATE_INVALID | 308 | IWCH_STAG_STATE_INVALID |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c index 9a3be3a9d5dc..3e4585c2318a 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_qp.c +++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c | |||
| @@ -565,7 +565,7 @@ int iwch_bind_mw(struct ib_qp *qp, | |||
| 565 | wqe->bind.type = TPT_VATO; | 565 | wqe->bind.type = TPT_VATO; |
| 566 | 566 | ||
| 567 | /* TBD: check perms */ | 567 | /* TBD: check perms */ |
| 568 | wqe->bind.perms = iwch_ib_to_tpt_access(mw_bind->mw_access_flags); | 568 | wqe->bind.perms = iwch_ib_to_tpt_bind_access(mw_bind->mw_access_flags); |
| 569 | wqe->bind.mr_stag = cpu_to_be32(mw_bind->mr->lkey); | 569 | wqe->bind.mr_stag = cpu_to_be32(mw_bind->mr->lkey); |
| 570 | wqe->bind.mw_stag = cpu_to_be32(mw->rkey); | 570 | wqe->bind.mw_stag = cpu_to_be32(mw->rkey); |
| 571 | wqe->bind.mw_len = cpu_to_be32(mw_bind->length); | 571 | wqe->bind.mw_len = cpu_to_be32(mw_bind->length); |
| @@ -879,20 +879,13 @@ static int rdma_init(struct iwch_dev *rhp, struct iwch_qp *qhp, | |||
| 879 | (qhp->attr.mpa_attr.xmit_marker_enabled << 1) | | 879 | (qhp->attr.mpa_attr.xmit_marker_enabled << 1) | |
| 880 | (qhp->attr.mpa_attr.crc_enabled << 2); | 880 | (qhp->attr.mpa_attr.crc_enabled << 2); |
| 881 | 881 | ||
| 882 | /* | 882 | init_attr.qpcaps = uP_RI_QP_RDMA_READ_ENABLE | |
| 883 | * XXX - The IWCM doesn't quite handle getting these | 883 | uP_RI_QP_RDMA_WRITE_ENABLE | |
| 884 | * attrs set before going into RTS. For now, just turn | 884 | uP_RI_QP_BIND_ENABLE; |
| 885 | * them on always... | 885 | if (!qhp->ibqp.uobject) |
| 886 | */ | 886 | init_attr.qpcaps |= uP_RI_QP_STAG0_ENABLE | |
| 887 | #if 0 | 887 | uP_RI_QP_FAST_REGISTER_ENABLE; |
| 888 | init_attr.qpcaps = qhp->attr.enableRdmaRead | | 888 | |
| 889 | (qhp->attr.enableRdmaWrite << 1) | | ||
| 890 | (qhp->attr.enableBind << 2) | | ||
| 891 | (qhp->attr.enable_stag0_fastreg << 3) | | ||
| 892 | (qhp->attr.enable_stag0_fastreg << 4); | ||
| 893 | #else | ||
| 894 | init_attr.qpcaps = 0x1f; | ||
| 895 | #endif | ||
| 896 | init_attr.tcp_emss = qhp->ep->emss; | 889 | init_attr.tcp_emss = qhp->ep->emss; |
| 897 | init_attr.ord = qhp->attr.max_ord; | 890 | init_attr.ord = qhp->attr.max_ord; |
| 898 | init_attr.ird = qhp->attr.max_ird; | 891 | init_attr.ird = qhp->attr.max_ird; |
| @@ -900,8 +893,6 @@ static int rdma_init(struct iwch_dev *rhp, struct iwch_qp *qhp, | |||
| 900 | init_attr.qp_dma_size = (1UL << qhp->wq.size_log2); | 893 | init_attr.qp_dma_size = (1UL << qhp->wq.size_log2); |
| 901 | init_attr.rqe_count = iwch_rqes_posted(qhp); | 894 | init_attr.rqe_count = iwch_rqes_posted(qhp); |
| 902 | init_attr.flags = qhp->attr.mpa_attr.initiator ? MPA_INITIATOR : 0; | 895 | init_attr.flags = qhp->attr.mpa_attr.initiator ? MPA_INITIATOR : 0; |
| 903 | if (!qhp->ibqp.uobject) | ||
| 904 | init_attr.flags |= PRIV_QP; | ||
| 905 | if (peer2peer) { | 896 | if (peer2peer) { |
| 906 | init_attr.rtr_type = RTR_READ; | 897 | init_attr.rtr_type = RTR_READ; |
| 907 | if (init_attr.ord == 0 && qhp->attr.mpa_attr.initiator) | 898 | if (init_attr.ord == 0 && qhp->attr.mpa_attr.initiator) |
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index daad09a45910..ad0aab60b051 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c | |||
| @@ -1259,7 +1259,7 @@ reloop: | |||
| 1259 | */ | 1259 | */ |
| 1260 | ipath_cdbg(ERRPKT, "Error Pkt, but no eflags! egrbuf" | 1260 | ipath_cdbg(ERRPKT, "Error Pkt, but no eflags! egrbuf" |
| 1261 | " %x, len %x hdrq+%x rhf: %Lx\n", | 1261 | " %x, len %x hdrq+%x rhf: %Lx\n", |
| 1262 | etail, tlen, l, | 1262 | etail, tlen, l, (unsigned long long) |
| 1263 | le64_to_cpu(*(__le64 *) rhf_addr)); | 1263 | le64_to_cpu(*(__le64 *) rhf_addr)); |
| 1264 | if (ipath_debug & __IPATH_ERRPKTDBG) { | 1264 | if (ipath_debug & __IPATH_ERRPKTDBG) { |
| 1265 | u32 j, *d, dw = rsize-2; | 1265 | u32 j, *d, dw = rsize-2; |
| @@ -1457,7 +1457,8 @@ static void ipath_reset_availshadow(struct ipath_devdata *dd) | |||
| 1457 | 0xaaaaaaaaaaaaaaaaULL); /* All BUSY bits in qword */ | 1457 | 0xaaaaaaaaaaaaaaaaULL); /* All BUSY bits in qword */ |
| 1458 | if (oldval != dd->ipath_pioavailshadow[i]) | 1458 | if (oldval != dd->ipath_pioavailshadow[i]) |
| 1459 | ipath_dbg("shadow[%d] was %Lx, now %lx\n", | 1459 | ipath_dbg("shadow[%d] was %Lx, now %lx\n", |
| 1460 | i, oldval, dd->ipath_pioavailshadow[i]); | 1460 | i, (unsigned long long) oldval, |
| 1461 | dd->ipath_pioavailshadow[i]); | ||
| 1461 | } | 1462 | } |
| 1462 | spin_unlock_irqrestore(&ipath_pioavail_lock, flags); | 1463 | spin_unlock_irqrestore(&ipath_pioavail_lock, flags); |
| 1463 | } | 1464 | } |
diff --git a/drivers/infiniband/hw/ipath/ipath_iba7220.c b/drivers/infiniband/hw/ipath/ipath_iba7220.c index fadbfbf55a6a..d90f5e9a54fa 100644 --- a/drivers/infiniband/hw/ipath/ipath_iba7220.c +++ b/drivers/infiniband/hw/ipath/ipath_iba7220.c | |||
| @@ -1032,7 +1032,7 @@ static int ipath_7220_bringup_serdes(struct ipath_devdata *dd) | |||
| 1032 | ipath_cdbg(VERBOSE, "done: xgxs=%llx from %llx\n", | 1032 | ipath_cdbg(VERBOSE, "done: xgxs=%llx from %llx\n", |
| 1033 | (unsigned long long) | 1033 | (unsigned long long) |
| 1034 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig), | 1034 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig), |
| 1035 | prev_val); | 1035 | (unsigned long long) prev_val); |
| 1036 | 1036 | ||
| 1037 | guid = be64_to_cpu(dd->ipath_guid); | 1037 | guid = be64_to_cpu(dd->ipath_guid); |
| 1038 | 1038 | ||
| @@ -1042,7 +1042,8 @@ static int ipath_7220_bringup_serdes(struct ipath_devdata *dd) | |||
| 1042 | ipath_dbg("No GUID for heartbeat, faking %llx\n", | 1042 | ipath_dbg("No GUID for heartbeat, faking %llx\n", |
| 1043 | (unsigned long long)guid); | 1043 | (unsigned long long)guid); |
| 1044 | } else | 1044 | } else |
| 1045 | ipath_cdbg(VERBOSE, "Wrote %llX to HRTBT_GUID\n", guid); | 1045 | ipath_cdbg(VERBOSE, "Wrote %llX to HRTBT_GUID\n", |
| 1046 | (unsigned long long) guid); | ||
| 1046 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hrtbt_guid, guid); | 1047 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hrtbt_guid, guid); |
| 1047 | return ret; | 1048 | return ret; |
| 1048 | } | 1049 | } |
| @@ -2505,7 +2506,7 @@ done: | |||
| 2505 | if (dd->ipath_flags & IPATH_IB_AUTONEG_INPROG) { | 2506 | if (dd->ipath_flags & IPATH_IB_AUTONEG_INPROG) { |
| 2506 | ipath_dbg("Did not get to DDR INIT (%x) after %Lu msecs\n", | 2507 | ipath_dbg("Did not get to DDR INIT (%x) after %Lu msecs\n", |
| 2507 | ipath_ib_state(dd, dd->ipath_lastibcstat), | 2508 | ipath_ib_state(dd, dd->ipath_lastibcstat), |
| 2508 | jiffies_to_msecs(jiffies)-startms); | 2509 | (unsigned long long) jiffies_to_msecs(jiffies)-startms); |
| 2509 | dd->ipath_flags &= ~IPATH_IB_AUTONEG_INPROG; | 2510 | dd->ipath_flags &= ~IPATH_IB_AUTONEG_INPROG; |
| 2510 | if (dd->ipath_autoneg_tries == IPATH_AUTONEG_TRIES) { | 2511 | if (dd->ipath_autoneg_tries == IPATH_AUTONEG_TRIES) { |
| 2511 | dd->ipath_flags |= IPATH_IB_AUTONEG_FAILED; | 2512 | dd->ipath_flags |= IPATH_IB_AUTONEG_FAILED; |
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c index 26900b3b7a4e..6c21b4b5ec71 100644 --- a/drivers/infiniband/hw/ipath/ipath_intr.c +++ b/drivers/infiniband/hw/ipath/ipath_intr.c | |||
| @@ -356,9 +356,10 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd, | |||
| 356 | dd->ipath_cregs->cr_iblinkerrrecovcnt); | 356 | dd->ipath_cregs->cr_iblinkerrrecovcnt); |
| 357 | if (linkrecov != dd->ipath_lastlinkrecov) { | 357 | if (linkrecov != dd->ipath_lastlinkrecov) { |
| 358 | ipath_dbg("IB linkrecov up %Lx (%s %s) recov %Lu\n", | 358 | ipath_dbg("IB linkrecov up %Lx (%s %s) recov %Lu\n", |
| 359 | ibcs, ib_linkstate(dd, ibcs), | 359 | (unsigned long long) ibcs, |
| 360 | ib_linkstate(dd, ibcs), | ||
| 360 | ipath_ibcstatus_str[ltstate], | 361 | ipath_ibcstatus_str[ltstate], |
| 361 | linkrecov); | 362 | (unsigned long long) linkrecov); |
| 362 | /* and no more until active again */ | 363 | /* and no more until active again */ |
| 363 | dd->ipath_lastlinkrecov = 0; | 364 | dd->ipath_lastlinkrecov = 0; |
| 364 | ipath_set_linkstate(dd, IPATH_IB_LINKDOWN); | 365 | ipath_set_linkstate(dd, IPATH_IB_LINKDOWN); |
| @@ -1118,9 +1119,11 @@ irqreturn_t ipath_intr(int irq, void *data) | |||
| 1118 | if (unlikely(istat & ~dd->ipath_i_bitsextant)) | 1119 | if (unlikely(istat & ~dd->ipath_i_bitsextant)) |
| 1119 | ipath_dev_err(dd, | 1120 | ipath_dev_err(dd, |
| 1120 | "interrupt with unknown interrupts %Lx set\n", | 1121 | "interrupt with unknown interrupts %Lx set\n", |
| 1122 | (unsigned long long) | ||
| 1121 | istat & ~dd->ipath_i_bitsextant); | 1123 | istat & ~dd->ipath_i_bitsextant); |
| 1122 | else if (istat & ~INFINIPATH_I_ERROR) /* errors do own printing */ | 1124 | else if (istat & ~INFINIPATH_I_ERROR) /* errors do own printing */ |
| 1123 | ipath_cdbg(VERBOSE, "intr stat=0x%Lx\n", istat); | 1125 | ipath_cdbg(VERBOSE, "intr stat=0x%Lx\n", |
| 1126 | (unsigned long long) istat); | ||
| 1124 | 1127 | ||
| 1125 | if (istat & INFINIPATH_I_ERROR) { | 1128 | if (istat & INFINIPATH_I_ERROR) { |
| 1126 | ipath_stats.sps_errints++; | 1129 | ipath_stats.sps_errints++; |
| @@ -1128,7 +1131,8 @@ irqreturn_t ipath_intr(int irq, void *data) | |||
| 1128 | dd->ipath_kregs->kr_errorstatus); | 1131 | dd->ipath_kregs->kr_errorstatus); |
| 1129 | if (!estat) | 1132 | if (!estat) |
| 1130 | dev_info(&dd->pcidev->dev, "error interrupt (%Lx), " | 1133 | dev_info(&dd->pcidev->dev, "error interrupt (%Lx), " |
| 1131 | "but no error bits set!\n", istat); | 1134 | "but no error bits set!\n", |
| 1135 | (unsigned long long) istat); | ||
| 1132 | else if (estat == -1LL) | 1136 | else if (estat == -1LL) |
| 1133 | /* | 1137 | /* |
| 1134 | * should we try clearing all, or hope next read | 1138 | * should we try clearing all, or hope next read |
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c index 55c718828826..b766e40e9ebf 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs.c +++ b/drivers/infiniband/hw/ipath/ipath_verbs.c | |||
| @@ -1021,7 +1021,7 @@ static void sdma_complete(void *cookie, int status) | |||
| 1021 | struct ipath_verbs_txreq *tx = cookie; | 1021 | struct ipath_verbs_txreq *tx = cookie; |
| 1022 | struct ipath_qp *qp = tx->qp; | 1022 | struct ipath_qp *qp = tx->qp; |
| 1023 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); | 1023 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); |
| 1024 | unsigned int flags; | 1024 | unsigned long flags; |
| 1025 | enum ib_wc_status ibs = status == IPATH_SDMA_TXREQ_S_OK ? | 1025 | enum ib_wc_status ibs = status == IPATH_SDMA_TXREQ_S_OK ? |
| 1026 | IB_WC_SUCCESS : IB_WC_WR_FLUSH_ERR; | 1026 | IB_WC_SUCCESS : IB_WC_WR_FLUSH_ERR; |
| 1027 | 1027 | ||
| @@ -1051,7 +1051,7 @@ static void sdma_complete(void *cookie, int status) | |||
| 1051 | 1051 | ||
| 1052 | static void decrement_dma_busy(struct ipath_qp *qp) | 1052 | static void decrement_dma_busy(struct ipath_qp *qp) |
| 1053 | { | 1053 | { |
| 1054 | unsigned int flags; | 1054 | unsigned long flags; |
| 1055 | 1055 | ||
| 1056 | if (atomic_dec_and_test(&qp->s_dma_busy)) { | 1056 | if (atomic_dec_and_test(&qp->s_dma_busy)) { |
| 1057 | spin_lock_irqsave(&qp->s_lock, flags); | 1057 | spin_lock_irqsave(&qp->s_lock, flags); |
| @@ -1221,7 +1221,7 @@ static int ipath_verbs_send_pio(struct ipath_qp *qp, | |||
| 1221 | unsigned flush_wc; | 1221 | unsigned flush_wc; |
| 1222 | u32 control; | 1222 | u32 control; |
| 1223 | int ret; | 1223 | int ret; |
| 1224 | unsigned int flags; | 1224 | unsigned long flags; |
| 1225 | 1225 | ||
| 1226 | piobuf = ipath_getpiobuf(dd, plen, NULL); | 1226 | piobuf = ipath_getpiobuf(dd, plen, NULL); |
| 1227 | if (unlikely(piobuf == NULL)) { | 1227 | if (unlikely(piobuf == NULL)) { |
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c index a1464574bfdd..d0866a3636e2 100644 --- a/drivers/infiniband/hw/mlx4/cq.c +++ b/drivers/infiniband/hw/mlx4/cq.c | |||
| @@ -515,17 +515,17 @@ static void mlx4_ib_handle_error_cqe(struct mlx4_err_cqe *cqe, | |||
| 515 | wc->vendor_err = cqe->vendor_err_syndrome; | 515 | wc->vendor_err = cqe->vendor_err_syndrome; |
| 516 | } | 516 | } |
| 517 | 517 | ||
| 518 | static int mlx4_ib_ipoib_csum_ok(__be32 status, __be16 checksum) | 518 | static int mlx4_ib_ipoib_csum_ok(__be16 status, __be16 checksum) |
| 519 | { | 519 | { |
| 520 | return ((status & cpu_to_be32(MLX4_CQE_IPOIB_STATUS_IPV4 | | 520 | return ((status & cpu_to_be16(MLX4_CQE_STATUS_IPV4 | |
| 521 | MLX4_CQE_IPOIB_STATUS_IPV4F | | 521 | MLX4_CQE_STATUS_IPV4F | |
| 522 | MLX4_CQE_IPOIB_STATUS_IPV4OPT | | 522 | MLX4_CQE_STATUS_IPV4OPT | |
| 523 | MLX4_CQE_IPOIB_STATUS_IPV6 | | 523 | MLX4_CQE_STATUS_IPV6 | |
| 524 | MLX4_CQE_IPOIB_STATUS_IPOK)) == | 524 | MLX4_CQE_STATUS_IPOK)) == |
| 525 | cpu_to_be32(MLX4_CQE_IPOIB_STATUS_IPV4 | | 525 | cpu_to_be16(MLX4_CQE_STATUS_IPV4 | |
| 526 | MLX4_CQE_IPOIB_STATUS_IPOK)) && | 526 | MLX4_CQE_STATUS_IPOK)) && |
| 527 | (status & cpu_to_be32(MLX4_CQE_IPOIB_STATUS_UDP | | 527 | (status & cpu_to_be16(MLX4_CQE_STATUS_UDP | |
| 528 | MLX4_CQE_IPOIB_STATUS_TCP)) && | 528 | MLX4_CQE_STATUS_TCP)) && |
| 529 | checksum == cpu_to_be16(0xffff); | 529 | checksum == cpu_to_be16(0xffff); |
| 530 | } | 530 | } |
| 531 | 531 | ||
| @@ -582,17 +582,17 @@ repoll: | |||
| 582 | } | 582 | } |
| 583 | 583 | ||
| 584 | if (!*cur_qp || | 584 | if (!*cur_qp || |
| 585 | (be32_to_cpu(cqe->my_qpn) & 0xffffff) != (*cur_qp)->mqp.qpn) { | 585 | (be32_to_cpu(cqe->vlan_my_qpn) & MLX4_CQE_QPN_MASK) != (*cur_qp)->mqp.qpn) { |
| 586 | /* | 586 | /* |
| 587 | * We do not have to take the QP table lock here, | 587 | * We do not have to take the QP table lock here, |
| 588 | * because CQs will be locked while QPs are removed | 588 | * because CQs will be locked while QPs are removed |
| 589 | * from the table. | 589 | * from the table. |
| 590 | */ | 590 | */ |
| 591 | mqp = __mlx4_qp_lookup(to_mdev(cq->ibcq.device)->dev, | 591 | mqp = __mlx4_qp_lookup(to_mdev(cq->ibcq.device)->dev, |
| 592 | be32_to_cpu(cqe->my_qpn)); | 592 | be32_to_cpu(cqe->vlan_my_qpn)); |
| 593 | if (unlikely(!mqp)) { | 593 | if (unlikely(!mqp)) { |
| 594 | printk(KERN_WARNING "CQ %06x with entry for unknown QPN %06x\n", | 594 | printk(KERN_WARNING "CQ %06x with entry for unknown QPN %06x\n", |
| 595 | cq->mcq.cqn, be32_to_cpu(cqe->my_qpn) & 0xffffff); | 595 | cq->mcq.cqn, be32_to_cpu(cqe->vlan_my_qpn) & MLX4_CQE_QPN_MASK); |
| 596 | return -EINVAL; | 596 | return -EINVAL; |
| 597 | } | 597 | } |
| 598 | 598 | ||
| @@ -692,14 +692,13 @@ repoll: | |||
| 692 | } | 692 | } |
| 693 | 693 | ||
| 694 | wc->slid = be16_to_cpu(cqe->rlid); | 694 | wc->slid = be16_to_cpu(cqe->rlid); |
| 695 | wc->sl = cqe->sl >> 4; | 695 | wc->sl = be16_to_cpu(cqe->sl_vid >> 12); |
| 696 | g_mlpath_rqpn = be32_to_cpu(cqe->g_mlpath_rqpn); | 696 | g_mlpath_rqpn = be32_to_cpu(cqe->g_mlpath_rqpn); |
| 697 | wc->src_qp = g_mlpath_rqpn & 0xffffff; | 697 | wc->src_qp = g_mlpath_rqpn & 0xffffff; |
| 698 | wc->dlid_path_bits = (g_mlpath_rqpn >> 24) & 0x7f; | 698 | wc->dlid_path_bits = (g_mlpath_rqpn >> 24) & 0x7f; |
| 699 | wc->wc_flags |= g_mlpath_rqpn & 0x80000000 ? IB_WC_GRH : 0; | 699 | wc->wc_flags |= g_mlpath_rqpn & 0x80000000 ? IB_WC_GRH : 0; |
| 700 | wc->pkey_index = be32_to_cpu(cqe->immed_rss_invalid) & 0x7f; | 700 | wc->pkey_index = be32_to_cpu(cqe->immed_rss_invalid) & 0x7f; |
| 701 | wc->csum_ok = mlx4_ib_ipoib_csum_ok(cqe->ipoib_status, | 701 | wc->csum_ok = mlx4_ib_ipoib_csum_ok(cqe->status, cqe->checksum); |
| 702 | cqe->checksum); | ||
| 703 | } | 702 | } |
| 704 | 703 | ||
| 705 | return 0; | 704 | return 0; |
| @@ -767,7 +766,7 @@ void __mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq) | |||
| 767 | */ | 766 | */ |
| 768 | while ((int) --prod_index - (int) cq->mcq.cons_index >= 0) { | 767 | while ((int) --prod_index - (int) cq->mcq.cons_index >= 0) { |
| 769 | cqe = get_cqe(cq, prod_index & cq->ibcq.cqe); | 768 | cqe = get_cqe(cq, prod_index & cq->ibcq.cqe); |
| 770 | if ((be32_to_cpu(cqe->my_qpn) & 0xffffff) == qpn) { | 769 | if ((be32_to_cpu(cqe->vlan_my_qpn) & MLX4_CQE_QPN_MASK) == qpn) { |
| 771 | if (srq && !(cqe->owner_sr_opcode & MLX4_CQE_IS_SEND_MASK)) | 770 | if (srq && !(cqe->owner_sr_opcode & MLX4_CQE_IS_SEND_MASK)) |
| 772 | mlx4_ib_free_srq_wqe(srq, be16_to_cpu(cqe->wqe_index)); | 771 | mlx4_ib_free_srq_wqe(srq, be16_to_cpu(cqe->wqe_index)); |
| 773 | ++nfreed; | 772 | ++nfreed; |
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index f7bc7dd8578a..f29dbb767e87 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c | |||
| @@ -902,7 +902,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, | |||
| 902 | context->mtu_msgmax = (IB_MTU_4096 << 5) | | 902 | context->mtu_msgmax = (IB_MTU_4096 << 5) | |
| 903 | ilog2(dev->dev->caps.max_gso_sz); | 903 | ilog2(dev->dev->caps.max_gso_sz); |
| 904 | else | 904 | else |
| 905 | context->mtu_msgmax = (IB_MTU_4096 << 5) | 11; | 905 | context->mtu_msgmax = (IB_MTU_4096 << 5) | 12; |
| 906 | } else if (attr_mask & IB_QP_PATH_MTU) { | 906 | } else if (attr_mask & IB_QP_PATH_MTU) { |
| 907 | if (attr->path_mtu < IB_MTU_256 || attr->path_mtu > IB_MTU_4096) { | 907 | if (attr->path_mtu < IB_MTU_256 || attr->path_mtu > IB_MTU_4096) { |
| 908 | printk(KERN_ERR "path MTU (%u) is invalid\n", | 908 | printk(KERN_ERR "path MTU (%u) is invalid\n", |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 0f2d3045061a..7ebc400a4b3d 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c | |||
| @@ -337,7 +337,7 @@ static void ipoib_cm_init_rx_wr(struct net_device *dev, | |||
| 337 | sge[i].length = PAGE_SIZE; | 337 | sge[i].length = PAGE_SIZE; |
| 338 | 338 | ||
| 339 | wr->next = NULL; | 339 | wr->next = NULL; |
| 340 | wr->sg_list = priv->cm.rx_sge; | 340 | wr->sg_list = sge; |
| 341 | wr->num_sge = priv->cm.num_frags; | 341 | wr->num_sge = priv->cm.num_frags; |
| 342 | } | 342 | } |
| 343 | 343 | ||
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index 578afce6884c..aaa0b6f0b521 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c | |||
| @@ -565,7 +565,8 @@ static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap) | |||
| 565 | 565 | ||
| 566 | static int dvico_bluebird_xc2028_callback(void *ptr, int command, int arg) | 566 | static int dvico_bluebird_xc2028_callback(void *ptr, int command, int arg) |
| 567 | { | 567 | { |
| 568 | struct dvb_usb_device *d = ptr; | 568 | struct dvb_usb_adapter *adap = ptr; |
| 569 | struct dvb_usb_device *d = adap->dev; | ||
| 569 | 570 | ||
| 570 | switch (command) { | 571 | switch (command) { |
| 571 | case XC2028_TUNER_RESET: | 572 | case XC2028_TUNER_RESET: |
| @@ -593,9 +594,9 @@ static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap) | |||
| 593 | .callback = dvico_bluebird_xc2028_callback, | 594 | .callback = dvico_bluebird_xc2028_callback, |
| 594 | }; | 595 | }; |
| 595 | static struct xc2028_ctrl ctl = { | 596 | static struct xc2028_ctrl ctl = { |
| 596 | .fname = "xc3028-dvico-au-01.fw", | 597 | .fname = "xc3028-v27.fw", |
| 597 | .max_len = 64, | 598 | .max_len = 64, |
| 598 | .scode_table = XC3028_FE_ZARLINK456, | 599 | .demod = XC3028_FE_ZARLINK456, |
| 599 | }; | 600 | }; |
| 600 | 601 | ||
| 601 | fe = dvb_attach(xc2028_attach, adap->fe, &cfg); | 602 | fe = dvb_attach(xc2028_attach, adap->fe, &cfg); |
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 574dffe91b68..7dbb4a223c99 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig | |||
| @@ -135,9 +135,8 @@ config DVB_CX22702 | |||
| 135 | 135 | ||
| 136 | config DVB_DRX397XD | 136 | config DVB_DRX397XD |
| 137 | tristate "Micronas DRX3975D/DRX3977D based" | 137 | tristate "Micronas DRX3975D/DRX3977D based" |
| 138 | depends on DVB_CORE && I2C && HOTPLUG | 138 | depends on DVB_CORE && I2C |
| 139 | default m if DVB_FE_CUSTOMISE | 139 | default m if DVB_FE_CUSTOMISE |
| 140 | select FW_LOADER | ||
| 141 | help | 140 | help |
| 142 | A DVB-T tuner module. Say Y when you want to support this frontend. | 141 | A DVB-T tuner module. Say Y when you want to support this frontend. |
| 143 | 142 | ||
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index d4a6e56a7135..ecbfa1b39b70 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
| @@ -630,7 +630,7 @@ config VIDEO_ZORAN_ZR36060 | |||
| 630 | depends on VIDEO_ZORAN | 630 | depends on VIDEO_ZORAN |
| 631 | help | 631 | help |
| 632 | Say Y to support Zoran boards based on 36060 chips. | 632 | Say Y to support Zoran boards based on 36060 chips. |
| 633 | This includes Iomega Bus, Pinnacle DC10, Linux media Labs 33 | 633 | This includes Iomega Buz, Pinnacle DC10, Linux media Labs 33 |
| 634 | and 33 R10 and AverMedia 6 boards. | 634 | and 33 R10 and AverMedia 6 boards. |
| 635 | 635 | ||
| 636 | config VIDEO_ZORAN_BUZ | 636 | config VIDEO_ZORAN_BUZ |
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c index 56ebfd5ef6fa..9e436ad3d34b 100644 --- a/drivers/media/video/arv.c +++ b/drivers/media/video/arv.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
| 30 | #include <linux/videodev.h> | 30 | #include <linux/videodev.h> |
| 31 | #include <media/v4l2-common.h> | 31 | #include <media/v4l2-common.h> |
| 32 | #include <media/v4l2-ioctl.h> | ||
| 32 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
| 33 | 34 | ||
| 34 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
| @@ -755,7 +756,6 @@ static const struct file_operations ar_fops = { | |||
| 755 | 756 | ||
| 756 | static struct video_device ar_template = { | 757 | static struct video_device ar_template = { |
| 757 | .name = "Colour AR VGA", | 758 | .name = "Colour AR VGA", |
| 758 | .type = VID_TYPE_CAPTURE, | ||
| 759 | .fops = &ar_fops, | 759 | .fops = &ar_fops, |
| 760 | .release = ar_release, | 760 | .release = ar_release, |
| 761 | .minor = -1, | 761 | .minor = -1, |
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 476ae44a62d2..452da70e719f 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
| @@ -1015,6 +1015,7 @@ struct em28xx_board em28xx_boards[] = { | |||
| 1015 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 1015 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
| 1016 | .vchannels = 3, | 1016 | .vchannels = 3, |
| 1017 | .tuner_type = TUNER_XC2028, | 1017 | .tuner_type = TUNER_XC2028, |
| 1018 | .mts_firmware = 1, | ||
| 1018 | .decoder = EM28XX_TVP5150, | 1019 | .decoder = EM28XX_TVP5150, |
| 1019 | .input = { { | 1020 | .input = { { |
| 1020 | .type = EM28XX_VMUX_TELEVISION, | 1021 | .type = EM28XX_VMUX_TELEVISION, |
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c index 44b0bffeb20e..cd3a3f5829b2 100644 --- a/drivers/media/video/gspca/conex.c +++ b/drivers/media/video/gspca/conex.c | |||
| @@ -123,7 +123,7 @@ static void reg_r(struct gspca_dev *gspca_dev, | |||
| 123 | { | 123 | { |
| 124 | struct usb_device *dev = gspca_dev->dev; | 124 | struct usb_device *dev = gspca_dev->dev; |
| 125 | 125 | ||
| 126 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 126 | #ifdef GSPCA_DEBUG |
| 127 | if (len > sizeof gspca_dev->usb_buf) { | 127 | if (len > sizeof gspca_dev->usb_buf) { |
| 128 | err("reg_r: buffer overflow"); | 128 | err("reg_r: buffer overflow"); |
| 129 | return; | 129 | return; |
| @@ -163,7 +163,7 @@ static void reg_w(struct gspca_dev *gspca_dev, | |||
| 163 | { | 163 | { |
| 164 | struct usb_device *dev = gspca_dev->dev; | 164 | struct usb_device *dev = gspca_dev->dev; |
| 165 | 165 | ||
| 166 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 166 | #ifdef GSPCA_DEBUG |
| 167 | if (len > sizeof gspca_dev->usb_buf) { | 167 | if (len > sizeof gspca_dev->usb_buf) { |
| 168 | err("reg_w: buffer overflow"); | 168 | err("reg_w: buffer overflow"); |
| 169 | return; | 169 | return; |
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c index c8c2f02fcf00..1dbe92d01e6a 100644 --- a/drivers/media/video/gspca/etoms.c +++ b/drivers/media/video/gspca/etoms.c | |||
| @@ -233,7 +233,7 @@ static void reg_r(struct gspca_dev *gspca_dev, | |||
| 233 | { | 233 | { |
| 234 | struct usb_device *dev = gspca_dev->dev; | 234 | struct usb_device *dev = gspca_dev->dev; |
| 235 | 235 | ||
| 236 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 236 | #ifdef GSPCA_DEBUG |
| 237 | if (len > sizeof gspca_dev->usb_buf) { | 237 | if (len > sizeof gspca_dev->usb_buf) { |
| 238 | err("reg_r: buffer overflow"); | 238 | err("reg_r: buffer overflow"); |
| 239 | return; | 239 | return; |
| @@ -271,7 +271,7 @@ static void reg_w(struct gspca_dev *gspca_dev, | |||
| 271 | { | 271 | { |
| 272 | struct usb_device *dev = gspca_dev->dev; | 272 | struct usb_device *dev = gspca_dev->dev; |
| 273 | 273 | ||
| 274 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 274 | #ifdef GSPCA_DEBUG |
| 275 | if (len > sizeof gspca_dev->usb_buf) { | 275 | if (len > sizeof gspca_dev->usb_buf) { |
| 276 | err("reg_w: buffer overflow"); | 276 | err("reg_w: buffer overflow"); |
| 277 | return; | 277 | return; |
| @@ -461,6 +461,52 @@ static void Et_init2(struct gspca_dev *gspca_dev) | |||
| 461 | reg_w_val(gspca_dev, 0x80, 0x20); /* 0x20; */ | 461 | reg_w_val(gspca_dev, 0x80, 0x20); /* 0x20; */ |
| 462 | } | 462 | } |
| 463 | 463 | ||
| 464 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
| 465 | { | ||
| 466 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 467 | int i; | ||
| 468 | __u8 brightness = sd->brightness; | ||
| 469 | |||
| 470 | for (i = 0; i < 4; i++) | ||
| 471 | reg_w_val(gspca_dev, ET_O_RED + i, brightness); | ||
| 472 | } | ||
| 473 | |||
| 474 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
| 475 | { | ||
| 476 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 477 | int i; | ||
| 478 | int brightness = 0; | ||
| 479 | |||
| 480 | for (i = 0; i < 4; i++) { | ||
| 481 | reg_r(gspca_dev, ET_O_RED + i, 1); | ||
| 482 | brightness += gspca_dev->usb_buf[0]; | ||
| 483 | } | ||
| 484 | sd->brightness = brightness >> 3; | ||
| 485 | } | ||
| 486 | |||
| 487 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
| 488 | { | ||
| 489 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 490 | __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; | ||
| 491 | __u8 contrast = sd->contrast; | ||
| 492 | |||
| 493 | memset(RGBG, contrast, sizeof(RGBG) - 2); | ||
| 494 | reg_w(gspca_dev, ET_G_RED, RGBG, 6); | ||
| 495 | } | ||
| 496 | |||
| 497 | static void getcontrast(struct gspca_dev *gspca_dev) | ||
| 498 | { | ||
| 499 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 500 | int i; | ||
| 501 | int contrast = 0; | ||
| 502 | |||
| 503 | for (i = 0; i < 4; i++) { | ||
| 504 | reg_r(gspca_dev, ET_G_RED + i, 1); | ||
| 505 | contrast += gspca_dev->usb_buf[0]; | ||
| 506 | } | ||
| 507 | sd->contrast = contrast >> 2; | ||
| 508 | } | ||
| 509 | |||
| 464 | static void setcolors(struct gspca_dev *gspca_dev) | 510 | static void setcolors(struct gspca_dev *gspca_dev) |
| 465 | { | 511 | { |
| 466 | struct sd *sd = (struct sd *) gspca_dev; | 512 | struct sd *sd = (struct sd *) gspca_dev; |
| @@ -492,6 +538,16 @@ static void getcolors(struct gspca_dev *gspca_dev) | |||
| 492 | } | 538 | } |
| 493 | } | 539 | } |
| 494 | 540 | ||
| 541 | static void setautogain(struct gspca_dev *gspca_dev) | ||
| 542 | { | ||
| 543 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 544 | |||
| 545 | if (sd->autogain) | ||
| 546 | sd->ag_cnt = AG_CNT_START; | ||
| 547 | else | ||
| 548 | sd->ag_cnt = -1; | ||
| 549 | } | ||
| 550 | |||
| 495 | static void Et_init1(struct gspca_dev *gspca_dev) | 551 | static void Et_init1(struct gspca_dev *gspca_dev) |
| 496 | { | 552 | { |
| 497 | __u8 value; | 553 | __u8 value; |
| @@ -614,6 +670,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
| 614 | sd->contrast = CONTRAST_DEF; | 670 | sd->contrast = CONTRAST_DEF; |
| 615 | sd->colors = COLOR_DEF; | 671 | sd->colors = COLOR_DEF; |
| 616 | sd->autogain = AUTOGAIN_DEF; | 672 | sd->autogain = AUTOGAIN_DEF; |
| 673 | sd->ag_cnt = -1; | ||
| 617 | return 0; | 674 | return 0; |
| 618 | } | 675 | } |
| 619 | 676 | ||
| @@ -641,6 +698,8 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
| 641 | else | 698 | else |
| 642 | Et_init2(gspca_dev); | 699 | Et_init2(gspca_dev); |
| 643 | 700 | ||
| 701 | setautogain(gspca_dev); | ||
| 702 | |||
| 644 | reg_w_val(gspca_dev, ET_RESET_ALL, 0x08); | 703 | reg_w_val(gspca_dev, ET_RESET_ALL, 0x08); |
| 645 | et_video(gspca_dev, 1); /* video on */ | 704 | et_video(gspca_dev, 1); /* video on */ |
| 646 | } | 705 | } |
| @@ -658,52 +717,6 @@ static void sd_close(struct gspca_dev *gspca_dev) | |||
| 658 | { | 717 | { |
| 659 | } | 718 | } |
| 660 | 719 | ||
| 661 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
| 662 | { | ||
| 663 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 664 | int i; | ||
| 665 | __u8 brightness = sd->brightness; | ||
| 666 | |||
| 667 | for (i = 0; i < 4; i++) | ||
| 668 | reg_w_val(gspca_dev, ET_O_RED + i, brightness); | ||
| 669 | } | ||
| 670 | |||
| 671 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
| 672 | { | ||
| 673 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 674 | int i; | ||
| 675 | int brightness = 0; | ||
| 676 | |||
| 677 | for (i = 0; i < 4; i++) { | ||
| 678 | reg_r(gspca_dev, ET_O_RED + i, 1); | ||
| 679 | brightness += gspca_dev->usb_buf[0]; | ||
| 680 | } | ||
| 681 | sd->brightness = brightness >> 3; | ||
| 682 | } | ||
| 683 | |||
| 684 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
| 685 | { | ||
| 686 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 687 | __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; | ||
| 688 | __u8 contrast = sd->contrast; | ||
| 689 | |||
| 690 | memset(RGBG, contrast, sizeof(RGBG) - 2); | ||
| 691 | reg_w(gspca_dev, ET_G_RED, RGBG, 6); | ||
| 692 | } | ||
| 693 | |||
| 694 | static void getcontrast(struct gspca_dev *gspca_dev) | ||
| 695 | { | ||
| 696 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 697 | int i; | ||
| 698 | int contrast = 0; | ||
| 699 | |||
| 700 | for (i = 0; i < 4; i++) { | ||
| 701 | reg_r(gspca_dev, ET_G_RED + i, 1); | ||
| 702 | contrast += gspca_dev->usb_buf[0]; | ||
| 703 | } | ||
| 704 | sd->contrast = contrast >> 2; | ||
| 705 | } | ||
| 706 | |||
| 707 | static __u8 Et_getgainG(struct gspca_dev *gspca_dev) | 720 | static __u8 Et_getgainG(struct gspca_dev *gspca_dev) |
| 708 | { | 721 | { |
| 709 | struct sd *sd = (struct sd *) gspca_dev; | 722 | struct sd *sd = (struct sd *) gspca_dev; |
| @@ -733,15 +746,22 @@ static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain) | |||
| 733 | #define LIMIT(color) \ | 746 | #define LIMIT(color) \ |
| 734 | (unsigned char)((color > 0xff)?0xff:((color < 0)?0:color)) | 747 | (unsigned char)((color > 0xff)?0xff:((color < 0)?0:color)) |
| 735 | 748 | ||
| 736 | static void setautogain(struct gspca_dev *gspca_dev) | 749 | static void do_autogain(struct gspca_dev *gspca_dev) |
| 737 | { | 750 | { |
| 738 | __u8 luma = 0; | 751 | struct sd *sd = (struct sd *) gspca_dev; |
| 752 | __u8 luma; | ||
| 739 | __u8 luma_mean = 128; | 753 | __u8 luma_mean = 128; |
| 740 | __u8 luma_delta = 20; | 754 | __u8 luma_delta = 20; |
| 741 | __u8 spring = 4; | 755 | __u8 spring = 4; |
| 742 | int Gbright = 0; | 756 | int Gbright; |
| 743 | __u8 r, g, b; | 757 | __u8 r, g, b; |
| 744 | 758 | ||
| 759 | if (sd->ag_cnt < 0) | ||
| 760 | return; | ||
| 761 | if (--sd->ag_cnt >= 0) | ||
| 762 | return; | ||
| 763 | sd->ag_cnt = AG_CNT_START; | ||
| 764 | |||
| 745 | Gbright = Et_getgainG(gspca_dev); | 765 | Gbright = Et_getgainG(gspca_dev); |
| 746 | reg_r(gspca_dev, ET_LUMA_CENTER, 4); | 766 | reg_r(gspca_dev, ET_LUMA_CENTER, 4); |
| 747 | g = (gspca_dev->usb_buf[0] + gspca_dev->usb_buf[3]) >> 1; | 767 | g = (gspca_dev->usb_buf[0] + gspca_dev->usb_buf[3]) >> 1; |
| @@ -768,7 +788,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
| 768 | __u8 *data, /* isoc packet */ | 788 | __u8 *data, /* isoc packet */ |
| 769 | int len) /* iso packet length */ | 789 | int len) /* iso packet length */ |
| 770 | { | 790 | { |
| 771 | struct sd *sd; | ||
| 772 | int seqframe; | 791 | int seqframe; |
| 773 | 792 | ||
| 774 | seqframe = data[0] & 0x3f; | 793 | seqframe = data[0] & 0x3f; |
| @@ -783,13 +802,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
| 783 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | 802 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, |
| 784 | data, 0); | 803 | data, 0); |
| 785 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); | 804 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); |
| 786 | sd = (struct sd *) gspca_dev; | ||
| 787 | if (sd->ag_cnt >= 0) { | ||
| 788 | if (--sd->ag_cnt < 0) { | ||
| 789 | sd->ag_cnt = AG_CNT_START; | ||
| 790 | setautogain(gspca_dev); | ||
| 791 | } | ||
| 792 | } | ||
| 793 | return; | 805 | return; |
| 794 | } | 806 | } |
| 795 | if (len) { | 807 | if (len) { |
| @@ -862,10 +874,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | |||
| 862 | struct sd *sd = (struct sd *) gspca_dev; | 874 | struct sd *sd = (struct sd *) gspca_dev; |
| 863 | 875 | ||
| 864 | sd->autogain = val; | 876 | sd->autogain = val; |
| 865 | if (val) | 877 | if (gspca_dev->streaming) |
| 866 | sd->ag_cnt = AG_CNT_START; | 878 | setautogain(gspca_dev); |
| 867 | else | ||
| 868 | sd->ag_cnt = -1; | ||
| 869 | return 0; | 879 | return 0; |
| 870 | } | 880 | } |
| 871 | 881 | ||
| @@ -889,6 +899,7 @@ static struct sd_desc sd_desc = { | |||
| 889 | .stop0 = sd_stop0, | 899 | .stop0 = sd_stop0, |
| 890 | .close = sd_close, | 900 | .close = sd_close, |
| 891 | .pkt_scan = sd_pkt_scan, | 901 | .pkt_scan = sd_pkt_scan, |
| 902 | .dq_callback = do_autogain, | ||
| 892 | }; | 903 | }; |
| 893 | 904 | ||
| 894 | /* -- module initialisation -- */ | 905 | /* -- module initialisation -- */ |
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 3a051c925ff6..15d302b28b79 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
| @@ -47,7 +47,7 @@ MODULE_LICENSE("GPL"); | |||
| 47 | 47 | ||
| 48 | static int video_nr = -1; | 48 | static int video_nr = -1; |
| 49 | 49 | ||
| 50 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 50 | #ifdef GSPCA_DEBUG |
| 51 | int gspca_debug = D_ERR | D_PROBE; | 51 | int gspca_debug = D_ERR | D_PROBE; |
| 52 | EXPORT_SYMBOL(gspca_debug); | 52 | EXPORT_SYMBOL(gspca_debug); |
| 53 | 53 | ||
| @@ -677,7 +677,7 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev, | |||
| 677 | w = fmt->fmt.pix.width; | 677 | w = fmt->fmt.pix.width; |
| 678 | h = fmt->fmt.pix.height; | 678 | h = fmt->fmt.pix.height; |
| 679 | 679 | ||
| 680 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 680 | #ifdef GSPCA_DEBUG |
| 681 | if (gspca_debug & D_CONF) | 681 | if (gspca_debug & D_CONF) |
| 682 | PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h); | 682 | PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h); |
| 683 | #endif | 683 | #endif |
| @@ -785,7 +785,7 @@ static int dev_open(struct inode *inode, struct file *file) | |||
| 785 | } | 785 | } |
| 786 | gspca_dev->users++; | 786 | gspca_dev->users++; |
| 787 | file->private_data = gspca_dev; | 787 | file->private_data = gspca_dev; |
| 788 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 788 | #ifdef GSPCA_DEBUG |
| 789 | /* activate the v4l2 debug */ | 789 | /* activate the v4l2 debug */ |
| 790 | if (gspca_debug & D_V4L2) | 790 | if (gspca_debug & D_V4L2) |
| 791 | gspca_dev->vdev.debug |= 3; | 791 | gspca_dev->vdev.debug |= 3; |
| @@ -904,7 +904,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
| 904 | if (ctrl->id != ctrls->qctrl.id) | 904 | if (ctrl->id != ctrls->qctrl.id) |
| 905 | continue; | 905 | continue; |
| 906 | if (ctrl->value < ctrls->qctrl.minimum | 906 | if (ctrl->value < ctrls->qctrl.minimum |
| 907 | && ctrl->value > ctrls->qctrl.maximum) | 907 | || ctrl->value > ctrls->qctrl.maximum) |
| 908 | return -ERANGE; | 908 | return -ERANGE; |
| 909 | PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); | 909 | PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); |
| 910 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 910 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
| @@ -1080,7 +1080,7 @@ static int vidioc_streamon(struct file *file, void *priv, | |||
| 1080 | if (ret < 0) | 1080 | if (ret < 0) |
| 1081 | goto out; | 1081 | goto out; |
| 1082 | } | 1082 | } |
| 1083 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1083 | #ifdef GSPCA_DEBUG |
| 1084 | if (gspca_debug & D_STREAM) { | 1084 | if (gspca_debug & D_STREAM) { |
| 1085 | PDEBUG_MODE("stream on OK", | 1085 | PDEBUG_MODE("stream on OK", |
| 1086 | gspca_dev->pixfmt, | 1086 | gspca_dev->pixfmt, |
| @@ -1913,7 +1913,7 @@ static void __exit gspca_exit(void) | |||
| 1913 | module_init(gspca_init); | 1913 | module_init(gspca_init); |
| 1914 | module_exit(gspca_exit); | 1914 | module_exit(gspca_exit); |
| 1915 | 1915 | ||
| 1916 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1916 | #ifdef GSPCA_DEBUG |
| 1917 | module_param_named(debug, gspca_debug, int, 0644); | 1917 | module_param_named(debug, gspca_debug, int, 0644); |
| 1918 | MODULE_PARM_DESC(debug, | 1918 | MODULE_PARM_DESC(debug, |
| 1919 | "Debug (bit) 0x01:error 0x02:probe 0x04:config" | 1919 | "Debug (bit) 0x01:error 0x02:probe 0x04:config" |
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 3fd2c4eee204..67e448940eaa 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h | |||
| @@ -9,7 +9,10 @@ | |||
| 9 | #include <media/v4l2-common.h> | 9 | #include <media/v4l2-common.h> |
| 10 | #include <linux/mutex.h> | 10 | #include <linux/mutex.h> |
| 11 | 11 | ||
| 12 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 12 | /* compilation option */ |
| 13 | #define GSPCA_DEBUG 1 | ||
| 14 | |||
| 15 | #ifdef GSPCA_DEBUG | ||
| 13 | /* GSPCA our debug messages */ | 16 | /* GSPCA our debug messages */ |
| 14 | extern int gspca_debug; | 17 | extern int gspca_debug; |
| 15 | #define PDEBUG(level, fmt, args...) \ | 18 | #define PDEBUG(level, fmt, args...) \ |
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index 83139efc4629..b4f00ec0885c 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c | |||
| @@ -40,14 +40,15 @@ struct sd { | |||
| 40 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 40 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
| 41 | 41 | ||
| 42 | /* Determined by sensor type */ | 42 | /* Determined by sensor type */ |
| 43 | short maxwidth; | 43 | char sif; |
| 44 | short maxheight; | ||
| 45 | 44 | ||
| 46 | unsigned char primary_i2c_slave; /* I2C write id of sensor */ | 45 | unsigned char primary_i2c_slave; /* I2C write id of sensor */ |
| 47 | 46 | ||
| 48 | unsigned char brightness; | 47 | unsigned char brightness; |
| 49 | unsigned char contrast; | 48 | unsigned char contrast; |
| 50 | unsigned char colors; | 49 | unsigned char colors; |
| 50 | __u8 hflip; | ||
| 51 | __u8 vflip; | ||
| 51 | 52 | ||
| 52 | char compress; /* Should the next frame be compressed? */ | 53 | char compress; /* Should the next frame be compressed? */ |
| 53 | char compress_inited; /* Are compression params uploaded? */ | 54 | char compress_inited; /* Are compression params uploaded? */ |
| @@ -77,9 +78,12 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | |||
| 77 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | 78 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); |
| 78 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | 79 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); |
| 79 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | 80 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); |
| 81 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); | ||
| 82 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
| 83 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); | ||
| 84 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
| 80 | 85 | ||
| 81 | static struct ctrl sd_ctrls[] = { | 86 | static struct ctrl sd_ctrls[] = { |
| 82 | #define SD_BRIGHTNESS 0 | ||
| 83 | { | 87 | { |
| 84 | { | 88 | { |
| 85 | .id = V4L2_CID_BRIGHTNESS, | 89 | .id = V4L2_CID_BRIGHTNESS, |
| @@ -88,12 +92,12 @@ static struct ctrl sd_ctrls[] = { | |||
| 88 | .minimum = 0, | 92 | .minimum = 0, |
| 89 | .maximum = 255, | 93 | .maximum = 255, |
| 90 | .step = 1, | 94 | .step = 1, |
| 91 | .default_value = 127, | 95 | #define BRIGHTNESS_DEF 127 |
| 96 | .default_value = BRIGHTNESS_DEF, | ||
| 92 | }, | 97 | }, |
| 93 | .set = sd_setbrightness, | 98 | .set = sd_setbrightness, |
| 94 | .get = sd_getbrightness, | 99 | .get = sd_getbrightness, |
| 95 | }, | 100 | }, |
| 96 | #define SD_CONTRAST 1 | ||
| 97 | { | 101 | { |
| 98 | { | 102 | { |
| 99 | .id = V4L2_CID_CONTRAST, | 103 | .id = V4L2_CID_CONTRAST, |
| @@ -102,31 +106,61 @@ static struct ctrl sd_ctrls[] = { | |||
| 102 | .minimum = 0, | 106 | .minimum = 0, |
| 103 | .maximum = 255, | 107 | .maximum = 255, |
| 104 | .step = 1, | 108 | .step = 1, |
| 105 | .default_value = 127, | 109 | #define CONTRAST_DEF 127 |
| 110 | .default_value = CONTRAST_DEF, | ||
| 106 | }, | 111 | }, |
| 107 | .set = sd_setcontrast, | 112 | .set = sd_setcontrast, |
| 108 | .get = sd_getcontrast, | 113 | .get = sd_getcontrast, |
| 109 | }, | 114 | }, |
| 110 | #define SD_COLOR 2 | ||
| 111 | { | 115 | { |
| 112 | { | 116 | { |
| 113 | .id = V4L2_CID_SATURATION, | 117 | .id = V4L2_CID_SATURATION, |
| 114 | .type = V4L2_CTRL_TYPE_INTEGER, | 118 | .type = V4L2_CTRL_TYPE_INTEGER, |
| 115 | .name = "Saturation", | 119 | .name = "Color", |
| 116 | .minimum = 0, | 120 | .minimum = 0, |
| 117 | .maximum = 255, | 121 | .maximum = 255, |
| 118 | .step = 1, | 122 | .step = 1, |
| 119 | .default_value = 127, | 123 | #define COLOR_DEF 127 |
| 124 | .default_value = COLOR_DEF, | ||
| 120 | }, | 125 | }, |
| 121 | .set = sd_setcolors, | 126 | .set = sd_setcolors, |
| 122 | .get = sd_getcolors, | 127 | .get = sd_getcolors, |
| 123 | }, | 128 | }, |
| 129 | /* next controls work with ov7670 only */ | ||
| 130 | { | ||
| 131 | { | ||
| 132 | .id = V4L2_CID_HFLIP, | ||
| 133 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
| 134 | .name = "Mirror", | ||
| 135 | .minimum = 0, | ||
| 136 | .maximum = 1, | ||
| 137 | .step = 1, | ||
| 138 | #define HFLIP_DEF 0 | ||
| 139 | .default_value = HFLIP_DEF, | ||
| 140 | }, | ||
| 141 | .set = sd_sethflip, | ||
| 142 | .get = sd_gethflip, | ||
| 143 | }, | ||
| 144 | { | ||
| 145 | { | ||
| 146 | .id = V4L2_CID_VFLIP, | ||
| 147 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
| 148 | .name = "Vflip", | ||
| 149 | .minimum = 0, | ||
| 150 | .maximum = 1, | ||
| 151 | .step = 1, | ||
| 152 | #define VFLIP_DEF 0 | ||
| 153 | .default_value = VFLIP_DEF, | ||
| 154 | }, | ||
| 155 | .set = sd_setvflip, | ||
| 156 | .get = sd_getvflip, | ||
| 157 | }, | ||
| 124 | }; | 158 | }; |
| 125 | 159 | ||
| 126 | static struct v4l2_pix_format vga_mode[] = { | 160 | static struct v4l2_pix_format vga_mode[] = { |
| 127 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 161 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
| 128 | .bytesperline = 320, | 162 | .bytesperline = 320, |
| 129 | .sizeimage = 320 * 240 * 3 / 8 + 589, | 163 | .sizeimage = 320 * 240 * 3 / 8 + 590, |
| 130 | .colorspace = V4L2_COLORSPACE_JPEG, | 164 | .colorspace = V4L2_COLORSPACE_JPEG, |
| 131 | .priv = 1}, | 165 | .priv = 1}, |
| 132 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 166 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
| @@ -138,12 +172,12 @@ static struct v4l2_pix_format vga_mode[] = { | |||
| 138 | static struct v4l2_pix_format sif_mode[] = { | 172 | static struct v4l2_pix_format sif_mode[] = { |
| 139 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 173 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
| 140 | .bytesperline = 176, | 174 | .bytesperline = 176, |
| 141 | .sizeimage = 176 * 144 * 3 / 8 + 589, | 175 | .sizeimage = 176 * 144 * 3 / 8 + 590, |
| 142 | .colorspace = V4L2_COLORSPACE_JPEG, | 176 | .colorspace = V4L2_COLORSPACE_JPEG, |
| 143 | .priv = 1}, | 177 | .priv = 1}, |
| 144 | {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 178 | {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
| 145 | .bytesperline = 352, | 179 | .bytesperline = 352, |
| 146 | .sizeimage = 352 * 288 * 3 / 8 + 589, | 180 | .sizeimage = 352 * 288 * 3 / 8 + 590, |
| 147 | .colorspace = V4L2_COLORSPACE_JPEG, | 181 | .colorspace = V4L2_COLORSPACE_JPEG, |
| 148 | .priv = 0}, | 182 | .priv = 0}, |
| 149 | }; | 183 | }; |
| @@ -225,6 +259,7 @@ static struct v4l2_pix_format sif_mode[] = { | |||
| 225 | #define OV7670_REG_VSTART 0x19 /* Vert start high bits */ | 259 | #define OV7670_REG_VSTART 0x19 /* Vert start high bits */ |
| 226 | #define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */ | 260 | #define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */ |
| 227 | #define OV7670_REG_MVFP 0x1e /* Mirror / vflip */ | 261 | #define OV7670_REG_MVFP 0x1e /* Mirror / vflip */ |
| 262 | #define OV7670_MVFP_VFLIP 0x10 /* vertical flip */ | ||
| 228 | #define OV7670_MVFP_MIRROR 0x20 /* Mirror image */ | 263 | #define OV7670_MVFP_MIRROR 0x20 /* Mirror image */ |
| 229 | #define OV7670_REG_AEW 0x24 /* AGC upper limit */ | 264 | #define OV7670_REG_AEW 0x24 /* AGC upper limit */ |
| 230 | #define OV7670_REG_AEB 0x25 /* AGC lower limit */ | 265 | #define OV7670_REG_AEB 0x25 /* AGC lower limit */ |
| @@ -258,16 +293,6 @@ static struct v4l2_pix_format sif_mode[] = { | |||
| 258 | #define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */ | 293 | #define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */ |
| 259 | #define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */ | 294 | #define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */ |
| 260 | 295 | ||
| 261 | struct ovsensor_window { | ||
| 262 | short x; | ||
| 263 | short y; | ||
| 264 | short width; | ||
| 265 | short height; | ||
| 266 | /* int format; */ | ||
| 267 | short quarter; /* Scale width and height down 2x */ | ||
| 268 | short clockdiv; /* Clock divisor setting */ | ||
| 269 | }; | ||
| 270 | |||
| 271 | static unsigned char ov7670_abs_to_sm(unsigned char v) | 296 | static unsigned char ov7670_abs_to_sm(unsigned char v) |
| 272 | { | 297 | { |
| 273 | if (v > 127) | 298 | if (v > 127) |
| @@ -499,19 +524,6 @@ static int init_ov_sensor(struct sd *sd) | |||
| 499 | return 0; | 524 | return 0; |
| 500 | } | 525 | } |
| 501 | 526 | ||
| 502 | /* Switch on standard JPEG compression. Returns 0 for success. */ | ||
| 503 | static int ov519_init_compression(struct sd *sd) | ||
| 504 | { | ||
| 505 | if (!sd->compress_inited) { | ||
| 506 | if (reg_w_mask(sd, OV519_SYS_EN_CLK1, 1 << 2, 1 << 2) < 0) { | ||
| 507 | PDEBUG(D_ERR, "Error switching to compressed mode"); | ||
| 508 | return -EIO; | ||
| 509 | } | ||
| 510 | sd->compress_inited = 1; | ||
| 511 | } | ||
| 512 | return 0; | ||
| 513 | } | ||
| 514 | |||
| 515 | /* Set the read and write slave IDs. The "slave" argument is the write slave, | 527 | /* Set the read and write slave IDs. The "slave" argument is the write slave, |
| 516 | * and the read slave will be set to (slave + 1). | 528 | * and the read slave will be set to (slave + 1). |
| 517 | * This should not be called from outside the i2c I/O functions. | 529 | * This should not be called from outside the i2c I/O functions. |
| @@ -681,21 +693,17 @@ static int ov8xx0_configure(struct sd *sd) | |||
| 681 | return -1; | 693 | return -1; |
| 682 | } | 694 | } |
| 683 | if ((rc & 3) == 1) { | 695 | if ((rc & 3) == 1) { |
| 684 | PDEBUG(D_PROBE, "Sensor is an OV8610"); | ||
| 685 | sd->sensor = SEN_OV8610; | 696 | sd->sensor = SEN_OV8610; |
| 686 | } else { | 697 | } else { |
| 687 | PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3); | 698 | PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3); |
| 688 | return -1; | 699 | return -1; |
| 689 | } | 700 | } |
| 690 | PDEBUG(D_PROBE, "Writing 8610 registers"); | 701 | PDEBUG(D_PROBE, "Writing 8610 registers"); |
| 691 | if (write_i2c_regvals(sd, | 702 | if (write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610))) |
| 692 | norm_8610, | ||
| 693 | sizeof norm_8610 / sizeof norm_8610[0])) | ||
| 694 | return -1; | 703 | return -1; |
| 695 | 704 | ||
| 696 | /* Set sensor-specific vars */ | 705 | /* Set sensor-specific vars */ |
| 697 | sd->maxwidth = 640; | 706 | /* sd->sif = 0; already done */ |
| 698 | sd->maxheight = 480; | ||
| 699 | return 0; | 707 | return 0; |
| 700 | } | 708 | } |
| 701 | 709 | ||
| @@ -825,7 +833,7 @@ static int ov7xx0_configure(struct sd *sd) | |||
| 825 | { OV7670_REG_COM7, OV7670_COM7_RESET }, | 833 | { OV7670_REG_COM7, OV7670_COM7_RESET }, |
| 826 | { OV7670_REG_TSLB, 0x04 }, /* OV */ | 834 | { OV7670_REG_TSLB, 0x04 }, /* OV */ |
| 827 | { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */ | 835 | { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */ |
| 828 | { OV7670_REG_CLKRC, 0x1 }, | 836 | { OV7670_REG_CLKRC, 0x01 }, |
| 829 | /* | 837 | /* |
| 830 | * Set the hardware window. These values from OV don't entirely | 838 | * Set the hardware window. These values from OV don't entirely |
| 831 | * make sense - hstop is less than hstart. But they work... | 839 | * make sense - hstop is less than hstart. But they work... |
| @@ -839,16 +847,12 @@ static int ov7xx0_configure(struct sd *sd) | |||
| 839 | { 0x70, 0x3a }, { 0x71, 0x35 }, | 847 | { 0x70, 0x3a }, { 0x71, 0x35 }, |
| 840 | { 0x72, 0x11 }, { 0x73, 0xf0 }, | 848 | { 0x72, 0x11 }, { 0x73, 0xf0 }, |
| 841 | { 0xa2, 0x02 }, | 849 | { 0xa2, 0x02 }, |
| 842 | /* jfm */ | 850 | /* { OV7670_REG_COM10, 0x0 }, */ |
| 843 | /* { OV7670_REG_COM10, 0x0 }, */ | ||
| 844 | 851 | ||
| 845 | /* Gamma curve values */ | 852 | /* Gamma curve values */ |
| 846 | { 0x7a, 0x20 }, | 853 | { 0x7a, 0x20 }, |
| 847 | /* jfm:win 7b=1c */ | ||
| 848 | { 0x7b, 0x10 }, | 854 | { 0x7b, 0x10 }, |
| 849 | /* jfm:win 7c=28 */ | ||
| 850 | { 0x7c, 0x1e }, | 855 | { 0x7c, 0x1e }, |
| 851 | /* jfm:win 7d=3c */ | ||
| 852 | { 0x7d, 0x35 }, | 856 | { 0x7d, 0x35 }, |
| 853 | { 0x7e, 0x5a }, { 0x7f, 0x69 }, | 857 | { 0x7e, 0x5a }, { 0x7f, 0x69 }, |
| 854 | { 0x80, 0x76 }, { 0x81, 0x80 }, | 858 | { 0x80, 0x76 }, { 0x81, 0x80 }, |
| @@ -864,13 +868,11 @@ static int ov7xx0_configure(struct sd *sd) | |||
| 864 | | OV7670_COM8_BFILT }, | 868 | | OV7670_COM8_BFILT }, |
| 865 | { OV7670_REG_GAIN, 0 }, { OV7670_REG_AECH, 0 }, | 869 | { OV7670_REG_GAIN, 0 }, { OV7670_REG_AECH, 0 }, |
| 866 | { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */ | 870 | { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */ |
| 867 | /* jfm:win 14=38 */ | ||
| 868 | { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */ | 871 | { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */ |
| 869 | { OV7670_REG_BD50MAX, 0x05 }, { OV7670_REG_BD60MAX, 0x07 }, | 872 | { OV7670_REG_BD50MAX, 0x05 }, { OV7670_REG_BD60MAX, 0x07 }, |
| 870 | { OV7670_REG_AEW, 0x95 }, { OV7670_REG_AEB, 0x33 }, | 873 | { OV7670_REG_AEW, 0x95 }, { OV7670_REG_AEB, 0x33 }, |
| 871 | { OV7670_REG_VPT, 0xe3 }, { OV7670_REG_HAECC1, 0x78 }, | 874 | { OV7670_REG_VPT, 0xe3 }, { OV7670_REG_HAECC1, 0x78 }, |
| 872 | { OV7670_REG_HAECC2, 0x68 }, | 875 | { OV7670_REG_HAECC2, 0x68 }, |
| 873 | /* jfm:win a1=0b */ | ||
| 874 | { 0xa1, 0x03 }, /* magic */ | 876 | { 0xa1, 0x03 }, /* magic */ |
| 875 | { OV7670_REG_HAECC3, 0xd8 }, { OV7670_REG_HAECC4, 0xd8 }, | 877 | { OV7670_REG_HAECC3, 0xd8 }, { OV7670_REG_HAECC4, 0xd8 }, |
| 876 | { OV7670_REG_HAECC5, 0xf0 }, { OV7670_REG_HAECC6, 0x90 }, | 878 | { OV7670_REG_HAECC5, 0xf0 }, { OV7670_REG_HAECC6, 0x90 }, |
| @@ -884,8 +886,6 @@ static int ov7xx0_configure(struct sd *sd) | |||
| 884 | /* Almost all of these are magic "reserved" values. */ | 886 | /* Almost all of these are magic "reserved" values. */ |
| 885 | { OV7670_REG_COM5, 0x61 }, { OV7670_REG_COM6, 0x4b }, | 887 | { OV7670_REG_COM5, 0x61 }, { OV7670_REG_COM6, 0x4b }, |
| 886 | { 0x16, 0x02 }, | 888 | { 0x16, 0x02 }, |
| 887 | /* jfm */ | ||
| 888 | /* { OV7670_REG_MVFP, 0x07|OV7670_MVFP_MIRROR }, */ | ||
| 889 | { OV7670_REG_MVFP, 0x07 }, | 889 | { OV7670_REG_MVFP, 0x07 }, |
| 890 | { 0x21, 0x02 }, { 0x22, 0x91 }, | 890 | { 0x21, 0x02 }, { 0x22, 0x91 }, |
| 891 | { 0x29, 0x07 }, { 0x33, 0x0b }, | 891 | { 0x29, 0x07 }, { 0x33, 0x0b }, |
| @@ -930,7 +930,10 @@ static int ov7xx0_configure(struct sd *sd) | |||
| 930 | { OV7670_REG_EDGE, 0 }, | 930 | { OV7670_REG_EDGE, 0 }, |
| 931 | { 0x75, 0x05 }, { 0x76, 0xe1 }, | 931 | { 0x75, 0x05 }, { 0x76, 0xe1 }, |
| 932 | { 0x4c, 0 }, { 0x77, 0x01 }, | 932 | { 0x4c, 0 }, { 0x77, 0x01 }, |
| 933 | { OV7670_REG_COM13, 0xc3 }, { 0x4b, 0x09 }, | 933 | { OV7670_REG_COM13, OV7670_COM13_GAMMA |
| 934 | | OV7670_COM13_UVSAT | ||
| 935 | | 2}, /* was 3 */ | ||
| 936 | { 0x4b, 0x09 }, | ||
| 934 | { 0xc9, 0x60 }, { OV7670_REG_COM16, 0x38 }, | 937 | { 0xc9, 0x60 }, { OV7670_REG_COM16, 0x38 }, |
| 935 | { 0x56, 0x40 }, | 938 | { 0x56, 0x40 }, |
| 936 | 939 | ||
| @@ -956,30 +959,10 @@ static int ov7xx0_configure(struct sd *sd) | |||
| 956 | { 0x79, 0x03 }, { 0xc8, 0x40 }, | 959 | { 0x79, 0x03 }, { 0xc8, 0x40 }, |
| 957 | { 0x79, 0x05 }, { 0xc8, 0x30 }, | 960 | { 0x79, 0x05 }, { 0xc8, 0x30 }, |
| 958 | { 0x79, 0x26 }, | 961 | { 0x79, 0x26 }, |
| 959 | 962 | }; | |
| 960 | /* Format YUV422 */ | ||
| 961 | { OV7670_REG_COM7, OV7670_COM7_YUV }, /* Selects YUV mode */ | ||
| 962 | { OV7670_REG_RGB444, 0 }, /* No RGB444 please */ | ||
| 963 | { OV7670_REG_COM1, 0 }, | ||
| 964 | { OV7670_REG_COM15, OV7670_COM15_R00FF }, | ||
| 965 | { OV7670_REG_COM9, 0x18 }, | ||
| 966 | /* 4x gain ceiling; 0x8 is reserved bit */ | ||
| 967 | { 0x4f, 0x80 }, /* "matrix coefficient 1" */ | ||
| 968 | { 0x50, 0x80 }, /* "matrix coefficient 2" */ | ||
| 969 | { 0x52, 0x22 }, /* "matrix coefficient 4" */ | ||
| 970 | { 0x53, 0x5e }, /* "matrix coefficient 5" */ | ||
| 971 | { 0x54, 0x80 }, /* "matrix coefficient 6" */ | ||
| 972 | { OV7670_REG_COM13, OV7670_COM13_GAMMA|OV7670_COM13_UVSAT }, | ||
| 973 | }; | ||
| 974 | 963 | ||
| 975 | PDEBUG(D_PROBE, "starting OV7xx0 configuration"); | 964 | PDEBUG(D_PROBE, "starting OV7xx0 configuration"); |
| 976 | 965 | ||
| 977 | /* jfm:already done? */ | ||
| 978 | if (init_ov_sensor(sd) < 0) | ||
| 979 | PDEBUG(D_ERR, "Failed to read sensor ID"); | ||
| 980 | else | ||
| 981 | PDEBUG(D_PROBE, "OV7xx0 initialized"); | ||
| 982 | |||
| 983 | /* Detect sensor (sub)type */ | 966 | /* Detect sensor (sub)type */ |
| 984 | rc = i2c_r(sd, OV7610_REG_COM_I); | 967 | rc = i2c_r(sd, OV7610_REG_COM_I); |
| 985 | 968 | ||
| @@ -1025,20 +1008,25 @@ static int ov7xx0_configure(struct sd *sd) | |||
| 1025 | return low; | 1008 | return low; |
| 1026 | } | 1009 | } |
| 1027 | if (high == 0x76) { | 1010 | if (high == 0x76) { |
| 1028 | if (low == 0x30) { | 1011 | switch (low) { |
| 1012 | case 0x30: | ||
| 1029 | PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635"); | 1013 | PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635"); |
| 1030 | sd->sensor = SEN_OV7630; | 1014 | sd->sensor = SEN_OV7630; |
| 1031 | } else if (low == 0x40) { | 1015 | break; |
| 1016 | case 0x40: | ||
| 1032 | PDEBUG(D_PROBE, "Sensor is an OV7645"); | 1017 | PDEBUG(D_PROBE, "Sensor is an OV7645"); |
| 1033 | sd->sensor = SEN_OV7640; /* FIXME */ | 1018 | sd->sensor = SEN_OV7640; /* FIXME */ |
| 1034 | } else if (low == 0x45) { | 1019 | break; |
| 1020 | case 0x45: | ||
| 1035 | PDEBUG(D_PROBE, "Sensor is an OV7645B"); | 1021 | PDEBUG(D_PROBE, "Sensor is an OV7645B"); |
| 1036 | sd->sensor = SEN_OV7640; /* FIXME */ | 1022 | sd->sensor = SEN_OV7640; /* FIXME */ |
| 1037 | } else if (low == 0x48) { | 1023 | break; |
| 1024 | case 0x48: | ||
| 1038 | PDEBUG(D_PROBE, "Sensor is an OV7648"); | 1025 | PDEBUG(D_PROBE, "Sensor is an OV7648"); |
| 1039 | sd->sensor = SEN_OV7640; /* FIXME */ | 1026 | sd->sensor = SEN_OV7640; /* FIXME */ |
| 1040 | } else { | 1027 | break; |
| 1041 | PDEBUG(D_PROBE, "Unknown sensor: 0x76%X", low); | 1028 | default: |
| 1029 | PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low); | ||
| 1042 | return -1; | 1030 | return -1; |
| 1043 | } | 1031 | } |
| 1044 | } else { | 1032 | } else { |
| @@ -1050,34 +1038,34 @@ static int ov7xx0_configure(struct sd *sd) | |||
| 1050 | return -1; | 1038 | return -1; |
| 1051 | } | 1039 | } |
| 1052 | 1040 | ||
| 1053 | if (sd->sensor == SEN_OV7620) { | 1041 | switch (sd->sensor) { |
| 1042 | case SEN_OV7620: | ||
| 1054 | PDEBUG(D_PROBE, "Writing 7620 registers"); | 1043 | PDEBUG(D_PROBE, "Writing 7620 registers"); |
| 1055 | if (write_i2c_regvals(sd, norm_7620, | 1044 | if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620))) |
| 1056 | sizeof norm_7620 / sizeof norm_7620[0])) | ||
| 1057 | return -1; | 1045 | return -1; |
| 1058 | } else if (sd->sensor == SEN_OV7630) { | 1046 | break; |
| 1047 | case SEN_OV7630: | ||
| 1059 | PDEBUG(D_ERR, "7630 is not supported by this driver version"); | 1048 | PDEBUG(D_ERR, "7630 is not supported by this driver version"); |
| 1060 | return -1; | 1049 | return -1; |
| 1061 | } else if (sd->sensor == SEN_OV7640) { | 1050 | case SEN_OV7640: |
| 1062 | PDEBUG(D_PROBE, "Writing 7640 registers"); | 1051 | PDEBUG(D_PROBE, "Writing 7640 registers"); |
| 1063 | if (write_i2c_regvals(sd, norm_7640, | 1052 | if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640))) |
| 1064 | sizeof norm_7640 / sizeof norm_7640[0])) | ||
| 1065 | return -1; | 1053 | return -1; |
| 1066 | } else if (sd->sensor == SEN_OV7670) { | 1054 | break; |
| 1055 | case SEN_OV7670: | ||
| 1067 | PDEBUG(D_PROBE, "Writing 7670 registers"); | 1056 | PDEBUG(D_PROBE, "Writing 7670 registers"); |
| 1068 | if (write_i2c_regvals(sd, norm_7670, | 1057 | if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670))) |
| 1069 | sizeof norm_7670 / sizeof norm_7670[0])) | ||
| 1070 | return -1; | 1058 | return -1; |
| 1071 | } else { | 1059 | break; |
| 1060 | default: | ||
| 1072 | PDEBUG(D_PROBE, "Writing 7610 registers"); | 1061 | PDEBUG(D_PROBE, "Writing 7610 registers"); |
| 1073 | if (write_i2c_regvals(sd, norm_7610, | 1062 | if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610))) |
| 1074 | sizeof norm_7610 / sizeof norm_7610[0])) | ||
| 1075 | return -1; | 1063 | return -1; |
| 1064 | break; | ||
| 1076 | } | 1065 | } |
| 1077 | 1066 | ||
| 1078 | /* Set sensor-specific vars */ | 1067 | /* Set sensor-specific vars */ |
| 1079 | sd->maxwidth = 640; | 1068 | /* sd->sif = 0; already done */ |
| 1080 | sd->maxheight = 480; | ||
| 1081 | return 0; | 1069 | return 0; |
| 1082 | } | 1070 | } |
| 1083 | 1071 | ||
| @@ -1231,43 +1219,45 @@ static int ov6xx0_configure(struct sd *sd) | |||
| 1231 | /* Ugh. The first two bits are the version bits, but | 1219 | /* Ugh. The first two bits are the version bits, but |
| 1232 | * the entire register value must be used. I guess OVT | 1220 | * the entire register value must be used. I guess OVT |
| 1233 | * underestimated how many variants they would make. */ | 1221 | * underestimated how many variants they would make. */ |
| 1234 | if (rc == 0x00) { | 1222 | switch (rc) { |
| 1223 | case 0x00: | ||
| 1235 | sd->sensor = SEN_OV6630; | 1224 | sd->sensor = SEN_OV6630; |
| 1236 | PDEBUG(D_ERR, | 1225 | PDEBUG(D_ERR, |
| 1237 | "WARNING: Sensor is an OV66308. Your camera may have"); | 1226 | "WARNING: Sensor is an OV66308. Your camera may have"); |
| 1238 | PDEBUG(D_ERR, "been misdetected in previous driver versions."); | 1227 | PDEBUG(D_ERR, "been misdetected in previous driver versions."); |
| 1239 | } else if (rc == 0x01) { | 1228 | break; |
| 1229 | case 0x01: | ||
| 1240 | sd->sensor = SEN_OV6620; | 1230 | sd->sensor = SEN_OV6620; |
| 1241 | PDEBUG(D_PROBE, "Sensor is an OV6620"); | 1231 | break; |
| 1242 | } else if (rc == 0x02) { | 1232 | case 0x02: |
| 1243 | sd->sensor = SEN_OV6630; | 1233 | sd->sensor = SEN_OV6630; |
| 1244 | PDEBUG(D_PROBE, "Sensor is an OV66308AE"); | 1234 | PDEBUG(D_PROBE, "Sensor is an OV66308AE"); |
| 1245 | } else if (rc == 0x03) { | 1235 | break; |
| 1236 | case 0x03: | ||
| 1246 | sd->sensor = SEN_OV6630; | 1237 | sd->sensor = SEN_OV6630; |
| 1247 | PDEBUG(D_PROBE, "Sensor is an OV66308AF"); | 1238 | PDEBUG(D_PROBE, "Sensor is an OV66308AF"); |
| 1248 | } else if (rc == 0x90) { | 1239 | break; |
| 1240 | case 0x90: | ||
| 1249 | sd->sensor = SEN_OV6630; | 1241 | sd->sensor = SEN_OV6630; |
| 1250 | PDEBUG(D_ERR, | 1242 | PDEBUG(D_ERR, |
| 1251 | "WARNING: Sensor is an OV66307. Your camera may have"); | 1243 | "WARNING: Sensor is an OV66307. Your camera may have"); |
| 1252 | PDEBUG(D_ERR, "been misdetected in previous driver versions."); | 1244 | PDEBUG(D_ERR, "been misdetected in previous driver versions."); |
| 1253 | } else { | 1245 | break; |
| 1246 | default: | ||
| 1254 | PDEBUG(D_ERR, "FATAL: Unknown sensor version: 0x%02x", rc); | 1247 | PDEBUG(D_ERR, "FATAL: Unknown sensor version: 0x%02x", rc); |
| 1255 | return -1; | 1248 | return -1; |
| 1256 | } | 1249 | } |
| 1257 | 1250 | ||
| 1258 | /* Set sensor-specific vars */ | 1251 | /* Set sensor-specific vars */ |
| 1259 | sd->maxwidth = 352; | 1252 | sd->sif = 1; |
| 1260 | sd->maxheight = 288; | ||
| 1261 | 1253 | ||
| 1262 | if (sd->sensor == SEN_OV6620) { | 1254 | if (sd->sensor == SEN_OV6620) { |
| 1263 | PDEBUG(D_PROBE, "Writing 6x20 registers"); | 1255 | PDEBUG(D_PROBE, "Writing 6x20 registers"); |
| 1264 | if (write_i2c_regvals(sd, norm_6x20, | 1256 | if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20))) |
| 1265 | sizeof norm_6x20 / sizeof norm_6x20[0])) | ||
| 1266 | return -1; | 1257 | return -1; |
| 1267 | } else { | 1258 | } else { |
| 1268 | PDEBUG(D_PROBE, "Writing 6x30 registers"); | 1259 | PDEBUG(D_PROBE, "Writing 6x30 registers"); |
| 1269 | if (write_i2c_regvals(sd, norm_6x30, | 1260 | if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30))) |
| 1270 | sizeof norm_6x30 / sizeof norm_6x30[0])) | ||
| 1271 | return -1; | 1261 | return -1; |
| 1272 | } | 1262 | } |
| 1273 | return 0; | 1263 | return 0; |
| @@ -1276,14 +1266,8 @@ static int ov6xx0_configure(struct sd *sd) | |||
| 1276 | /* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ | 1266 | /* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ |
| 1277 | static void ov51x_led_control(struct sd *sd, int on) | 1267 | static void ov51x_led_control(struct sd *sd, int on) |
| 1278 | { | 1268 | { |
| 1279 | PDEBUG(D_STREAM, "LED (%s)", on ? "on" : "off"); | 1269 | /* PDEBUG(D_STREAM, "LED (%s)", on ? "on" : "off"); */ |
| 1280 | 1270 | reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ | |
| 1281 | /* if (sd->bridge == BRG_OV511PLUS) */ | ||
| 1282 | /* reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0); */ | ||
| 1283 | /* else if (sd->bridge == BRG_OV519) */ | ||
| 1284 | reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ | ||
| 1285 | /* else if (sd->bclass == BCL_OV518) */ | ||
| 1286 | /* reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02); */ | ||
| 1287 | } | 1271 | } |
| 1288 | 1272 | ||
| 1289 | /* this function is called at probe time */ | 1273 | /* this function is called at probe time */ |
| @@ -1293,11 +1277,8 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
| 1293 | struct sd *sd = (struct sd *) gspca_dev; | 1277 | struct sd *sd = (struct sd *) gspca_dev; |
| 1294 | struct cam *cam; | 1278 | struct cam *cam; |
| 1295 | 1279 | ||
| 1296 | /* (from ov519_configure) */ | ||
| 1297 | static const struct ov_regvals init_519[] = { | 1280 | static const struct ov_regvals init_519[] = { |
| 1298 | { 0x5a, 0x6d }, /* EnableSystem */ | 1281 | { 0x5a, 0x6d }, /* EnableSystem */ |
| 1299 | /* jfm trace usbsnoop3-1.txt */ | ||
| 1300 | /* jfm 53 = fb */ | ||
| 1301 | { 0x53, 0x9b }, | 1282 | { 0x53, 0x9b }, |
| 1302 | { 0x54, 0xff }, /* set bit2 to enable jpeg */ | 1283 | { 0x54, 0xff }, /* set bit2 to enable jpeg */ |
| 1303 | { 0x5d, 0x03 }, | 1284 | { 0x5d, 0x03 }, |
| @@ -1314,9 +1295,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
| 1314 | 1295 | ||
| 1315 | if (write_regvals(sd, init_519, ARRAY_SIZE(init_519))) | 1296 | if (write_regvals(sd, init_519, ARRAY_SIZE(init_519))) |
| 1316 | goto error; | 1297 | goto error; |
| 1317 | /* jfm: not seen in windows trace */ | ||
| 1318 | if (ov519_init_compression(sd)) | ||
| 1319 | goto error; | ||
| 1320 | ov51x_led_control(sd, 0); /* turn LED off */ | 1298 | ov51x_led_control(sd, 0); /* turn LED off */ |
| 1321 | 1299 | ||
| 1322 | /* Test for 76xx */ | 1300 | /* Test for 76xx */ |
| @@ -1365,16 +1343,18 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
| 1365 | 1343 | ||
| 1366 | cam = &gspca_dev->cam; | 1344 | cam = &gspca_dev->cam; |
| 1367 | cam->epaddr = OV511_ENDPOINT_ADDRESS; | 1345 | cam->epaddr = OV511_ENDPOINT_ADDRESS; |
| 1368 | if (sd->maxwidth == 640) { | 1346 | if (!sd->sif) { |
| 1369 | cam->cam_mode = vga_mode; | 1347 | cam->cam_mode = vga_mode; |
| 1370 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; | 1348 | cam->nmodes = ARRAY_SIZE(vga_mode); |
| 1371 | } else { | 1349 | } else { |
| 1372 | cam->cam_mode = sif_mode; | 1350 | cam->cam_mode = sif_mode; |
| 1373 | cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; | 1351 | cam->nmodes = ARRAY_SIZE(sif_mode); |
| 1374 | } | 1352 | } |
| 1375 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | 1353 | sd->brightness = BRIGHTNESS_DEF; |
| 1376 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | 1354 | sd->contrast = CONTRAST_DEF; |
| 1377 | sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; | 1355 | sd->colors = COLOR_DEF; |
| 1356 | sd->hflip = HFLIP_DEF; | ||
| 1357 | sd->vflip = VFLIP_DEF; | ||
| 1378 | return 0; | 1358 | return 0; |
| 1379 | error: | 1359 | error: |
| 1380 | PDEBUG(D_ERR, "OV519 Config failed"); | 1360 | PDEBUG(D_ERR, "OV519 Config failed"); |
| @@ -1394,8 +1374,7 @@ static int sd_open(struct gspca_dev *gspca_dev) | |||
| 1394 | * | 1374 | * |
| 1395 | * Do not put any sensor-specific code in here (including I2C I/O functions) | 1375 | * Do not put any sensor-specific code in here (including I2C I/O functions) |
| 1396 | */ | 1376 | */ |
| 1397 | static int ov519_mode_init_regs(struct sd *sd, | 1377 | static int ov519_mode_init_regs(struct sd *sd) |
| 1398 | int width, int height) | ||
| 1399 | { | 1378 | { |
| 1400 | static const struct ov_regvals mode_init_519_ov7670[] = { | 1379 | static const struct ov_regvals mode_init_519_ov7670[] = { |
| 1401 | { 0x5d, 0x03 }, /* Turn off suspend mode */ | 1380 | { 0x5d, 0x03 }, /* Turn off suspend mode */ |
| @@ -1441,36 +1420,23 @@ static int ov519_mode_init_regs(struct sd *sd, | |||
| 1441 | /* windows reads 0x55 at this point, why? */ | 1420 | /* windows reads 0x55 at this point, why? */ |
| 1442 | }; | 1421 | }; |
| 1443 | 1422 | ||
| 1444 | /* int hi_res; */ | ||
| 1445 | |||
| 1446 | PDEBUG(D_CONF, "mode init %dx%d", width, height); | ||
| 1447 | |||
| 1448 | /* if (width >= 800 && height >= 600) | ||
| 1449 | hi_res = 1; | ||
| 1450 | else | ||
| 1451 | hi_res = 0; */ | ||
| 1452 | |||
| 1453 | /* if (ov51x_stop(sd) < 0) | ||
| 1454 | return -EIO; */ | ||
| 1455 | |||
| 1456 | /******** Set the mode ********/ | 1423 | /******** Set the mode ********/ |
| 1457 | if (sd->sensor != SEN_OV7670) { | 1424 | if (sd->sensor != SEN_OV7670) { |
| 1458 | if (write_regvals(sd, mode_init_519, | 1425 | if (write_regvals(sd, mode_init_519, |
| 1459 | ARRAY_SIZE(mode_init_519))) | 1426 | ARRAY_SIZE(mode_init_519))) |
| 1460 | return -EIO; | 1427 | return -EIO; |
| 1428 | if (sd->sensor == SEN_OV7640) { | ||
| 1429 | /* Select 8-bit input mode */ | ||
| 1430 | reg_w_mask(sd, OV519_CAM_DFR, 0x10, 0x10); | ||
| 1431 | } | ||
| 1461 | } else { | 1432 | } else { |
| 1462 | if (write_regvals(sd, mode_init_519_ov7670, | 1433 | if (write_regvals(sd, mode_init_519_ov7670, |
| 1463 | ARRAY_SIZE(mode_init_519_ov7670))) | 1434 | ARRAY_SIZE(mode_init_519_ov7670))) |
| 1464 | return -EIO; | 1435 | return -EIO; |
| 1465 | } | 1436 | } |
| 1466 | 1437 | ||
| 1467 | if (sd->sensor == SEN_OV7640) { | 1438 | reg_w(sd, OV519_CAM_H_SIZE, sd->gspca_dev.width >> 4); |
| 1468 | /* Select 8-bit input mode */ | 1439 | reg_w(sd, OV519_CAM_V_SIZE, sd->gspca_dev.height >> 3); |
| 1469 | reg_w_mask(sd, OV519_CAM_DFR, 0x10, 0x10); | ||
| 1470 | } | ||
| 1471 | |||
| 1472 | reg_w(sd, OV519_CAM_H_SIZE, width >> 4); | ||
| 1473 | reg_w(sd, OV519_CAM_V_SIZE, height >> 3); | ||
| 1474 | reg_w(sd, OV519_CAM_X_OFFSETL, 0x00); | 1440 | reg_w(sd, OV519_CAM_X_OFFSETL, 0x00); |
| 1475 | reg_w(sd, OV519_CAM_X_OFFSETH, 0x00); | 1441 | reg_w(sd, OV519_CAM_X_OFFSETH, 0x00); |
| 1476 | reg_w(sd, OV519_CAM_Y_OFFSETL, 0x00); | 1442 | reg_w(sd, OV519_CAM_Y_OFFSETL, 0x00); |
| @@ -1485,9 +1451,10 @@ static int ov519_mode_init_regs(struct sd *sd, | |||
| 1485 | 1451 | ||
| 1486 | /* FIXME: These are only valid at the max resolution. */ | 1452 | /* FIXME: These are only valid at the max resolution. */ |
| 1487 | sd->clockdiv = 0; | 1453 | sd->clockdiv = 0; |
| 1488 | if (sd->sensor == SEN_OV7640) { | 1454 | switch (sd->sensor) { |
| 1455 | case SEN_OV7640: | ||
| 1489 | switch (sd->frame_rate) { | 1456 | switch (sd->frame_rate) { |
| 1490 | /*jfm: default was 30 fps */ | 1457 | /*fixme: default was 30 fps */ |
| 1491 | case 30: | 1458 | case 30: |
| 1492 | reg_w(sd, 0xa4, 0x0c); | 1459 | reg_w(sd, 0xa4, 0x0c); |
| 1493 | reg_w(sd, 0x23, 0xff); | 1460 | reg_w(sd, 0x23, 0xff); |
| @@ -1517,7 +1484,8 @@ static int ov519_mode_init_regs(struct sd *sd, | |||
| 1517 | sd->clockdiv = 1; | 1484 | sd->clockdiv = 1; |
| 1518 | break; | 1485 | break; |
| 1519 | } | 1486 | } |
| 1520 | } else if (sd->sensor == SEN_OV8610) { | 1487 | break; |
| 1488 | case SEN_OV8610: | ||
| 1521 | switch (sd->frame_rate) { | 1489 | switch (sd->frame_rate) { |
| 1522 | default: /* 15 fps */ | 1490 | default: /* 15 fps */ |
| 1523 | /* case 15: */ | 1491 | /* case 15: */ |
| @@ -1533,41 +1501,37 @@ static int ov519_mode_init_regs(struct sd *sd, | |||
| 1533 | reg_w(sd, 0x23, 0x1b); | 1501 | reg_w(sd, 0x23, 0x1b); |
| 1534 | break; | 1502 | break; |
| 1535 | } | 1503 | } |
| 1536 | sd->clockdiv = 0; | 1504 | break; |
| 1537 | } else if (sd->sensor == SEN_OV7670) { /* guesses, based on 7640 */ | 1505 | case SEN_OV7670: /* guesses, based on 7640 */ |
| 1538 | PDEBUG(D_STREAM, "Setting framerate to %d fps", | 1506 | PDEBUG(D_STREAM, "Setting framerate to %d fps", |
| 1539 | (sd->frame_rate == 0) ? 15 : sd->frame_rate); | 1507 | (sd->frame_rate == 0) ? 15 : sd->frame_rate); |
| 1508 | reg_w(sd, 0xa4, 0x10); | ||
| 1540 | switch (sd->frame_rate) { | 1509 | switch (sd->frame_rate) { |
| 1541 | case 30: | 1510 | case 30: |
| 1542 | reg_w(sd, 0xa4, 0x10); | ||
| 1543 | reg_w(sd, 0x23, 0xff); | 1511 | reg_w(sd, 0x23, 0xff); |
| 1544 | break; | 1512 | break; |
| 1545 | case 20: | 1513 | case 20: |
| 1546 | reg_w(sd, 0xa4, 0x10); | ||
| 1547 | reg_w(sd, 0x23, 0x1b); | 1514 | reg_w(sd, 0x23, 0x1b); |
| 1548 | break; | 1515 | break; |
| 1549 | default: /* 15 fps */ | 1516 | default: |
| 1550 | /* case 15: */ | 1517 | /* case 15: */ |
| 1551 | reg_w(sd, 0xa4, 0x10); | ||
| 1552 | reg_w(sd, 0x23, 0xff); | 1518 | reg_w(sd, 0x23, 0xff); |
| 1553 | sd->clockdiv = 1; | 1519 | sd->clockdiv = 1; |
| 1554 | break; | 1520 | break; |
| 1555 | } | 1521 | } |
| 1522 | break; | ||
| 1556 | } | 1523 | } |
| 1557 | 1524 | ||
| 1558 | /* if (ov51x_restart(sd) < 0) | ||
| 1559 | return -EIO; */ | ||
| 1560 | |||
| 1561 | /* Reset it just for good measure */ | ||
| 1562 | /* if (ov51x_reset(sd, OV511_RESET_NOREGS) < 0) | ||
| 1563 | return -EIO; */ | ||
| 1564 | return 0; | 1525 | return 0; |
| 1565 | } | 1526 | } |
| 1566 | 1527 | ||
| 1567 | static int mode_init_ov_sensor_regs(struct sd *sd, | 1528 | static int mode_init_ov_sensor_regs(struct sd *sd) |
| 1568 | struct ovsensor_window *win) | ||
| 1569 | { | 1529 | { |
| 1570 | int qvga = win->quarter; | 1530 | struct gspca_dev *gspca_dev; |
| 1531 | int qvga; | ||
| 1532 | |||
| 1533 | gspca_dev = &sd->gspca_dev; | ||
| 1534 | qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | ||
| 1571 | 1535 | ||
| 1572 | /******** Mode (VGA/QVGA) and sensor specific regs ********/ | 1536 | /******** Mode (VGA/QVGA) and sensor specific regs ********/ |
| 1573 | switch (sd->sensor) { | 1537 | switch (sd->sensor) { |
| @@ -1611,8 +1575,6 @@ static int mode_init_ov_sensor_regs(struct sd *sd, | |||
| 1611 | OV7670_COM7_FMT_MASK); | 1575 | OV7670_COM7_FMT_MASK); |
| 1612 | break; | 1576 | break; |
| 1613 | case SEN_OV6620: | 1577 | case SEN_OV6620: |
| 1614 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | ||
| 1615 | break; | ||
| 1616 | case SEN_OV6630: | 1578 | case SEN_OV6630: |
| 1617 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | 1579 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); |
| 1618 | break; | 1580 | break; |
| @@ -1621,24 +1583,21 @@ static int mode_init_ov_sensor_regs(struct sd *sd, | |||
| 1621 | } | 1583 | } |
| 1622 | 1584 | ||
| 1623 | /******** Palette-specific regs ********/ | 1585 | /******** Palette-specific regs ********/ |
| 1624 | /* Need to do work here for the OV7670 */ | 1586 | if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { |
| 1625 | 1587 | /* not valid on the OV6620/OV7620/6630? */ | |
| 1626 | if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { | 1588 | i2c_w_mask(sd, 0x0e, 0x00, 0x40); |
| 1627 | /* not valid on the OV6620/OV7620/6630? */ | 1589 | } |
| 1628 | i2c_w_mask(sd, 0x0e, 0x00, 0x40); | ||
| 1629 | } | ||
| 1630 | 1590 | ||
| 1631 | /* The OV518 needs special treatment. Although both the OV518 | 1591 | /* The OV518 needs special treatment. Although both the OV518 |
| 1632 | * and the OV6630 support a 16-bit video bus, only the 8 bit Y | 1592 | * and the OV6630 support a 16-bit video bus, only the 8 bit Y |
| 1633 | * bus is actually used. The UV bus is tied to ground. | 1593 | * bus is actually used. The UV bus is tied to ground. |
| 1634 | * Therefore, the OV6630 needs to be in 8-bit multiplexed | 1594 | * Therefore, the OV6630 needs to be in 8-bit multiplexed |
| 1635 | * output mode */ | 1595 | * output mode */ |
| 1636 | 1596 | ||
| 1637 | /* OV7640 is 8-bit only */ | 1597 | /* OV7640 is 8-bit only */ |
| 1638 | 1598 | ||
| 1639 | if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV7640) | 1599 | if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV7640) |
| 1640 | i2c_w_mask(sd, 0x13, 0x00, 0x20); | 1600 | i2c_w_mask(sd, 0x13, 0x00, 0x20); |
| 1641 | /* } */ | ||
| 1642 | 1601 | ||
| 1643 | /******** Clock programming ********/ | 1602 | /******** Clock programming ********/ |
| 1644 | /* The OV6620 needs special handling. This prevents the | 1603 | /* The OV6620 needs special handling. This prevents the |
| @@ -1647,14 +1606,14 @@ static int mode_init_ov_sensor_regs(struct sd *sd, | |||
| 1647 | 1606 | ||
| 1648 | /* Clock down */ | 1607 | /* Clock down */ |
| 1649 | i2c_w(sd, 0x2a, 0x04); | 1608 | i2c_w(sd, 0x2a, 0x04); |
| 1650 | i2c_w(sd, 0x11, win->clockdiv); | 1609 | i2c_w(sd, 0x11, sd->clockdiv); |
| 1651 | i2c_w(sd, 0x2a, 0x84); | 1610 | i2c_w(sd, 0x2a, 0x84); |
| 1652 | /* This next setting is critical. It seems to improve | 1611 | /* This next setting is critical. It seems to improve |
| 1653 | * the gain or the contrast. The "reserved" bits seem | 1612 | * the gain or the contrast. The "reserved" bits seem |
| 1654 | * to have some effect in this case. */ | 1613 | * to have some effect in this case. */ |
| 1655 | i2c_w(sd, 0x2d, 0x85); | 1614 | i2c_w(sd, 0x2d, 0x85); |
| 1656 | } else if (win->clockdiv >= 0) { | 1615 | } else if (sd->clockdiv >= 0) { |
| 1657 | i2c_w(sd, 0x11, win->clockdiv); | 1616 | i2c_w(sd, 0x11, sd->clockdiv); |
| 1658 | } | 1617 | } |
| 1659 | 1618 | ||
| 1660 | /******** Special Features ********/ | 1619 | /******** Special Features ********/ |
| @@ -1674,7 +1633,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd, | |||
| 1674 | /* is fully tested. */ | 1633 | /* is fully tested. */ |
| 1675 | /* 7620/6620/6630? don't have register 0x35, so play it safe */ | 1634 | /* 7620/6620/6630? don't have register 0x35, so play it safe */ |
| 1676 | if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { | 1635 | if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { |
| 1677 | if (win->width == 640 /*&& win->height == 480*/) | 1636 | if (!qvga) |
| 1678 | i2c_w(sd, 0x35, 0x9e); | 1637 | i2c_w(sd, 0x35, 0x9e); |
| 1679 | else | 1638 | else |
| 1680 | i2c_w(sd, 0x35, 0x1e); | 1639 | i2c_w(sd, 0x35, 0x1e); |
| @@ -1682,13 +1641,31 @@ static int mode_init_ov_sensor_regs(struct sd *sd, | |||
| 1682 | return 0; | 1641 | return 0; |
| 1683 | } | 1642 | } |
| 1684 | 1643 | ||
| 1685 | static int set_ov_sensor_window(struct sd *sd, | 1644 | static void sethvflip(struct sd *sd) |
| 1686 | struct ovsensor_window *win) | ||
| 1687 | { | 1645 | { |
| 1646 | if (sd->sensor != SEN_OV7670) | ||
| 1647 | return; | ||
| 1648 | if (sd->gspca_dev.streaming) | ||
| 1649 | ov51x_stop(sd); | ||
| 1650 | i2c_w_mask(sd, OV7670_REG_MVFP, | ||
| 1651 | OV7670_MVFP_MIRROR * sd->hflip | ||
| 1652 | | OV7670_MVFP_VFLIP * sd->vflip, | ||
| 1653 | OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP); | ||
| 1654 | if (sd->gspca_dev.streaming) | ||
| 1655 | ov51x_restart(sd); | ||
| 1656 | } | ||
| 1657 | |||
| 1658 | static int set_ov_sensor_window(struct sd *sd) | ||
| 1659 | { | ||
| 1660 | struct gspca_dev *gspca_dev; | ||
| 1661 | int qvga; | ||
| 1688 | int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; | 1662 | int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; |
| 1689 | int ret, hstart, hstop, vstop, vstart; | 1663 | int ret, hstart, hstop, vstop, vstart; |
| 1690 | __u8 v; | 1664 | __u8 v; |
| 1691 | 1665 | ||
| 1666 | gspca_dev = &sd->gspca_dev; | ||
| 1667 | qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | ||
| 1668 | |||
| 1692 | /* The different sensor ICs handle setting up of window differently. | 1669 | /* The different sensor ICs handle setting up of window differently. |
| 1693 | * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */ | 1670 | * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */ |
| 1694 | switch (sd->sensor) { | 1671 | switch (sd->sensor) { |
| @@ -1733,7 +1710,7 @@ static int set_ov_sensor_window(struct sd *sd, | |||
| 1733 | switch (sd->sensor) { | 1710 | switch (sd->sensor) { |
| 1734 | case SEN_OV6620: | 1711 | case SEN_OV6620: |
| 1735 | case SEN_OV6630: | 1712 | case SEN_OV6630: |
| 1736 | if (win->quarter) { /* QCIF */ | 1713 | if (qvga) { /* QCIF */ |
| 1737 | hwscale = 0; | 1714 | hwscale = 0; |
| 1738 | vwscale = 0; | 1715 | vwscale = 0; |
| 1739 | } else { /* CIF */ | 1716 | } else { /* CIF */ |
| @@ -1743,7 +1720,7 @@ static int set_ov_sensor_window(struct sd *sd, | |||
| 1743 | } | 1720 | } |
| 1744 | break; | 1721 | break; |
| 1745 | case SEN_OV8610: | 1722 | case SEN_OV8610: |
| 1746 | if (win->quarter) { /* QSVGA */ | 1723 | if (qvga) { /* QSVGA */ |
| 1747 | hwscale = 1; | 1724 | hwscale = 1; |
| 1748 | vwscale = 1; | 1725 | vwscale = 1; |
| 1749 | } else { /* SVGA */ | 1726 | } else { /* SVGA */ |
| @@ -1752,7 +1729,7 @@ static int set_ov_sensor_window(struct sd *sd, | |||
| 1752 | } | 1729 | } |
| 1753 | break; | 1730 | break; |
| 1754 | default: /* SEN_OV7xx0 */ | 1731 | default: /* SEN_OV7xx0 */ |
| 1755 | if (win->quarter) { /* QVGA */ | 1732 | if (qvga) { /* QVGA */ |
| 1756 | hwscale = 1; | 1733 | hwscale = 1; |
| 1757 | vwscale = 0; | 1734 | vwscale = 0; |
| 1758 | } else { /* VGA */ | 1735 | } else { /* VGA */ |
| @@ -1761,7 +1738,7 @@ static int set_ov_sensor_window(struct sd *sd, | |||
| 1761 | } | 1738 | } |
| 1762 | } | 1739 | } |
| 1763 | 1740 | ||
| 1764 | ret = mode_init_ov_sensor_regs(sd, win); | 1741 | ret = mode_init_ov_sensor_regs(sd); |
| 1765 | if (ret < 0) | 1742 | if (ret < 0) |
| 1766 | return ret; | 1743 | return ret; |
| 1767 | 1744 | ||
| @@ -1782,7 +1759,7 @@ static int set_ov_sensor_window(struct sd *sd, | |||
| 1782 | /* I can hard code this for OV7670s */ | 1759 | /* I can hard code this for OV7670s */ |
| 1783 | /* Yes, these numbers do look odd, but they're tested and work! */ | 1760 | /* Yes, these numbers do look odd, but they're tested and work! */ |
| 1784 | if (sd->sensor == SEN_OV7670) { | 1761 | if (sd->sensor == SEN_OV7670) { |
| 1785 | if (win->quarter) { /* QVGA from ov7670.c by | 1762 | if (qvga) { /* QVGA from ov7670.c by |
| 1786 | * Jonathan Corbet */ | 1763 | * Jonathan Corbet */ |
| 1787 | hstart = 164; | 1764 | hstart = 164; |
| 1788 | hstop = 20; | 1765 | hstop = 20; |
| @@ -1796,75 +1773,45 @@ static int set_ov_sensor_window(struct sd *sd, | |||
| 1796 | } | 1773 | } |
| 1797 | /* OV7670 hardware window registers are split across | 1774 | /* OV7670 hardware window registers are split across |
| 1798 | * multiple locations */ | 1775 | * multiple locations */ |
| 1799 | i2c_w(sd, OV7670_REG_HSTART, (hstart >> 3) & 0xff); | 1776 | i2c_w(sd, OV7670_REG_HSTART, hstart >> 3); |
| 1800 | i2c_w(sd, OV7670_REG_HSTOP, (hstop >> 3) & 0xff); | 1777 | i2c_w(sd, OV7670_REG_HSTOP, hstop >> 3); |
| 1801 | v = i2c_r(sd, OV7670_REG_HREF); | 1778 | v = i2c_r(sd, OV7670_REG_HREF); |
| 1802 | v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07); | 1779 | v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07); |
| 1803 | msleep(10); /* need to sleep between read and write to | 1780 | msleep(10); /* need to sleep between read and write to |
| 1804 | * same reg! */ | 1781 | * same reg! */ |
| 1805 | i2c_w(sd, OV7670_REG_HREF, v); | 1782 | i2c_w(sd, OV7670_REG_HREF, v); |
| 1806 | 1783 | ||
| 1807 | i2c_w(sd, OV7670_REG_VSTART, (vstart >> 2) & 0xff); | 1784 | i2c_w(sd, OV7670_REG_VSTART, vstart >> 2); |
| 1808 | i2c_w(sd, OV7670_REG_VSTOP, (vstop >> 2) & 0xff); | 1785 | i2c_w(sd, OV7670_REG_VSTOP, vstop >> 2); |
| 1809 | v = i2c_r(sd, OV7670_REG_VREF); | 1786 | v = i2c_r(sd, OV7670_REG_VREF); |
| 1810 | v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03); | 1787 | v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03); |
| 1811 | msleep(10); /* need to sleep between read and write to | 1788 | msleep(10); /* need to sleep between read and write to |
| 1812 | * same reg! */ | 1789 | * same reg! */ |
| 1813 | i2c_w(sd, OV7670_REG_VREF, v); | 1790 | i2c_w(sd, OV7670_REG_VREF, v); |
| 1814 | 1791 | sethvflip(sd); | |
| 1815 | } else { | 1792 | } else { |
| 1816 | i2c_w(sd, 0x17, hwsbase + (win->x >> hwscale)); | 1793 | i2c_w(sd, 0x17, hwsbase); |
| 1817 | i2c_w(sd, 0x18, hwebase + ((win->x + win->width) >> hwscale)); | 1794 | i2c_w(sd, 0x18, hwebase + (sd->gspca_dev.width >> hwscale)); |
| 1818 | i2c_w(sd, 0x19, vwsbase + (win->y >> vwscale)); | 1795 | i2c_w(sd, 0x19, vwsbase); |
| 1819 | i2c_w(sd, 0x1a, vwebase + ((win->y + win->height) >> vwscale)); | 1796 | i2c_w(sd, 0x1a, vwebase + (sd->gspca_dev.height >> vwscale)); |
| 1820 | } | 1797 | } |
| 1821 | return 0; | 1798 | return 0; |
| 1822 | } | 1799 | } |
| 1823 | 1800 | ||
| 1824 | static int ov_sensor_mode_setup(struct sd *sd, | ||
| 1825 | int width, int height) | ||
| 1826 | { | ||
| 1827 | struct ovsensor_window win; | ||
| 1828 | |||
| 1829 | /* win.format = mode; */ | ||
| 1830 | |||
| 1831 | /* Unless subcapture is enabled, | ||
| 1832 | * center the image window and downsample | ||
| 1833 | * if possible to increase the field of view */ | ||
| 1834 | /* NOTE: OV518(+) and OV519 does downsampling on its own */ | ||
| 1835 | win.width = width; | ||
| 1836 | win.height = height; | ||
| 1837 | if (width == sd->maxwidth) | ||
| 1838 | win.quarter = 0; | ||
| 1839 | else | ||
| 1840 | win.quarter = 1; | ||
| 1841 | |||
| 1842 | /* Center it */ | ||
| 1843 | win.x = (win.width - width) / 2; | ||
| 1844 | win.y = (win.height - height) / 2; | ||
| 1845 | |||
| 1846 | /* Clock is determined by OV519 frame rate code */ | ||
| 1847 | win.clockdiv = sd->clockdiv; | ||
| 1848 | |||
| 1849 | PDEBUG(D_CONF, "Setting clock divider to %d", win.clockdiv); | ||
| 1850 | return set_ov_sensor_window(sd, &win); | ||
| 1851 | } | ||
| 1852 | |||
| 1853 | /* -- start the camera -- */ | 1801 | /* -- start the camera -- */ |
| 1854 | static void sd_start(struct gspca_dev *gspca_dev) | 1802 | static void sd_start(struct gspca_dev *gspca_dev) |
| 1855 | { | 1803 | { |
| 1856 | struct sd *sd = (struct sd *) gspca_dev; | 1804 | struct sd *sd = (struct sd *) gspca_dev; |
| 1857 | int ret; | 1805 | int ret; |
| 1858 | 1806 | ||
| 1859 | 1807 | ret = ov519_mode_init_regs(sd); | |
| 1860 | ret = ov519_mode_init_regs(sd, gspca_dev->width, gspca_dev->height); | ||
| 1861 | if (ret < 0) | 1808 | if (ret < 0) |
| 1862 | goto out; | 1809 | goto out; |
| 1863 | ret = ov_sensor_mode_setup(sd, gspca_dev->width, gspca_dev->height); | 1810 | ret = set_ov_sensor_window(sd); |
| 1864 | if (ret < 0) | 1811 | if (ret < 0) |
| 1865 | goto out; | 1812 | goto out; |
| 1866 | 1813 | ||
| 1867 | ret = ov51x_restart((struct sd *) gspca_dev); | 1814 | ret = ov51x_restart(sd); |
| 1868 | if (ret < 0) | 1815 | if (ret < 0) |
| 1869 | goto out; | 1816 | goto out; |
| 1870 | PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt); | 1817 | PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt); |
| @@ -1938,12 +1885,10 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
| 1938 | { | 1885 | { |
| 1939 | struct sd *sd = (struct sd *) gspca_dev; | 1886 | struct sd *sd = (struct sd *) gspca_dev; |
| 1940 | int val; | 1887 | int val; |
| 1941 | /* int was_streaming; */ | ||
| 1942 | 1888 | ||
| 1943 | val = sd->brightness; | 1889 | val = sd->brightness; |
| 1944 | PDEBUG(D_CONF, "brightness:%d", val); | 1890 | PDEBUG(D_CONF, "brightness:%d", val); |
| 1945 | /* was_streaming = gspca_dev->streaming; | 1891 | /* if (gspca_dev->streaming) |
| 1946 | * if (was_streaming) | ||
| 1947 | * ov51x_stop(sd); */ | 1892 | * ov51x_stop(sd); */ |
| 1948 | switch (sd->sensor) { | 1893 | switch (sd->sensor) { |
| 1949 | case SEN_OV8610: | 1894 | case SEN_OV8610: |
| @@ -1961,12 +1906,12 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
| 1961 | i2c_w(sd, OV7610_REG_BRT, val); | 1906 | i2c_w(sd, OV7610_REG_BRT, val); |
| 1962 | break; | 1907 | break; |
| 1963 | case SEN_OV7670: | 1908 | case SEN_OV7670: |
| 1964 | /*jfm - from windblows | 1909 | /*win trace |
| 1965 | * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */ | 1910 | * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */ |
| 1966 | i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val)); | 1911 | i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val)); |
| 1967 | break; | 1912 | break; |
| 1968 | } | 1913 | } |
| 1969 | /* if (was_streaming) | 1914 | /* if (gspca_dev->streaming) |
| 1970 | * ov51x_restart(sd); */ | 1915 | * ov51x_restart(sd); */ |
| 1971 | } | 1916 | } |
| 1972 | 1917 | ||
| @@ -1974,12 +1919,10 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
| 1974 | { | 1919 | { |
| 1975 | struct sd *sd = (struct sd *) gspca_dev; | 1920 | struct sd *sd = (struct sd *) gspca_dev; |
| 1976 | int val; | 1921 | int val; |
| 1977 | /* int was_streaming; */ | ||
| 1978 | 1922 | ||
| 1979 | val = sd->contrast; | 1923 | val = sd->contrast; |
| 1980 | PDEBUG(D_CONF, "contrast:%d", val); | 1924 | PDEBUG(D_CONF, "contrast:%d", val); |
| 1981 | /* was_streaming = gspca_dev->streaming; | 1925 | /* if (gspca_dev->streaming) |
| 1982 | if (was_streaming) | ||
| 1983 | ov51x_stop(sd); */ | 1926 | ov51x_stop(sd); */ |
| 1984 | switch (sd->sensor) { | 1927 | switch (sd->sensor) { |
| 1985 | case SEN_OV7610: | 1928 | case SEN_OV7610: |
| @@ -2016,7 +1959,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
| 2016 | i2c_w(sd, OV7670_REG_CONTRAS, val >> 1); | 1959 | i2c_w(sd, OV7670_REG_CONTRAS, val >> 1); |
| 2017 | break; | 1960 | break; |
| 2018 | } | 1961 | } |
| 2019 | /* if (was_streaming) | 1962 | /* if (gspca_dev->streaming) |
| 2020 | ov51x_restart(sd); */ | 1963 | ov51x_restart(sd); */ |
| 2021 | } | 1964 | } |
| 2022 | 1965 | ||
| @@ -2024,12 +1967,10 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
| 2024 | { | 1967 | { |
| 2025 | struct sd *sd = (struct sd *) gspca_dev; | 1968 | struct sd *sd = (struct sd *) gspca_dev; |
| 2026 | int val; | 1969 | int val; |
| 2027 | /* int was_streaming; */ | ||
| 2028 | 1970 | ||
| 2029 | val = sd->colors; | 1971 | val = sd->colors; |
| 2030 | PDEBUG(D_CONF, "saturation:%d", val); | 1972 | PDEBUG(D_CONF, "saturation:%d", val); |
| 2031 | /* was_streaming = gspca_dev->streaming; | 1973 | /* if (gspca_dev->streaming) |
| 2032 | if (was_streaming) | ||
| 2033 | ov51x_stop(sd); */ | 1974 | ov51x_stop(sd); */ |
| 2034 | switch (sd->sensor) { | 1975 | switch (sd->sensor) { |
| 2035 | case SEN_OV8610: | 1976 | case SEN_OV8610: |
| @@ -2055,7 +1996,7 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
| 2055 | /* set REG_COM13 values for UV sat auto mode */ | 1996 | /* set REG_COM13 values for UV sat auto mode */ |
| 2056 | break; | 1997 | break; |
| 2057 | } | 1998 | } |
| 2058 | /* if (was_streaming) | 1999 | /* if (gspca_dev->streaming) |
| 2059 | ov51x_restart(sd); */ | 2000 | ov51x_restart(sd); */ |
| 2060 | } | 2001 | } |
| 2061 | 2002 | ||
| @@ -2110,6 +2051,40 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | |||
| 2110 | return 0; | 2051 | return 0; |
| 2111 | } | 2052 | } |
| 2112 | 2053 | ||
| 2054 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) | ||
| 2055 | { | ||
| 2056 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 2057 | |||
| 2058 | sd->hflip = val; | ||
| 2059 | sethvflip(sd); | ||
| 2060 | return 0; | ||
| 2061 | } | ||
| 2062 | |||
| 2063 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
| 2064 | { | ||
| 2065 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 2066 | |||
| 2067 | *val = sd->hflip; | ||
| 2068 | return 0; | ||
| 2069 | } | ||
| 2070 | |||
| 2071 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val) | ||
| 2072 | { | ||
| 2073 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 2074 | |||
| 2075 | sd->vflip = val; | ||
| 2076 | sethvflip(sd); | ||
| 2077 | return 0; | ||
| 2078 | } | ||
| 2079 | |||
| 2080 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
| 2081 | { | ||
| 2082 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 2083 | |||
| 2084 | *val = sd->vflip; | ||
| 2085 | return 0; | ||
| 2086 | } | ||
| 2087 | |||
| 2113 | /* sub-driver description */ | 2088 | /* sub-driver description */ |
| 2114 | static const struct sd_desc sd_desc = { | 2089 | static const struct sd_desc sd_desc = { |
| 2115 | .name = MODULE_NAME, | 2090 | .name = MODULE_NAME, |
| @@ -2178,4 +2153,3 @@ module_exit(sd_mod_exit); | |||
| 2178 | 2153 | ||
| 2179 | module_param(frame_rate, int, 0644); | 2154 | module_param(frame_rate, int, 0644); |
| 2180 | MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)"); | 2155 | MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)"); |
| 2181 | |||
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index ea3d7021f401..815bea6edc44 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c | |||
| @@ -31,7 +31,9 @@ MODULE_LICENSE("GPL"); | |||
| 31 | struct sd { | 31 | struct sd { |
| 32 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 32 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
| 33 | 33 | ||
| 34 | int avg_lum; | 34 | int lum_sum; |
| 35 | atomic_t avg_lum; | ||
| 36 | atomic_t do_gain; | ||
| 35 | 37 | ||
| 36 | unsigned char brightness; | 38 | unsigned char brightness; |
| 37 | unsigned char contrast; | 39 | unsigned char contrast; |
| @@ -271,6 +273,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
| 271 | sd->contrast = CONTRAST_DEF; | 273 | sd->contrast = CONTRAST_DEF; |
| 272 | sd->colors = COLOR_DEF; | 274 | sd->colors = COLOR_DEF; |
| 273 | sd->autogain = AUTOGAIN_DEF; | 275 | sd->autogain = AUTOGAIN_DEF; |
| 276 | sd->ag_cnt = -1; | ||
| 274 | return 0; | 277 | return 0; |
| 275 | } | 278 | } |
| 276 | 279 | ||
| @@ -311,6 +314,18 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
| 311 | PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); | 314 | PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); |
| 312 | } | 315 | } |
| 313 | 316 | ||
| 317 | static void setautogain(struct gspca_dev *gspca_dev) | ||
| 318 | { | ||
| 319 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 320 | |||
| 321 | if (sd->autogain) { | ||
| 322 | sd->lum_sum = 0; | ||
| 323 | sd->ag_cnt = AG_CNT_START; | ||
| 324 | } else { | ||
| 325 | sd->ag_cnt = -1; | ||
| 326 | } | ||
| 327 | } | ||
| 328 | |||
| 314 | /* this function is called at open time */ | 329 | /* this function is called at open time */ |
| 315 | static int sd_open(struct gspca_dev *gspca_dev) | 330 | static int sd_open(struct gspca_dev *gspca_dev) |
| 316 | { | 331 | { |
| @@ -320,8 +335,6 @@ static int sd_open(struct gspca_dev *gspca_dev) | |||
| 320 | 335 | ||
| 321 | static void sd_start(struct gspca_dev *gspca_dev) | 336 | static void sd_start(struct gspca_dev *gspca_dev) |
| 322 | { | 337 | { |
| 323 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 324 | |||
| 325 | reg_w(gspca_dev, 0xff, 0x01); | 338 | reg_w(gspca_dev, 0xff, 0x01); |
| 326 | reg_w_buf(gspca_dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8); | 339 | reg_w_buf(gspca_dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8); |
| 327 | reg_w_buf(gspca_dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8); | 340 | reg_w_buf(gspca_dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8); |
| @@ -394,6 +407,7 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
| 394 | setcontrast(gspca_dev); | 407 | setcontrast(gspca_dev); |
| 395 | setbrightness(gspca_dev); | 408 | setbrightness(gspca_dev); |
| 396 | setcolors(gspca_dev); | 409 | setcolors(gspca_dev); |
| 410 | setautogain(gspca_dev); | ||
| 397 | 411 | ||
| 398 | /* set correct resolution */ | 412 | /* set correct resolution */ |
| 399 | switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { | 413 | switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { |
| @@ -431,13 +445,6 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
| 431 | reg_w(gspca_dev, 0xff, 0x01); | 445 | reg_w(gspca_dev, 0xff, 0x01); |
| 432 | reg_w(gspca_dev, 0x78, 0x04); | 446 | reg_w(gspca_dev, 0x78, 0x04); |
| 433 | reg_w(gspca_dev, 0x78, 0x05); | 447 | reg_w(gspca_dev, 0x78, 0x05); |
| 434 | |||
| 435 | if (sd->autogain) { | ||
| 436 | sd->ag_cnt = AG_CNT_START; | ||
| 437 | sd->avg_lum = 0; | ||
| 438 | } else { | ||
| 439 | sd->ag_cnt = -1; | ||
| 440 | } | ||
| 441 | } | 448 | } |
| 442 | 449 | ||
| 443 | static void sd_stopN(struct gspca_dev *gspca_dev) | 450 | static void sd_stopN(struct gspca_dev *gspca_dev) |
| @@ -473,13 +480,20 @@ static void sd_close(struct gspca_dev *gspca_dev) | |||
| 473 | reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ | 480 | reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ |
| 474 | } | 481 | } |
| 475 | 482 | ||
| 476 | static void setautogain(struct gspca_dev *gspca_dev, int luma) | 483 | static void do_autogain(struct gspca_dev *gspca_dev) |
| 477 | { | 484 | { |
| 485 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 486 | int luma; | ||
| 478 | int luma_mean = 128; | 487 | int luma_mean = 128; |
| 479 | int luma_delta = 20; | 488 | int luma_delta = 20; |
| 480 | __u8 spring = 5; | 489 | __u8 spring = 5; |
| 481 | int Gbright; | 490 | int Gbright; |
| 482 | 491 | ||
| 492 | if (!atomic_read(&sd->do_gain)) | ||
| 493 | return; | ||
| 494 | atomic_set(&sd->do_gain, 0); | ||
| 495 | |||
| 496 | luma = atomic_read(&sd->avg_lum); | ||
| 483 | Gbright = reg_r(gspca_dev, 0x02); | 497 | Gbright = reg_r(gspca_dev, 0x02); |
| 484 | PDEBUG(D_FRAM, "luma mean %d", luma); | 498 | PDEBUG(D_FRAM, "luma mean %d", luma); |
| 485 | if (luma < luma_mean - luma_delta || | 499 | if (luma < luma_mean - luma_delta || |
| @@ -523,12 +537,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
| 523 | 537 | ||
| 524 | /* start of frame */ | 538 | /* start of frame */ |
| 525 | if (sd->ag_cnt >= 0 && p > 28) { | 539 | if (sd->ag_cnt >= 0 && p > 28) { |
| 526 | sd->avg_lum += data[p - 23]; | 540 | sd->lum_sum += data[p - 23]; |
| 527 | if (--sd->ag_cnt < 0) { | 541 | if (--sd->ag_cnt < 0) { |
| 528 | sd->ag_cnt = AG_CNT_START; | 542 | sd->ag_cnt = AG_CNT_START; |
| 529 | setautogain(gspca_dev, | 543 | atomic_set(&sd->avg_lum, |
| 530 | sd->avg_lum / AG_CNT_START); | 544 | sd->lum_sum / AG_CNT_START); |
| 531 | sd->avg_lum = 0; | 545 | sd->lum_sum = 0; |
| 546 | atomic_set(&sd->do_gain, 1); | ||
| 532 | } | 547 | } |
| 533 | } | 548 | } |
| 534 | 549 | ||
| @@ -677,12 +692,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | |||
| 677 | struct sd *sd = (struct sd *) gspca_dev; | 692 | struct sd *sd = (struct sd *) gspca_dev; |
| 678 | 693 | ||
| 679 | sd->autogain = val; | 694 | sd->autogain = val; |
| 680 | if (val) { | 695 | if (gspca_dev->streaming) |
| 681 | sd->ag_cnt = AG_CNT_START; | 696 | setautogain(gspca_dev); |
| 682 | sd->avg_lum = 0; | ||
| 683 | } else { | ||
| 684 | sd->ag_cnt = -1; | ||
| 685 | } | ||
| 686 | return 0; | 697 | return 0; |
| 687 | } | 698 | } |
| 688 | 699 | ||
| @@ -706,6 +717,7 @@ static struct sd_desc sd_desc = { | |||
| 706 | .stop0 = sd_stop0, | 717 | .stop0 = sd_stop0, |
| 707 | .close = sd_close, | 718 | .close = sd_close, |
| 708 | .pkt_scan = sd_pkt_scan, | 719 | .pkt_scan = sd_pkt_scan, |
| 720 | .dq_callback = do_autogain, | ||
| 709 | }; | 721 | }; |
| 710 | 722 | ||
| 711 | /* -- module initialisation -- */ | 723 | /* -- module initialisation -- */ |
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index e18748c5a14d..11210c71f66c 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c | |||
| @@ -408,7 +408,7 @@ static void reg_w(struct gspca_dev *gspca_dev, | |||
| 408 | const __u8 *buffer, | 408 | const __u8 *buffer, |
| 409 | int len) | 409 | int len) |
| 410 | { | 410 | { |
| 411 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 411 | #ifdef GSPCA_DEBUG |
| 412 | if (len > sizeof gspca_dev->usb_buf) { | 412 | if (len > sizeof gspca_dev->usb_buf) { |
| 413 | PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow"); | 413 | PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow"); |
| 414 | return; | 414 | return; |
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 33a3df1f6915..245a30ec5fb1 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c | |||
| @@ -32,7 +32,7 @@ MODULE_LICENSE("GPL"); | |||
| 32 | struct sd { | 32 | struct sd { |
| 33 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 33 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
| 34 | 34 | ||
| 35 | int avg_lum; | 35 | atomic_t avg_lum; |
| 36 | unsigned int exposure; | 36 | unsigned int exposure; |
| 37 | 37 | ||
| 38 | unsigned short brightness; | 38 | unsigned short brightness; |
| @@ -148,55 +148,58 @@ static struct v4l2_pix_format vga_mode[] = { | |||
| 148 | 148 | ||
| 149 | /*Data from sn9c102p+hv71331r */ | 149 | /*Data from sn9c102p+hv71331r */ |
| 150 | static const __u8 sn_hv7131[] = { | 150 | static const __u8 sn_hv7131[] = { |
| 151 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */ | 151 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
| 152 | 0x00, 0x03, 0x64, 0x00, 0x1A, 0x20, 0x20, 0x20, 0xA1, 0x11, | 152 | 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20, |
| 153 | /* rega regb regc regd rege regf reg10 reg11 */ | 153 | /* reg8 reg9 rega regb regc regd rege regf */ |
| 154 | 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, /* 00 */ | 154 | 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, |
| 155 | /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */ | 155 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ |
| 156 | 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, 0x0a, 0x00, 0x00, 0x00, | 156 | 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, |
| 157 | /* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */ | 157 | /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ |
| 158 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | 158 | 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
| 159 | }; | 159 | }; |
| 160 | 160 | ||
| 161 | static const __u8 sn_mi0360[] = { | 161 | static const __u8 sn_mi0360[] = { |
| 162 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */ | 162 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
| 163 | 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xb1, 0x5d, | 163 | 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, |
| 164 | /* rega regb regc regd rege regf reg10 reg11 */ | 164 | /* reg8 reg9 rega regb regc regd rege regf */ |
| 165 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, | 165 | 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, |
| 166 | /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */ | 166 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ |
| 167 | 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, 0x06, 0x00, 0x00, 0x00, | 167 | 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, |
| 168 | /* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */ | 168 | /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ |
| 169 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | 169 | 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
| 170 | }; | 170 | }; |
| 171 | 171 | ||
| 172 | static const __u8 sn_mo4000[] = { | 172 | static const __u8 sn_mo4000[] = { |
| 173 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */ | 173 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
| 174 | 0x12, 0x23, 0x60, 0x00, 0x1A, 0x00, 0x20, 0x18, 0x81, | 174 | 0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18, |
| 175 | /* reg9 rega regb regc regd rege regf reg10 reg11*/ | 175 | /* reg8 reg9 rega regb regc regd rege regf */ |
| 176 | 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, | 176 | 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 177 | /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/ | 177 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ |
| 178 | 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40, 0x08, 0x00, 0x00, | 178 | 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40, |
| 179 | /* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/ | 179 | /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ |
| 180 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x25, 0x39, 0x4b, | 180 | 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
| 181 | 0x5c, 0x6b, 0x79, 0x87, 0x95, 0xa2, 0xaf, 0xbb, 0xc7, | ||
| 182 | 0xd3, 0xdf, 0xea, 0xf5 | ||
| 183 | }; | 181 | }; |
| 184 | 182 | ||
| 185 | static const __u8 sn_ov7648[] = { | 183 | static const __u8 sn_ov7648[] = { |
| 186 | 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xA1, 0x6E, 0x18, 0x65, | 184 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
| 187 | 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1E, 0x82, | 185 | 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, |
| 188 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x00 | 186 | /* reg8 reg9 rega regb regc regd rege regf */ |
| 187 | 0xa1, 0x6e, 0x18, 0x65, 0x00, 0x00, 0x00, 0x10, | ||
| 188 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ | ||
| 189 | 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x82, | ||
| 190 | /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ | ||
| 191 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
| 189 | }; | 192 | }; |
| 190 | 193 | ||
| 191 | static const __u8 sn_ov7660[] = { | 194 | static const __u8 sn_ov7660[] = { |
| 192 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */ | 195 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
| 193 | 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x81, | 196 | 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, |
| 194 | /* reg9 rega regb regc regd rege regf reg10 reg11*/ | 197 | /* reg8 reg9 rega regb regc regd rege regf */ |
| 195 | 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, | 198 | 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, |
| 196 | /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/ | 199 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ |
| 197 | 0x01, 0x01, 0x14, 0x28, 0x1e, 0x00, 0x07, 0x00, 0x00, | 200 | 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20, |
| 198 | /* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/ | 201 | /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ |
| 199 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | 202 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 200 | }; | 203 | }; |
| 201 | 204 | ||
| 202 | /* sequence specific to the sensors - !! index = SENSOR_xxx */ | 205 | /* sequence specific to the sensors - !! index = SENSOR_xxx */ |
| @@ -212,10 +215,6 @@ static const __u8 regsn20[] = { | |||
| 212 | 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, | 215 | 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, |
| 213 | 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff | 216 | 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff |
| 214 | }; | 217 | }; |
| 215 | static const __u8 regsn20_sn9c120[] = { | ||
| 216 | 0x00, 0x25, 0x3c, 0x50, 0x62, 0x72, 0x81, 0x90, | ||
| 217 | 0x9e, 0xab, 0xb8, 0xc5, 0xd1, 0xdd, 0xe9, 0xf4, 0xff | ||
| 218 | }; | ||
| 219 | static const __u8 regsn20_sn9c325[] = { | 218 | static const __u8 regsn20_sn9c325[] = { |
| 220 | 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4, | 219 | 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4, |
| 221 | 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5 | 220 | 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5 |
| @@ -227,21 +226,6 @@ static const __u8 reg84[] = { | |||
| 227 | /* 0x00, 0x00, 0x00, 0x00, 0x00 */ | 226 | /* 0x00, 0x00, 0x00, 0x00, 0x00 */ |
| 228 | 0xf7, 0x0f, 0x0a, 0x00, 0x00 | 227 | 0xf7, 0x0f, 0x0a, 0x00, 0x00 |
| 229 | }; | 228 | }; |
| 230 | static const __u8 reg84_sn9c120_1[] = { | ||
| 231 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 232 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 233 | 0x00, 0x00, 0x0c, 0x00, 0x00 | ||
| 234 | }; | ||
| 235 | static const __u8 reg84_sn9c120_2[] = { | ||
| 236 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 237 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 238 | 0x00, 0x00, 0x0c, 0x02, 0x3b | ||
| 239 | }; | ||
| 240 | static const __u8 reg84_sn9c120_3[] = { | ||
| 241 | 0x14, 0x00, 0x27, 0x00, 0x08, 0x00, 0xeb, 0x0f, | ||
| 242 | 0xd5, 0x0f, 0x42, 0x00, 0x41, 0x00, 0xca, 0x0f, | ||
| 243 | 0xf5, 0x0f, 0x0c, 0x02, 0x3b | ||
| 244 | }; | ||
| 245 | static const __u8 reg84_sn9c325[] = { | 229 | static const __u8 reg84_sn9c325[] = { |
| 246 | 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f, | 230 | 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f, |
| 247 | 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f, | 231 | 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f, |
| @@ -360,17 +344,15 @@ static const __u8 ov7660_sensor_init[][8] = { | |||
| 360 | {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ | 344 | {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ |
| 361 | /* (delay 20ms) */ | 345 | /* (delay 20ms) */ |
| 362 | {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, | 346 | {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, |
| 363 | /* Outformat ?? rawRGB */ | 347 | /* Outformat = rawRGB */ |
| 364 | {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */ | 348 | {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */ |
| 365 | {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10}, | 349 | {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10}, |
| 366 | /* {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10}, */ | ||
| 367 | /* GAIN BLUE RED VREF */ | 350 | /* GAIN BLUE RED VREF */ |
| 368 | {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10}, | 351 | {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10}, |
| 369 | /* COM 1 BAVE GEAVE AECHH */ | 352 | /* COM 1 BAVE GEAVE AECHH */ |
| 370 | {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */ | 353 | {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */ |
| 371 | {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */ | 354 | {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */ |
| 372 | {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xf8, 0x10}, | 355 | {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10}, |
| 373 | /* {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10}, */ | ||
| 374 | /* AECH CLKRC COM7 COM8 */ | 356 | /* AECH CLKRC COM7 COM8 */ |
| 375 | {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */ | 357 | {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */ |
| 376 | {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10}, | 358 | {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10}, |
| @@ -379,8 +361,8 @@ static const __u8 ov7660_sensor_init[][8] = { | |||
| 379 | {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */ | 361 | {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */ |
| 380 | {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10}, | 362 | {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10}, |
| 381 | /* BOS GBOS GROS ROS (BGGR offset) */ | 363 | /* BOS GBOS GROS ROS (BGGR offset) */ |
| 382 | {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, | 364 | /* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */ |
| 383 | /* {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10}, */ | 365 | {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10}, |
| 384 | /* AEW AEB VPT BBIAS */ | 366 | /* AEW AEB VPT BBIAS */ |
| 385 | {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10}, | 367 | {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10}, |
| 386 | /* GbBIAS RSVD EXHCH EXHCL */ | 368 | /* GbBIAS RSVD EXHCH EXHCL */ |
| @@ -407,9 +389,9 @@ static const __u8 ov7660_sensor_init[][8] = { | |||
| 407 | {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10}, | 389 | {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10}, |
| 408 | /* LCC1 LCC2 LCC3 LCC4 */ | 390 | /* LCC1 LCC2 LCC3 LCC4 */ |
| 409 | {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */ | 391 | {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */ |
| 410 | {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, | 392 | {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */ |
| 411 | {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10}, | 393 | {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10}, |
| 412 | /* band gap reference [0..3] DBLV */ | 394 | /* band gap reference [0:3] DBLV */ |
| 413 | {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */ | 395 | {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */ |
| 414 | {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */ | 396 | {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */ |
| 415 | {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */ | 397 | {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */ |
| @@ -419,37 +401,35 @@ static const __u8 ov7660_sensor_init[][8] = { | |||
| 419 | {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */ | 401 | {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */ |
| 420 | {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ | 402 | {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ |
| 421 | {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ | 403 | {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ |
| 422 | {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, | 404 | {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */ |
| 423 | /****** (some exchanges in the win trace) ******/ | 405 | /****** (some exchanges in the win trace) ******/ |
| 424 | {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, | 406 | {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */ |
| 425 | /* bits[3..0]reserved */ | 407 | /* bits[3..0]reserved */ |
| 426 | {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, | 408 | {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, |
| 427 | {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, | 409 | {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, |
| 428 | /* VREF vertical frame ctrl */ | 410 | /* VREF vertical frame ctrl */ |
| 429 | {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, | 411 | {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, |
| 430 | {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* 0x20 */ | 412 | {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */ |
| 431 | {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, | 413 | {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */ |
| 432 | {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, | 414 | {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */ |
| 433 | /* {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, */ | 415 | {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */ |
| 434 | {0xa1, 0x21, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x10}, | 416 | /* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */ |
| 435 | {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, | ||
| 436 | /****** (some exchanges in the win trace) ******/ | 417 | /****** (some exchanges in the win trace) ******/ |
| 437 | {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */ | 418 | {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */ |
| 438 | {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10},/* dummy line low */ | 419 | {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */ |
| 439 | {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, | 420 | {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */ |
| 440 | {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, | 421 | {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */ |
| 441 | {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, | 422 | /* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */ |
| 442 | /****** (some exchanges in the win trace) ******/ | 423 | /****** (some exchanges in the win trace) ******/ |
| 443 | /**********startsensor KO if changed !!****/ | 424 | /******!! startsensor KO if changed !!****/ |
| 444 | {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10}, | 425 | {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10}, |
| 445 | {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10}, | 426 | {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10}, |
| 446 | {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, | 427 | {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, |
| 447 | {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10}, | 428 | {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10}, |
| 448 | /* here may start the isoc exchanges */ | ||
| 449 | {} | 429 | {} |
| 450 | }; | 430 | }; |
| 451 | /* reg0x04 reg0x07 reg 0x10 */ | 431 | /* reg 0x04 reg 0x07 reg 0x10 */ |
| 452 | /* expo = (COM1 & 0x02) | (AECHH & 0x2f <<10) [ (AECh << 2) */ | 432 | /* expo = (COM1 & 0x02) | ((AECHH & 0x2f) << 10) | (AECh << 2) */ |
| 453 | 433 | ||
| 454 | static const __u8 ov7648_sensor_init[][8] = { | 434 | static const __u8 ov7648_sensor_init[][8] = { |
| 455 | {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00}, | 435 | {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00}, |
| @@ -680,13 +660,12 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
| 680 | const __u8 *reg9a; | 660 | const __u8 *reg9a; |
| 681 | static const __u8 reg9a_def[] = | 661 | static const __u8 reg9a_def[] = |
| 682 | {0x08, 0x40, 0x20, 0x10, 0x00, 0x04}; | 662 | {0x08, 0x40, 0x20, 0x10, 0x00, 0x04}; |
| 683 | static const __u8 reg9a_sn9c120[] = /* from win trace */ | ||
| 684 | {0x00, 0x40, 0x38, 0x30, 0x00, 0x20}; | ||
| 685 | static const __u8 reg9a_sn9c325[] = | 663 | static const __u8 reg9a_sn9c325[] = |
| 686 | {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20}; | 664 | {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20}; |
| 665 | static const __u8 regd4[] = {0x60, 0x00, 0x00}; | ||
| 687 | 666 | ||
| 688 | reg_w1(gspca_dev, 0xf1, 0x00); | 667 | reg_w1(gspca_dev, 0xf1, 0x00); |
| 689 | reg_w1(gspca_dev, 0x01, sn9c1xx[0]); /*fixme:jfm was [1] en v1*/ | 668 | reg_w1(gspca_dev, 0x01, 0x00); /*jfm was sn9c1xx[1] in v1*/ |
| 690 | 669 | ||
| 691 | /* configure gpio */ | 670 | /* configure gpio */ |
| 692 | reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); | 671 | reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); |
| @@ -696,25 +675,17 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
| 696 | case BRIDGE_SN9C325: | 675 | case BRIDGE_SN9C325: |
| 697 | reg9a = reg9a_sn9c325; | 676 | reg9a = reg9a_sn9c325; |
| 698 | break; | 677 | break; |
| 699 | case BRIDGE_SN9C120: | ||
| 700 | reg9a = reg9a_sn9c120; | ||
| 701 | break; | ||
| 702 | default: | 678 | default: |
| 703 | reg9a = reg9a_def; | 679 | reg9a = reg9a_def; |
| 704 | break; | 680 | break; |
| 705 | } | 681 | } |
| 706 | reg_w(gspca_dev, 0x9a, reg9a, 6); | 682 | reg_w(gspca_dev, 0x9a, reg9a, 6); |
| 707 | 683 | ||
| 708 | reg_w1(gspca_dev, 0xd4, 0x60); /*fixme:jfm 60 00 00 (3) ? */ | 684 | reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/ |
| 709 | 685 | ||
| 710 | reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); | 686 | reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); |
| 711 | 687 | ||
| 712 | switch (sd->bridge) { | 688 | switch (sd->bridge) { |
| 713 | case BRIDGE_SN9C120: /* from win trace */ | ||
| 714 | reg_w1(gspca_dev, 0x01, 0x61); | ||
| 715 | reg_w1(gspca_dev, 0x17, 0x20); | ||
| 716 | reg_w1(gspca_dev, 0x01, 0x60); | ||
| 717 | break; | ||
| 718 | case BRIDGE_SN9C325: | 689 | case BRIDGE_SN9C325: |
| 719 | reg_w1(gspca_dev, 0x01, 0x43); | 690 | reg_w1(gspca_dev, 0x01, 0x43); |
| 720 | reg_w1(gspca_dev, 0x17, 0xae); | 691 | reg_w1(gspca_dev, 0x17, 0xae); |
| @@ -810,6 +781,8 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
| 810 | sd->contrast = CONTRAST_DEF; | 781 | sd->contrast = CONTRAST_DEF; |
| 811 | sd->colors = COLOR_DEF; | 782 | sd->colors = COLOR_DEF; |
| 812 | sd->autogain = AUTOGAIN_DEF; | 783 | sd->autogain = AUTOGAIN_DEF; |
| 784 | sd->ag_cnt = -1; | ||
| 785 | |||
| 813 | return 0; | 786 | return 0; |
| 814 | } | 787 | } |
| 815 | 788 | ||
| @@ -823,10 +796,11 @@ static int sd_open(struct gspca_dev *gspca_dev) | |||
| 823 | 796 | ||
| 824 | /* setup a selector by bridge */ | 797 | /* setup a selector by bridge */ |
| 825 | reg_w1(gspca_dev, 0xf1, 0x01); | 798 | reg_w1(gspca_dev, 0xf1, 0x01); |
| 826 | reg_r(gspca_dev, 0x00, 1); /* -> regF1 = 0x00 */ | ||
| 827 | reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]); | ||
| 828 | reg_r(gspca_dev, 0x00, 1); | 799 | reg_r(gspca_dev, 0x00, 1); |
| 800 | reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]); | ||
| 801 | reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */ | ||
| 829 | regF1 = gspca_dev->usb_buf[0]; | 802 | regF1 = gspca_dev->usb_buf[0]; |
| 803 | PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1); | ||
| 830 | switch (sd->bridge) { | 804 | switch (sd->bridge) { |
| 831 | case BRIDGE_SN9C102P: | 805 | case BRIDGE_SN9C102P: |
| 832 | if (regF1 != 0x11) | 806 | if (regF1 != 0x11) |
| @@ -937,15 +911,10 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
| 937 | sd->exposure = setexposure(gspca_dev, expo); | 911 | sd->exposure = setexposure(gspca_dev, expo); |
| 938 | break; | 912 | break; |
| 939 | case SENSOR_MI0360: | 913 | case SENSOR_MI0360: |
| 940 | expo = sd->brightness >> 4; | ||
| 941 | sd->exposure = setexposure(gspca_dev, expo); | ||
| 942 | break; | ||
| 943 | case SENSOR_MO4000: | 914 | case SENSOR_MO4000: |
| 944 | expo = sd->brightness >> 4; | 915 | expo = sd->brightness >> 4; |
| 945 | sd->exposure = setexposure(gspca_dev, expo); | 916 | sd->exposure = setexposure(gspca_dev, expo); |
| 946 | break; | 917 | break; |
| 947 | case SENSOR_OV7660: | ||
| 948 | return; /*jfm??*/ | ||
| 949 | } | 918 | } |
| 950 | 919 | ||
| 951 | k2 = sd->brightness >> 10; | 920 | k2 = sd->brightness >> 10; |
| @@ -958,8 +927,6 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
| 958 | __u8 k2; | 927 | __u8 k2; |
| 959 | __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 }; | 928 | __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 }; |
| 960 | 929 | ||
| 961 | if (sd->sensor == SENSOR_OV7660) | ||
| 962 | return; /*jfm??*/ | ||
| 963 | k2 = sd->contrast; | 930 | k2 = sd->contrast; |
| 964 | contrast[2] = k2; | 931 | contrast[2] = k2; |
| 965 | contrast[0] = (k2 + 1) >> 1; | 932 | contrast[0] = (k2 + 1) >> 1; |
| @@ -981,20 +948,32 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
| 981 | reg_w1(gspca_dev, 0x05, data); | 948 | reg_w1(gspca_dev, 0x05, data); |
| 982 | } | 949 | } |
| 983 | 950 | ||
| 951 | static void setautogain(struct gspca_dev *gspca_dev) | ||
| 952 | { | ||
| 953 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 954 | |||
| 955 | switch (sd->sensor) { | ||
| 956 | case SENSOR_HV7131R: | ||
| 957 | case SENSOR_MO4000: | ||
| 958 | case SENSOR_MI0360: | ||
| 959 | if (sd->autogain) | ||
| 960 | sd->ag_cnt = AG_CNT_START; | ||
| 961 | else | ||
| 962 | sd->ag_cnt = -1; | ||
| 963 | break; | ||
| 964 | } | ||
| 965 | } | ||
| 966 | |||
| 984 | /* -- start the camera -- */ | 967 | /* -- start the camera -- */ |
| 985 | static void sd_start(struct gspca_dev *gspca_dev) | 968 | static void sd_start(struct gspca_dev *gspca_dev) |
| 986 | { | 969 | { |
| 987 | struct sd *sd = (struct sd *) gspca_dev; | 970 | struct sd *sd = (struct sd *) gspca_dev; |
| 988 | int i; | 971 | int i; |
| 989 | __u8 data; | 972 | __u8 reg1, reg17, reg18; |
| 990 | __u8 reg1; | ||
| 991 | __u8 reg17; | ||
| 992 | const __u8 *sn9c1xx; | 973 | const __u8 *sn9c1xx; |
| 993 | int mode; | 974 | int mode; |
| 994 | static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; | 975 | static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; |
| 995 | static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; | 976 | static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; |
| 996 | static const __u8 CA_sn9c120[] = | ||
| 997 | { 0x14, 0xec, 0x0a, 0xf6 }; /* SN9C120 */ | ||
| 998 | static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ | 977 | static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ |
| 999 | static const __u8 CE_sn9c325[] = | 978 | static const __u8 CE_sn9c325[] = |
| 1000 | { 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */ | 979 | { 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */ |
| @@ -1002,9 +981,7 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
| 1002 | sn9c1xx = sn_tb[(int) sd->sensor]; | 981 | sn9c1xx = sn_tb[(int) sd->sensor]; |
| 1003 | configure_gpio(gspca_dev, sn9c1xx); | 982 | configure_gpio(gspca_dev, sn9c1xx); |
| 1004 | 983 | ||
| 1005 | /*fixme:jfm this sequence should appear at end of sd_start */ | 984 | /* reg_w1(gspca_dev, 0x01, 0x44); jfm from win trace*/ |
| 1006 | /* with | ||
| 1007 | reg_w1(gspca_dev, 0x01, 0x44); */ | ||
| 1008 | reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]); | 985 | reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]); |
| 1009 | reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]); | 986 | reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]); |
| 1010 | reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]); | 987 | reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]); |
| @@ -1016,20 +993,16 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
| 1016 | reg_w1(gspca_dev, 0xc7, 0x00); | 993 | reg_w1(gspca_dev, 0xc7, 0x00); |
| 1017 | reg_w1(gspca_dev, 0xc8, 0x50); | 994 | reg_w1(gspca_dev, 0xc8, 0x50); |
| 1018 | reg_w1(gspca_dev, 0xc9, 0x3c); | 995 | reg_w1(gspca_dev, 0xc9, 0x3c); |
| 1019 | /*fixme:jfm end of ending sequence */ | ||
| 1020 | reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); | 996 | reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); |
| 1021 | switch (sd->bridge) { | 997 | switch (sd->bridge) { |
| 1022 | case BRIDGE_SN9C325: | 998 | case BRIDGE_SN9C325: |
| 1023 | data = 0xae; | 999 | reg17 = 0xae; |
| 1024 | break; | ||
| 1025 | case BRIDGE_SN9C120: | ||
| 1026 | data = 0xa0; | ||
| 1027 | break; | 1000 | break; |
| 1028 | default: | 1001 | default: |
| 1029 | data = 0x60; | 1002 | reg17 = 0x60; |
| 1030 | break; | 1003 | break; |
| 1031 | } | 1004 | } |
| 1032 | reg_w1(gspca_dev, 0x17, data); | 1005 | reg_w1(gspca_dev, 0x17, reg17); |
| 1033 | reg_w1(gspca_dev, 0x05, sn9c1xx[5]); | 1006 | reg_w1(gspca_dev, 0x05, sn9c1xx[5]); |
| 1034 | reg_w1(gspca_dev, 0x07, sn9c1xx[7]); | 1007 | reg_w1(gspca_dev, 0x07, sn9c1xx[7]); |
| 1035 | reg_w1(gspca_dev, 0x06, sn9c1xx[6]); | 1008 | reg_w1(gspca_dev, 0x06, sn9c1xx[6]); |
| @@ -1044,20 +1017,6 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
| 1044 | reg_w1(gspca_dev, 0x9a, 0x0a); | 1017 | reg_w1(gspca_dev, 0x9a, 0x0a); |
| 1045 | reg_w1(gspca_dev, 0x99, 0x60); | 1018 | reg_w1(gspca_dev, 0x99, 0x60); |
| 1046 | break; | 1019 | break; |
| 1047 | case BRIDGE_SN9C120: | ||
| 1048 | reg_w(gspca_dev, 0x20, regsn20_sn9c120, | ||
| 1049 | sizeof regsn20_sn9c120); | ||
| 1050 | for (i = 0; i < 2; i++) | ||
| 1051 | reg_w(gspca_dev, 0x84, reg84_sn9c120_1, | ||
| 1052 | sizeof reg84_sn9c120_1); | ||
| 1053 | for (i = 0; i < 6; i++) | ||
| 1054 | reg_w(gspca_dev, 0x84, reg84_sn9c120_2, | ||
| 1055 | sizeof reg84_sn9c120_2); | ||
| 1056 | reg_w(gspca_dev, 0x84, reg84_sn9c120_3, | ||
| 1057 | sizeof reg84_sn9c120_3); | ||
| 1058 | reg_w1(gspca_dev, 0x9a, 0x05); | ||
| 1059 | reg_w1(gspca_dev, 0x99, 0x5b); | ||
| 1060 | break; | ||
| 1061 | default: | 1020 | default: |
| 1062 | reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20); | 1021 | reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20); |
| 1063 | for (i = 0; i < 8; i++) | 1022 | for (i = 0; i < 8; i++) |
| @@ -1107,22 +1066,14 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
| 1107 | /* reg1 = 0x44; */ | 1066 | /* reg1 = 0x44; */ |
| 1108 | /* reg1 = 0x46; (done) */ | 1067 | /* reg1 = 0x46; (done) */ |
| 1109 | } else { | 1068 | } else { |
| 1110 | reg17 = 0xa2; /* 640 */ | 1069 | reg17 = 0x22; /* 640 MCKSIZE */ |
| 1111 | reg1 = 0x40; | 1070 | reg1 = 0x06; |
| 1112 | } | 1071 | } |
| 1113 | break; | 1072 | break; |
| 1114 | } | 1073 | } |
| 1115 | reg_w(gspca_dev, 0xc0, C0, 6); | 1074 | reg_w(gspca_dev, 0xc0, C0, 6); |
| 1075 | reg_w(gspca_dev, 0xca, CA, 4); | ||
| 1116 | switch (sd->bridge) { | 1076 | switch (sd->bridge) { |
| 1117 | case BRIDGE_SN9C120: /*jfm ?? */ | ||
| 1118 | reg_w(gspca_dev, 0xca, CA_sn9c120, 4); | ||
| 1119 | break; | ||
| 1120 | default: | ||
| 1121 | reg_w(gspca_dev, 0xca, CA, 4); | ||
| 1122 | break; | ||
| 1123 | } | ||
| 1124 | switch (sd->bridge) { | ||
| 1125 | case BRIDGE_SN9C120: /*jfm ?? */ | ||
| 1126 | case BRIDGE_SN9C325: | 1077 | case BRIDGE_SN9C325: |
| 1127 | reg_w(gspca_dev, 0xce, CE_sn9c325, 4); | 1078 | reg_w(gspca_dev, 0xce, CE_sn9c325, 4); |
| 1128 | break; | 1079 | break; |
| @@ -1133,19 +1084,19 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
| 1133 | } | 1084 | } |
| 1134 | 1085 | ||
| 1135 | /* here change size mode 0 -> VGA; 1 -> CIF */ | 1086 | /* here change size mode 0 -> VGA; 1 -> CIF */ |
| 1136 | data = 0x40 | sn9c1xx[0x18] | (mode << 4); | 1087 | reg18 = sn9c1xx[0x18] | (mode << 4); |
| 1137 | reg_w1(gspca_dev, 0x18, data); | 1088 | reg_w1(gspca_dev, 0x18, reg18 | 0x40); |
| 1138 | 1089 | ||
| 1139 | reg_w(gspca_dev, 0x100, qtable4, 0x40); | 1090 | reg_w(gspca_dev, 0x100, qtable4, 0x40); |
| 1140 | reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40); | 1091 | reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40); |
| 1141 | 1092 | ||
| 1142 | data = sn9c1xx[0x18] | (mode << 4); | 1093 | reg_w1(gspca_dev, 0x18, reg18); |
| 1143 | reg_w1(gspca_dev, 0x18, data); | ||
| 1144 | 1094 | ||
| 1145 | reg_w1(gspca_dev, 0x17, reg17); | 1095 | reg_w1(gspca_dev, 0x17, reg17); |
| 1146 | reg_w1(gspca_dev, 0x01, reg1); | 1096 | reg_w1(gspca_dev, 0x01, reg1); |
| 1147 | setbrightness(gspca_dev); | 1097 | setbrightness(gspca_dev); |
| 1148 | setcontrast(gspca_dev); | 1098 | setcontrast(gspca_dev); |
| 1099 | setautogain(gspca_dev); | ||
| 1149 | } | 1100 | } |
| 1150 | 1101 | ||
| 1151 | static void sd_stopN(struct gspca_dev *gspca_dev) | 1102 | static void sd_stopN(struct gspca_dev *gspca_dev) |
| @@ -1168,12 +1119,11 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
| 1168 | i2c_w8(gspca_dev, stopmi0360); | 1119 | i2c_w8(gspca_dev, stopmi0360); |
| 1169 | data = 0x29; | 1120 | data = 0x29; |
| 1170 | break; | 1121 | break; |
| 1171 | case SENSOR_MO4000: | ||
| 1172 | break; | ||
| 1173 | case SENSOR_OV7648: | 1122 | case SENSOR_OV7648: |
| 1174 | data = 0x29; | 1123 | data = 0x29; |
| 1175 | break; | 1124 | break; |
| 1176 | default: | 1125 | default: |
| 1126 | /* case SENSOR_MO4000: */ | ||
| 1177 | /* case SENSOR_OV7660: */ | 1127 | /* case SENSOR_OV7660: */ |
| 1178 | break; | 1128 | break; |
| 1179 | } | 1129 | } |
| @@ -1193,16 +1143,23 @@ static void sd_close(struct gspca_dev *gspca_dev) | |||
| 1193 | { | 1143 | { |
| 1194 | } | 1144 | } |
| 1195 | 1145 | ||
| 1196 | static void setautogain(struct gspca_dev *gspca_dev) | 1146 | static void do_autogain(struct gspca_dev *gspca_dev) |
| 1197 | { | 1147 | { |
| 1198 | struct sd *sd = (struct sd *) gspca_dev; | 1148 | struct sd *sd = (struct sd *) gspca_dev; |
| 1199 | /* Thanks S., without your advice, autobright should not work :) */ | ||
| 1200 | int delta; | 1149 | int delta; |
| 1201 | int expotimes = 0; | 1150 | int expotimes; |
| 1202 | __u8 luma_mean = 130; | 1151 | __u8 luma_mean = 130; |
| 1203 | __u8 luma_delta = 20; | 1152 | __u8 luma_delta = 20; |
| 1204 | 1153 | ||
| 1205 | delta = sd->avg_lum; | 1154 | /* Thanks S., without your advice, autobright should not work :) */ |
| 1155 | if (sd->ag_cnt < 0) | ||
| 1156 | return; | ||
| 1157 | if (--sd->ag_cnt >= 0) | ||
| 1158 | return; | ||
| 1159 | sd->ag_cnt = AG_CNT_START; | ||
| 1160 | |||
| 1161 | delta = atomic_read(&sd->avg_lum); | ||
| 1162 | PDEBUG(D_FRAM, "mean lum %d", delta); | ||
| 1206 | if (delta < luma_mean - luma_delta || | 1163 | if (delta < luma_mean - luma_delta || |
| 1207 | delta > luma_mean + luma_delta) { | 1164 | delta > luma_mean + luma_delta) { |
| 1208 | switch (sd->sensor) { | 1165 | switch (sd->sensor) { |
| @@ -1214,8 +1171,9 @@ static void setautogain(struct gspca_dev *gspca_dev) | |||
| 1214 | sd->exposure = setexposure(gspca_dev, | 1171 | sd->exposure = setexposure(gspca_dev, |
| 1215 | (unsigned int) (expotimes << 8)); | 1172 | (unsigned int) (expotimes << 8)); |
| 1216 | break; | 1173 | break; |
| 1217 | case SENSOR_MO4000: | 1174 | default: |
| 1218 | case SENSOR_MI0360: | 1175 | /* case SENSOR_MO4000: */ |
| 1176 | /* case SENSOR_MI0360: */ | ||
| 1219 | expotimes = sd->exposure; | 1177 | expotimes = sd->exposure; |
| 1220 | expotimes += (luma_mean - delta) >> 6; | 1178 | expotimes += (luma_mean - delta) >> 6; |
| 1221 | if (expotimes < 0) | 1179 | if (expotimes < 0) |
| @@ -1228,6 +1186,8 @@ static void setautogain(struct gspca_dev *gspca_dev) | |||
| 1228 | } | 1186 | } |
| 1229 | } | 1187 | } |
| 1230 | 1188 | ||
| 1189 | /* scan the URB packets */ | ||
| 1190 | /* This function is run at interrupt level. */ | ||
| 1231 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 1191 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, |
| 1232 | struct gspca_frame *frame, /* target */ | 1192 | struct gspca_frame *frame, /* target */ |
| 1233 | __u8 *data, /* isoc packet */ | 1193 | __u8 *data, /* isoc packet */ |
| @@ -1244,9 +1204,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
| 1244 | frame, data, sof + 2); | 1204 | frame, data, sof + 2); |
| 1245 | if (sd->ag_cnt < 0) | 1205 | if (sd->ag_cnt < 0) |
| 1246 | return; | 1206 | return; |
| 1247 | if (--sd->ag_cnt >= 0) | ||
| 1248 | return; | ||
| 1249 | sd->ag_cnt = AG_CNT_START; | ||
| 1250 | /* w1 w2 w3 */ | 1207 | /* w1 w2 w3 */ |
| 1251 | /* w4 w5 w6 */ | 1208 | /* w4 w5 w6 */ |
| 1252 | /* w7 w8 */ | 1209 | /* w7 w8 */ |
| @@ -1261,9 +1218,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
| 1261 | /* w5 */ | 1218 | /* w5 */ |
| 1262 | avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4; | 1219 | avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4; |
| 1263 | avg_lum >>= 4; | 1220 | avg_lum >>= 4; |
| 1264 | sd->avg_lum = avg_lum; | 1221 | atomic_set(&sd->avg_lum, avg_lum); |
| 1265 | PDEBUG(D_PACK, "mean lum %d", avg_lum); | ||
| 1266 | setautogain(gspca_dev); | ||
| 1267 | return; | 1222 | return; |
| 1268 | } | 1223 | } |
| 1269 | if (gspca_dev->last_packet_type == LAST_PACKET) { | 1224 | if (gspca_dev->last_packet_type == LAST_PACKET) { |
| @@ -1300,6 +1255,7 @@ static unsigned int getexposure(struct gspca_dev *gspca_dev) | |||
| 1300 | (hexpo << 10) | (mexpo << 2) | lexpo); | 1255 | (hexpo << 10) | (mexpo << 2) | lexpo); |
| 1301 | return (hexpo << 10) | (mexpo << 2) | lexpo; | 1256 | return (hexpo << 10) | (mexpo << 2) | lexpo; |
| 1302 | default: | 1257 | default: |
| 1258 | /* case SENSOR_OV7648: * jfm: is it ok for 7648? */ | ||
| 1303 | /* case SENSOR_OV7660: */ | 1259 | /* case SENSOR_OV7660: */ |
| 1304 | /* read sensor exposure */ | 1260 | /* read sensor exposure */ |
| 1305 | i2c_r5(gspca_dev, 0x04); | 1261 | i2c_r5(gspca_dev, 0x04); |
| @@ -1318,14 +1274,12 @@ static void getbrightness(struct gspca_dev *gspca_dev) | |||
| 1318 | /* hardcoded registers seem not readable */ | 1274 | /* hardcoded registers seem not readable */ |
| 1319 | switch (sd->sensor) { | 1275 | switch (sd->sensor) { |
| 1320 | case SENSOR_HV7131R: | 1276 | case SENSOR_HV7131R: |
| 1321 | /* sd->brightness = 0x7fff; */ | ||
| 1322 | sd->brightness = getexposure(gspca_dev) >> 4; | 1277 | sd->brightness = getexposure(gspca_dev) >> 4; |
| 1323 | break; | 1278 | break; |
| 1324 | case SENSOR_MI0360: | 1279 | case SENSOR_MI0360: |
| 1325 | sd->brightness = getexposure(gspca_dev) << 4; | 1280 | sd->brightness = getexposure(gspca_dev) << 4; |
| 1326 | break; | 1281 | break; |
| 1327 | case SENSOR_MO4000: | 1282 | case SENSOR_MO4000: |
| 1328 | /* sd->brightness = 0x1fff; */ | ||
| 1329 | sd->brightness = getexposure(gspca_dev) << 4; | 1283 | sd->brightness = getexposure(gspca_dev) << 4; |
| 1330 | break; | 1284 | break; |
| 1331 | } | 1285 | } |
| @@ -1391,10 +1345,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | |||
| 1391 | struct sd *sd = (struct sd *) gspca_dev; | 1345 | struct sd *sd = (struct sd *) gspca_dev; |
| 1392 | 1346 | ||
| 1393 | sd->autogain = val; | 1347 | sd->autogain = val; |
| 1394 | if (val) | 1348 | if (gspca_dev->streaming) |
| 1395 | sd->ag_cnt = AG_CNT_START; | 1349 | setautogain(gspca_dev); |
| 1396 | else | ||
| 1397 | sd->ag_cnt = -1; | ||
| 1398 | return 0; | 1350 | return 0; |
| 1399 | } | 1351 | } |
| 1400 | 1352 | ||
| @@ -1418,6 +1370,7 @@ static const struct sd_desc sd_desc = { | |||
| 1418 | .stop0 = sd_stop0, | 1370 | .stop0 = sd_stop0, |
| 1419 | .close = sd_close, | 1371 | .close = sd_close, |
| 1420 | .pkt_scan = sd_pkt_scan, | 1372 | .pkt_scan = sd_pkt_scan, |
| 1373 | .dq_callback = do_autogain, | ||
| 1421 | }; | 1374 | }; |
| 1422 | 1375 | ||
| 1423 | /* -- module initialisation -- */ | 1376 | /* -- module initialisation -- */ |
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c index 3c2be80cbd65..eda29d609359 100644 --- a/drivers/media/video/gspca/spca505.c +++ b/drivers/media/video/gspca/spca505.c | |||
| @@ -61,27 +61,27 @@ static struct ctrl sd_ctrls[] = { | |||
| 61 | 61 | ||
| 62 | static struct v4l2_pix_format vga_mode[] = { | 62 | static struct v4l2_pix_format vga_mode[] = { |
| 63 | {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, | 63 | {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
| 64 | .bytesperline = 160 * 3, | 64 | .bytesperline = 160, |
| 65 | .sizeimage = 160 * 120 * 3 / 2, | 65 | .sizeimage = 160 * 120 * 3 / 2, |
| 66 | .colorspace = V4L2_COLORSPACE_SRGB, | 66 | .colorspace = V4L2_COLORSPACE_SRGB, |
| 67 | .priv = 5}, | 67 | .priv = 5}, |
| 68 | {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, | 68 | {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
| 69 | .bytesperline = 176 * 3, | 69 | .bytesperline = 176, |
| 70 | .sizeimage = 176 * 144 * 3 / 2, | 70 | .sizeimage = 176 * 144 * 3 / 2, |
| 71 | .colorspace = V4L2_COLORSPACE_SRGB, | 71 | .colorspace = V4L2_COLORSPACE_SRGB, |
| 72 | .priv = 4}, | 72 | .priv = 4}, |
| 73 | {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, | 73 | {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
| 74 | .bytesperline = 320 * 3, | 74 | .bytesperline = 320, |
| 75 | .sizeimage = 320 * 240 * 3 / 2, | 75 | .sizeimage = 320 * 240 * 3 / 2, |
| 76 | .colorspace = V4L2_COLORSPACE_SRGB, | 76 | .colorspace = V4L2_COLORSPACE_SRGB, |
| 77 | .priv = 2}, | 77 | .priv = 2}, |
| 78 | {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, | 78 | {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
| 79 | .bytesperline = 352 * 3, | 79 | .bytesperline = 352, |
| 80 | .sizeimage = 352 * 288 * 3 / 2, | 80 | .sizeimage = 352 * 288 * 3 / 2, |
| 81 | .colorspace = V4L2_COLORSPACE_SRGB, | 81 | .colorspace = V4L2_COLORSPACE_SRGB, |
| 82 | .priv = 1}, | 82 | .priv = 1}, |
| 83 | {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, | 83 | {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
| 84 | .bytesperline = 640 * 3, | 84 | .bytesperline = 640, |
| 85 | .sizeimage = 640 * 480 * 3 / 2, | 85 | .sizeimage = 640 * 480 * 3 / 2, |
| 86 | .colorspace = V4L2_COLORSPACE_SRGB, | 86 | .colorspace = V4L2_COLORSPACE_SRGB, |
| 87 | .priv = 0}, | 87 | .priv = 0}, |
| @@ -776,7 +776,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
| 776 | default: | 776 | default: |
| 777 | data += 1; | 777 | data += 1; |
| 778 | len -= 1; | 778 | len -= 1; |
| 779 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | 779 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, |
| 780 | data, len); | 780 | data, len); |
| 781 | break; | 781 | break; |
| 782 | } | 782 | } |
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c index 6fe715c80ad2..f622fa75766d 100644 --- a/drivers/media/video/gspca/spca506.c +++ b/drivers/media/video/gspca/spca506.c | |||
| @@ -112,27 +112,27 @@ static struct ctrl sd_ctrls[] = { | |||
| 112 | 112 | ||
| 113 | static struct v4l2_pix_format vga_mode[] = { | 113 | static struct v4l2_pix_format vga_mode[] = { |
| 114 | {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, | 114 | {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
| 115 | .bytesperline = 160 * 3, | 115 | .bytesperline = 160, |
| 116 | .sizeimage = 160 * 120 * 3 / 2, | 116 | .sizeimage = 160 * 120 * 3 / 2, |
| 117 | .colorspace = V4L2_COLORSPACE_SRGB, | 117 | .colorspace = V4L2_COLORSPACE_SRGB, |
| 118 | .priv = 5}, | 118 | .priv = 5}, |
| 119 | {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, | 119 | {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
| 120 | .bytesperline = 176 * 3, | 120 | .bytesperline = 176, |
| 121 | .sizeimage = 176 * 144 * 3 / 2, | 121 | .sizeimage = 176 * 144 * 3 / 2, |
| 122 | .colorspace = V4L2_COLORSPACE_SRGB, | 122 | .colorspace = V4L2_COLORSPACE_SRGB, |
| 123 | .priv = 4}, | 123 | .priv = 4}, |
| 124 | {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, | 124 | {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
| 125 | .bytesperline = 320 * 3, | 125 | .bytesperline = 320, |
| 126 | .sizeimage = 320 * 240 * 3 / 2, | 126 | .sizeimage = 320 * 240 * 3 / 2, |
| 127 | .colorspace = V4L2_COLORSPACE_SRGB, | 127 | .colorspace = V4L2_COLORSPACE_SRGB, |
| 128 | .priv = 2}, | 128 | .priv = 2}, |
| 129 | {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, | 129 | {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
| 130 | .bytesperline = 352 * 3, | 130 | .bytesperline = 352, |
| 131 | .sizeimage = 352 * 288 * 3 / 2, | 131 | .sizeimage = 352 * 288 * 3 / 2, |
| 132 | .colorspace = V4L2_COLORSPACE_SRGB, | 132 | .colorspace = V4L2_COLORSPACE_SRGB, |
| 133 | .priv = 1}, | 133 | .priv = 1}, |
| 134 | {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, | 134 | {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, |
| 135 | .bytesperline = 640 * 3, | 135 | .bytesperline = 640, |
| 136 | .sizeimage = 640 * 480 * 3 / 2, | 136 | .sizeimage = 640 * 480 * 3 / 2, |
| 137 | .colorspace = V4L2_COLORSPACE_SRGB, | 137 | .colorspace = V4L2_COLORSPACE_SRGB, |
| 138 | .priv = 0}, | 138 | .priv = 0}, |
| @@ -588,7 +588,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
| 588 | default: | 588 | default: |
| 589 | data += 1; | 589 | data += 1; |
| 590 | len -= 1; | 590 | len -= 1; |
| 591 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | 591 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, |
| 592 | data, len); | 592 | data, len); |
| 593 | break; | 593 | break; |
| 594 | } | 594 | } |
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c index b608a27ad115..699340c17dea 100644 --- a/drivers/media/video/gspca/spca508.c +++ b/drivers/media/video/gspca/spca508.c | |||
| @@ -63,23 +63,23 @@ static struct ctrl sd_ctrls[] = { | |||
| 63 | }; | 63 | }; |
| 64 | 64 | ||
| 65 | static struct v4l2_pix_format sif_mode[] = { | 65 | static struct v4l2_pix_format sif_mode[] = { |
| 66 | {160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | 66 | {160, 120, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, |
| 67 | .bytesperline = 160 * 3, | 67 | .bytesperline = 160, |
| 68 | .sizeimage = 160 * 120 * 3 / 2, | 68 | .sizeimage = 160 * 120 * 3 / 2, |
| 69 | .colorspace = V4L2_COLORSPACE_SRGB, | 69 | .colorspace = V4L2_COLORSPACE_SRGB, |
| 70 | .priv = 3}, | 70 | .priv = 3}, |
| 71 | {176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | 71 | {176, 144, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, |
| 72 | .bytesperline = 176 * 3, | 72 | .bytesperline = 176, |
| 73 | .sizeimage = 176 * 144 * 3 / 2, | 73 | .sizeimage = 176 * 144 * 3 / 2, |
| 74 | .colorspace = V4L2_COLORSPACE_SRGB, | 74 | .colorspace = V4L2_COLORSPACE_SRGB, |
| 75 | .priv = 2}, | 75 | .priv = 2}, |
| 76 | {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | 76 | {320, 240, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, |
| 77 | .bytesperline = 320 * 3, | 77 | .bytesperline = 320, |
| 78 | .sizeimage = 320 * 240 * 3 / 2, | 78 | .sizeimage = 320 * 240 * 3 / 2, |
| 79 | .colorspace = V4L2_COLORSPACE_SRGB, | 79 | .colorspace = V4L2_COLORSPACE_SRGB, |
| 80 | .priv = 1}, | 80 | .priv = 1}, |
| 81 | {352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | 81 | {352, 288, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, |
| 82 | .bytesperline = 352 * 3, | 82 | .bytesperline = 352, |
| 83 | .sizeimage = 352 * 288 * 3 / 2, | 83 | .sizeimage = 352 * 288 * 3 / 2, |
| 84 | .colorspace = V4L2_COLORSPACE_SRGB, | 84 | .colorspace = V4L2_COLORSPACE_SRGB, |
| 85 | .priv = 0}, | 85 | .priv = 0}, |
| @@ -1583,7 +1583,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
| 1583 | default: | 1583 | default: |
| 1584 | data += 1; | 1584 | data += 1; |
| 1585 | len -= 1; | 1585 | len -= 1; |
| 1586 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | 1586 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, |
| 1587 | data, len); | 1587 | data, len); |
| 1588 | break; | 1588 | break; |
| 1589 | } | 1589 | } |
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index a26174508cb9..1073ac3d2ec6 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c | |||
| @@ -644,6 +644,18 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
| 644 | } | 644 | } |
| 645 | } | 645 | } |
| 646 | 646 | ||
| 647 | static void setautogain(struct gspca_dev *gspca_dev) | ||
| 648 | { | ||
| 649 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 650 | |||
| 651 | if (sd->chip_revision == Rev072A) { | ||
| 652 | if (sd->autogain) | ||
| 653 | sd->ag_cnt = AG_CNT_START; | ||
| 654 | else | ||
| 655 | sd->ag_cnt = -1; | ||
| 656 | } | ||
| 657 | } | ||
| 658 | |||
| 647 | static void sd_start(struct gspca_dev *gspca_dev) | 659 | static void sd_start(struct gspca_dev *gspca_dev) |
| 648 | { | 660 | { |
| 649 | struct sd *sd = (struct sd *) gspca_dev; | 661 | struct sd *sd = (struct sd *) gspca_dev; |
| @@ -671,6 +683,7 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
| 671 | reg_w_val(dev, 0x8500, mode); /* mode */ | 683 | reg_w_val(dev, 0x8500, mode); /* mode */ |
| 672 | reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ | 684 | reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ |
| 673 | reg_w_val(dev, 0x8112, 0x10 | 0x20); | 685 | reg_w_val(dev, 0x8112, 0x10 | 0x20); |
| 686 | setautogain(gspca_dev); | ||
| 674 | break; | 687 | break; |
| 675 | default: | 688 | default: |
| 676 | /* case Rev012A: */ | 689 | /* case Rev012A: */ |
| @@ -720,18 +733,24 @@ static void sd_close(struct gspca_dev *gspca_dev) | |||
| 720 | reg_w_val(gspca_dev->dev, 0x8114, 0); | 733 | reg_w_val(gspca_dev->dev, 0x8114, 0); |
| 721 | } | 734 | } |
| 722 | 735 | ||
| 723 | static void setautogain(struct gspca_dev *gspca_dev) | 736 | static void do_autogain(struct gspca_dev *gspca_dev) |
| 724 | { | 737 | { |
| 725 | struct sd *sd = (struct sd *) gspca_dev; | 738 | struct sd *sd = (struct sd *) gspca_dev; |
| 726 | int expotimes = 0; | 739 | int expotimes; |
| 727 | int pixelclk = 0; | 740 | int pixelclk; |
| 728 | int gainG = 0; | 741 | int gainG; |
| 729 | __u8 R, Gr, Gb, B; | 742 | __u8 R, Gr, Gb, B; |
| 730 | int y; | 743 | int y; |
| 731 | __u8 luma_mean = 110; | 744 | __u8 luma_mean = 110; |
| 732 | __u8 luma_delta = 20; | 745 | __u8 luma_delta = 20; |
| 733 | __u8 spring = 4; | 746 | __u8 spring = 4; |
| 734 | 747 | ||
| 748 | if (sd->ag_cnt < 0) | ||
| 749 | return; | ||
| 750 | if (--sd->ag_cnt >= 0) | ||
| 751 | return; | ||
| 752 | sd->ag_cnt = AG_CNT_START; | ||
| 753 | |||
| 735 | switch (sd->chip_revision) { | 754 | switch (sd->chip_revision) { |
| 736 | case Rev072A: | 755 | case Rev072A: |
| 737 | reg_r(gspca_dev, 0x8621, 1); | 756 | reg_r(gspca_dev, 0x8621, 1); |
| @@ -795,18 +814,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
| 795 | __u8 *data, /* isoc packet */ | 814 | __u8 *data, /* isoc packet */ |
| 796 | int len) /* iso packet length */ | 815 | int len) /* iso packet length */ |
| 797 | { | 816 | { |
| 798 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 799 | |||
| 800 | switch (data[0]) { | 817 | switch (data[0]) { |
| 801 | case 0: /* start of frame */ | 818 | case 0: /* start of frame */ |
| 802 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | 819 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, |
| 803 | data, 0); | 820 | data, 0); |
| 804 | if (sd->ag_cnt >= 0) { | ||
| 805 | if (--sd->ag_cnt < 0) { | ||
| 806 | sd->ag_cnt = AG_CNT_START; | ||
| 807 | setautogain(gspca_dev); | ||
| 808 | } | ||
| 809 | } | ||
| 810 | data += SPCA561_OFFSET_DATA; | 821 | data += SPCA561_OFFSET_DATA; |
| 811 | len -= SPCA561_OFFSET_DATA; | 822 | len -= SPCA561_OFFSET_DATA; |
| 812 | if (data[1] & 0x10) { | 823 | if (data[1] & 0x10) { |
| @@ -944,10 +955,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | |||
| 944 | struct sd *sd = (struct sd *) gspca_dev; | 955 | struct sd *sd = (struct sd *) gspca_dev; |
| 945 | 956 | ||
| 946 | sd->autogain = val; | 957 | sd->autogain = val; |
| 947 | if (val) | 958 | if (gspca_dev->streaming) |
| 948 | sd->ag_cnt = AG_CNT_START; | 959 | setautogain(gspca_dev); |
| 949 | else | ||
| 950 | sd->ag_cnt = -1; | ||
| 951 | return 0; | 960 | return 0; |
| 952 | } | 961 | } |
| 953 | 962 | ||
| @@ -971,6 +980,7 @@ static const struct sd_desc sd_desc = { | |||
| 971 | .stop0 = sd_stop0, | 980 | .stop0 = sd_stop0, |
| 972 | .close = sd_close, | 981 | .close = sd_close, |
| 973 | .pkt_scan = sd_pkt_scan, | 982 | .pkt_scan = sd_pkt_scan, |
| 983 | .dq_callback = do_autogain, | ||
| 974 | }; | 984 | }; |
| 975 | 985 | ||
| 976 | /* -- module initialisation -- */ | 986 | /* -- module initialisation -- */ |
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index a4221753e1bf..f4a52956e0d9 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c | |||
| @@ -88,12 +88,12 @@ static struct ctrl sd_ctrls[] = { | |||
| 88 | 88 | ||
| 89 | static struct v4l2_pix_format vc0321_mode[] = { | 89 | static struct v4l2_pix_format vc0321_mode[] = { |
| 90 | {320, 240, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE, | 90 | {320, 240, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE, |
| 91 | .bytesperline = 320 * 2, | 91 | .bytesperline = 320, |
| 92 | .sizeimage = 320 * 240 * 2, | 92 | .sizeimage = 320 * 240 * 2, |
| 93 | .colorspace = V4L2_COLORSPACE_SRGB, | 93 | .colorspace = V4L2_COLORSPACE_SRGB, |
| 94 | .priv = 1}, | 94 | .priv = 1}, |
| 95 | {640, 480, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE, | 95 | {640, 480, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE, |
| 96 | .bytesperline = 640 * 2, | 96 | .bytesperline = 640, |
| 97 | .sizeimage = 640 * 480 * 2, | 97 | .sizeimage = 640 * 480 * 2, |
| 98 | .colorspace = V4L2_COLORSPACE_SRGB, | 98 | .colorspace = V4L2_COLORSPACE_SRGB, |
| 99 | .priv = 0}, | 99 | .priv = 0}, |
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 22a994ccb1d5..bc7d0eedcd81 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c | |||
| @@ -6469,7 +6469,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
| 6469 | NULL, Tgradient_1, Tgradient_2, | 6469 | NULL, Tgradient_1, Tgradient_2, |
| 6470 | Tgradient_3, Tgradient_4, Tgradient_5, Tgradient_6 | 6470 | Tgradient_3, Tgradient_4, Tgradient_5, Tgradient_6 |
| 6471 | }; | 6471 | }; |
| 6472 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 6472 | #ifdef GSPCA_DEBUG |
| 6473 | __u8 v[16]; | 6473 | __u8 v[16]; |
| 6474 | #endif | 6474 | #endif |
| 6475 | 6475 | ||
| @@ -6487,7 +6487,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
| 6487 | else if (g <= 0) | 6487 | else if (g <= 0) |
| 6488 | g = 1; | 6488 | g = 1; |
| 6489 | reg_w(dev, g, 0x0120 + i); /* gamma */ | 6489 | reg_w(dev, g, 0x0120 + i); /* gamma */ |
| 6490 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 6490 | #ifdef GSPCA_DEBUG |
| 6491 | if (gspca_debug & D_CONF) | 6491 | if (gspca_debug & D_CONF) |
| 6492 | v[i] = g; | 6492 | v[i] = g; |
| 6493 | #endif | 6493 | #endif |
| @@ -6507,7 +6507,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
| 6507 | g = 1; | 6507 | g = 1; |
| 6508 | } | 6508 | } |
| 6509 | reg_w(dev, g, 0x0130 + i); /* gradient */ | 6509 | reg_w(dev, g, 0x0130 + i); /* gradient */ |
| 6510 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 6510 | #ifdef GSPCA_DEBUG |
| 6511 | if (gspca_debug & D_CONF) | 6511 | if (gspca_debug & D_CONF) |
| 6512 | v[i] = g; | 6512 | v[i] = g; |
| 6513 | #endif | 6513 | #endif |
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c index 5e7ebca1968e..388cf94055d3 100644 --- a/drivers/media/video/pxa_camera.c +++ b/drivers/media/video/pxa_camera.c | |||
| @@ -128,6 +128,8 @@ struct pxa_camera_dev { | |||
| 128 | 128 | ||
| 129 | struct pxa_buffer *active; | 129 | struct pxa_buffer *active; |
| 130 | struct pxa_dma_desc *sg_tail[3]; | 130 | struct pxa_dma_desc *sg_tail[3]; |
| 131 | |||
| 132 | u32 save_cicr[5]; | ||
| 131 | }; | 133 | }; |
| 132 | 134 | ||
| 133 | static const char *pxa_cam_driver_description = "PXA_Camera"; | 135 | static const char *pxa_cam_driver_description = "PXA_Camera"; |
| @@ -997,10 +999,64 @@ static int pxa_camera_querycap(struct soc_camera_host *ici, | |||
| 997 | return 0; | 999 | return 0; |
| 998 | } | 1000 | } |
| 999 | 1001 | ||
| 1002 | static int pxa_camera_suspend(struct soc_camera_device *icd, pm_message_t state) | ||
| 1003 | { | ||
| 1004 | struct soc_camera_host *ici = | ||
| 1005 | to_soc_camera_host(icd->dev.parent); | ||
| 1006 | struct pxa_camera_dev *pcdev = ici->priv; | ||
| 1007 | int i = 0, ret = 0; | ||
| 1008 | |||
| 1009 | pcdev->save_cicr[i++] = CICR0; | ||
| 1010 | pcdev->save_cicr[i++] = CICR1; | ||
| 1011 | pcdev->save_cicr[i++] = CICR2; | ||
| 1012 | pcdev->save_cicr[i++] = CICR3; | ||
| 1013 | pcdev->save_cicr[i++] = CICR4; | ||
| 1014 | |||
| 1015 | if ((pcdev->icd) && (pcdev->icd->ops->suspend)) | ||
| 1016 | ret = pcdev->icd->ops->suspend(pcdev->icd, state); | ||
| 1017 | |||
| 1018 | return ret; | ||
| 1019 | } | ||
| 1020 | |||
| 1021 | static int pxa_camera_resume(struct soc_camera_device *icd) | ||
| 1022 | { | ||
| 1023 | struct soc_camera_host *ici = | ||
| 1024 | to_soc_camera_host(icd->dev.parent); | ||
| 1025 | struct pxa_camera_dev *pcdev = ici->priv; | ||
| 1026 | int i = 0, ret = 0; | ||
| 1027 | |||
| 1028 | DRCMR68 = pcdev->dma_chans[0] | DRCMR_MAPVLD; | ||
| 1029 | DRCMR69 = pcdev->dma_chans[1] | DRCMR_MAPVLD; | ||
| 1030 | DRCMR70 = pcdev->dma_chans[2] | DRCMR_MAPVLD; | ||
| 1031 | |||
| 1032 | CICR0 = pcdev->save_cicr[i++] & ~CICR0_ENB; | ||
| 1033 | CICR1 = pcdev->save_cicr[i++]; | ||
| 1034 | CICR2 = pcdev->save_cicr[i++]; | ||
| 1035 | CICR3 = pcdev->save_cicr[i++]; | ||
| 1036 | CICR4 = pcdev->save_cicr[i++]; | ||
| 1037 | |||
| 1038 | if ((pcdev->icd) && (pcdev->icd->ops->resume)) | ||
| 1039 | ret = pcdev->icd->ops->resume(pcdev->icd); | ||
| 1040 | |||
| 1041 | /* Restart frame capture if active buffer exists */ | ||
| 1042 | if (!ret && pcdev->active) { | ||
| 1043 | /* Reset the FIFOs */ | ||
| 1044 | CIFR |= CIFR_RESET_F; | ||
| 1045 | /* Enable End-Of-Frame Interrupt */ | ||
| 1046 | CICR0 &= ~CICR0_EOFM; | ||
| 1047 | /* Restart the Capture Interface */ | ||
| 1048 | CICR0 |= CICR0_ENB; | ||
| 1049 | } | ||
| 1050 | |||
| 1051 | return ret; | ||
| 1052 | } | ||
| 1053 | |||
| 1000 | static struct soc_camera_host_ops pxa_soc_camera_host_ops = { | 1054 | static struct soc_camera_host_ops pxa_soc_camera_host_ops = { |
| 1001 | .owner = THIS_MODULE, | 1055 | .owner = THIS_MODULE, |
| 1002 | .add = pxa_camera_add_device, | 1056 | .add = pxa_camera_add_device, |
| 1003 | .remove = pxa_camera_remove_device, | 1057 | .remove = pxa_camera_remove_device, |
| 1058 | .suspend = pxa_camera_suspend, | ||
| 1059 | .resume = pxa_camera_resume, | ||
| 1004 | .set_fmt_cap = pxa_camera_set_fmt_cap, | 1060 | .set_fmt_cap = pxa_camera_set_fmt_cap, |
| 1005 | .try_fmt_cap = pxa_camera_try_fmt_cap, | 1061 | .try_fmt_cap = pxa_camera_try_fmt_cap, |
| 1006 | .init_videobuf = pxa_camera_init_videobuf, | 1062 | .init_videobuf = pxa_camera_init_videobuf, |
| @@ -1198,7 +1254,7 @@ static int __devinit pxa_camera_init(void) | |||
| 1198 | 1254 | ||
| 1199 | static void __exit pxa_camera_exit(void) | 1255 | static void __exit pxa_camera_exit(void) |
| 1200 | { | 1256 | { |
| 1201 | return platform_driver_unregister(&pxa_camera_driver); | 1257 | platform_driver_unregister(&pxa_camera_driver); |
| 1202 | } | 1258 | } |
| 1203 | 1259 | ||
| 1204 | module_init(pxa_camera_init); | 1260 | module_init(pxa_camera_init); |
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index f7ca3cb9340a..318754e73132 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c | |||
| @@ -647,7 +647,7 @@ static int __init sh_mobile_ceu_init(void) | |||
| 647 | 647 | ||
| 648 | static void __exit sh_mobile_ceu_exit(void) | 648 | static void __exit sh_mobile_ceu_exit(void) |
| 649 | { | 649 | { |
| 650 | return platform_driver_unregister(&sh_mobile_ceu_driver); | 650 | platform_driver_unregister(&sh_mobile_ceu_driver); |
| 651 | } | 651 | } |
| 652 | 652 | ||
| 653 | module_init(sh_mobile_ceu_init); | 653 | module_init(sh_mobile_ceu_init); |
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index b6be5ee678b6..66ebe5956a87 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c | |||
| @@ -732,10 +732,36 @@ static int soc_camera_remove(struct device *dev) | |||
| 732 | return 0; | 732 | return 0; |
| 733 | } | 733 | } |
| 734 | 734 | ||
| 735 | static int soc_camera_suspend(struct device *dev, pm_message_t state) | ||
| 736 | { | ||
| 737 | struct soc_camera_device *icd = to_soc_camera_dev(dev); | ||
| 738 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | ||
| 739 | int ret = 0; | ||
| 740 | |||
| 741 | if (ici->ops->suspend) | ||
| 742 | ret = ici->ops->suspend(icd, state); | ||
| 743 | |||
| 744 | return ret; | ||
| 745 | } | ||
| 746 | |||
| 747 | static int soc_camera_resume(struct device *dev) | ||
| 748 | { | ||
| 749 | struct soc_camera_device *icd = to_soc_camera_dev(dev); | ||
| 750 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | ||
| 751 | int ret = 0; | ||
| 752 | |||
| 753 | if (ici->ops->resume) | ||
| 754 | ret = ici->ops->resume(icd); | ||
| 755 | |||
| 756 | return ret; | ||
| 757 | } | ||
| 758 | |||
| 735 | static struct bus_type soc_camera_bus_type = { | 759 | static struct bus_type soc_camera_bus_type = { |
| 736 | .name = "soc-camera", | 760 | .name = "soc-camera", |
| 737 | .probe = soc_camera_probe, | 761 | .probe = soc_camera_probe, |
| 738 | .remove = soc_camera_remove, | 762 | .remove = soc_camera_remove, |
| 763 | .suspend = soc_camera_suspend, | ||
| 764 | .resume = soc_camera_resume, | ||
| 739 | }; | 765 | }; |
| 740 | 766 | ||
| 741 | static struct device_driver ic_drv = { | 767 | static struct device_driver ic_drv = { |
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c index eefb0327ebb6..1adc257ebdb9 100644 --- a/drivers/media/video/soc_camera_platform.c +++ b/drivers/media/video/soc_camera_platform.c | |||
| @@ -187,7 +187,7 @@ static int __init soc_camera_platform_module_init(void) | |||
| 187 | 187 | ||
| 188 | static void __exit soc_camera_platform_module_exit(void) | 188 | static void __exit soc_camera_platform_module_exit(void) |
| 189 | { | 189 | { |
| 190 | return platform_driver_unregister(&soc_camera_platform_driver); | 190 | platform_driver_unregister(&soc_camera_platform_driver); |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | module_init(soc_camera_platform_module_init); | 193 | module_init(soc_camera_platform_module_init); |
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index 626f4ad7e876..6ef3e5297de8 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c | |||
| @@ -585,13 +585,17 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video, | |||
| 585 | struct uvc_control_mapping *mapping; | 585 | struct uvc_control_mapping *mapping; |
| 586 | struct uvc_menu_info *menu; | 586 | struct uvc_menu_info *menu; |
| 587 | unsigned int i; | 587 | unsigned int i; |
| 588 | __u8 data[8]; | 588 | __u8 *data; |
| 589 | int ret; | 589 | int ret; |
| 590 | 590 | ||
| 591 | ctrl = uvc_find_control(video, v4l2_ctrl->id, &mapping); | 591 | ctrl = uvc_find_control(video, v4l2_ctrl->id, &mapping); |
| 592 | if (ctrl == NULL) | 592 | if (ctrl == NULL) |
| 593 | return -EINVAL; | 593 | return -EINVAL; |
| 594 | 594 | ||
| 595 | data = kmalloc(8, GFP_KERNEL); | ||
| 596 | if (data == NULL) | ||
| 597 | return -ENOMEM; | ||
| 598 | |||
| 595 | memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl); | 599 | memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl); |
| 596 | v4l2_ctrl->id = mapping->id; | 600 | v4l2_ctrl->id = mapping->id; |
| 597 | v4l2_ctrl->type = mapping->v4l2_type; | 601 | v4l2_ctrl->type = mapping->v4l2_type; |
| @@ -604,8 +608,8 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video, | |||
| 604 | if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { | 608 | if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { |
| 605 | if ((ret = uvc_query_ctrl(video->dev, GET_DEF, ctrl->entity->id, | 609 | if ((ret = uvc_query_ctrl(video->dev, GET_DEF, ctrl->entity->id, |
| 606 | video->dev->intfnum, ctrl->info->selector, | 610 | video->dev->intfnum, ctrl->info->selector, |
| 607 | &data, ctrl->info->size)) < 0) | 611 | data, ctrl->info->size)) < 0) |
| 608 | return ret; | 612 | goto out; |
| 609 | v4l2_ctrl->default_value = uvc_get_le_value(data, mapping); | 613 | v4l2_ctrl->default_value = uvc_get_le_value(data, mapping); |
| 610 | } | 614 | } |
| 611 | 615 | ||
| @@ -623,13 +627,15 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video, | |||
| 623 | } | 627 | } |
| 624 | } | 628 | } |
| 625 | 629 | ||
| 626 | return 0; | 630 | ret = 0; |
| 631 | goto out; | ||
| 627 | 632 | ||
| 628 | case V4L2_CTRL_TYPE_BOOLEAN: | 633 | case V4L2_CTRL_TYPE_BOOLEAN: |
| 629 | v4l2_ctrl->minimum = 0; | 634 | v4l2_ctrl->minimum = 0; |
| 630 | v4l2_ctrl->maximum = 1; | 635 | v4l2_ctrl->maximum = 1; |
| 631 | v4l2_ctrl->step = 1; | 636 | v4l2_ctrl->step = 1; |
| 632 | return 0; | 637 | ret = 0; |
| 638 | goto out; | ||
| 633 | 639 | ||
| 634 | default: | 640 | default: |
| 635 | break; | 641 | break; |
| @@ -638,26 +644,29 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video, | |||
| 638 | if (ctrl->info->flags & UVC_CONTROL_GET_MIN) { | 644 | if (ctrl->info->flags & UVC_CONTROL_GET_MIN) { |
| 639 | if ((ret = uvc_query_ctrl(video->dev, GET_MIN, ctrl->entity->id, | 645 | if ((ret = uvc_query_ctrl(video->dev, GET_MIN, ctrl->entity->id, |
| 640 | video->dev->intfnum, ctrl->info->selector, | 646 | video->dev->intfnum, ctrl->info->selector, |
| 641 | &data, ctrl->info->size)) < 0) | 647 | data, ctrl->info->size)) < 0) |
| 642 | return ret; | 648 | goto out; |
| 643 | v4l2_ctrl->minimum = uvc_get_le_value(data, mapping); | 649 | v4l2_ctrl->minimum = uvc_get_le_value(data, mapping); |
| 644 | } | 650 | } |
| 645 | if (ctrl->info->flags & UVC_CONTROL_GET_MAX) { | 651 | if (ctrl->info->flags & UVC_CONTROL_GET_MAX) { |
| 646 | if ((ret = uvc_query_ctrl(video->dev, GET_MAX, ctrl->entity->id, | 652 | if ((ret = uvc_query_ctrl(video->dev, GET_MAX, ctrl->entity->id, |
| 647 | video->dev->intfnum, ctrl->info->selector, | 653 | video->dev->intfnum, ctrl->info->selector, |
| 648 | &data, ctrl->info->size)) < 0) | 654 | data, ctrl->info->size)) < 0) |
| 649 | return ret; | 655 | goto out; |
| 650 | v4l2_ctrl->maximum = uvc_get_le_value(data, mapping); | 656 | v4l2_ctrl->maximum = uvc_get_le_value(data, mapping); |
| 651 | } | 657 | } |
| 652 | if (ctrl->info->flags & UVC_CONTROL_GET_RES) { | 658 | if (ctrl->info->flags & UVC_CONTROL_GET_RES) { |
| 653 | if ((ret = uvc_query_ctrl(video->dev, GET_RES, ctrl->entity->id, | 659 | if ((ret = uvc_query_ctrl(video->dev, GET_RES, ctrl->entity->id, |
| 654 | video->dev->intfnum, ctrl->info->selector, | 660 | video->dev->intfnum, ctrl->info->selector, |
| 655 | &data, ctrl->info->size)) < 0) | 661 | data, ctrl->info->size)) < 0) |
| 656 | return ret; | 662 | goto out; |
| 657 | v4l2_ctrl->step = uvc_get_le_value(data, mapping); | 663 | v4l2_ctrl->step = uvc_get_le_value(data, mapping); |
| 658 | } | 664 | } |
| 659 | 665 | ||
| 660 | return 0; | 666 | ret = 0; |
| 667 | out: | ||
| 668 | kfree(data); | ||
| 669 | return ret; | ||
| 661 | } | 670 | } |
| 662 | 671 | ||
| 663 | 672 | ||
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index b3c4d75e8490..7e102034d38d 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c | |||
| @@ -1884,7 +1884,7 @@ static struct usb_device_id uvc_ids[] = { | |||
| 1884 | .bInterfaceSubClass = 1, | 1884 | .bInterfaceSubClass = 1, |
| 1885 | .bInterfaceProtocol = 0, | 1885 | .bInterfaceProtocol = 0, |
| 1886 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, | 1886 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, |
| 1887 | /* Packard Bell OEM Webcam */ | 1887 | /* Packard Bell OEM Webcam - Bison Electronics */ |
| 1888 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 1888 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
| 1889 | | USB_DEVICE_ID_MATCH_INT_INFO, | 1889 | | USB_DEVICE_ID_MATCH_INT_INFO, |
| 1890 | .idVendor = 0x5986, | 1890 | .idVendor = 0x5986, |
| @@ -1893,7 +1893,7 @@ static struct usb_device_id uvc_ids[] = { | |||
| 1893 | .bInterfaceSubClass = 1, | 1893 | .bInterfaceSubClass = 1, |
| 1894 | .bInterfaceProtocol = 0, | 1894 | .bInterfaceProtocol = 0, |
| 1895 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, | 1895 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, |
| 1896 | /* Acer Crystal Eye webcam */ | 1896 | /* Acer Crystal Eye webcam - Bison Electronics */ |
| 1897 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 1897 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
| 1898 | | USB_DEVICE_ID_MATCH_INT_INFO, | 1898 | | USB_DEVICE_ID_MATCH_INT_INFO, |
| 1899 | .idVendor = 0x5986, | 1899 | .idVendor = 0x5986, |
| @@ -1902,7 +1902,7 @@ static struct usb_device_id uvc_ids[] = { | |||
| 1902 | .bInterfaceSubClass = 1, | 1902 | .bInterfaceSubClass = 1, |
| 1903 | .bInterfaceProtocol = 0, | 1903 | .bInterfaceProtocol = 0, |
| 1904 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, | 1904 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, |
| 1905 | /* Medion Akoya Mini E1210 */ | 1905 | /* Medion Akoya Mini E1210 - Bison Electronics */ |
| 1906 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 1906 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
| 1907 | | USB_DEVICE_ID_MATCH_INT_INFO, | 1907 | | USB_DEVICE_ID_MATCH_INT_INFO, |
| 1908 | .idVendor = 0x5986, | 1908 | .idVendor = 0x5986, |
| @@ -1911,7 +1911,7 @@ static struct usb_device_id uvc_ids[] = { | |||
| 1911 | .bInterfaceSubClass = 1, | 1911 | .bInterfaceSubClass = 1, |
| 1912 | .bInterfaceProtocol = 0, | 1912 | .bInterfaceProtocol = 0, |
| 1913 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, | 1913 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, |
| 1914 | /* Acer OrbiCam - Unknown vendor */ | 1914 | /* Acer OrbiCam - Bison Electronics */ |
| 1915 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 1915 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
| 1916 | | USB_DEVICE_ID_MATCH_INT_INFO, | 1916 | | USB_DEVICE_ID_MATCH_INT_INFO, |
| 1917 | .idVendor = 0x5986, | 1917 | .idVendor = 0x5986, |
| @@ -1920,6 +1920,24 @@ static struct usb_device_id uvc_ids[] = { | |||
| 1920 | .bInterfaceSubClass = 1, | 1920 | .bInterfaceSubClass = 1, |
| 1921 | .bInterfaceProtocol = 0, | 1921 | .bInterfaceProtocol = 0, |
| 1922 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, | 1922 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, |
| 1923 | /* Bison Electronics */ | ||
| 1924 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | ||
| 1925 | | USB_DEVICE_ID_MATCH_INT_INFO, | ||
| 1926 | .idVendor = 0x5986, | ||
| 1927 | .idProduct = 0x0300, | ||
| 1928 | .bInterfaceClass = USB_CLASS_VIDEO, | ||
| 1929 | .bInterfaceSubClass = 1, | ||
| 1930 | .bInterfaceProtocol = 0, | ||
| 1931 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, | ||
| 1932 | /* Clevo M570TU - Bison Electronics */ | ||
| 1933 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | ||
| 1934 | | USB_DEVICE_ID_MATCH_INT_INFO, | ||
| 1935 | .idVendor = 0x5986, | ||
| 1936 | .idProduct = 0x0303, | ||
| 1937 | .bInterfaceClass = USB_CLASS_VIDEO, | ||
| 1938 | .bInterfaceSubClass = 1, | ||
| 1939 | .bInterfaceProtocol = 0, | ||
| 1940 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, | ||
| 1923 | /* Generic USB Video Class */ | 1941 | /* Generic USB Video Class */ |
| 1924 | { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, | 1942 | { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, |
| 1925 | {} | 1943 | {} |
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index ad63794fda77..6854ac78a161 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c | |||
| @@ -90,17 +90,20 @@ static void uvc_fixup_buffer_size(struct uvc_video_device *video, | |||
| 90 | static int uvc_get_video_ctrl(struct uvc_video_device *video, | 90 | static int uvc_get_video_ctrl(struct uvc_video_device *video, |
| 91 | struct uvc_streaming_control *ctrl, int probe, __u8 query) | 91 | struct uvc_streaming_control *ctrl, int probe, __u8 query) |
| 92 | { | 92 | { |
| 93 | __u8 data[34]; | 93 | __u8 *data; |
| 94 | __u8 size; | 94 | __u16 size; |
| 95 | int ret; | 95 | int ret; |
| 96 | 96 | ||
| 97 | size = video->dev->uvc_version >= 0x0110 ? 34 : 26; | 97 | size = video->dev->uvc_version >= 0x0110 ? 34 : 26; |
| 98 | data = kmalloc(size, GFP_KERNEL); | ||
| 99 | if (data == NULL) | ||
| 100 | return -ENOMEM; | ||
| 101 | |||
| 98 | ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum, | 102 | ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum, |
| 99 | probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, &data, size, | 103 | probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size, |
| 100 | UVC_CTRL_STREAMING_TIMEOUT); | 104 | UVC_CTRL_STREAMING_TIMEOUT); |
| 101 | |||
| 102 | if (ret < 0) | 105 | if (ret < 0) |
| 103 | return ret; | 106 | goto out; |
| 104 | 107 | ||
| 105 | ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]); | 108 | ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]); |
| 106 | ctrl->bFormatIndex = data[2]; | 109 | ctrl->bFormatIndex = data[2]; |
| @@ -136,17 +139,22 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video, | |||
| 136 | */ | 139 | */ |
| 137 | uvc_fixup_buffer_size(video, ctrl); | 140 | uvc_fixup_buffer_size(video, ctrl); |
| 138 | 141 | ||
| 139 | return 0; | 142 | out: |
| 143 | kfree(data); | ||
| 144 | return ret; | ||
| 140 | } | 145 | } |
| 141 | 146 | ||
| 142 | int uvc_set_video_ctrl(struct uvc_video_device *video, | 147 | int uvc_set_video_ctrl(struct uvc_video_device *video, |
| 143 | struct uvc_streaming_control *ctrl, int probe) | 148 | struct uvc_streaming_control *ctrl, int probe) |
| 144 | { | 149 | { |
| 145 | __u8 data[34]; | 150 | __u8 *data; |
| 146 | __u8 size; | 151 | __u16 size; |
| 152 | int ret; | ||
| 147 | 153 | ||
| 148 | size = video->dev->uvc_version >= 0x0110 ? 34 : 26; | 154 | size = video->dev->uvc_version >= 0x0110 ? 34 : 26; |
| 149 | memset(data, 0, sizeof data); | 155 | data = kzalloc(size, GFP_KERNEL); |
| 156 | if (data == NULL) | ||
| 157 | return -ENOMEM; | ||
| 150 | 158 | ||
| 151 | *(__le16 *)&data[0] = cpu_to_le16(ctrl->bmHint); | 159 | *(__le16 *)&data[0] = cpu_to_le16(ctrl->bmHint); |
| 152 | data[2] = ctrl->bFormatIndex; | 160 | data[2] = ctrl->bFormatIndex; |
| @@ -174,10 +182,13 @@ int uvc_set_video_ctrl(struct uvc_video_device *video, | |||
| 174 | data[33] = ctrl->bMaxVersion; | 182 | data[33] = ctrl->bMaxVersion; |
| 175 | } | 183 | } |
| 176 | 184 | ||
| 177 | return __uvc_query_ctrl(video->dev, SET_CUR, 0, | 185 | ret = __uvc_query_ctrl(video->dev, SET_CUR, 0, |
| 178 | video->streaming->intfnum, | 186 | video->streaming->intfnum, |
| 179 | probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, &data, size, | 187 | probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size, |
| 180 | UVC_CTRL_STREAMING_TIMEOUT); | 188 | UVC_CTRL_STREAMING_TIMEOUT); |
| 189 | |||
| 190 | kfree(data); | ||
| 191 | return ret; | ||
| 181 | } | 192 | } |
| 182 | 193 | ||
| 183 | int uvc_probe_video(struct uvc_video_device *video, | 194 | int uvc_probe_video(struct uvc_video_device *video, |
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 556615fe93de..6f36006aecda 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c | |||
| @@ -222,11 +222,13 @@ int video_register_device(struct video_device *vfd, int type, int nr) | |||
| 222 | EXPORT_SYMBOL(video_register_device); | 222 | EXPORT_SYMBOL(video_register_device); |
| 223 | 223 | ||
| 224 | /** | 224 | /** |
| 225 | * video_register_device - register video4linux devices | 225 | * video_register_device_index - register video4linux devices |
| 226 | * @vfd: video device structure we want to register | 226 | * @vfd: video device structure we want to register |
| 227 | * @type: type of device to register | 227 | * @type: type of device to register |
| 228 | * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ... | 228 | * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ... |
| 229 | * -1 == first free) | 229 | * -1 == first free) |
| 230 | * @index: stream number based on parent device; | ||
| 231 | * -1 if auto assign, requested number otherwise | ||
| 230 | * | 232 | * |
| 231 | * The registration code assigns minor numbers based on the type | 233 | * The registration code assigns minor numbers based on the type |
| 232 | * requested. -ENFILE is returned in all the device slots for this | 234 | * requested. -ENFILE is returned in all the device slots for this |
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index ef7572cbc4ab..1edda456fc64 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | #include <linux/videodev2.h> | 41 | #include <linux/videodev2.h> |
| 42 | #include <media/v4l2-ioctl.h> | 42 | #include <media/v4l2-ioctl.h> |
| 43 | #include <media/v4l2-common.h> | 43 | #include <media/v4l2-common.h> |
| 44 | #include <media/v4l2-ioctl.h> | ||
| 44 | #include <linux/video_decoder.h> | 45 | #include <linux/video_decoder.h> |
| 45 | #include <linux/mutex.h> | 46 | #include <linux/mutex.h> |
| 46 | 47 | ||
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 82af385460e4..a726f3b01a6b 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
| @@ -427,10 +427,10 @@ config ENCLOSURE_SERVICES | |||
| 427 | config SGI_XP | 427 | config SGI_XP |
| 428 | tristate "Support communication between SGI SSIs" | 428 | tristate "Support communication between SGI SSIs" |
| 429 | depends on NET | 429 | depends on NET |
| 430 | depends on IA64_GENERIC || IA64_SGI_SN2 || IA64_SGI_UV || (X86_64 && SMP) | 430 | depends on (IA64_GENERIC || IA64_SGI_SN2 || IA64_SGI_UV || X86_64) && SMP |
| 431 | select IA64_UNCACHED_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2 | 431 | select IA64_UNCACHED_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2 |
| 432 | select GENERIC_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2 | 432 | select GENERIC_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2 |
| 433 | select SGI_GRU if IA64_GENERIC || IA64_SGI_UV || (X86_64 && SMP) | 433 | select SGI_GRU if (IA64_GENERIC || IA64_SGI_UV || X86_64) && SMP |
| 434 | ---help--- | 434 | ---help--- |
| 435 | An SGI machine can be divided into multiple Single System | 435 | An SGI machine can be divided into multiple Single System |
| 436 | Images which act independently of each other and have | 436 | Images which act independently of each other and have |
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 48399e134c0d..32b9fe153641 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
| @@ -463,7 +463,7 @@ config PC87413_WDT | |||
| 463 | module will be called pc87413_wdt. | 463 | module will be called pc87413_wdt. |
| 464 | 464 | ||
| 465 | Most people will say N. | 465 | Most people will say N. |
| 466 | 466 | ||
| 467 | config 60XX_WDT | 467 | config 60XX_WDT |
| 468 | tristate "SBC-60XX Watchdog Timer" | 468 | tristate "SBC-60XX Watchdog Timer" |
| 469 | depends on X86 | 469 | depends on X86 |
| @@ -695,9 +695,17 @@ config 8xx_WDT | |||
| 695 | tristate "MPC8xx Watchdog Timer" | 695 | tristate "MPC8xx Watchdog Timer" |
| 696 | depends on 8xx | 696 | depends on 8xx |
| 697 | 697 | ||
| 698 | config 83xx_WDT | 698 | config 8xxx_WDT |
| 699 | tristate "MPC83xx Watchdog Timer" | 699 | tristate "MPC8xxx Platform Watchdog Timer" |
| 700 | depends on PPC_83xx | 700 | depends on PPC_8xx || PPC_83xx || PPC_86xx |
| 701 | help | ||
| 702 | This driver is for a SoC level watchdog that exists on some | ||
| 703 | Freescale PowerPC processors. So far this driver supports: | ||
| 704 | - MPC8xx watchdogs | ||
| 705 | - MPC83xx watchdogs | ||
| 706 | - MPC86xx watchdogs | ||
| 707 | |||
| 708 | For BookE processors (MPC85xx) use the BOOKE_WDT driver instead. | ||
| 701 | 709 | ||
| 702 | config MV64X60_WDT | 710 | config MV64X60_WDT |
| 703 | tristate "MV64X60 (Marvell Discovery) Watchdog Timer" | 711 | tristate "MV64X60 (Marvell Discovery) Watchdog Timer" |
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index edd305a64e63..049c91895699 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile | |||
| @@ -92,7 +92,7 @@ obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o | |||
| 92 | 92 | ||
| 93 | # MIPS Architecture | 93 | # MIPS Architecture |
| 94 | obj-$(CONFIG_INDYDOG) += indydog.o | 94 | obj-$(CONFIG_INDYDOG) += indydog.o |
| 95 | obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o | 95 | obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o |
| 96 | obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o | 96 | obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o |
| 97 | obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o | 97 | obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o |
| 98 | obj-$(CONFIG_AR7_WDT) += ar7_wdt.o | 98 | obj-$(CONFIG_AR7_WDT) += ar7_wdt.o |
| @@ -103,7 +103,7 @@ obj-$(CONFIG_TXX9_WDT) += txx9wdt.o | |||
| 103 | # POWERPC Architecture | 103 | # POWERPC Architecture |
| 104 | obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o | 104 | obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o |
| 105 | obj-$(CONFIG_MPC5200_WDT) += mpc5200_wdt.o | 105 | obj-$(CONFIG_MPC5200_WDT) += mpc5200_wdt.o |
| 106 | obj-$(CONFIG_83xx_WDT) += mpc83xx_wdt.o | 106 | obj-$(CONFIG_8xxx_WDT) += mpc8xxx_wdt.o |
| 107 | obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o | 107 | obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o |
| 108 | obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o | 108 | obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o |
| 109 | 109 | ||
diff --git a/drivers/watchdog/acquirewdt.c b/drivers/watchdog/acquirewdt.c index 85269c365a10..6e46a551395c 100644 --- a/drivers/watchdog/acquirewdt.c +++ b/drivers/watchdog/acquirewdt.c | |||
| @@ -58,39 +58,45 @@ | |||
| 58 | #include <linux/types.h> /* For standard types (like size_t) */ | 58 | #include <linux/types.h> /* For standard types (like size_t) */ |
| 59 | #include <linux/errno.h> /* For the -ENODEV/... values */ | 59 | #include <linux/errno.h> /* For the -ENODEV/... values */ |
| 60 | #include <linux/kernel.h> /* For printk/panic/... */ | 60 | #include <linux/kernel.h> /* For printk/panic/... */ |
| 61 | #include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */ | 61 | #include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV |
| 62 | (WATCHDOG_MINOR) */ | ||
| 62 | #include <linux/watchdog.h> /* For the watchdog specific items */ | 63 | #include <linux/watchdog.h> /* For the watchdog specific items */ |
| 63 | #include <linux/fs.h> /* For file operations */ | 64 | #include <linux/fs.h> /* For file operations */ |
| 64 | #include <linux/ioport.h> /* For io-port access */ | 65 | #include <linux/ioport.h> /* For io-port access */ |
| 65 | #include <linux/platform_device.h> /* For platform_driver framework */ | 66 | #include <linux/platform_device.h> /* For platform_driver framework */ |
| 66 | #include <linux/init.h> /* For __init/__exit/... */ | 67 | #include <linux/init.h> /* For __init/__exit/... */ |
| 67 | 68 | #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ | |
| 68 | #include <asm/uaccess.h> /* For copy_to_user/put_user/... */ | 69 | #include <linux/io.h> /* For inb/outb/... */ |
| 69 | #include <asm/io.h> /* For inb/outb/... */ | ||
| 70 | 70 | ||
| 71 | /* Module information */ | 71 | /* Module information */ |
| 72 | #define DRV_NAME "acquirewdt" | 72 | #define DRV_NAME "acquirewdt" |
| 73 | #define PFX DRV_NAME ": " | 73 | #define PFX DRV_NAME ": " |
| 74 | #define WATCHDOG_NAME "Acquire WDT" | 74 | #define WATCHDOG_NAME "Acquire WDT" |
| 75 | #define WATCHDOG_HEARTBEAT 0 /* There is no way to see what the correct time-out period is */ | 75 | /* There is no way to see what the correct time-out period is */ |
| 76 | #define WATCHDOG_HEARTBEAT 0 | ||
| 76 | 77 | ||
| 77 | /* internal variables */ | 78 | /* internal variables */ |
| 78 | static struct platform_device *acq_platform_device; /* the watchdog platform device */ | 79 | /* the watchdog platform device */ |
| 80 | static struct platform_device *acq_platform_device; | ||
| 79 | static unsigned long acq_is_open; | 81 | static unsigned long acq_is_open; |
| 80 | static char expect_close; | 82 | static char expect_close; |
| 81 | 83 | ||
| 82 | /* module parameters */ | 84 | /* module parameters */ |
| 83 | static int wdt_stop = 0x43; /* You must set this - there is no sane way to probe for this board. */ | 85 | /* You must set this - there is no sane way to probe for this board. */ |
| 86 | static int wdt_stop = 0x43; | ||
| 84 | module_param(wdt_stop, int, 0); | 87 | module_param(wdt_stop, int, 0); |
| 85 | MODULE_PARM_DESC(wdt_stop, "Acquire WDT 'stop' io port (default 0x43)"); | 88 | MODULE_PARM_DESC(wdt_stop, "Acquire WDT 'stop' io port (default 0x43)"); |
| 86 | 89 | ||
| 87 | static int wdt_start = 0x443; /* You must set this - there is no sane way to probe for this board. */ | 90 | /* You must set this - there is no sane way to probe for this board. */ |
| 91 | static int wdt_start = 0x443; | ||
| 88 | module_param(wdt_start, int, 0); | 92 | module_param(wdt_start, int, 0); |
| 89 | MODULE_PARM_DESC(wdt_start, "Acquire WDT 'start' io port (default 0x443)"); | 93 | MODULE_PARM_DESC(wdt_start, "Acquire WDT 'start' io port (default 0x443)"); |
| 90 | 94 | ||
| 91 | static int nowayout = WATCHDOG_NOWAYOUT; | 95 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 92 | module_param(nowayout, int, 0); | 96 | module_param(nowayout, int, 0); |
| 93 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 97 | MODULE_PARM_DESC(nowayout, |
| 98 | "Watchdog cannot be stopped once started (default=" | ||
| 99 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 94 | 100 | ||
| 95 | /* | 101 | /* |
| 96 | * Watchdog Operations | 102 | * Watchdog Operations |
| @@ -112,18 +118,18 @@ static void acq_stop(void) | |||
| 112 | * /dev/watchdog handling | 118 | * /dev/watchdog handling |
| 113 | */ | 119 | */ |
| 114 | 120 | ||
| 115 | static ssize_t acq_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | 121 | static ssize_t acq_write(struct file *file, const char __user *buf, |
| 122 | size_t count, loff_t *ppos) | ||
| 116 | { | 123 | { |
| 117 | /* See if we got the magic character 'V' and reload the timer */ | 124 | /* See if we got the magic character 'V' and reload the timer */ |
| 118 | if(count) { | 125 | if (count) { |
| 119 | if (!nowayout) { | 126 | if (!nowayout) { |
| 120 | size_t i; | 127 | size_t i; |
| 121 | |||
| 122 | /* note: just in case someone wrote the magic character | 128 | /* note: just in case someone wrote the magic character |
| 123 | * five months ago... */ | 129 | five months ago... */ |
| 124 | expect_close = 0; | 130 | expect_close = 0; |
| 125 | 131 | /* scan to see whether or not we got the | |
| 126 | /* scan to see whether or not we got the magic character */ | 132 | magic character */ |
| 127 | for (i = 0; i != count; i++) { | 133 | for (i = 0; i != count; i++) { |
| 128 | char c; | 134 | char c; |
| 129 | if (get_user(c, buf + i)) | 135 | if (get_user(c, buf + i)) |
| @@ -132,64 +138,55 @@ static ssize_t acq_write(struct file *file, const char __user *buf, size_t count | |||
| 132 | expect_close = 42; | 138 | expect_close = 42; |
| 133 | } | 139 | } |
| 134 | } | 140 | } |
| 135 | 141 | /* Well, anyhow someone wrote to us, we should | |
| 136 | /* Well, anyhow someone wrote to us, we should return that favour */ | 142 | return that favour */ |
| 137 | acq_keepalive(); | 143 | acq_keepalive(); |
| 138 | } | 144 | } |
| 139 | return count; | 145 | return count; |
| 140 | } | 146 | } |
| 141 | 147 | ||
| 142 | static int acq_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 148 | static long acq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 143 | unsigned long arg) | ||
| 144 | { | 149 | { |
| 145 | int options, retval = -EINVAL; | 150 | int options, retval = -EINVAL; |
| 146 | void __user *argp = (void __user *)arg; | 151 | void __user *argp = (void __user *)arg; |
| 147 | int __user *p = argp; | 152 | int __user *p = argp; |
| 148 | static struct watchdog_info ident = | 153 | static struct watchdog_info ident = { |
| 149 | { | ||
| 150 | .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, | 154 | .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, |
| 151 | .firmware_version = 1, | 155 | .firmware_version = 1, |
| 152 | .identity = WATCHDOG_NAME, | 156 | .identity = WATCHDOG_NAME, |
| 153 | }; | 157 | }; |
| 154 | 158 | ||
| 155 | switch(cmd) | 159 | switch (cmd) { |
| 156 | { | ||
| 157 | case WDIOC_GETSUPPORT: | 160 | case WDIOC_GETSUPPORT: |
| 158 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; | 161 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; |
| 159 | 162 | ||
| 160 | case WDIOC_GETSTATUS: | 163 | case WDIOC_GETSTATUS: |
| 161 | case WDIOC_GETBOOTSTATUS: | 164 | case WDIOC_GETBOOTSTATUS: |
| 162 | return put_user(0, p); | 165 | return put_user(0, p); |
| 163 | |||
| 164 | case WDIOC_KEEPALIVE: | ||
| 165 | acq_keepalive(); | ||
| 166 | return 0; | ||
| 167 | |||
| 168 | case WDIOC_GETTIMEOUT: | ||
| 169 | return put_user(WATCHDOG_HEARTBEAT, p); | ||
| 170 | 166 | ||
| 171 | case WDIOC_SETOPTIONS: | 167 | case WDIOC_SETOPTIONS: |
| 172 | { | 168 | { |
| 173 | if (get_user(options, p)) | 169 | if (get_user(options, p)) |
| 174 | return -EFAULT; | 170 | return -EFAULT; |
| 175 | 171 | if (options & WDIOS_DISABLECARD) { | |
| 176 | if (options & WDIOS_DISABLECARD) | 172 | acq_stop(); |
| 177 | { | 173 | retval = 0; |
| 178 | acq_stop(); | 174 | } |
| 179 | retval = 0; | 175 | if (options & WDIOS_ENABLECARD) { |
| 180 | } | 176 | acq_keepalive(); |
| 181 | 177 | retval = 0; | |
| 182 | if (options & WDIOS_ENABLECARD) | 178 | } |
| 183 | { | 179 | return retval; |
| 184 | acq_keepalive(); | ||
| 185 | retval = 0; | ||
| 186 | } | ||
| 187 | |||
| 188 | return retval; | ||
| 189 | } | 180 | } |
| 181 | case WDIOC_KEEPALIVE: | ||
| 182 | acq_keepalive(); | ||
| 183 | return 0; | ||
| 184 | |||
| 185 | case WDIOC_GETTIMEOUT: | ||
| 186 | return put_user(WATCHDOG_HEARTBEAT, p); | ||
| 190 | 187 | ||
| 191 | default: | 188 | default: |
| 192 | return -ENOTTY; | 189 | return -ENOTTY; |
| 193 | } | 190 | } |
| 194 | } | 191 | } |
| 195 | 192 | ||
| @@ -211,7 +208,8 @@ static int acq_close(struct inode *inode, struct file *file) | |||
| 211 | if (expect_close == 42) { | 208 | if (expect_close == 42) { |
| 212 | acq_stop(); | 209 | acq_stop(); |
| 213 | } else { | 210 | } else { |
| 214 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 211 | printk(KERN_CRIT PFX |
| 212 | "Unexpected close, not stopping watchdog!\n"); | ||
| 215 | acq_keepalive(); | 213 | acq_keepalive(); |
| 216 | } | 214 | } |
| 217 | clear_bit(0, &acq_is_open); | 215 | clear_bit(0, &acq_is_open); |
| @@ -227,7 +225,7 @@ static const struct file_operations acq_fops = { | |||
| 227 | .owner = THIS_MODULE, | 225 | .owner = THIS_MODULE, |
| 228 | .llseek = no_llseek, | 226 | .llseek = no_llseek, |
| 229 | .write = acq_write, | 227 | .write = acq_write, |
| 230 | .ioctl = acq_ioctl, | 228 | .unlocked_ioctl = acq_ioctl, |
| 231 | .open = acq_open, | 229 | .open = acq_open, |
| 232 | .release = acq_close, | 230 | .release = acq_close, |
| 233 | }; | 231 | }; |
| @@ -248,32 +246,29 @@ static int __devinit acq_probe(struct platform_device *dev) | |||
| 248 | 246 | ||
| 249 | if (wdt_stop != wdt_start) { | 247 | if (wdt_stop != wdt_start) { |
| 250 | if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) { | 248 | if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) { |
| 251 | printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", | 249 | printk(KERN_ERR PFX |
| 252 | wdt_stop); | 250 | "I/O address 0x%04x already in use\n", wdt_stop); |
| 253 | ret = -EIO; | 251 | ret = -EIO; |
| 254 | goto out; | 252 | goto out; |
| 255 | } | 253 | } |
| 256 | } | 254 | } |
| 257 | 255 | ||
| 258 | if (!request_region(wdt_start, 1, WATCHDOG_NAME)) { | 256 | if (!request_region(wdt_start, 1, WATCHDOG_NAME)) { |
| 259 | printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", | 257 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", |
| 260 | wdt_start); | 258 | wdt_start); |
| 261 | ret = -EIO; | 259 | ret = -EIO; |
| 262 | goto unreg_stop; | 260 | goto unreg_stop; |
| 263 | } | 261 | } |
| 264 | |||
| 265 | ret = misc_register(&acq_miscdev); | 262 | ret = misc_register(&acq_miscdev); |
| 266 | if (ret != 0) { | 263 | if (ret != 0) { |
| 267 | printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 264 | printk(KERN_ERR PFX |
| 268 | WATCHDOG_MINOR, ret); | 265 | "cannot register miscdev on minor=%d (err=%d)\n", |
| 266 | WATCHDOG_MINOR, ret); | ||
| 269 | goto unreg_regions; | 267 | goto unreg_regions; |
| 270 | } | 268 | } |
| 271 | 269 | printk(KERN_INFO PFX "initialized. (nowayout=%d)\n", nowayout); | |
| 272 | printk (KERN_INFO PFX "initialized. (nowayout=%d)\n", | ||
| 273 | nowayout); | ||
| 274 | 270 | ||
| 275 | return 0; | 271 | return 0; |
| 276 | |||
| 277 | unreg_regions: | 272 | unreg_regions: |
| 278 | release_region(wdt_start, 1); | 273 | release_region(wdt_start, 1); |
| 279 | unreg_stop: | 274 | unreg_stop: |
| @@ -286,9 +281,9 @@ out: | |||
| 286 | static int __devexit acq_remove(struct platform_device *dev) | 281 | static int __devexit acq_remove(struct platform_device *dev) |
| 287 | { | 282 | { |
| 288 | misc_deregister(&acq_miscdev); | 283 | misc_deregister(&acq_miscdev); |
| 289 | release_region(wdt_start,1); | 284 | release_region(wdt_start, 1); |
| 290 | if(wdt_stop != wdt_start) | 285 | if (wdt_stop != wdt_start) |
| 291 | release_region(wdt_stop,1); | 286 | release_region(wdt_stop, 1); |
| 292 | 287 | ||
| 293 | return 0; | 288 | return 0; |
| 294 | } | 289 | } |
| @@ -313,18 +308,19 @@ static int __init acq_init(void) | |||
| 313 | { | 308 | { |
| 314 | int err; | 309 | int err; |
| 315 | 310 | ||
| 316 | printk(KERN_INFO "WDT driver for Acquire single board computer initialising.\n"); | 311 | printk(KERN_INFO |
| 312 | "WDT driver for Acquire single board computer initialising.\n"); | ||
| 317 | 313 | ||
| 318 | err = platform_driver_register(&acquirewdt_driver); | 314 | err = platform_driver_register(&acquirewdt_driver); |
| 319 | if (err) | 315 | if (err) |
| 320 | return err; | 316 | return err; |
| 321 | 317 | ||
| 322 | acq_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0); | 318 | acq_platform_device = platform_device_register_simple(DRV_NAME, |
| 319 | -1, NULL, 0); | ||
| 323 | if (IS_ERR(acq_platform_device)) { | 320 | if (IS_ERR(acq_platform_device)) { |
| 324 | err = PTR_ERR(acq_platform_device); | 321 | err = PTR_ERR(acq_platform_device); |
| 325 | goto unreg_platform_driver; | 322 | goto unreg_platform_driver; |
| 326 | } | 323 | } |
| 327 | |||
| 328 | return 0; | 324 | return 0; |
| 329 | 325 | ||
| 330 | unreg_platform_driver: | 326 | unreg_platform_driver: |
diff --git a/drivers/watchdog/advantechwdt.c b/drivers/watchdog/advantechwdt.c index 8121cc247343..a5110f93a755 100644 --- a/drivers/watchdog/advantechwdt.c +++ b/drivers/watchdog/advantechwdt.c | |||
| @@ -37,9 +37,9 @@ | |||
| 37 | #include <linux/ioport.h> | 37 | #include <linux/ioport.h> |
| 38 | #include <linux/platform_device.h> | 38 | #include <linux/platform_device.h> |
| 39 | #include <linux/init.h> | 39 | #include <linux/init.h> |
| 40 | #include <linux/io.h> | ||
| 41 | #include <linux/uaccess.h> | ||
| 40 | 42 | ||
| 41 | #include <asm/io.h> | ||
| 42 | #include <asm/uaccess.h> | ||
| 43 | #include <asm/system.h> | 43 | #include <asm/system.h> |
| 44 | 44 | ||
| 45 | #define DRV_NAME "advantechwdt" | 45 | #define DRV_NAME "advantechwdt" |
| @@ -47,7 +47,8 @@ | |||
| 47 | #define WATCHDOG_NAME "Advantech WDT" | 47 | #define WATCHDOG_NAME "Advantech WDT" |
| 48 | #define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ | 48 | #define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ |
| 49 | 49 | ||
| 50 | static struct platform_device *advwdt_platform_device; /* the watchdog platform device */ | 50 | /* the watchdog platform device */ |
| 51 | static struct platform_device *advwdt_platform_device; | ||
| 51 | static unsigned long advwdt_is_open; | 52 | static unsigned long advwdt_is_open; |
| 52 | static char adv_expect_close; | 53 | static char adv_expect_close; |
| 53 | 54 | ||
| @@ -72,35 +73,35 @@ MODULE_PARM_DESC(wdt_start, "Advantech WDT 'start' io port (default 0x443)"); | |||
| 72 | 73 | ||
| 73 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ | 74 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ |
| 74 | module_param(timeout, int, 0); | 75 | module_param(timeout, int, 0); |
| 75 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=63, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) "."); | 76 | MODULE_PARM_DESC(timeout, |
| 77 | "Watchdog timeout in seconds. 1<= timeout <=63, default=" | ||
| 78 | __MODULE_STRING(WATCHDOG_TIMEOUT) "."); | ||
| 76 | 79 | ||
| 77 | static int nowayout = WATCHDOG_NOWAYOUT; | 80 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 78 | module_param(nowayout, int, 0); | 81 | module_param(nowayout, int, 0); |
| 79 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 82 | MODULE_PARM_DESC(nowayout, |
| 83 | "Watchdog cannot be stopped once started (default=" | ||
| 84 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 80 | 85 | ||
| 81 | /* | 86 | /* |
| 82 | * Watchdog Operations | 87 | * Watchdog Operations |
| 83 | */ | 88 | */ |
| 84 | 89 | ||
| 85 | static void | 90 | static void advwdt_ping(void) |
| 86 | advwdt_ping(void) | ||
| 87 | { | 91 | { |
| 88 | /* Write a watchdog value */ | 92 | /* Write a watchdog value */ |
| 89 | outb_p(timeout, wdt_start); | 93 | outb_p(timeout, wdt_start); |
| 90 | } | 94 | } |
| 91 | 95 | ||
| 92 | static void | 96 | static void advwdt_disable(void) |
| 93 | advwdt_disable(void) | ||
| 94 | { | 97 | { |
| 95 | inb_p(wdt_stop); | 98 | inb_p(wdt_stop); |
| 96 | } | 99 | } |
| 97 | 100 | ||
| 98 | static int | 101 | static int advwdt_set_heartbeat(int t) |
| 99 | advwdt_set_heartbeat(int t) | ||
| 100 | { | 102 | { |
| 101 | if ((t < 1) || (t > 63)) | 103 | if (t < 1 || t > 63) |
| 102 | return -EINVAL; | 104 | return -EINVAL; |
| 103 | |||
| 104 | timeout = t; | 105 | timeout = t; |
| 105 | return 0; | 106 | return 0; |
| 106 | } | 107 | } |
| @@ -109,8 +110,8 @@ advwdt_set_heartbeat(int t) | |||
| 109 | * /dev/watchdog handling | 110 | * /dev/watchdog handling |
| 110 | */ | 111 | */ |
| 111 | 112 | ||
| 112 | static ssize_t | 113 | static ssize_t advwdt_write(struct file *file, const char __user *buf, |
| 113 | advwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | 114 | size_t count, loff_t *ppos) |
| 114 | { | 115 | { |
| 115 | if (count) { | 116 | if (count) { |
| 116 | if (!nowayout) { | 117 | if (!nowayout) { |
| @@ -120,7 +121,7 @@ advwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *pp | |||
| 120 | 121 | ||
| 121 | for (i = 0; i != count; i++) { | 122 | for (i = 0; i != count; i++) { |
| 122 | char c; | 123 | char c; |
| 123 | if (get_user(c, buf+i)) | 124 | if (get_user(c, buf + i)) |
| 124 | return -EFAULT; | 125 | return -EFAULT; |
| 125 | if (c == 'V') | 126 | if (c == 'V') |
| 126 | adv_expect_close = 42; | 127 | adv_expect_close = 42; |
| @@ -131,9 +132,7 @@ advwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *pp | |||
| 131 | return count; | 132 | return count; |
| 132 | } | 133 | } |
| 133 | 134 | ||
| 134 | static int | 135 | static long advwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 135 | advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | ||
| 136 | unsigned long arg) | ||
| 137 | { | 136 | { |
| 138 | int new_timeout; | 137 | int new_timeout; |
| 139 | void __user *argp = (void __user *)arg; | 138 | void __user *argp = (void __user *)arg; |
| @@ -146,57 +145,50 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
| 146 | 145 | ||
| 147 | switch (cmd) { | 146 | switch (cmd) { |
| 148 | case WDIOC_GETSUPPORT: | 147 | case WDIOC_GETSUPPORT: |
| 149 | if (copy_to_user(argp, &ident, sizeof(ident))) | 148 | if (copy_to_user(argp, &ident, sizeof(ident))) |
| 150 | return -EFAULT; | 149 | return -EFAULT; |
| 151 | break; | 150 | break; |
| 152 | 151 | ||
| 153 | case WDIOC_GETSTATUS: | 152 | case WDIOC_GETSTATUS: |
| 154 | case WDIOC_GETBOOTSTATUS: | 153 | case WDIOC_GETBOOTSTATUS: |
| 155 | return put_user(0, p); | 154 | return put_user(0, p); |
| 156 | |||
| 157 | case WDIOC_KEEPALIVE: | ||
| 158 | advwdt_ping(); | ||
| 159 | break; | ||
| 160 | |||
| 161 | case WDIOC_SETTIMEOUT: | ||
| 162 | if (get_user(new_timeout, p)) | ||
| 163 | return -EFAULT; | ||
| 164 | if (advwdt_set_heartbeat(new_timeout)) | ||
| 165 | return -EINVAL; | ||
| 166 | advwdt_ping(); | ||
| 167 | /* Fall */ | ||
| 168 | |||
| 169 | case WDIOC_GETTIMEOUT: | ||
| 170 | return put_user(timeout, p); | ||
| 171 | 155 | ||
| 172 | case WDIOC_SETOPTIONS: | 156 | case WDIOC_SETOPTIONS: |
| 173 | { | 157 | { |
| 174 | int options, retval = -EINVAL; | 158 | int options, retval = -EINVAL; |
| 175 | |||
| 176 | if (get_user(options, p)) | ||
| 177 | return -EFAULT; | ||
| 178 | |||
| 179 | if (options & WDIOS_DISABLECARD) { | ||
| 180 | advwdt_disable(); | ||
| 181 | retval = 0; | ||
| 182 | } | ||
| 183 | 159 | ||
| 184 | if (options & WDIOS_ENABLECARD) { | 160 | if (get_user(options, p)) |
| 185 | advwdt_ping(); | 161 | return -EFAULT; |
| 186 | retval = 0; | 162 | if (options & WDIOS_DISABLECARD) { |
| 187 | } | 163 | advwdt_disable(); |
| 188 | 164 | retval = 0; | |
| 189 | return retval; | 165 | } |
| 166 | if (options & WDIOS_ENABLECARD) { | ||
| 167 | advwdt_ping(); | ||
| 168 | retval = 0; | ||
| 169 | } | ||
| 170 | return retval; | ||
| 190 | } | 171 | } |
| 172 | case WDIOC_KEEPALIVE: | ||
| 173 | advwdt_ping(); | ||
| 174 | break; | ||
| 191 | 175 | ||
| 176 | case WDIOC_SETTIMEOUT: | ||
| 177 | if (get_user(new_timeout, p)) | ||
| 178 | return -EFAULT; | ||
| 179 | if (advwdt_set_heartbeat(new_timeout)) | ||
| 180 | return -EINVAL; | ||
| 181 | advwdt_ping(); | ||
| 182 | /* Fall */ | ||
| 183 | case WDIOC_GETTIMEOUT: | ||
| 184 | return put_user(timeout, p); | ||
| 192 | default: | 185 | default: |
| 193 | return -ENOTTY; | 186 | return -ENOTTY; |
| 194 | } | 187 | } |
| 195 | return 0; | 188 | return 0; |
| 196 | } | 189 | } |
| 197 | 190 | ||
| 198 | static int | 191 | static int advwdt_open(struct inode *inode, struct file *file) |
| 199 | advwdt_open(struct inode *inode, struct file *file) | ||
| 200 | { | 192 | { |
| 201 | if (test_and_set_bit(0, &advwdt_is_open)) | 193 | if (test_and_set_bit(0, &advwdt_is_open)) |
| 202 | return -EBUSY; | 194 | return -EBUSY; |
| @@ -208,13 +200,13 @@ advwdt_open(struct inode *inode, struct file *file) | |||
| 208 | return nonseekable_open(inode, file); | 200 | return nonseekable_open(inode, file); |
| 209 | } | 201 | } |
| 210 | 202 | ||
| 211 | static int | 203 | static int advwdt_close(struct inode *inode, struct file *file) |
| 212 | advwdt_close(struct inode *inode, struct file *file) | ||
| 213 | { | 204 | { |
| 214 | if (adv_expect_close == 42) { | 205 | if (adv_expect_close == 42) { |
| 215 | advwdt_disable(); | 206 | advwdt_disable(); |
| 216 | } else { | 207 | } else { |
| 217 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 208 | printk(KERN_CRIT PFX |
| 209 | "Unexpected close, not stopping watchdog!\n"); | ||
| 218 | advwdt_ping(); | 210 | advwdt_ping(); |
| 219 | } | 211 | } |
| 220 | clear_bit(0, &advwdt_is_open); | 212 | clear_bit(0, &advwdt_is_open); |
| @@ -230,7 +222,7 @@ static const struct file_operations advwdt_fops = { | |||
| 230 | .owner = THIS_MODULE, | 222 | .owner = THIS_MODULE, |
| 231 | .llseek = no_llseek, | 223 | .llseek = no_llseek, |
| 232 | .write = advwdt_write, | 224 | .write = advwdt_write, |
| 233 | .ioctl = advwdt_ioctl, | 225 | .unlocked_ioctl = advwdt_ioctl, |
| 234 | .open = advwdt_open, | 226 | .open = advwdt_open, |
| 235 | .release = advwdt_close, | 227 | .release = advwdt_close, |
| 236 | }; | 228 | }; |
| @@ -245,23 +237,24 @@ static struct miscdevice advwdt_miscdev = { | |||
| 245 | * Init & exit routines | 237 | * Init & exit routines |
| 246 | */ | 238 | */ |
| 247 | 239 | ||
| 248 | static int __devinit | 240 | static int __devinit advwdt_probe(struct platform_device *dev) |
| 249 | advwdt_probe(struct platform_device *dev) | ||
| 250 | { | 241 | { |
| 251 | int ret; | 242 | int ret; |
| 252 | 243 | ||
| 253 | if (wdt_stop != wdt_start) { | 244 | if (wdt_stop != wdt_start) { |
| 254 | if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) { | 245 | if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) { |
| 255 | printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", | 246 | printk(KERN_ERR PFX |
| 256 | wdt_stop); | 247 | "I/O address 0x%04x already in use\n", |
| 248 | wdt_stop); | ||
| 257 | ret = -EIO; | 249 | ret = -EIO; |
| 258 | goto out; | 250 | goto out; |
| 259 | } | 251 | } |
| 260 | } | 252 | } |
| 261 | 253 | ||
| 262 | if (!request_region(wdt_start, 1, WATCHDOG_NAME)) { | 254 | if (!request_region(wdt_start, 1, WATCHDOG_NAME)) { |
| 263 | printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", | 255 | printk(KERN_ERR PFX |
| 264 | wdt_start); | 256 | "I/O address 0x%04x already in use\n", |
| 257 | wdt_start); | ||
| 265 | ret = -EIO; | 258 | ret = -EIO; |
| 266 | goto unreg_stop; | 259 | goto unreg_stop; |
| 267 | } | 260 | } |
| @@ -269,20 +262,19 @@ advwdt_probe(struct platform_device *dev) | |||
| 269 | /* Check that the heartbeat value is within it's range ; if not reset to the default */ | 262 | /* Check that the heartbeat value is within it's range ; if not reset to the default */ |
| 270 | if (advwdt_set_heartbeat(timeout)) { | 263 | if (advwdt_set_heartbeat(timeout)) { |
| 271 | advwdt_set_heartbeat(WATCHDOG_TIMEOUT); | 264 | advwdt_set_heartbeat(WATCHDOG_TIMEOUT); |
| 272 | printk (KERN_INFO PFX "timeout value must be 1<=x<=63, using %d\n", | 265 | printk(KERN_INFO PFX |
| 273 | timeout); | 266 | "timeout value must be 1<=x<=63, using %d\n", timeout); |
| 274 | } | 267 | } |
| 275 | 268 | ||
| 276 | ret = misc_register(&advwdt_miscdev); | 269 | ret = misc_register(&advwdt_miscdev); |
| 277 | if (ret != 0) { | 270 | if (ret != 0) { |
| 278 | printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 271 | printk(KERN_ERR PFX |
| 279 | WATCHDOG_MINOR, ret); | 272 | "cannot register miscdev on minor=%d (err=%d)\n", |
| 273 | WATCHDOG_MINOR, ret); | ||
| 280 | goto unreg_regions; | 274 | goto unreg_regions; |
| 281 | } | 275 | } |
| 282 | 276 | printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", | |
| 283 | printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", | ||
| 284 | timeout, nowayout); | 277 | timeout, nowayout); |
| 285 | |||
| 286 | out: | 278 | out: |
| 287 | return ret; | 279 | return ret; |
| 288 | unreg_regions: | 280 | unreg_regions: |
| @@ -293,19 +285,17 @@ unreg_stop: | |||
| 293 | goto out; | 285 | goto out; |
| 294 | } | 286 | } |
| 295 | 287 | ||
| 296 | static int __devexit | 288 | static int __devexit advwdt_remove(struct platform_device *dev) |
| 297 | advwdt_remove(struct platform_device *dev) | ||
| 298 | { | 289 | { |
| 299 | misc_deregister(&advwdt_miscdev); | 290 | misc_deregister(&advwdt_miscdev); |
| 300 | release_region(wdt_start,1); | 291 | release_region(wdt_start, 1); |
| 301 | if(wdt_stop != wdt_start) | 292 | if (wdt_stop != wdt_start) |
| 302 | release_region(wdt_stop,1); | 293 | release_region(wdt_stop, 1); |
| 303 | 294 | ||
| 304 | return 0; | 295 | return 0; |
| 305 | } | 296 | } |
| 306 | 297 | ||
| 307 | static void | 298 | static void advwdt_shutdown(struct platform_device *dev) |
| 308 | advwdt_shutdown(struct platform_device *dev) | ||
| 309 | { | 299 | { |
| 310 | /* Turn the WDT off if we have a soft shutdown */ | 300 | /* Turn the WDT off if we have a soft shutdown */ |
| 311 | advwdt_disable(); | 301 | advwdt_disable(); |
| @@ -321,18 +311,19 @@ static struct platform_driver advwdt_driver = { | |||
| 321 | }, | 311 | }, |
| 322 | }; | 312 | }; |
| 323 | 313 | ||
| 324 | static int __init | 314 | static int __init advwdt_init(void) |
| 325 | advwdt_init(void) | ||
| 326 | { | 315 | { |
| 327 | int err; | 316 | int err; |
| 328 | 317 | ||
| 329 | printk(KERN_INFO "WDT driver for Advantech single board computer initialising.\n"); | 318 | printk(KERN_INFO |
| 319 | "WDT driver for Advantech single board computer initialising.\n"); | ||
| 330 | 320 | ||
| 331 | err = platform_driver_register(&advwdt_driver); | 321 | err = platform_driver_register(&advwdt_driver); |
| 332 | if (err) | 322 | if (err) |
| 333 | return err; | 323 | return err; |
| 334 | 324 | ||
| 335 | advwdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0); | 325 | advwdt_platform_device = platform_device_register_simple(DRV_NAME, |
| 326 | -1, NULL, 0); | ||
| 336 | if (IS_ERR(advwdt_platform_device)) { | 327 | if (IS_ERR(advwdt_platform_device)) { |
| 337 | err = PTR_ERR(advwdt_platform_device); | 328 | err = PTR_ERR(advwdt_platform_device); |
| 338 | goto unreg_platform_driver; | 329 | goto unreg_platform_driver; |
| @@ -345,8 +336,7 @@ unreg_platform_driver: | |||
| 345 | return err; | 336 | return err; |
| 346 | } | 337 | } |
| 347 | 338 | ||
| 348 | static void __exit | 339 | static void __exit advwdt_exit(void) |
| 349 | advwdt_exit(void) | ||
| 350 | { | 340 | { |
| 351 | platform_device_unregister(advwdt_platform_device); | 341 | platform_device_unregister(advwdt_platform_device); |
| 352 | platform_driver_unregister(&advwdt_driver); | 342 | platform_driver_unregister(&advwdt_driver); |
diff --git a/drivers/watchdog/alim1535_wdt.c b/drivers/watchdog/alim1535_wdt.c index 2b1fbdb2fcf7..2a7690ecf97d 100644 --- a/drivers/watchdog/alim1535_wdt.c +++ b/drivers/watchdog/alim1535_wdt.c | |||
| @@ -18,9 +18,8 @@ | |||
| 18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
| 19 | #include <linux/fs.h> | 19 | #include <linux/fs.h> |
| 20 | #include <linux/pci.h> | 20 | #include <linux/pci.h> |
| 21 | 21 | #include <linux/uaccess.h> | |
| 22 | #include <asm/uaccess.h> | 22 | #include <linux/io.h> |
| 23 | #include <asm/io.h> | ||
| 24 | 23 | ||
| 25 | #define WATCHDOG_NAME "ALi_M1535" | 24 | #define WATCHDOG_NAME "ALi_M1535" |
| 26 | #define PFX WATCHDOG_NAME ": " | 25 | #define PFX WATCHDOG_NAME ": " |
| @@ -30,17 +29,21 @@ | |||
| 30 | static unsigned long ali_is_open; | 29 | static unsigned long ali_is_open; |
| 31 | static char ali_expect_release; | 30 | static char ali_expect_release; |
| 32 | static struct pci_dev *ali_pci; | 31 | static struct pci_dev *ali_pci; |
| 33 | static u32 ali_timeout_bits; /* stores the computed timeout */ | 32 | static u32 ali_timeout_bits; /* stores the computed timeout */ |
| 34 | static DEFINE_SPINLOCK(ali_lock); /* Guards the hardware */ | 33 | static DEFINE_SPINLOCK(ali_lock); /* Guards the hardware */ |
| 35 | 34 | ||
| 36 | /* module parameters */ | 35 | /* module parameters */ |
| 37 | static int timeout = WATCHDOG_TIMEOUT; | 36 | static int timeout = WATCHDOG_TIMEOUT; |
| 38 | module_param(timeout, int, 0); | 37 | module_param(timeout, int, 0); |
| 39 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (0<timeout<18000, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | 38 | MODULE_PARM_DESC(timeout, |
| 39 | "Watchdog timeout in seconds. (0 < timeout < 18000, default=" | ||
| 40 | __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | ||
| 40 | 41 | ||
| 41 | static int nowayout = WATCHDOG_NOWAYOUT; | 42 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 42 | module_param(nowayout, int, 0); | 43 | module_param(nowayout, int, 0); |
| 43 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 44 | MODULE_PARM_DESC(nowayout, |
| 45 | "Watchdog cannot be stopped once started (default=" | ||
| 46 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 44 | 47 | ||
| 45 | /* | 48 | /* |
| 46 | * ali_start - start watchdog countdown | 49 | * ali_start - start watchdog countdown |
| @@ -103,15 +106,16 @@ static void ali_keepalive(void) | |||
| 103 | 106 | ||
| 104 | static int ali_settimer(int t) | 107 | static int ali_settimer(int t) |
| 105 | { | 108 | { |
| 106 | if(t < 0) | 109 | if (t < 0) |
| 107 | return -EINVAL; | 110 | return -EINVAL; |
| 108 | else if(t < 60) | 111 | else if (t < 60) |
| 109 | ali_timeout_bits = t|(1<<6); | 112 | ali_timeout_bits = t|(1<<6); |
| 110 | else if(t < 3600) | 113 | else if (t < 3600) |
| 111 | ali_timeout_bits = (t/60)|(1<<7); | 114 | ali_timeout_bits = (t/60)|(1<<7); |
| 112 | else if(t < 18000) | 115 | else if (t < 18000) |
| 113 | ali_timeout_bits = (t/300)|(1<<6)|(1<<7); | 116 | ali_timeout_bits = (t/300)|(1<<6)|(1<<7); |
| 114 | else return -EINVAL; | 117 | else |
| 118 | return -EINVAL; | ||
| 115 | 119 | ||
| 116 | timeout = t; | 120 | timeout = t; |
| 117 | return 0; | 121 | return 0; |
| @@ -134,21 +138,22 @@ static int ali_settimer(int t) | |||
| 134 | */ | 138 | */ |
| 135 | 139 | ||
| 136 | static ssize_t ali_write(struct file *file, const char __user *data, | 140 | static ssize_t ali_write(struct file *file, const char __user *data, |
| 137 | size_t len, loff_t * ppos) | 141 | size_t len, loff_t *ppos) |
| 138 | { | 142 | { |
| 139 | /* See if we got the magic character 'V' and reload the timer */ | 143 | /* See if we got the magic character 'V' and reload the timer */ |
| 140 | if (len) { | 144 | if (len) { |
| 141 | if (!nowayout) { | 145 | if (!nowayout) { |
| 142 | size_t i; | 146 | size_t i; |
| 143 | 147 | ||
| 144 | /* note: just in case someone wrote the magic character | 148 | /* note: just in case someone wrote the |
| 145 | * five months ago... */ | 149 | magic character five months ago... */ |
| 146 | ali_expect_release = 0; | 150 | ali_expect_release = 0; |
| 147 | 151 | ||
| 148 | /* scan to see whether or not we got the magic character */ | 152 | /* scan to see whether or not we got |
| 153 | the magic character */ | ||
| 149 | for (i = 0; i != len; i++) { | 154 | for (i = 0; i != len; i++) { |
| 150 | char c; | 155 | char c; |
| 151 | if(get_user(c, data+i)) | 156 | if (get_user(c, data + i)) |
| 152 | return -EFAULT; | 157 | return -EFAULT; |
| 153 | if (c == 'V') | 158 | if (c == 'V') |
| 154 | ali_expect_release = 42; | 159 | ali_expect_release = 42; |
| @@ -163,7 +168,6 @@ static ssize_t ali_write(struct file *file, const char __user *data, | |||
| 163 | 168 | ||
| 164 | /* | 169 | /* |
| 165 | * ali_ioctl - handle watchdog ioctls | 170 | * ali_ioctl - handle watchdog ioctls |
| 166 | * @inode: VFS inode | ||
| 167 | * @file: VFS file pointer | 171 | * @file: VFS file pointer |
| 168 | * @cmd: ioctl number | 172 | * @cmd: ioctl number |
| 169 | * @arg: arguments to the ioctl | 173 | * @arg: arguments to the ioctl |
| @@ -172,8 +176,7 @@ static ssize_t ali_write(struct file *file, const char __user *data, | |||
| 172 | * we want an extension to enable irq ack monitoring and the like | 176 | * we want an extension to enable irq ack monitoring and the like |
| 173 | */ | 177 | */ |
| 174 | 178 | ||
| 175 | static int ali_ioctl(struct inode *inode, struct file *file, | 179 | static long ali_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 176 | unsigned int cmd, unsigned long arg) | ||
| 177 | { | 180 | { |
| 178 | void __user *argp = (void __user *)arg; | 181 | void __user *argp = (void __user *)arg; |
| 179 | int __user *p = argp; | 182 | int __user *p = argp; |
| @@ -186,57 +189,45 @@ static int ali_ioctl(struct inode *inode, struct file *file, | |||
| 186 | }; | 189 | }; |
| 187 | 190 | ||
| 188 | switch (cmd) { | 191 | switch (cmd) { |
| 189 | case WDIOC_GETSUPPORT: | 192 | case WDIOC_GETSUPPORT: |
| 190 | return copy_to_user(argp, &ident, | 193 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; |
| 191 | sizeof (ident)) ? -EFAULT : 0; | 194 | |
| 192 | 195 | case WDIOC_GETSTATUS: | |
| 193 | case WDIOC_GETSTATUS: | 196 | case WDIOC_GETBOOTSTATUS: |
| 194 | case WDIOC_GETBOOTSTATUS: | 197 | return put_user(0, p); |
| 195 | return put_user(0, p); | 198 | case WDIOC_SETOPTIONS: |
| 196 | 199 | { | |
| 197 | case WDIOC_KEEPALIVE: | 200 | int new_options, retval = -EINVAL; |
| 198 | ali_keepalive(); | 201 | |
| 199 | return 0; | 202 | if (get_user(new_options, p)) |
| 200 | 203 | return -EFAULT; | |
| 201 | case WDIOC_SETOPTIONS: | 204 | if (new_options & WDIOS_DISABLECARD) { |
| 202 | { | 205 | ali_stop(); |
| 203 | int new_options, retval = -EINVAL; | 206 | retval = 0; |
| 204 | |||
| 205 | if (get_user (new_options, p)) | ||
| 206 | return -EFAULT; | ||
| 207 | |||
| 208 | if (new_options & WDIOS_DISABLECARD) { | ||
| 209 | ali_stop(); | ||
| 210 | retval = 0; | ||
| 211 | } | ||
| 212 | |||
| 213 | if (new_options & WDIOS_ENABLECARD) { | ||
| 214 | ali_start(); | ||
| 215 | retval = 0; | ||
| 216 | } | ||
| 217 | |||
| 218 | return retval; | ||
| 219 | } | 207 | } |
| 220 | 208 | if (new_options & WDIOS_ENABLECARD) { | |
| 221 | case WDIOC_SETTIMEOUT: | 209 | ali_start(); |
| 222 | { | 210 | retval = 0; |
| 223 | int new_timeout; | ||
| 224 | |||
| 225 | if (get_user(new_timeout, p)) | ||
| 226 | return -EFAULT; | ||
| 227 | |||
| 228 | if (ali_settimer(new_timeout)) | ||
| 229 | return -EINVAL; | ||
| 230 | |||
| 231 | ali_keepalive(); | ||
| 232 | /* Fall */ | ||
| 233 | } | 211 | } |
| 234 | 212 | return retval; | |
| 235 | case WDIOC_GETTIMEOUT: | 213 | } |
| 236 | return put_user(timeout, p); | 214 | case WDIOC_KEEPALIVE: |
| 237 | 215 | ali_keepalive(); | |
| 238 | default: | 216 | return 0; |
| 239 | return -ENOTTY; | 217 | case WDIOC_SETTIMEOUT: |
| 218 | { | ||
| 219 | int new_timeout; | ||
| 220 | if (get_user(new_timeout, p)) | ||
| 221 | return -EFAULT; | ||
| 222 | if (ali_settimer(new_timeout)) | ||
| 223 | return -EINVAL; | ||
| 224 | ali_keepalive(); | ||
| 225 | /* Fall */ | ||
| 226 | } | ||
| 227 | case WDIOC_GETTIMEOUT: | ||
| 228 | return put_user(timeout, p); | ||
| 229 | default: | ||
| 230 | return -ENOTTY; | ||
| 240 | } | 231 | } |
| 241 | } | 232 | } |
| 242 | 233 | ||
| @@ -274,10 +265,11 @@ static int ali_release(struct inode *inode, struct file *file) | |||
| 274 | /* | 265 | /* |
| 275 | * Shut off the timer. | 266 | * Shut off the timer. |
| 276 | */ | 267 | */ |
| 277 | if (ali_expect_release == 42) { | 268 | if (ali_expect_release == 42) |
| 278 | ali_stop(); | 269 | ali_stop(); |
| 279 | } else { | 270 | else { |
| 280 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 271 | printk(KERN_CRIT PFX |
| 272 | "Unexpected close, not stopping watchdog!\n"); | ||
| 281 | ali_keepalive(); | 273 | ali_keepalive(); |
| 282 | } | 274 | } |
| 283 | clear_bit(0, &ali_is_open); | 275 | clear_bit(0, &ali_is_open); |
| @@ -292,13 +284,11 @@ static int ali_release(struct inode *inode, struct file *file) | |||
| 292 | */ | 284 | */ |
| 293 | 285 | ||
| 294 | 286 | ||
| 295 | static int ali_notify_sys(struct notifier_block *this, unsigned long code, void *unused) | 287 | static int ali_notify_sys(struct notifier_block *this, |
| 288 | unsigned long code, void *unused) | ||
| 296 | { | 289 | { |
| 297 | if (code==SYS_DOWN || code==SYS_HALT) { | 290 | if (code == SYS_DOWN || code == SYS_HALT) |
| 298 | /* Turn the WDT off */ | 291 | ali_stop(); /* Turn the WDT off */ |
| 299 | ali_stop(); | ||
| 300 | } | ||
| 301 | |||
| 302 | return NOTIFY_DONE; | 292 | return NOTIFY_DONE; |
| 303 | } | 293 | } |
| 304 | 294 | ||
| @@ -340,10 +330,10 @@ static int __init ali_find_watchdog(void) | |||
| 340 | 330 | ||
| 341 | /* Check for the a 7101 PMU */ | 331 | /* Check for the a 7101 PMU */ |
| 342 | pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x7101, NULL); | 332 | pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x7101, NULL); |
| 343 | if(pdev == NULL) | 333 | if (pdev == NULL) |
| 344 | return -ENODEV; | 334 | return -ENODEV; |
| 345 | 335 | ||
| 346 | if(pci_enable_device(pdev)) { | 336 | if (pci_enable_device(pdev)) { |
| 347 | pci_dev_put(pdev); | 337 | pci_dev_put(pdev); |
| 348 | return -EIO; | 338 | return -EIO; |
| 349 | } | 339 | } |
| @@ -355,9 +345,12 @@ static int __init ali_find_watchdog(void) | |||
| 355 | */ | 345 | */ |
| 356 | pci_read_config_dword(pdev, 0xCC, &wdog); | 346 | pci_read_config_dword(pdev, 0xCC, &wdog); |
| 357 | 347 | ||
| 358 | wdog &= ~0x3F; /* Timer bits */ | 348 | /* Timer bits */ |
| 359 | wdog &= ~((1<<27)|(1<<26)|(1<<25)|(1<<24)); /* Issued events */ | 349 | wdog &= ~0x3F; |
| 360 | wdog &= ~((1<<16)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)); /* No monitor bits */ | 350 | /* Issued events */ |
| 351 | wdog &= ~((1<<27)|(1<<26)|(1<<25)|(1<<24)); | ||
| 352 | /* No monitor bits */ | ||
| 353 | wdog &= ~((1<<16)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)); | ||
| 361 | 354 | ||
| 362 | pci_write_config_dword(pdev, 0xCC, wdog); | 355 | pci_write_config_dword(pdev, 0xCC, wdog); |
| 363 | 356 | ||
| @@ -369,12 +362,12 @@ static int __init ali_find_watchdog(void) | |||
| 369 | */ | 362 | */ |
| 370 | 363 | ||
| 371 | static const struct file_operations ali_fops = { | 364 | static const struct file_operations ali_fops = { |
| 372 | .owner = THIS_MODULE, | 365 | .owner = THIS_MODULE, |
| 373 | .llseek = no_llseek, | 366 | .llseek = no_llseek, |
| 374 | .write = ali_write, | 367 | .write = ali_write, |
| 375 | .ioctl = ali_ioctl, | 368 | .unlocked_ioctl = ali_ioctl, |
| 376 | .open = ali_open, | 369 | .open = ali_open, |
| 377 | .release = ali_release, | 370 | .release = ali_release, |
| 378 | }; | 371 | }; |
| 379 | 372 | ||
| 380 | static struct miscdevice ali_miscdev = { | 373 | static struct miscdevice ali_miscdev = { |
| @@ -399,15 +392,16 @@ static int __init watchdog_init(void) | |||
| 399 | int ret; | 392 | int ret; |
| 400 | 393 | ||
| 401 | /* Check whether or not the hardware watchdog is there */ | 394 | /* Check whether or not the hardware watchdog is there */ |
| 402 | if (ali_find_watchdog() != 0) { | 395 | if (ali_find_watchdog() != 0) |
| 403 | return -ENODEV; | 396 | return -ENODEV; |
| 404 | } | ||
| 405 | 397 | ||
| 406 | /* Check that the timeout value is within it's range ; if not reset to the default */ | 398 | /* Check that the timeout value is within it's range; |
| 399 | if not reset to the default */ | ||
| 407 | if (timeout < 1 || timeout >= 18000) { | 400 | if (timeout < 1 || timeout >= 18000) { |
| 408 | timeout = WATCHDOG_TIMEOUT; | 401 | timeout = WATCHDOG_TIMEOUT; |
| 409 | printk(KERN_INFO PFX "timeout value must be 0<timeout<18000, using %d\n", | 402 | printk(KERN_INFO PFX |
| 410 | timeout); | 403 | "timeout value must be 0 < timeout < 18000, using %d\n", |
| 404 | timeout); | ||
| 411 | } | 405 | } |
| 412 | 406 | ||
| 413 | /* Calculate the watchdog's timeout */ | 407 | /* Calculate the watchdog's timeout */ |
| @@ -415,15 +409,16 @@ static int __init watchdog_init(void) | |||
| 415 | 409 | ||
| 416 | ret = register_reboot_notifier(&ali_notifier); | 410 | ret = register_reboot_notifier(&ali_notifier); |
| 417 | if (ret != 0) { | 411 | if (ret != 0) { |
| 418 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 412 | printk(KERN_ERR PFX |
| 419 | ret); | 413 | "cannot register reboot notifier (err=%d)\n", ret); |
| 420 | goto out; | 414 | goto out; |
| 421 | } | 415 | } |
| 422 | 416 | ||
| 423 | ret = misc_register(&ali_miscdev); | 417 | ret = misc_register(&ali_miscdev); |
| 424 | if (ret != 0) { | 418 | if (ret != 0) { |
| 425 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 419 | printk(KERN_ERR PFX |
| 426 | WATCHDOG_MINOR, ret); | 420 | "cannot register miscdev on minor=%d (err=%d)\n", |
| 421 | WATCHDOG_MINOR, ret); | ||
| 427 | goto unreg_reboot; | 422 | goto unreg_reboot; |
| 428 | } | 423 | } |
| 429 | 424 | ||
diff --git a/drivers/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c index 238273c98656..a045ef869439 100644 --- a/drivers/watchdog/alim7101_wdt.c +++ b/drivers/watchdog/alim7101_wdt.c | |||
| @@ -31,9 +31,9 @@ | |||
| 31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
| 32 | #include <linux/fs.h> | 32 | #include <linux/fs.h> |
| 33 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
| 34 | #include <linux/io.h> | ||
| 35 | #include <linux/uaccess.h> | ||
| 34 | 36 | ||
| 35 | #include <asm/io.h> | ||
| 36 | #include <asm/uaccess.h> | ||
| 37 | #include <asm/system.h> | 37 | #include <asm/system.h> |
| 38 | 38 | ||
| 39 | #define OUR_NAME "alim7101_wdt" | 39 | #define OUR_NAME "alim7101_wdt" |
| @@ -60,13 +60,17 @@ | |||
| 60 | */ | 60 | */ |
| 61 | 61 | ||
| 62 | #define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ | 62 | #define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ |
| 63 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ | 63 | /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ |
| 64 | static int timeout = WATCHDOG_TIMEOUT; | ||
| 64 | module_param(timeout, int, 0); | 65 | module_param(timeout, int, 0); |
| 65 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | 66 | MODULE_PARM_DESC(timeout, |
| 67 | "Watchdog timeout in seconds. (1<=timeout<=3600, default=" | ||
| 68 | __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | ||
| 66 | 69 | ||
| 67 | static int use_gpio = 0; /* Use the pic (for a1d revision alim7101) */ | 70 | static int use_gpio; /* Use the pic (for a1d revision alim7101) */ |
| 68 | module_param(use_gpio, int, 0); | 71 | module_param(use_gpio, int, 0); |
| 69 | MODULE_PARM_DESC(use_gpio, "Use the gpio watchdog. (required by old cobalt boards)"); | 72 | MODULE_PARM_DESC(use_gpio, |
| 73 | "Use the gpio watchdog (required by old cobalt boards)."); | ||
| 70 | 74 | ||
| 71 | static void wdt_timer_ping(unsigned long); | 75 | static void wdt_timer_ping(unsigned long); |
| 72 | static DEFINE_TIMER(timer, wdt_timer_ping, 0, 1); | 76 | static DEFINE_TIMER(timer, wdt_timer_ping, 0, 1); |
| @@ -77,8 +81,9 @@ static struct pci_dev *alim7101_pmu; | |||
| 77 | 81 | ||
| 78 | static int nowayout = WATCHDOG_NOWAYOUT; | 82 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 79 | module_param(nowayout, int, 0); | 83 | module_param(nowayout, int, 0); |
| 80 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" | 84 | MODULE_PARM_DESC(nowayout, |
| 81 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 85 | "Watchdog cannot be stopped once started (default=" |
| 86 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 82 | 87 | ||
| 83 | /* | 88 | /* |
| 84 | * Whack the dog | 89 | * Whack the dog |
| @@ -89,23 +94,26 @@ static void wdt_timer_ping(unsigned long data) | |||
| 89 | /* If we got a heartbeat pulse within the WDT_US_INTERVAL | 94 | /* If we got a heartbeat pulse within the WDT_US_INTERVAL |
| 90 | * we agree to ping the WDT | 95 | * we agree to ping the WDT |
| 91 | */ | 96 | */ |
| 92 | char tmp; | 97 | char tmp; |
| 93 | 98 | ||
| 94 | if(time_before(jiffies, next_heartbeat)) | 99 | if (time_before(jiffies, next_heartbeat)) { |
| 95 | { | ||
| 96 | /* Ping the WDT (this is actually a disarm/arm sequence) */ | 100 | /* Ping the WDT (this is actually a disarm/arm sequence) */ |
| 97 | pci_read_config_byte(alim7101_pmu, 0x92, &tmp); | 101 | pci_read_config_byte(alim7101_pmu, 0x92, &tmp); |
| 98 | pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM)); | 102 | pci_write_config_byte(alim7101_pmu, |
| 99 | pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM)); | 103 | ALI_7101_WDT, (tmp & ~ALI_WDT_ARM)); |
| 104 | pci_write_config_byte(alim7101_pmu, | ||
| 105 | ALI_7101_WDT, (tmp | ALI_WDT_ARM)); | ||
| 100 | if (use_gpio) { | 106 | if (use_gpio) { |
| 101 | pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); | 107 | pci_read_config_byte(alim7101_pmu, |
| 102 | pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp | 108 | ALI_7101_GPIO_O, &tmp); |
| 103 | | 0x20); | 109 | pci_write_config_byte(alim7101_pmu, |
| 104 | pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp | 110 | ALI_7101_GPIO_O, tmp | 0x20); |
| 105 | & ~0x20); | 111 | pci_write_config_byte(alim7101_pmu, |
| 112 | ALI_7101_GPIO_O, tmp & ~0x20); | ||
| 106 | } | 113 | } |
| 107 | } else { | 114 | } else { |
| 108 | printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); | 115 | printk(KERN_WARNING PFX |
| 116 | "Heartbeat lost! Will not ping the watchdog\n"); | ||
| 109 | } | 117 | } |
| 110 | /* Re-set the timer interval */ | 118 | /* Re-set the timer interval */ |
| 111 | mod_timer(&timer, jiffies + WDT_INTERVAL); | 119 | mod_timer(&timer, jiffies + WDT_INTERVAL); |
| @@ -117,21 +125,27 @@ static void wdt_timer_ping(unsigned long data) | |||
| 117 | 125 | ||
| 118 | static void wdt_change(int writeval) | 126 | static void wdt_change(int writeval) |
| 119 | { | 127 | { |
| 120 | char tmp; | 128 | char tmp; |
| 121 | 129 | ||
| 122 | pci_read_config_byte(alim7101_pmu, ALI_7101_WDT, &tmp); | 130 | pci_read_config_byte(alim7101_pmu, ALI_7101_WDT, &tmp); |
| 123 | if (writeval == WDT_ENABLE) { | 131 | if (writeval == WDT_ENABLE) { |
| 124 | pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM)); | 132 | pci_write_config_byte(alim7101_pmu, |
| 133 | ALI_7101_WDT, (tmp | ALI_WDT_ARM)); | ||
| 125 | if (use_gpio) { | 134 | if (use_gpio) { |
| 126 | pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); | 135 | pci_read_config_byte(alim7101_pmu, |
| 127 | pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp & ~0x20); | 136 | ALI_7101_GPIO_O, &tmp); |
| 137 | pci_write_config_byte(alim7101_pmu, | ||
| 138 | ALI_7101_GPIO_O, tmp & ~0x20); | ||
| 128 | } | 139 | } |
| 129 | 140 | ||
| 130 | } else { | 141 | } else { |
| 131 | pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM)); | 142 | pci_write_config_byte(alim7101_pmu, |
| 143 | ALI_7101_WDT, (tmp & ~ALI_WDT_ARM)); | ||
| 132 | if (use_gpio) { | 144 | if (use_gpio) { |
| 133 | pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); | 145 | pci_read_config_byte(alim7101_pmu, |
| 134 | pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp | 0x20); | 146 | ALI_7101_GPIO_O, &tmp); |
| 147 | pci_write_config_byte(alim7101_pmu, | ||
| 148 | ALI_7101_GPIO_O, tmp | 0x20); | ||
| 135 | } | 149 | } |
| 136 | } | 150 | } |
| 137 | } | 151 | } |
| @@ -169,10 +183,11 @@ static void wdt_keepalive(void) | |||
| 169 | * /dev/watchdog handling | 183 | * /dev/watchdog handling |
| 170 | */ | 184 | */ |
| 171 | 185 | ||
| 172 | static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos) | 186 | static ssize_t fop_write(struct file *file, const char __user *buf, |
| 187 | size_t count, loff_t *ppos) | ||
| 173 | { | 188 | { |
| 174 | /* See if we got the magic character 'V' and reload the timer */ | 189 | /* See if we got the magic character 'V' and reload the timer */ |
| 175 | if(count) { | 190 | if (count) { |
| 176 | if (!nowayout) { | 191 | if (!nowayout) { |
| 177 | size_t ofs; | 192 | size_t ofs; |
| 178 | 193 | ||
| @@ -183,7 +198,7 @@ static ssize_t fop_write(struct file * file, const char __user * buf, size_t cou | |||
| 183 | /* now scan */ | 198 | /* now scan */ |
| 184 | for (ofs = 0; ofs != count; ofs++) { | 199 | for (ofs = 0; ofs != count; ofs++) { |
| 185 | char c; | 200 | char c; |
| 186 | if (get_user(c, buf+ofs)) | 201 | if (get_user(c, buf + ofs)) |
| 187 | return -EFAULT; | 202 | return -EFAULT; |
| 188 | if (c == 'V') | 203 | if (c == 'V') |
| 189 | wdt_expect_close = 42; | 204 | wdt_expect_close = 42; |
| @@ -195,119 +210,116 @@ static ssize_t fop_write(struct file * file, const char __user * buf, size_t cou | |||
| 195 | return count; | 210 | return count; |
| 196 | } | 211 | } |
| 197 | 212 | ||
| 198 | static int fop_open(struct inode * inode, struct file * file) | 213 | static int fop_open(struct inode *inode, struct file *file) |
| 199 | { | 214 | { |
| 200 | /* Just in case we're already talking to someone... */ | 215 | /* Just in case we're already talking to someone... */ |
| 201 | if(test_and_set_bit(0, &wdt_is_open)) | 216 | if (test_and_set_bit(0, &wdt_is_open)) |
| 202 | return -EBUSY; | 217 | return -EBUSY; |
| 203 | /* Good, fire up the show */ | 218 | /* Good, fire up the show */ |
| 204 | wdt_startup(); | 219 | wdt_startup(); |
| 205 | return nonseekable_open(inode, file); | 220 | return nonseekable_open(inode, file); |
| 206 | } | 221 | } |
| 207 | 222 | ||
| 208 | static int fop_close(struct inode * inode, struct file * file) | 223 | static int fop_close(struct inode *inode, struct file *file) |
| 209 | { | 224 | { |
| 210 | if(wdt_expect_close == 42) | 225 | if (wdt_expect_close == 42) |
| 211 | wdt_turnoff(); | 226 | wdt_turnoff(); |
| 212 | else { | 227 | else { |
| 213 | /* wim: shouldn't there be a: del_timer(&timer); */ | 228 | /* wim: shouldn't there be a: del_timer(&timer); */ |
| 214 | printk(KERN_CRIT PFX "device file closed unexpectedly. Will not stop the WDT!\n"); | 229 | printk(KERN_CRIT PFX |
| 230 | "device file closed unexpectedly. Will not stop the WDT!\n"); | ||
| 215 | } | 231 | } |
| 216 | clear_bit(0, &wdt_is_open); | 232 | clear_bit(0, &wdt_is_open); |
| 217 | wdt_expect_close = 0; | 233 | wdt_expect_close = 0; |
| 218 | return 0; | 234 | return 0; |
| 219 | } | 235 | } |
| 220 | 236 | ||
| 221 | static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 237 | static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 222 | { | 238 | { |
| 223 | void __user *argp = (void __user *)arg; | 239 | void __user *argp = (void __user *)arg; |
| 224 | int __user *p = argp; | 240 | int __user *p = argp; |
| 225 | static struct watchdog_info ident = | 241 | static struct watchdog_info ident = { |
| 226 | { | 242 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
| 227 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, | 243 | | WDIOF_MAGICCLOSE, |
| 228 | .firmware_version = 1, | 244 | .firmware_version = 1, |
| 229 | .identity = "ALiM7101", | 245 | .identity = "ALiM7101", |
| 230 | }; | 246 | }; |
| 231 | 247 | ||
| 232 | switch(cmd) | 248 | switch (cmd) { |
| 249 | case WDIOC_GETSUPPORT: | ||
| 250 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; | ||
| 251 | case WDIOC_GETSTATUS: | ||
| 252 | case WDIOC_GETBOOTSTATUS: | ||
| 253 | return put_user(0, p); | ||
| 254 | case WDIOC_SETOPTIONS: | ||
| 233 | { | 255 | { |
| 234 | case WDIOC_GETSUPPORT: | 256 | int new_options, retval = -EINVAL; |
| 235 | return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; | ||
| 236 | case WDIOC_GETSTATUS: | ||
| 237 | case WDIOC_GETBOOTSTATUS: | ||
| 238 | return put_user(0, p); | ||
| 239 | case WDIOC_KEEPALIVE: | ||
| 240 | wdt_keepalive(); | ||
| 241 | return 0; | ||
| 242 | case WDIOC_SETOPTIONS: | ||
| 243 | { | ||
| 244 | int new_options, retval = -EINVAL; | ||
| 245 | |||
| 246 | if(get_user(new_options, p)) | ||
| 247 | return -EFAULT; | ||
| 248 | |||
| 249 | if(new_options & WDIOS_DISABLECARD) { | ||
| 250 | wdt_turnoff(); | ||
| 251 | retval = 0; | ||
| 252 | } | ||
| 253 | 257 | ||
| 254 | if(new_options & WDIOS_ENABLECARD) { | 258 | if (get_user(new_options, p)) |
| 255 | wdt_startup(); | 259 | return -EFAULT; |
| 256 | retval = 0; | 260 | if (new_options & WDIOS_DISABLECARD) { |
| 257 | } | 261 | wdt_turnoff(); |
| 258 | 262 | retval = 0; | |
| 259 | return retval; | ||
| 260 | } | 263 | } |
| 261 | case WDIOC_SETTIMEOUT: | 264 | if (new_options & WDIOS_ENABLECARD) { |
| 262 | { | 265 | wdt_startup(); |
| 263 | int new_timeout; | 266 | retval = 0; |
| 264 | |||
| 265 | if(get_user(new_timeout, p)) | ||
| 266 | return -EFAULT; | ||
| 267 | |||
| 268 | if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */ | ||
| 269 | return -EINVAL; | ||
| 270 | |||
| 271 | timeout = new_timeout; | ||
| 272 | wdt_keepalive(); | ||
| 273 | /* Fall through */ | ||
| 274 | } | 267 | } |
| 275 | case WDIOC_GETTIMEOUT: | 268 | return retval; |
| 276 | return put_user(timeout, p); | 269 | } |
| 277 | default: | 270 | case WDIOC_KEEPALIVE: |
| 278 | return -ENOTTY; | 271 | wdt_keepalive(); |
| 272 | return 0; | ||
| 273 | case WDIOC_SETTIMEOUT: | ||
| 274 | { | ||
| 275 | int new_timeout; | ||
| 276 | |||
| 277 | if (get_user(new_timeout, p)) | ||
| 278 | return -EFAULT; | ||
| 279 | /* arbitrary upper limit */ | ||
| 280 | if (new_timeout < 1 || new_timeout > 3600) | ||
| 281 | return -EINVAL; | ||
| 282 | timeout = new_timeout; | ||
| 283 | wdt_keepalive(); | ||
| 284 | /* Fall through */ | ||
| 285 | } | ||
| 286 | case WDIOC_GETTIMEOUT: | ||
| 287 | return put_user(timeout, p); | ||
| 288 | default: | ||
| 289 | return -ENOTTY; | ||
| 279 | } | 290 | } |
| 280 | } | 291 | } |
| 281 | 292 | ||
| 282 | static const struct file_operations wdt_fops = { | 293 | static const struct file_operations wdt_fops = { |
| 283 | .owner= THIS_MODULE, | 294 | .owner = THIS_MODULE, |
| 284 | .llseek= no_llseek, | 295 | .llseek = no_llseek, |
| 285 | .write= fop_write, | 296 | .write = fop_write, |
| 286 | .open= fop_open, | 297 | .open = fop_open, |
| 287 | .release= fop_close, | 298 | .release = fop_close, |
| 288 | .ioctl= fop_ioctl, | 299 | .unlocked_ioctl = fop_ioctl, |
| 289 | }; | 300 | }; |
| 290 | 301 | ||
| 291 | static struct miscdevice wdt_miscdev = { | 302 | static struct miscdevice wdt_miscdev = { |
| 292 | .minor=WATCHDOG_MINOR, | 303 | .minor = WATCHDOG_MINOR, |
| 293 | .name="watchdog", | 304 | .name = "watchdog", |
| 294 | .fops=&wdt_fops, | 305 | .fops = &wdt_fops, |
| 295 | }; | 306 | }; |
| 296 | 307 | ||
| 297 | /* | 308 | /* |
| 298 | * Notifier for system down | 309 | * Notifier for system down |
| 299 | */ | 310 | */ |
| 300 | 311 | ||
| 301 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) | 312 | static int wdt_notify_sys(struct notifier_block *this, |
| 313 | unsigned long code, void *unused) | ||
| 302 | { | 314 | { |
| 303 | if (code==SYS_DOWN || code==SYS_HALT) | 315 | if (code == SYS_DOWN || code == SYS_HALT) |
| 304 | wdt_turnoff(); | 316 | wdt_turnoff(); |
| 305 | 317 | ||
| 306 | if (code==SYS_RESTART) { | 318 | if (code == SYS_RESTART) { |
| 307 | /* | 319 | /* |
| 308 | * Cobalt devices have no way of rebooting themselves other than | 320 | * Cobalt devices have no way of rebooting themselves other |
| 309 | * getting the watchdog to pull reset, so we restart the watchdog on | 321 | * than getting the watchdog to pull reset, so we restart the |
| 310 | * reboot with no heartbeat | 322 | * watchdog on reboot with no heartbeat |
| 311 | */ | 323 | */ |
| 312 | wdt_change(WDT_ENABLE); | 324 | wdt_change(WDT_ENABLE); |
| 313 | printk(KERN_INFO PFX "Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second.\n"); | 325 | printk(KERN_INFO PFX "Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second.\n"); |
| @@ -320,8 +332,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void | |||
| 320 | * turn the timebomb registers off. | 332 | * turn the timebomb registers off. |
| 321 | */ | 333 | */ |
| 322 | 334 | ||
| 323 | static struct notifier_block wdt_notifier= | 335 | static struct notifier_block wdt_notifier = { |
| 324 | { | ||
| 325 | .notifier_call = wdt_notify_sys, | 336 | .notifier_call = wdt_notify_sys, |
| 326 | }; | 337 | }; |
| 327 | 338 | ||
| @@ -354,7 +365,8 @@ static int __init alim7101_wdt_init(void) | |||
| 354 | ali1543_south = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, | 365 | ali1543_south = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, |
| 355 | NULL); | 366 | NULL); |
| 356 | if (!ali1543_south) { | 367 | if (!ali1543_south) { |
| 357 | printk(KERN_INFO PFX "ALi 1543 South-Bridge not present - WDT not set\n"); | 368 | printk(KERN_INFO PFX |
| 369 | "ALi 1543 South-Bridge not present - WDT not set\n"); | ||
| 358 | goto err_out; | 370 | goto err_out; |
| 359 | } | 371 | } |
| 360 | pci_read_config_byte(ali1543_south, 0x5e, &tmp); | 372 | pci_read_config_byte(ali1543_south, 0x5e, &tmp); |
| @@ -363,24 +375,25 @@ static int __init alim7101_wdt_init(void) | |||
| 363 | if (!use_gpio) { | 375 | if (!use_gpio) { |
| 364 | printk(KERN_INFO PFX "Detected old alim7101 revision 'a1d'. If this is a cobalt board, set the 'use_gpio' module parameter.\n"); | 376 | printk(KERN_INFO PFX "Detected old alim7101 revision 'a1d'. If this is a cobalt board, set the 'use_gpio' module parameter.\n"); |
| 365 | goto err_out; | 377 | goto err_out; |
| 366 | } | 378 | } |
| 367 | nowayout = 1; | 379 | nowayout = 1; |
| 368 | } else if ((tmp & 0x1e) != 0x12 && (tmp & 0x1e) != 0x00) { | 380 | } else if ((tmp & 0x1e) != 0x12 && (tmp & 0x1e) != 0x00) { |
| 369 | printk(KERN_INFO PFX "ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n"); | 381 | printk(KERN_INFO PFX "ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n"); |
| 370 | goto err_out; | 382 | goto err_out; |
| 371 | } | 383 | } |
| 372 | 384 | ||
| 373 | if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */ | 385 | if (timeout < 1 || timeout > 3600) { |
| 374 | { | 386 | /* arbitrary upper limit */ |
| 375 | timeout = WATCHDOG_TIMEOUT; | 387 | timeout = WATCHDOG_TIMEOUT; |
| 376 | printk(KERN_INFO PFX "timeout value must be 1<=x<=3600, using %d\n", | 388 | printk(KERN_INFO PFX |
| 377 | timeout); | 389 | "timeout value must be 1 <= x <= 3600, using %d\n", |
| 390 | timeout); | ||
| 378 | } | 391 | } |
| 379 | 392 | ||
| 380 | rc = register_reboot_notifier(&wdt_notifier); | 393 | rc = register_reboot_notifier(&wdt_notifier); |
| 381 | if (rc) { | 394 | if (rc) { |
| 382 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 395 | printk(KERN_ERR PFX |
| 383 | rc); | 396 | "cannot register reboot notifier (err=%d)\n", rc); |
| 384 | goto err_out; | 397 | goto err_out; |
| 385 | } | 398 | } |
| 386 | 399 | ||
| @@ -391,9 +404,8 @@ static int __init alim7101_wdt_init(void) | |||
| 391 | goto err_out_reboot; | 404 | goto err_out_reboot; |
| 392 | } | 405 | } |
| 393 | 406 | ||
| 394 | if (nowayout) { | 407 | if (nowayout) |
| 395 | __module_get(THIS_MODULE); | 408 | __module_get(THIS_MODULE); |
| 396 | } | ||
| 397 | 409 | ||
| 398 | printk(KERN_INFO PFX "WDT driver for ALi M7101 initialised. timeout=%d sec (nowayout=%d)\n", | 410 | printk(KERN_INFO PFX "WDT driver for ALi M7101 initialised. timeout=%d sec (nowayout=%d)\n", |
| 399 | timeout, nowayout); | 411 | timeout, nowayout); |
diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c index ef7b0d67095e..55dcbfe2bb72 100644 --- a/drivers/watchdog/ar7_wdt.c +++ b/drivers/watchdog/ar7_wdt.c | |||
| @@ -213,7 +213,7 @@ static int ar7_wdt_notify_sys(struct notifier_block *this, | |||
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | static struct notifier_block ar7_wdt_notifier = { | 215 | static struct notifier_block ar7_wdt_notifier = { |
| 216 | .notifier_call = ar7_wdt_notify_sys | 216 | .notifier_call = ar7_wdt_notify_sys, |
| 217 | }; | 217 | }; |
| 218 | 218 | ||
| 219 | static ssize_t ar7_wdt_write(struct file *file, const char *data, | 219 | static ssize_t ar7_wdt_write(struct file *file, const char *data, |
| @@ -230,7 +230,7 @@ static ssize_t ar7_wdt_write(struct file *file, const char *data, | |||
| 230 | expect_close = 0; | 230 | expect_close = 0; |
| 231 | for (i = 0; i < len; ++i) { | 231 | for (i = 0; i < len; ++i) { |
| 232 | char c; | 232 | char c; |
| 233 | if (get_user(c, data+i)) | 233 | if (get_user(c, data + i)) |
| 234 | return -EFAULT; | 234 | return -EFAULT; |
| 235 | if (c == 'V') | 235 | if (c == 'V') |
| 236 | expect_close = 1; | 236 | expect_close = 1; |
| @@ -251,8 +251,6 @@ static long ar7_wdt_ioctl(struct file *file, | |||
| 251 | int new_margin; | 251 | int new_margin; |
| 252 | 252 | ||
| 253 | switch (cmd) { | 253 | switch (cmd) { |
| 254 | default: | ||
| 255 | return -ENOTTY; | ||
| 256 | case WDIOC_GETSUPPORT: | 254 | case WDIOC_GETSUPPORT: |
| 257 | if (copy_to_user((struct watchdog_info *)arg, &ident, | 255 | if (copy_to_user((struct watchdog_info *)arg, &ident, |
| 258 | sizeof(ident))) | 256 | sizeof(ident))) |
| @@ -281,6 +279,8 @@ static long ar7_wdt_ioctl(struct file *file, | |||
| 281 | if (put_user(margin, (int *)arg)) | 279 | if (put_user(margin, (int *)arg)) |
| 282 | return -EFAULT; | 280 | return -EFAULT; |
| 283 | return 0; | 281 | return 0; |
| 282 | default: | ||
| 283 | return -ENOTTY; | ||
| 284 | } | 284 | } |
| 285 | } | 285 | } |
| 286 | 286 | ||
diff --git a/drivers/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c index ae0fca5e8749..e8ae638e5804 100644 --- a/drivers/watchdog/at32ap700x_wdt.c +++ b/drivers/watchdog/at32ap700x_wdt.c | |||
| @@ -212,8 +212,8 @@ static struct watchdog_info at32_wdt_info = { | |||
| 212 | /* | 212 | /* |
| 213 | * Handle commands from user-space. | 213 | * Handle commands from user-space. |
| 214 | */ | 214 | */ |
| 215 | static int at32_wdt_ioctl(struct inode *inode, struct file *file, | 215 | static long at32_wdt_ioctl(struct file *file, |
| 216 | unsigned int cmd, unsigned long arg) | 216 | unsigned int cmd, unsigned long arg) |
| 217 | { | 217 | { |
| 218 | int ret = -ENOTTY; | 218 | int ret = -ENOTTY; |
| 219 | int time; | 219 | int time; |
| @@ -221,27 +221,10 @@ static int at32_wdt_ioctl(struct inode *inode, struct file *file, | |||
| 221 | int __user *p = argp; | 221 | int __user *p = argp; |
| 222 | 222 | ||
| 223 | switch (cmd) { | 223 | switch (cmd) { |
| 224 | case WDIOC_KEEPALIVE: | ||
| 225 | at32_wdt_pat(); | ||
| 226 | ret = 0; | ||
| 227 | break; | ||
| 228 | case WDIOC_GETSUPPORT: | 224 | case WDIOC_GETSUPPORT: |
| 229 | ret = copy_to_user(argp, &at32_wdt_info, | 225 | ret = copy_to_user(argp, &at32_wdt_info, |
| 230 | sizeof(at32_wdt_info)) ? -EFAULT : 0; | 226 | sizeof(at32_wdt_info)) ? -EFAULT : 0; |
| 231 | break; | 227 | break; |
| 232 | case WDIOC_SETTIMEOUT: | ||
| 233 | ret = get_user(time, p); | ||
| 234 | if (ret) | ||
| 235 | break; | ||
| 236 | ret = at32_wdt_settimeout(time); | ||
| 237 | if (ret) | ||
| 238 | break; | ||
| 239 | /* Enable new time value */ | ||
| 240 | at32_wdt_start(); | ||
| 241 | /* fall through */ | ||
| 242 | case WDIOC_GETTIMEOUT: | ||
| 243 | ret = put_user(wdt->timeout, p); | ||
| 244 | break; | ||
| 245 | case WDIOC_GETSTATUS: | 228 | case WDIOC_GETSTATUS: |
| 246 | ret = put_user(0, p); | 229 | ret = put_user(0, p); |
| 247 | break; | 230 | break; |
| @@ -258,6 +241,23 @@ static int at32_wdt_ioctl(struct inode *inode, struct file *file, | |||
| 258 | at32_wdt_start(); | 241 | at32_wdt_start(); |
| 259 | ret = 0; | 242 | ret = 0; |
| 260 | break; | 243 | break; |
| 244 | case WDIOC_KEEPALIVE: | ||
| 245 | at32_wdt_pat(); | ||
| 246 | ret = 0; | ||
| 247 | break; | ||
| 248 | case WDIOC_SETTIMEOUT: | ||
| 249 | ret = get_user(time, p); | ||
| 250 | if (ret) | ||
| 251 | break; | ||
| 252 | ret = at32_wdt_settimeout(time); | ||
| 253 | if (ret) | ||
| 254 | break; | ||
| 255 | /* Enable new time value */ | ||
| 256 | at32_wdt_start(); | ||
| 257 | /* fall through */ | ||
| 258 | case WDIOC_GETTIMEOUT: | ||
| 259 | ret = put_user(wdt->timeout, p); | ||
| 260 | break; | ||
| 261 | } | 261 | } |
| 262 | 262 | ||
| 263 | return ret; | 263 | return ret; |
| @@ -283,7 +283,7 @@ static ssize_t at32_wdt_write(struct file *file, const char __user *data, | |||
| 283 | */ | 283 | */ |
| 284 | for (i = 0; i != len; i++) { | 284 | for (i = 0; i != len; i++) { |
| 285 | char c; | 285 | char c; |
| 286 | if (get_user(c, data+i)) | 286 | if (get_user(c, data + i)) |
| 287 | return -EFAULT; | 287 | return -EFAULT; |
| 288 | if (c == 'V') | 288 | if (c == 'V') |
| 289 | expect_release = 42; | 289 | expect_release = 42; |
| @@ -298,7 +298,7 @@ static ssize_t at32_wdt_write(struct file *file, const char __user *data, | |||
| 298 | static const struct file_operations at32_wdt_fops = { | 298 | static const struct file_operations at32_wdt_fops = { |
| 299 | .owner = THIS_MODULE, | 299 | .owner = THIS_MODULE, |
| 300 | .llseek = no_llseek, | 300 | .llseek = no_llseek, |
| 301 | .ioctl = at32_wdt_ioctl, | 301 | .unlocked_ioctl = at32_wdt_ioctl, |
| 302 | .open = at32_wdt_open, | 302 | .open = at32_wdt_open, |
| 303 | .release = at32_wdt_close, | 303 | .release = at32_wdt_close, |
| 304 | .write = at32_wdt_write, | 304 | .write = at32_wdt_write, |
| @@ -391,7 +391,6 @@ static int __exit at32_wdt_remove(struct platform_device *pdev) | |||
| 391 | wdt = NULL; | 391 | wdt = NULL; |
| 392 | platform_set_drvdata(pdev, NULL); | 392 | platform_set_drvdata(pdev, NULL); |
| 393 | } | 393 | } |
| 394 | |||
| 395 | return 0; | 394 | return 0; |
| 396 | } | 395 | } |
| 397 | 396 | ||
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c index bf872aa2b9f3..bacd867dd22e 100644 --- a/drivers/watchdog/at91rm9200_wdt.c +++ b/drivers/watchdog/at91rm9200_wdt.c | |||
| @@ -20,10 +20,9 @@ | |||
| 20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
| 21 | #include <linux/types.h> | 21 | #include <linux/types.h> |
| 22 | #include <linux/watchdog.h> | 22 | #include <linux/watchdog.h> |
| 23 | #include <asm/uaccess.h> | 23 | #include <linux/uaccess.h> |
| 24 | #include <mach/at91_st.h> | 24 | #include <mach/at91_st.h> |
| 25 | 25 | ||
| 26 | |||
| 27 | #define WDT_DEFAULT_TIME 5 /* seconds */ | 26 | #define WDT_DEFAULT_TIME 5 /* seconds */ |
| 28 | #define WDT_MAX_TIME 256 /* seconds */ | 27 | #define WDT_MAX_TIME 256 /* seconds */ |
| 29 | 28 | ||
| @@ -31,11 +30,14 @@ static int wdt_time = WDT_DEFAULT_TIME; | |||
| 31 | static int nowayout = WATCHDOG_NOWAYOUT; | 30 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 32 | 31 | ||
| 33 | module_param(wdt_time, int, 0); | 32 | module_param(wdt_time, int, 0); |
| 34 | MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")"); | 33 | MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default=" |
| 34 | __MODULE_STRING(WDT_DEFAULT_TIME) ")"); | ||
| 35 | 35 | ||
| 36 | #ifdef CONFIG_WATCHDOG_NOWAYOUT | 36 | #ifdef CONFIG_WATCHDOG_NOWAYOUT |
| 37 | module_param(nowayout, int, 0); | 37 | module_param(nowayout, int, 0); |
| 38 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 38 | MODULE_PARM_DESC(nowayout, |
| 39 | "Watchdog cannot be stopped once started (default=" | ||
| 40 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 39 | #endif | 41 | #endif |
| 40 | 42 | ||
| 41 | 43 | ||
| @@ -46,7 +48,7 @@ static unsigned long at91wdt_busy; | |||
| 46 | /* | 48 | /* |
| 47 | * Disable the watchdog. | 49 | * Disable the watchdog. |
| 48 | */ | 50 | */ |
| 49 | static void inline at91_wdt_stop(void) | 51 | static inline void at91_wdt_stop(void) |
| 50 | { | 52 | { |
| 51 | at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN); | 53 | at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN); |
| 52 | } | 54 | } |
| @@ -54,16 +56,17 @@ static void inline at91_wdt_stop(void) | |||
| 54 | /* | 56 | /* |
| 55 | * Enable and reset the watchdog. | 57 | * Enable and reset the watchdog. |
| 56 | */ | 58 | */ |
| 57 | static void inline at91_wdt_start(void) | 59 | static inline void at91_wdt_start(void) |
| 58 | { | 60 | { |
| 59 | at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN | (((65536 * wdt_time) >> 8) & AT91_ST_WDV)); | 61 | at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN | |
| 62 | (((65536 * wdt_time) >> 8) & AT91_ST_WDV)); | ||
| 60 | at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); | 63 | at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); |
| 61 | } | 64 | } |
| 62 | 65 | ||
| 63 | /* | 66 | /* |
| 64 | * Reload the watchdog timer. (ie, pat the watchdog) | 67 | * Reload the watchdog timer. (ie, pat the watchdog) |
| 65 | */ | 68 | */ |
| 66 | static void inline at91_wdt_reload(void) | 69 | static inline void at91_wdt_reload(void) |
| 67 | { | 70 | { |
| 68 | at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); | 71 | at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); |
| 69 | } | 72 | } |
| @@ -89,8 +92,9 @@ static int at91_wdt_open(struct inode *inode, struct file *file) | |||
| 89 | */ | 92 | */ |
| 90 | static int at91_wdt_close(struct inode *inode, struct file *file) | 93 | static int at91_wdt_close(struct inode *inode, struct file *file) |
| 91 | { | 94 | { |
| 95 | /* Disable the watchdog when file is closed */ | ||
| 92 | if (!nowayout) | 96 | if (!nowayout) |
| 93 | at91_wdt_stop(); /* Disable the watchdog when file is closed */ | 97 | at91_wdt_stop(); |
| 94 | 98 | ||
| 95 | clear_bit(0, &at91wdt_busy); | 99 | clear_bit(0, &at91wdt_busy); |
| 96 | return 0; | 100 | return 0; |
| @@ -110,7 +114,8 @@ static int at91_wdt_settimeout(int new_time) | |||
| 110 | if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) | 114 | if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) |
| 111 | return -EINVAL; | 115 | return -EINVAL; |
| 112 | 116 | ||
| 113 | /* Set new watchdog time. It will be used when at91_wdt_start() is called. */ | 117 | /* Set new watchdog time. It will be used when |
| 118 | at91_wdt_start() is called. */ | ||
| 114 | wdt_time = new_time; | 119 | wdt_time = new_time; |
| 115 | return 0; | 120 | return 0; |
| 116 | } | 121 | } |
| @@ -123,60 +128,52 @@ static struct watchdog_info at91_wdt_info = { | |||
| 123 | /* | 128 | /* |
| 124 | * Handle commands from user-space. | 129 | * Handle commands from user-space. |
| 125 | */ | 130 | */ |
| 126 | static int at91_wdt_ioctl(struct inode *inode, struct file *file, | 131 | static long at91_wdt_ioct(struct file *file, |
| 127 | unsigned int cmd, unsigned long arg) | 132 | unsigned int cmd, unsigned long arg) |
| 128 | { | 133 | { |
| 129 | void __user *argp = (void __user *)arg; | 134 | void __user *argp = (void __user *)arg; |
| 130 | int __user *p = argp; | 135 | int __user *p = argp; |
| 131 | int new_value; | 136 | int new_value; |
| 132 | 137 | ||
| 133 | switch(cmd) { | 138 | switch (cmd) { |
| 134 | case WDIOC_KEEPALIVE: | 139 | case WDIOC_GETSUPPORT: |
| 135 | at91_wdt_reload(); /* pat the watchdog */ | 140 | return copy_to_user(argp, &at91_wdt_info, |
| 136 | return 0; | 141 | sizeof(at91_wdt_info)) ? -EFAULT : 0; |
| 137 | 142 | case WDIOC_GETSTATUS: | |
| 138 | case WDIOC_GETSUPPORT: | 143 | case WDIOC_GETBOOTSTATUS: |
| 139 | return copy_to_user(argp, &at91_wdt_info, sizeof(at91_wdt_info)) ? -EFAULT : 0; | 144 | return put_user(0, p); |
| 140 | 145 | case WDIOC_SETOPTIONS: | |
| 141 | case WDIOC_SETTIMEOUT: | 146 | if (get_user(new_value, p)) |
| 142 | if (get_user(new_value, p)) | 147 | return -EFAULT; |
| 143 | return -EFAULT; | 148 | if (new_value & WDIOS_DISABLECARD) |
| 144 | 149 | at91_wdt_stop(); | |
| 145 | if (at91_wdt_settimeout(new_value)) | 150 | if (new_value & WDIOS_ENABLECARD) |
| 146 | return -EINVAL; | ||
| 147 | |||
| 148 | /* Enable new time value */ | ||
| 149 | at91_wdt_start(); | 151 | at91_wdt_start(); |
| 150 | 152 | return 0; | |
| 151 | /* Return current value */ | 153 | case WDIOC_KEEPALIVE: |
| 152 | return put_user(wdt_time, p); | 154 | at91_wdt_reload(); /* pat the watchdog */ |
| 153 | 155 | return 0; | |
| 154 | case WDIOC_GETTIMEOUT: | 156 | case WDIOC_SETTIMEOUT: |
| 155 | return put_user(wdt_time, p); | 157 | if (get_user(new_value, p)) |
| 156 | 158 | return -EFAULT; | |
| 157 | case WDIOC_GETSTATUS: | 159 | if (at91_wdt_settimeout(new_value)) |
| 158 | case WDIOC_GETBOOTSTATUS: | 160 | return -EINVAL; |
| 159 | return put_user(0, p); | 161 | /* Enable new time value */ |
| 160 | 162 | at91_wdt_start(); | |
| 161 | case WDIOC_SETOPTIONS: | 163 | /* Return current value */ |
| 162 | if (get_user(new_value, p)) | 164 | return put_user(wdt_time, p); |
| 163 | return -EFAULT; | 165 | case WDIOC_GETTIMEOUT: |
| 164 | 166 | return put_user(wdt_time, p); | |
| 165 | if (new_value & WDIOS_DISABLECARD) | 167 | default: |
| 166 | at91_wdt_stop(); | 168 | return -ENOTTY; |
| 167 | if (new_value & WDIOS_ENABLECARD) | ||
| 168 | at91_wdt_start(); | ||
| 169 | return 0; | ||
| 170 | |||
| 171 | default: | ||
| 172 | return -ENOTTY; | ||
| 173 | } | 169 | } |
| 174 | } | 170 | } |
| 175 | 171 | ||
| 176 | /* | 172 | /* |
| 177 | * Pat the watchdog whenever device is written to. | 173 | * Pat the watchdog whenever device is written to. |
| 178 | */ | 174 | */ |
| 179 | static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) | 175 | static ssize_t at91_wdt_write(struct file *file, const char *data, |
| 176 | size_t len, loff_t *ppos) | ||
| 180 | { | 177 | { |
| 181 | at91_wdt_reload(); /* pat the watchdog */ | 178 | at91_wdt_reload(); /* pat the watchdog */ |
| 182 | return len; | 179 | return len; |
| @@ -187,7 +184,7 @@ static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len, l | |||
| 187 | static const struct file_operations at91wdt_fops = { | 184 | static const struct file_operations at91wdt_fops = { |
| 188 | .owner = THIS_MODULE, | 185 | .owner = THIS_MODULE, |
| 189 | .llseek = no_llseek, | 186 | .llseek = no_llseek, |
| 190 | .ioctl = at91_wdt_ioctl, | 187 | .unlocked_ioctl = at91_wdt_ioctl, |
| 191 | .open = at91_wdt_open, | 188 | .open = at91_wdt_open, |
| 192 | .release = at91_wdt_close, | 189 | .release = at91_wdt_close, |
| 193 | .write = at91_wdt_write, | 190 | .write = at91_wdt_write, |
| @@ -211,7 +208,8 @@ static int __init at91wdt_probe(struct platform_device *pdev) | |||
| 211 | if (res) | 208 | if (res) |
| 212 | return res; | 209 | return res; |
| 213 | 210 | ||
| 214 | printk("AT91 Watchdog Timer enabled (%d seconds%s)\n", wdt_time, nowayout ? ", nowayout" : ""); | 211 | printk(KERN_INFO "AT91 Watchdog Timer enabled (%d seconds%s)\n", |
| 212 | wdt_time, nowayout ? ", nowayout" : ""); | ||
| 215 | return 0; | 213 | return 0; |
| 216 | } | 214 | } |
| 217 | 215 | ||
| @@ -265,7 +263,8 @@ static struct platform_driver at91wdt_driver = { | |||
| 265 | 263 | ||
| 266 | static int __init at91_wdt_init(void) | 264 | static int __init at91_wdt_init(void) |
| 267 | { | 265 | { |
| 268 | /* Check that the heartbeat value is within range; if not reset to the default */ | 266 | /* Check that the heartbeat value is within range; |
| 267 | if not reset to the default */ | ||
| 269 | if (at91_wdt_settimeout(wdt_time)) { | 268 | if (at91_wdt_settimeout(wdt_time)) { |
| 270 | at91_wdt_settimeout(WDT_DEFAULT_TIME); | 269 | at91_wdt_settimeout(WDT_DEFAULT_TIME); |
| 271 | pr_info("at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time); | 270 | pr_info("at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time); |
diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c index 03b3e3d91e7c..31b42253054e 100644 --- a/drivers/watchdog/bfin_wdt.c +++ b/drivers/watchdog/bfin_wdt.c | |||
| @@ -24,8 +24,8 @@ | |||
| 24 | #include <linux/reboot.h> | 24 | #include <linux/reboot.h> |
| 25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
| 26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
| 27 | #include <linux/uaccess.h> | ||
| 27 | #include <asm/blackfin.h> | 28 | #include <asm/blackfin.h> |
| 28 | #include <asm/uaccess.h> | ||
| 29 | 29 | ||
| 30 | #define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args) | 30 | #define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args) |
| 31 | #define stampit() stamp("here i am") | 31 | #define stampit() stamp("here i am") |
| @@ -148,7 +148,8 @@ static int bfin_wdt_set_timeout(unsigned long t) | |||
| 148 | int run = bfin_wdt_running(); | 148 | int run = bfin_wdt_running(); |
| 149 | bfin_wdt_stop(); | 149 | bfin_wdt_stop(); |
| 150 | bfin_write_WDOG_CNT(cnt); | 150 | bfin_write_WDOG_CNT(cnt); |
| 151 | if (run) bfin_wdt_start(); | 151 | if (run) |
| 152 | bfin_wdt_start(); | ||
| 152 | } | 153 | } |
| 153 | spin_unlock_irqrestore(&bfin_wdt_spinlock, flags); | 154 | spin_unlock_irqrestore(&bfin_wdt_spinlock, flags); |
| 154 | 155 | ||
| @@ -191,16 +192,15 @@ static int bfin_wdt_release(struct inode *inode, struct file *file) | |||
| 191 | { | 192 | { |
| 192 | stampit(); | 193 | stampit(); |
| 193 | 194 | ||
| 194 | if (expect_close == 42) { | 195 | if (expect_close == 42) |
| 195 | bfin_wdt_stop(); | 196 | bfin_wdt_stop(); |
| 196 | } else { | 197 | else { |
| 197 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 198 | printk(KERN_CRIT PFX |
| 199 | "Unexpected close, not stopping watchdog!\n"); | ||
| 198 | bfin_wdt_keepalive(); | 200 | bfin_wdt_keepalive(); |
| 199 | } | 201 | } |
| 200 | |||
| 201 | expect_close = 0; | 202 | expect_close = 0; |
| 202 | clear_bit(0, &open_check); | 203 | clear_bit(0, &open_check); |
| 203 | |||
| 204 | return 0; | 204 | return 0; |
| 205 | } | 205 | } |
| 206 | 206 | ||
| @@ -214,7 +214,7 @@ static int bfin_wdt_release(struct inode *inode, struct file *file) | |||
| 214 | * Pings the watchdog on write. | 214 | * Pings the watchdog on write. |
| 215 | */ | 215 | */ |
| 216 | static ssize_t bfin_wdt_write(struct file *file, const char __user *data, | 216 | static ssize_t bfin_wdt_write(struct file *file, const char __user *data, |
| 217 | size_t len, loff_t *ppos) | 217 | size_t len, loff_t *ppos) |
| 218 | { | 218 | { |
| 219 | stampit(); | 219 | stampit(); |
| 220 | 220 | ||
| @@ -241,7 +241,6 @@ static ssize_t bfin_wdt_write(struct file *file, const char __user *data, | |||
| 241 | 241 | ||
| 242 | /** | 242 | /** |
| 243 | * bfin_wdt_ioctl - Query Device | 243 | * bfin_wdt_ioctl - Query Device |
| 244 | * @inode: inode of device | ||
| 245 | * @file: file handle of device | 244 | * @file: file handle of device |
| 246 | * @cmd: watchdog command | 245 | * @cmd: watchdog command |
| 247 | * @arg: argument | 246 | * @arg: argument |
| @@ -249,8 +248,8 @@ static ssize_t bfin_wdt_write(struct file *file, const char __user *data, | |||
| 249 | * Query basic information from the device or ping it, as outlined by the | 248 | * Query basic information from the device or ping it, as outlined by the |
| 250 | * watchdog API. | 249 | * watchdog API. |
| 251 | */ | 250 | */ |
| 252 | static int bfin_wdt_ioctl(struct inode *inode, struct file *file, | 251 | static long bfin_wdt_ioctl(struct file *file, |
| 253 | unsigned int cmd, unsigned long arg) | 252 | unsigned int cmd, unsigned long arg) |
| 254 | { | 253 | { |
| 255 | void __user *argp = (void __user *)arg; | 254 | void __user *argp = (void __user *)arg; |
| 256 | int __user *p = argp; | 255 | int __user *p = argp; |
| @@ -258,59 +257,49 @@ static int bfin_wdt_ioctl(struct inode *inode, struct file *file, | |||
| 258 | stampit(); | 257 | stampit(); |
| 259 | 258 | ||
| 260 | switch (cmd) { | 259 | switch (cmd) { |
| 261 | default: | 260 | case WDIOC_GETSUPPORT: |
| 262 | return -ENOTTY; | 261 | if (copy_to_user(argp, &bfin_wdt_info, sizeof(bfin_wdt_info))) |
| 263 | 262 | return -EFAULT; | |
| 264 | case WDIOC_GETSUPPORT: | 263 | else |
| 265 | if (copy_to_user(argp, &bfin_wdt_info, sizeof(bfin_wdt_info))) | ||
| 266 | return -EFAULT; | ||
| 267 | else | ||
| 268 | return 0; | ||
| 269 | |||
| 270 | case WDIOC_GETSTATUS: | ||
| 271 | case WDIOC_GETBOOTSTATUS: | ||
| 272 | return put_user(!!(_bfin_swrst & SWRST_RESET_WDOG), p); | ||
| 273 | |||
| 274 | case WDIOC_KEEPALIVE: | ||
| 275 | bfin_wdt_keepalive(); | ||
| 276 | return 0; | 264 | return 0; |
| 277 | 265 | case WDIOC_GETSTATUS: | |
| 278 | case WDIOC_SETTIMEOUT: { | 266 | case WDIOC_GETBOOTSTATUS: |
| 279 | int new_timeout; | 267 | return put_user(!!(_bfin_swrst & SWRST_RESET_WDOG), p); |
| 280 | 268 | case WDIOC_SETOPTIONS: { | |
| 281 | if (get_user(new_timeout, p)) | 269 | unsigned long flags; |
| 282 | return -EFAULT; | 270 | int options, ret = -EINVAL; |
| 283 | 271 | ||
| 284 | if (bfin_wdt_set_timeout(new_timeout)) | 272 | if (get_user(options, p)) |
| 285 | return -EINVAL; | 273 | return -EFAULT; |
| 274 | |||
| 275 | spin_lock_irqsave(&bfin_wdt_spinlock, flags); | ||
| 276 | if (options & WDIOS_DISABLECARD) { | ||
| 277 | bfin_wdt_stop(); | ||
| 278 | ret = 0; | ||
| 286 | } | 279 | } |
| 287 | /* Fall */ | 280 | if (options & WDIOS_ENABLECARD) { |
| 288 | case WDIOC_GETTIMEOUT: | 281 | bfin_wdt_start(); |
| 289 | return put_user(timeout, p); | 282 | ret = 0; |
| 290 | |||
| 291 | case WDIOC_SETOPTIONS: { | ||
| 292 | unsigned long flags; | ||
| 293 | int options, ret = -EINVAL; | ||
| 294 | |||
| 295 | if (get_user(options, p)) | ||
| 296 | return -EFAULT; | ||
| 297 | |||
| 298 | spin_lock_irqsave(&bfin_wdt_spinlock, flags); | ||
| 299 | |||
| 300 | if (options & WDIOS_DISABLECARD) { | ||
| 301 | bfin_wdt_stop(); | ||
| 302 | ret = 0; | ||
| 303 | } | ||
| 304 | |||
| 305 | if (options & WDIOS_ENABLECARD) { | ||
| 306 | bfin_wdt_start(); | ||
| 307 | ret = 0; | ||
| 308 | } | ||
| 309 | |||
| 310 | spin_unlock_irqrestore(&bfin_wdt_spinlock, flags); | ||
| 311 | |||
| 312 | return ret; | ||
| 313 | } | 283 | } |
| 284 | spin_unlock_irqrestore(&bfin_wdt_spinlock, flags); | ||
| 285 | return ret; | ||
| 286 | } | ||
| 287 | case WDIOC_KEEPALIVE: | ||
| 288 | bfin_wdt_keepalive(); | ||
| 289 | return 0; | ||
| 290 | case WDIOC_SETTIMEOUT: { | ||
| 291 | int new_timeout; | ||
| 292 | |||
| 293 | if (get_user(new_timeout, p)) | ||
| 294 | return -EFAULT; | ||
| 295 | if (bfin_wdt_set_timeout(new_timeout)) | ||
| 296 | return -EINVAL; | ||
| 297 | } | ||
| 298 | /* Fall */ | ||
| 299 | case WDIOC_GETTIMEOUT: | ||
| 300 | return put_user(timeout, p); | ||
| 301 | default: | ||
| 302 | return -ENOTTY; | ||
| 314 | } | 303 | } |
| 315 | } | 304 | } |
| 316 | 305 | ||
| @@ -323,8 +312,8 @@ static int bfin_wdt_ioctl(struct inode *inode, struct file *file, | |||
| 323 | * Handles specific events, such as turning off the watchdog during a | 312 | * Handles specific events, such as turning off the watchdog during a |
| 324 | * shutdown event. | 313 | * shutdown event. |
| 325 | */ | 314 | */ |
| 326 | static int bfin_wdt_notify_sys(struct notifier_block *this, unsigned long code, | 315 | static int bfin_wdt_notify_sys(struct notifier_block *this, |
| 327 | void *unused) | 316 | unsigned long code, void *unused) |
| 328 | { | 317 | { |
| 329 | stampit(); | 318 | stampit(); |
| 330 | 319 | ||
| @@ -379,12 +368,12 @@ static int bfin_wdt_resume(struct platform_device *pdev) | |||
| 379 | #endif | 368 | #endif |
| 380 | 369 | ||
| 381 | static const struct file_operations bfin_wdt_fops = { | 370 | static const struct file_operations bfin_wdt_fops = { |
| 382 | .owner = THIS_MODULE, | 371 | .owner = THIS_MODULE, |
| 383 | .llseek = no_llseek, | 372 | .llseek = no_llseek, |
| 384 | .write = bfin_wdt_write, | 373 | .write = bfin_wdt_write, |
| 385 | .ioctl = bfin_wdt_ioctl, | 374 | .unlocked_ioctl = bfin_wdt_ioctl, |
| 386 | .open = bfin_wdt_open, | 375 | .open = bfin_wdt_open, |
| 387 | .release = bfin_wdt_release, | 376 | .release = bfin_wdt_release, |
| 388 | }; | 377 | }; |
| 389 | 378 | ||
| 390 | static struct miscdevice bfin_wdt_miscdev = { | 379 | static struct miscdevice bfin_wdt_miscdev = { |
| @@ -396,8 +385,8 @@ static struct miscdevice bfin_wdt_miscdev = { | |||
| 396 | static struct watchdog_info bfin_wdt_info = { | 385 | static struct watchdog_info bfin_wdt_info = { |
| 397 | .identity = "Blackfin Watchdog", | 386 | .identity = "Blackfin Watchdog", |
| 398 | .options = WDIOF_SETTIMEOUT | | 387 | .options = WDIOF_SETTIMEOUT | |
| 399 | WDIOF_KEEPALIVEPING | | 388 | WDIOF_KEEPALIVEPING | |
| 400 | WDIOF_MAGICCLOSE, | 389 | WDIOF_MAGICCLOSE, |
| 401 | }; | 390 | }; |
| 402 | 391 | ||
| 403 | static struct notifier_block bfin_wdt_notifier = { | 392 | static struct notifier_block bfin_wdt_notifier = { |
| @@ -416,14 +405,16 @@ static int __devinit bfin_wdt_probe(struct platform_device *pdev) | |||
| 416 | 405 | ||
| 417 | ret = register_reboot_notifier(&bfin_wdt_notifier); | 406 | ret = register_reboot_notifier(&bfin_wdt_notifier); |
| 418 | if (ret) { | 407 | if (ret) { |
| 419 | pr_devinit(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret); | 408 | pr_devinit(KERN_ERR PFX |
| 409 | "cannot register reboot notifier (err=%d)\n", ret); | ||
| 420 | return ret; | 410 | return ret; |
| 421 | } | 411 | } |
| 422 | 412 | ||
| 423 | ret = misc_register(&bfin_wdt_miscdev); | 413 | ret = misc_register(&bfin_wdt_miscdev); |
| 424 | if (ret) { | 414 | if (ret) { |
| 425 | pr_devinit(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 415 | pr_devinit(KERN_ERR PFX |
| 426 | WATCHDOG_MINOR, ret); | 416 | "cannot register miscdev on minor=%d (err=%d)\n", |
| 417 | WATCHDOG_MINOR, ret); | ||
| 427 | unregister_reboot_notifier(&bfin_wdt_notifier); | 418 | unregister_reboot_notifier(&bfin_wdt_notifier); |
| 428 | return ret; | 419 | return ret; |
| 429 | } | 420 | } |
| @@ -516,7 +507,11 @@ MODULE_LICENSE("GPL"); | |||
| 516 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | 507 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); |
| 517 | 508 | ||
| 518 | module_param(timeout, uint, 0); | 509 | module_param(timeout, uint, 0); |
| 519 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=((2^32)/SCLK), default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | 510 | MODULE_PARM_DESC(timeout, |
| 511 | "Watchdog timeout in seconds. (1<=timeout<=((2^32)/SCLK), default=" | ||
| 512 | __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | ||
| 520 | 513 | ||
| 521 | module_param(nowayout, int, 0); | 514 | module_param(nowayout, int, 0); |
| 522 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 515 | MODULE_PARM_DESC(nowayout, |
| 516 | "Watchdog cannot be stopped once started (default=" | ||
| 517 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c index 770824458d45..c3b78a76f173 100644 --- a/drivers/watchdog/booke_wdt.c +++ b/drivers/watchdog/booke_wdt.c | |||
| @@ -18,9 +18,9 @@ | |||
| 18 | #include <linux/miscdevice.h> | 18 | #include <linux/miscdevice.h> |
| 19 | #include <linux/notifier.h> | 19 | #include <linux/notifier.h> |
| 20 | #include <linux/watchdog.h> | 20 | #include <linux/watchdog.h> |
| 21 | #include <linux/uaccess.h> | ||
| 21 | 22 | ||
| 22 | #include <asm/reg_booke.h> | 23 | #include <asm/reg_booke.h> |
| 23 | #include <asm/uaccess.h> | ||
| 24 | #include <asm/system.h> | 24 | #include <asm/system.h> |
| 25 | 25 | ||
| 26 | /* If the kernel parameter wdt=1, the watchdog will be enabled at boot. | 26 | /* If the kernel parameter wdt=1, the watchdog will be enabled at boot. |
| @@ -32,7 +32,7 @@ | |||
| 32 | */ | 32 | */ |
| 33 | 33 | ||
| 34 | #ifdef CONFIG_FSL_BOOKE | 34 | #ifdef CONFIG_FSL_BOOKE |
| 35 | #define WDT_PERIOD_DEFAULT 63 /* Ex. wdt_period=28 bus=333Mhz , reset=~40sec */ | 35 | #define WDT_PERIOD_DEFAULT 63 /* Ex. wdt_period=28 bus=333Mhz,reset=~40sec */ |
| 36 | #else | 36 | #else |
| 37 | #define WDT_PERIOD_DEFAULT 3 /* Refer to the PPC40x and PPC4xx manuals */ | 37 | #define WDT_PERIOD_DEFAULT 3 /* Refer to the PPC40x and PPC4xx manuals */ |
| 38 | #endif /* for timing information */ | 38 | #endif /* for timing information */ |
| @@ -82,16 +82,15 @@ static struct watchdog_info ident = { | |||
| 82 | .identity = "PowerPC Book-E Watchdog", | 82 | .identity = "PowerPC Book-E Watchdog", |
| 83 | }; | 83 | }; |
| 84 | 84 | ||
| 85 | static int booke_wdt_ioctl(struct inode *inode, struct file *file, | 85 | static long booke_wdt_ioctl(struct file *file, |
| 86 | unsigned int cmd, unsigned long arg) | 86 | unsigned int cmd, unsigned long arg) |
| 87 | { | 87 | { |
| 88 | u32 tmp = 0; | 88 | u32 tmp = 0; |
| 89 | u32 __user *p = (u32 __user *)arg; | 89 | u32 __user *p = (u32 __user *)arg; |
| 90 | 90 | ||
| 91 | switch (cmd) { | 91 | switch (cmd) { |
| 92 | case WDIOC_GETSUPPORT: | 92 | case WDIOC_GETSUPPORT: |
| 93 | if (copy_to_user((struct watchdog_info __user *)arg, &ident, | 93 | if (copy_to_user(arg, &ident, sizeof(struct watchdog_info))) |
| 94 | sizeof(struct watchdog_info))) | ||
| 95 | return -EFAULT; | 94 | return -EFAULT; |
| 96 | case WDIOC_GETSTATUS: | 95 | case WDIOC_GETSTATUS: |
| 97 | return put_user(ident.options, p); | 96 | return put_user(ident.options, p); |
| @@ -100,16 +99,6 @@ static int booke_wdt_ioctl(struct inode *inode, struct file *file, | |||
| 100 | tmp = mfspr(SPRN_TSR) & TSR_WRS(3); | 99 | tmp = mfspr(SPRN_TSR) & TSR_WRS(3); |
| 101 | /* returns 1 if last reset was caused by the WDT */ | 100 | /* returns 1 if last reset was caused by the WDT */ |
| 102 | return (tmp ? 1 : 0); | 101 | return (tmp ? 1 : 0); |
| 103 | case WDIOC_KEEPALIVE: | ||
| 104 | booke_wdt_ping(); | ||
| 105 | return 0; | ||
| 106 | case WDIOC_SETTIMEOUT: | ||
| 107 | if (get_user(booke_wdt_period, p)) | ||
| 108 | return -EFAULT; | ||
| 109 | mtspr(SPRN_TCR, (mfspr(SPRN_TCR)&~WDTP(0))|WDTP(booke_wdt_period)); | ||
| 110 | return 0; | ||
| 111 | case WDIOC_GETTIMEOUT: | ||
| 112 | return put_user(booke_wdt_period, p); | ||
| 113 | case WDIOC_SETOPTIONS: | 102 | case WDIOC_SETOPTIONS: |
| 114 | if (get_user(tmp, p)) | 103 | if (get_user(tmp, p)) |
| 115 | return -EINVAL; | 104 | return -EINVAL; |
| @@ -119,6 +108,17 @@ static int booke_wdt_ioctl(struct inode *inode, struct file *file, | |||
| 119 | } else | 108 | } else |
| 120 | return -EINVAL; | 109 | return -EINVAL; |
| 121 | return 0; | 110 | return 0; |
| 111 | case WDIOC_KEEPALIVE: | ||
| 112 | booke_wdt_ping(); | ||
| 113 | return 0; | ||
| 114 | case WDIOC_SETTIMEOUT: | ||
| 115 | if (get_user(booke_wdt_period, p)) | ||
| 116 | return -EFAULT; | ||
| 117 | mtspr(SPRN_TCR, (mfspr(SPRN_TCR) & ~WDTP(0)) | | ||
| 118 | WDTP(booke_wdt_period)); | ||
| 119 | return 0; | ||
| 120 | case WDIOC_GETTIMEOUT: | ||
| 121 | return put_user(booke_wdt_period, p); | ||
| 122 | default: | 122 | default: |
| 123 | return -ENOTTY; | 123 | return -ENOTTY; |
| 124 | } | 124 | } |
| @@ -132,8 +132,9 @@ static int booke_wdt_open(struct inode *inode, struct file *file) | |||
| 132 | if (booke_wdt_enabled == 0) { | 132 | if (booke_wdt_enabled == 0) { |
| 133 | booke_wdt_enabled = 1; | 133 | booke_wdt_enabled = 1; |
| 134 | on_each_cpu(__booke_wdt_enable, NULL, 0); | 134 | on_each_cpu(__booke_wdt_enable, NULL, 0); |
| 135 | printk(KERN_INFO "PowerPC Book-E Watchdog Timer Enabled " | 135 | printk(KERN_INFO |
| 136 | "(wdt_period=%d)\n", booke_wdt_period); | 136 | "PowerPC Book-E Watchdog Timer Enabled (wdt_period=%d)\n", |
| 137 | booke_wdt_period); | ||
| 137 | } | 138 | } |
| 138 | spin_unlock(&booke_wdt_lock); | 139 | spin_unlock(&booke_wdt_lock); |
| 139 | 140 | ||
| @@ -144,7 +145,7 @@ static const struct file_operations booke_wdt_fops = { | |||
| 144 | .owner = THIS_MODULE, | 145 | .owner = THIS_MODULE, |
| 145 | .llseek = no_llseek, | 146 | .llseek = no_llseek, |
| 146 | .write = booke_wdt_write, | 147 | .write = booke_wdt_write, |
| 147 | .ioctl = booke_wdt_ioctl, | 148 | .unlocked_ioctl = booke_wdt_ioctl, |
| 148 | .open = booke_wdt_open, | 149 | .open = booke_wdt_open, |
| 149 | }; | 150 | }; |
| 150 | 151 | ||
| @@ -175,8 +176,9 @@ static int __init booke_wdt_init(void) | |||
| 175 | 176 | ||
| 176 | spin_lock(&booke_wdt_lock); | 177 | spin_lock(&booke_wdt_lock); |
| 177 | if (booke_wdt_enabled == 1) { | 178 | if (booke_wdt_enabled == 1) { |
| 178 | printk(KERN_INFO "PowerPC Book-E Watchdog Timer Enabled " | 179 | printk(KERN_INFO |
| 179 | "(wdt_period=%d)\n", booke_wdt_period); | 180 | "PowerPC Book-E Watchdog Timer Enabled (wdt_period=%d)\n", |
| 181 | booke_wdt_period); | ||
| 180 | on_each_cpu(__booke_wdt_enable, NULL, 0); | 182 | on_each_cpu(__booke_wdt_enable, NULL, 0); |
| 181 | } | 183 | } |
| 182 | spin_unlock(&booke_wdt_lock); | 184 | spin_unlock(&booke_wdt_lock); |
diff --git a/drivers/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c index df72f90123df..71f6d7eec9a8 100644 --- a/drivers/watchdog/cpu5wdt.c +++ b/drivers/watchdog/cpu5wdt.c | |||
| @@ -30,16 +30,16 @@ | |||
| 30 | #include <linux/timer.h> | 30 | #include <linux/timer.h> |
| 31 | #include <linux/completion.h> | 31 | #include <linux/completion.h> |
| 32 | #include <linux/jiffies.h> | 32 | #include <linux/jiffies.h> |
| 33 | #include <asm/io.h> | 33 | #include <linux/io.h> |
| 34 | #include <asm/uaccess.h> | 34 | #include <linux/uaccess.h> |
| 35 | |||
| 36 | #include <linux/watchdog.h> | 35 | #include <linux/watchdog.h> |
| 37 | 36 | ||
| 38 | /* adjustable parameters */ | 37 | /* adjustable parameters */ |
| 39 | 38 | ||
| 40 | static int verbose = 0; | 39 | static int verbose; |
| 41 | static int port = 0x91; | 40 | static int port = 0x91; |
| 42 | static int ticks = 10000; | 41 | static int ticks = 10000; |
| 42 | static spinlock_t cpu5wdt_lock; | ||
| 43 | 43 | ||
| 44 | #define PFX "cpu5wdt: " | 44 | #define PFX "cpu5wdt: " |
| 45 | 45 | ||
| @@ -70,12 +70,13 @@ static struct { | |||
| 70 | 70 | ||
| 71 | static void cpu5wdt_trigger(unsigned long unused) | 71 | static void cpu5wdt_trigger(unsigned long unused) |
| 72 | { | 72 | { |
| 73 | if ( verbose > 2 ) | 73 | if (verbose > 2) |
| 74 | printk(KERN_DEBUG PFX "trigger at %i ticks\n", ticks); | 74 | printk(KERN_DEBUG PFX "trigger at %i ticks\n", ticks); |
| 75 | 75 | ||
| 76 | if( cpu5wdt_device.running ) | 76 | if (cpu5wdt_device.running) |
| 77 | ticks--; | 77 | ticks--; |
| 78 | 78 | ||
| 79 | spin_lock(&cpu5wdt_lock); | ||
| 79 | /* keep watchdog alive */ | 80 | /* keep watchdog alive */ |
| 80 | outb(1, port + CPU5WDT_TRIGGER_REG); | 81 | outb(1, port + CPU5WDT_TRIGGER_REG); |
| 81 | 82 | ||
| @@ -86,6 +87,7 @@ static void cpu5wdt_trigger(unsigned long unused) | |||
| 86 | /* ticks doesn't matter anyway */ | 87 | /* ticks doesn't matter anyway */ |
| 87 | complete(&cpu5wdt_device.stop); | 88 | complete(&cpu5wdt_device.stop); |
| 88 | } | 89 | } |
| 90 | spin_unlock(&cpu5wdt_lock); | ||
| 89 | 91 | ||
| 90 | } | 92 | } |
| 91 | 93 | ||
| @@ -93,14 +95,17 @@ static void cpu5wdt_reset(void) | |||
| 93 | { | 95 | { |
| 94 | ticks = cpu5wdt_device.default_ticks; | 96 | ticks = cpu5wdt_device.default_ticks; |
| 95 | 97 | ||
| 96 | if ( verbose ) | 98 | if (verbose) |
| 97 | printk(KERN_DEBUG PFX "reset (%i ticks)\n", (int) ticks); | 99 | printk(KERN_DEBUG PFX "reset (%i ticks)\n", (int) ticks); |
| 98 | 100 | ||
| 99 | } | 101 | } |
| 100 | 102 | ||
| 101 | static void cpu5wdt_start(void) | 103 | static void cpu5wdt_start(void) |
| 102 | { | 104 | { |
| 103 | if ( !cpu5wdt_device.queue ) { | 105 | unsigned long flags; |
| 106 | |||
| 107 | spin_lock_irqsave(&cpu5wdt_lock, flags); | ||
| 108 | if (!cpu5wdt_device.queue) { | ||
| 104 | cpu5wdt_device.queue = 1; | 109 | cpu5wdt_device.queue = 1; |
| 105 | outb(0, port + CPU5WDT_TIME_A_REG); | 110 | outb(0, port + CPU5WDT_TIME_A_REG); |
| 106 | outb(0, port + CPU5WDT_TIME_B_REG); | 111 | outb(0, port + CPU5WDT_TIME_B_REG); |
| @@ -111,18 +116,20 @@ static void cpu5wdt_start(void) | |||
| 111 | } | 116 | } |
| 112 | /* if process dies, counter is not decremented */ | 117 | /* if process dies, counter is not decremented */ |
| 113 | cpu5wdt_device.running++; | 118 | cpu5wdt_device.running++; |
| 119 | spin_unlock_irqrestore(&cpu5wdt_lock, flags); | ||
| 114 | } | 120 | } |
| 115 | 121 | ||
| 116 | static int cpu5wdt_stop(void) | 122 | static int cpu5wdt_stop(void) |
| 117 | { | 123 | { |
| 118 | if ( cpu5wdt_device.running ) | 124 | unsigned long flags; |
| 119 | cpu5wdt_device.running = 0; | ||
| 120 | 125 | ||
| 126 | spin_lock_irqsave(&cpu5wdt_lock, flags); | ||
| 127 | if (cpu5wdt_device.running) | ||
| 128 | cpu5wdt_device.running = 0; | ||
| 121 | ticks = cpu5wdt_device.default_ticks; | 129 | ticks = cpu5wdt_device.default_ticks; |
| 122 | 130 | spin_unlock_irqrestore(&cpu5wdt_lock, flags); | |
| 123 | if ( verbose ) | 131 | if (verbose) |
| 124 | printk(KERN_CRIT PFX "stop not possible\n"); | 132 | printk(KERN_CRIT PFX "stop not possible\n"); |
| 125 | |||
| 126 | return -EIO; | 133 | return -EIO; |
| 127 | } | 134 | } |
| 128 | 135 | ||
| @@ -130,9 +137,8 @@ static int cpu5wdt_stop(void) | |||
| 130 | 137 | ||
| 131 | static int cpu5wdt_open(struct inode *inode, struct file *file) | 138 | static int cpu5wdt_open(struct inode *inode, struct file *file) |
| 132 | { | 139 | { |
| 133 | if ( test_and_set_bit(0, &cpu5wdt_device.inuse) ) | 140 | if (test_and_set_bit(0, &cpu5wdt_device.inuse)) |
| 134 | return -EBUSY; | 141 | return -EBUSY; |
| 135 | |||
| 136 | return nonseekable_open(inode, file); | 142 | return nonseekable_open(inode, file); |
| 137 | } | 143 | } |
| 138 | 144 | ||
| @@ -142,67 +148,58 @@ static int cpu5wdt_release(struct inode *inode, struct file *file) | |||
| 142 | return 0; | 148 | return 0; |
| 143 | } | 149 | } |
| 144 | 150 | ||
| 145 | static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 151 | static long cpu5wdt_ioctl(struct file *file, unsigned int cmd, |
| 152 | unsigned long arg) | ||
| 146 | { | 153 | { |
| 147 | void __user *argp = (void __user *)arg; | 154 | void __user *argp = (void __user *)arg; |
| 155 | int __user *p = argp; | ||
| 148 | unsigned int value; | 156 | unsigned int value; |
| 149 | static struct watchdog_info ident = | 157 | static struct watchdog_info ident = { |
| 150 | { | ||
| 151 | .options = WDIOF_CARDRESET, | 158 | .options = WDIOF_CARDRESET, |
| 152 | .identity = "CPU5 WDT", | 159 | .identity = "CPU5 WDT", |
| 153 | }; | 160 | }; |
| 154 | 161 | ||
| 155 | switch(cmd) { | 162 | switch (cmd) { |
| 156 | case WDIOC_KEEPALIVE: | 163 | case WDIOC_GETSUPPORT: |
| 157 | cpu5wdt_reset(); | 164 | if (copy_to_user(argp, &ident, sizeof(ident))) |
| 158 | break; | 165 | return -EFAULT; |
| 159 | case WDIOC_GETSTATUS: | 166 | break; |
| 160 | value = inb(port + CPU5WDT_STATUS_REG); | 167 | case WDIOC_GETSTATUS: |
| 161 | value = (value >> 2) & 1; | 168 | value = inb(port + CPU5WDT_STATUS_REG); |
| 162 | if ( copy_to_user(argp, &value, sizeof(int)) ) | 169 | value = (value >> 2) & 1; |
| 163 | return -EFAULT; | 170 | return put_user(value, p); |
| 164 | break; | 171 | case WDIOC_GETBOOTSTATUS: |
| 165 | case WDIOC_GETBOOTSTATUS: | 172 | return put_user(0, p); |
| 166 | if ( copy_to_user(argp, &value, sizeof(int)) ) | 173 | case WDIOC_SETOPTIONS: |
| 167 | return -EFAULT; | 174 | if (get_user(value, p)) |
| 168 | break; | 175 | return -EFAULT; |
| 169 | case WDIOC_GETSUPPORT: | 176 | if (value & WDIOS_ENABLECARD) |
| 170 | if ( copy_to_user(argp, &ident, sizeof(ident)) ) | 177 | cpu5wdt_start(); |
| 171 | return -EFAULT; | 178 | if (value & WDIOS_DISABLECARD) |
| 172 | break; | 179 | cpu5wdt_stop(); |
| 173 | case WDIOC_SETOPTIONS: | 180 | break; |
| 174 | if ( copy_from_user(&value, argp, sizeof(int)) ) | 181 | case WDIOC_KEEPALIVE: |
| 175 | return -EFAULT; | 182 | cpu5wdt_reset(); |
| 176 | switch(value) { | 183 | break; |
| 177 | case WDIOS_ENABLECARD: | 184 | default: |
| 178 | cpu5wdt_start(); | 185 | return -ENOTTY; |
| 179 | break; | ||
| 180 | case WDIOS_DISABLECARD: | ||
| 181 | return cpu5wdt_stop(); | ||
| 182 | default: | ||
| 183 | return -EINVAL; | ||
| 184 | } | ||
| 185 | break; | ||
| 186 | default: | ||
| 187 | return -ENOTTY; | ||
| 188 | } | 186 | } |
| 189 | return 0; | 187 | return 0; |
| 190 | } | 188 | } |
| 191 | 189 | ||
| 192 | static ssize_t cpu5wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | 190 | static ssize_t cpu5wdt_write(struct file *file, const char __user *buf, |
| 191 | size_t count, loff_t *ppos) | ||
| 193 | { | 192 | { |
| 194 | if ( !count ) | 193 | if (!count) |
| 195 | return -EIO; | 194 | return -EIO; |
| 196 | |||
| 197 | cpu5wdt_reset(); | 195 | cpu5wdt_reset(); |
| 198 | |||
| 199 | return count; | 196 | return count; |
| 200 | } | 197 | } |
| 201 | 198 | ||
| 202 | static const struct file_operations cpu5wdt_fops = { | 199 | static const struct file_operations cpu5wdt_fops = { |
| 203 | .owner = THIS_MODULE, | 200 | .owner = THIS_MODULE, |
| 204 | .llseek = no_llseek, | 201 | .llseek = no_llseek, |
| 205 | .ioctl = cpu5wdt_ioctl, | 202 | .unlocked_ioctl = cpu5wdt_ioctl, |
| 206 | .open = cpu5wdt_open, | 203 | .open = cpu5wdt_open, |
| 207 | .write = cpu5wdt_write, | 204 | .write = cpu5wdt_write, |
| 208 | .release = cpu5wdt_release, | 205 | .release = cpu5wdt_release, |
| @@ -221,37 +218,36 @@ static int __devinit cpu5wdt_init(void) | |||
| 221 | unsigned int val; | 218 | unsigned int val; |
| 222 | int err; | 219 | int err; |
| 223 | 220 | ||
| 224 | if ( verbose ) | 221 | if (verbose) |
| 225 | printk(KERN_DEBUG PFX "port=0x%x, verbose=%i\n", port, verbose); | 222 | printk(KERN_DEBUG PFX |
| 223 | "port=0x%x, verbose=%i\n", port, verbose); | ||
| 226 | 224 | ||
| 227 | if ( !request_region(port, CPU5WDT_EXTENT, PFX) ) { | 225 | init_completion(&cpu5wdt_device.stop); |
| 226 | spin_lock_init(&cpu5wdt_lock); | ||
| 227 | cpu5wdt_device.queue = 0; | ||
| 228 | setup_timer(&cpu5wdt_device.timer, cpu5wdt_trigger, 0); | ||
| 229 | cpu5wdt_device.default_ticks = ticks; | ||
| 230 | |||
| 231 | if (!request_region(port, CPU5WDT_EXTENT, PFX)) { | ||
| 228 | printk(KERN_ERR PFX "request_region failed\n"); | 232 | printk(KERN_ERR PFX "request_region failed\n"); |
| 229 | err = -EBUSY; | 233 | err = -EBUSY; |
| 230 | goto no_port; | 234 | goto no_port; |
| 231 | } | 235 | } |
| 232 | 236 | ||
| 233 | if ( (err = misc_register(&cpu5wdt_misc)) < 0 ) { | ||
| 234 | printk(KERN_ERR PFX "misc_register failed\n"); | ||
| 235 | goto no_misc; | ||
| 236 | } | ||
| 237 | |||
| 238 | /* watchdog reboot? */ | 237 | /* watchdog reboot? */ |
| 239 | val = inb(port + CPU5WDT_STATUS_REG); | 238 | val = inb(port + CPU5WDT_STATUS_REG); |
| 240 | val = (val >> 2) & 1; | 239 | val = (val >> 2) & 1; |
| 241 | if ( !val ) | 240 | if (!val) |
| 242 | printk(KERN_INFO PFX "sorry, was my fault\n"); | 241 | printk(KERN_INFO PFX "sorry, was my fault\n"); |
| 243 | 242 | ||
| 244 | init_completion(&cpu5wdt_device.stop); | 243 | err = misc_register(&cpu5wdt_misc); |
| 245 | cpu5wdt_device.queue = 0; | 244 | if (err < 0) { |
| 246 | 245 | printk(KERN_ERR PFX "misc_register failed\n"); | |
| 247 | clear_bit(0, &cpu5wdt_device.inuse); | 246 | goto no_misc; |
| 248 | 247 | } | |
| 249 | setup_timer(&cpu5wdt_device.timer, cpu5wdt_trigger, 0); | ||
| 250 | 248 | ||
| 251 | cpu5wdt_device.default_ticks = ticks; | ||
| 252 | 249 | ||
| 253 | printk(KERN_INFO PFX "init success\n"); | 250 | printk(KERN_INFO PFX "init success\n"); |
| 254 | |||
| 255 | return 0; | 251 | return 0; |
| 256 | 252 | ||
| 257 | no_misc: | 253 | no_misc: |
| @@ -267,7 +263,7 @@ static int __devinit cpu5wdt_init_module(void) | |||
| 267 | 263 | ||
| 268 | static void __devexit cpu5wdt_exit(void) | 264 | static void __devexit cpu5wdt_exit(void) |
| 269 | { | 265 | { |
| 270 | if ( cpu5wdt_device.queue ) { | 266 | if (cpu5wdt_device.queue) { |
| 271 | cpu5wdt_device.queue = 0; | 267 | cpu5wdt_device.queue = 0; |
| 272 | wait_for_completion(&cpu5wdt_device.stop); | 268 | wait_for_completion(&cpu5wdt_device.stop); |
| 273 | } | 269 | } |
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c index 003dffe5cb19..2e1360286732 100644 --- a/drivers/watchdog/davinci_wdt.c +++ b/drivers/watchdog/davinci_wdt.c | |||
| @@ -22,10 +22,9 @@ | |||
| 22 | #include <linux/bitops.h> | 22 | #include <linux/bitops.h> |
| 23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
| 24 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
| 25 | 25 | #include <linux/uaccess.h> | |
| 26 | #include <linux/io.h> | ||
| 26 | #include <mach/hardware.h> | 27 | #include <mach/hardware.h> |
| 27 | #include <asm/uaccess.h> | ||
| 28 | #include <asm/io.h> | ||
| 29 | 28 | ||
| 30 | #define MODULE_NAME "DAVINCI-WDT: " | 29 | #define MODULE_NAME "DAVINCI-WDT: " |
| 31 | 30 | ||
| @@ -143,9 +142,8 @@ static struct watchdog_info ident = { | |||
| 143 | .identity = "DaVinci Watchdog", | 142 | .identity = "DaVinci Watchdog", |
| 144 | }; | 143 | }; |
| 145 | 144 | ||
| 146 | static int | 145 | static long davinci_wdt_ioctl(struct file *file, |
| 147 | davinci_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 146 | unsigned int cmd, unsigned long arg) |
| 148 | unsigned long arg) | ||
| 149 | { | 147 | { |
| 150 | int ret = -ENOTTY; | 148 | int ret = -ENOTTY; |
| 151 | 149 | ||
| @@ -160,14 +158,14 @@ davinci_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
| 160 | ret = put_user(0, (int *)arg); | 158 | ret = put_user(0, (int *)arg); |
| 161 | break; | 159 | break; |
| 162 | 160 | ||
| 163 | case WDIOC_GETTIMEOUT: | ||
| 164 | ret = put_user(heartbeat, (int *)arg); | ||
| 165 | break; | ||
| 166 | |||
| 167 | case WDIOC_KEEPALIVE: | 161 | case WDIOC_KEEPALIVE: |
| 168 | wdt_service(); | 162 | wdt_service(); |
| 169 | ret = 0; | 163 | ret = 0; |
| 170 | break; | 164 | break; |
| 165 | |||
| 166 | case WDIOC_GETTIMEOUT: | ||
| 167 | ret = put_user(heartbeat, (int *)arg); | ||
| 168 | break; | ||
| 171 | } | 169 | } |
| 172 | return ret; | 170 | return ret; |
| 173 | } | 171 | } |
| @@ -184,7 +182,7 @@ static const struct file_operations davinci_wdt_fops = { | |||
| 184 | .owner = THIS_MODULE, | 182 | .owner = THIS_MODULE, |
| 185 | .llseek = no_llseek, | 183 | .llseek = no_llseek, |
| 186 | .write = davinci_wdt_write, | 184 | .write = davinci_wdt_write, |
| 187 | .ioctl = davinci_wdt_ioctl, | 185 | .unlocked_ioctl = davinci_wdt_ioctl, |
| 188 | .open = davinci_wdt_open, | 186 | .open = davinci_wdt_open, |
| 189 | .release = davinci_wdt_release, | 187 | .release = davinci_wdt_release, |
| 190 | }; | 188 | }; |
diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c index af8ef14c0e4c..e9f950ff86ea 100644 --- a/drivers/watchdog/ep93xx_wdt.c +++ b/drivers/watchdog/ep93xx_wdt.c | |||
| @@ -28,9 +28,8 @@ | |||
| 28 | #include <linux/miscdevice.h> | 28 | #include <linux/miscdevice.h> |
| 29 | #include <linux/watchdog.h> | 29 | #include <linux/watchdog.h> |
| 30 | #include <linux/timer.h> | 30 | #include <linux/timer.h> |
| 31 | 31 | #include <linux/uaccess.h> | |
| 32 | #include <mach/hardware.h> | 32 | #include <mach/hardware.h> |
| 33 | #include <asm/uaccess.h> | ||
| 34 | 33 | ||
| 35 | #define WDT_VERSION "0.3" | 34 | #define WDT_VERSION "0.3" |
| 36 | #define PFX "ep93xx_wdt: " | 35 | #define PFX "ep93xx_wdt: " |
| @@ -136,9 +135,8 @@ static struct watchdog_info ident = { | |||
| 136 | .identity = "EP93xx Watchdog", | 135 | .identity = "EP93xx Watchdog", |
| 137 | }; | 136 | }; |
| 138 | 137 | ||
| 139 | static int | 138 | static long ep93xx_wdt_ioctl(struct file *file, |
| 140 | ep93xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 139 | unsigned int cmd, unsigned long arg) |
| 141 | unsigned long arg) | ||
| 142 | { | 140 | { |
| 143 | int ret = -ENOTTY; | 141 | int ret = -ENOTTY; |
| 144 | 142 | ||
| @@ -156,15 +154,15 @@ ep93xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
| 156 | ret = put_user(boot_status, (int __user *)arg); | 154 | ret = put_user(boot_status, (int __user *)arg); |
| 157 | break; | 155 | break; |
| 158 | 156 | ||
| 159 | case WDIOC_GETTIMEOUT: | ||
| 160 | /* actually, it is 0.250 seconds.... */ | ||
| 161 | ret = put_user(1, (int __user *)arg); | ||
| 162 | break; | ||
| 163 | |||
| 164 | case WDIOC_KEEPALIVE: | 157 | case WDIOC_KEEPALIVE: |
| 165 | wdt_keepalive(); | 158 | wdt_keepalive(); |
| 166 | ret = 0; | 159 | ret = 0; |
| 167 | break; | 160 | break; |
| 161 | |||
| 162 | case WDIOC_GETTIMEOUT: | ||
| 163 | /* actually, it is 0.250 seconds.... */ | ||
| 164 | ret = put_user(1, (int __user *)arg); | ||
| 165 | break; | ||
| 168 | } | 166 | } |
| 169 | return ret; | 167 | return ret; |
| 170 | } | 168 | } |
| @@ -174,8 +172,8 @@ static int ep93xx_wdt_release(struct inode *inode, struct file *file) | |||
| 174 | if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) | 172 | if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) |
| 175 | wdt_shutdown(); | 173 | wdt_shutdown(); |
| 176 | else | 174 | else |
| 177 | printk(KERN_CRIT PFX "Device closed unexpectedly - " | 175 | printk(KERN_CRIT PFX |
| 178 | "timer will not stop\n"); | 176 | "Device closed unexpectedly - timer will not stop\n"); |
| 179 | 177 | ||
| 180 | clear_bit(WDT_IN_USE, &wdt_status); | 178 | clear_bit(WDT_IN_USE, &wdt_status); |
| 181 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | 179 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); |
| @@ -186,7 +184,7 @@ static int ep93xx_wdt_release(struct inode *inode, struct file *file) | |||
| 186 | static const struct file_operations ep93xx_wdt_fops = { | 184 | static const struct file_operations ep93xx_wdt_fops = { |
| 187 | .owner = THIS_MODULE, | 185 | .owner = THIS_MODULE, |
| 188 | .write = ep93xx_wdt_write, | 186 | .write = ep93xx_wdt_write, |
| 189 | .ioctl = ep93xx_wdt_ioctl, | 187 | .unlocked_ioctl = ep93xx_wdt_ioctl, |
| 190 | .open = ep93xx_wdt_open, | 188 | .open = ep93xx_wdt_open, |
| 191 | .release = ep93xx_wdt_release, | 189 | .release = ep93xx_wdt_release, |
| 192 | }; | 190 | }; |
| @@ -243,7 +241,9 @@ module_param(nowayout, int, 0); | |||
| 243 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); | 241 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); |
| 244 | 242 | ||
| 245 | module_param(timeout, int, 0); | 243 | module_param(timeout, int, 0); |
| 246 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | 244 | MODULE_PARM_DESC(timeout, |
| 245 | "Watchdog timeout in seconds. (1<=timeout<=3600, default=" | ||
| 246 | __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | ||
| 247 | 247 | ||
| 248 | MODULE_AUTHOR("Ray Lehtiniemi <rayl@mail.com>," | 248 | MODULE_AUTHOR("Ray Lehtiniemi <rayl@mail.com>," |
| 249 | "Alessandro Zummo <a.zummo@towertech.it>"); | 249 | "Alessandro Zummo <a.zummo@towertech.it>"); |
diff --git a/drivers/watchdog/eurotechwdt.c b/drivers/watchdog/eurotechwdt.c index b14e9d1f164d..bbd14e34319f 100644 --- a/drivers/watchdog/eurotechwdt.c +++ b/drivers/watchdog/eurotechwdt.c | |||
| @@ -56,14 +56,15 @@ | |||
| 56 | #include <linux/notifier.h> | 56 | #include <linux/notifier.h> |
| 57 | #include <linux/reboot.h> | 57 | #include <linux/reboot.h> |
| 58 | #include <linux/init.h> | 58 | #include <linux/init.h> |
| 59 | #include <linux/io.h> | ||
| 60 | #include <linux/uaccess.h> | ||
| 59 | 61 | ||
| 60 | #include <asm/io.h> | ||
| 61 | #include <asm/uaccess.h> | ||
| 62 | #include <asm/system.h> | 62 | #include <asm/system.h> |
| 63 | 63 | ||
| 64 | static unsigned long eurwdt_is_open; | 64 | static unsigned long eurwdt_is_open; |
| 65 | static int eurwdt_timeout; | 65 | static int eurwdt_timeout; |
| 66 | static char eur_expect_close; | 66 | static char eur_expect_close; |
| 67 | static spinlock_t eurwdt_lock; | ||
| 67 | 68 | ||
| 68 | /* | 69 | /* |
| 69 | * You must set these - there is no sane way to probe for this board. | 70 | * You must set these - there is no sane way to probe for this board. |
| @@ -78,7 +79,9 @@ static char *ev = "int"; | |||
| 78 | 79 | ||
| 79 | static int nowayout = WATCHDOG_NOWAYOUT; | 80 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 80 | module_param(nowayout, int, 0); | 81 | module_param(nowayout, int, 0); |
| 81 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 82 | MODULE_PARM_DESC(nowayout, |
| 83 | "Watchdog cannot be stopped once started (default=" | ||
| 84 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 82 | 85 | ||
| 83 | /* | 86 | /* |
| 84 | * Some symbolic names | 87 | * Some symbolic names |
| @@ -137,7 +140,8 @@ static void eurwdt_activate_timer(void) | |||
| 137 | { | 140 | { |
| 138 | eurwdt_disable_timer(); | 141 | eurwdt_disable_timer(); |
| 139 | eurwdt_write_reg(WDT_CTRL_REG, 0x01); /* activate the WDT */ | 142 | eurwdt_write_reg(WDT_CTRL_REG, 0x01); /* activate the WDT */ |
| 140 | eurwdt_write_reg(WDT_OUTPIN_CFG, !strcmp("int", ev) ? WDT_EVENT_INT : WDT_EVENT_REBOOT); | 143 | eurwdt_write_reg(WDT_OUTPIN_CFG, |
| 144 | !strcmp("int", ev) ? WDT_EVENT_INT : WDT_EVENT_REBOOT); | ||
| 141 | 145 | ||
| 142 | /* Setting interrupt line */ | 146 | /* Setting interrupt line */ |
| 143 | if (irq == 2 || irq > 15 || irq < 0) { | 147 | if (irq == 2 || irq > 15 || irq < 0) { |
| @@ -206,21 +210,21 @@ size_t count, loff_t *ppos) | |||
| 206 | 210 | ||
| 207 | for (i = 0; i != count; i++) { | 211 | for (i = 0; i != count; i++) { |
| 208 | char c; | 212 | char c; |
| 209 | if(get_user(c, buf+i)) | 213 | if (get_user(c, buf + i)) |
| 210 | return -EFAULT; | 214 | return -EFAULT; |
| 211 | if (c == 'V') | 215 | if (c == 'V') |
| 212 | eur_expect_close = 42; | 216 | eur_expect_close = 42; |
| 213 | } | 217 | } |
| 214 | } | 218 | } |
| 219 | spin_lock(&eurwdt_lock); | ||
| 215 | eurwdt_ping(); /* the default timeout */ | 220 | eurwdt_ping(); /* the default timeout */ |
| 221 | spin_unlock(&eurwdt_lock); | ||
| 216 | } | 222 | } |
| 217 | |||
| 218 | return count; | 223 | return count; |
| 219 | } | 224 | } |
| 220 | 225 | ||
| 221 | /** | 226 | /** |
| 222 | * eurwdt_ioctl: | 227 | * eurwdt_ioctl: |
| 223 | * @inode: inode of the device | ||
| 224 | * @file: file handle to the device | 228 | * @file: file handle to the device |
| 225 | * @cmd: watchdog command | 229 | * @cmd: watchdog command |
| 226 | * @arg: argument pointer | 230 | * @arg: argument pointer |
| @@ -229,13 +233,14 @@ size_t count, loff_t *ppos) | |||
| 229 | * according to their available features. | 233 | * according to their available features. |
| 230 | */ | 234 | */ |
| 231 | 235 | ||
| 232 | static int eurwdt_ioctl(struct inode *inode, struct file *file, | 236 | static long eurwdt_ioctl(struct file *file, |
| 233 | unsigned int cmd, unsigned long arg) | 237 | unsigned int cmd, unsigned long arg) |
| 234 | { | 238 | { |
| 235 | void __user *argp = (void __user *)arg; | 239 | void __user *argp = (void __user *)arg; |
| 236 | int __user *p = argp; | 240 | int __user *p = argp; |
| 237 | static struct watchdog_info ident = { | 241 | static struct watchdog_info ident = { |
| 238 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, | 242 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
| 243 | | WDIOF_MAGICCLOSE, | ||
| 239 | .firmware_version = 1, | 244 | .firmware_version = 1, |
| 240 | .identity = "WDT Eurotech CPU-1220/1410", | 245 | .identity = "WDT Eurotech CPU-1220/1410", |
| 241 | }; | 246 | }; |
| @@ -243,10 +248,7 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file, | |||
| 243 | int time; | 248 | int time; |
| 244 | int options, retval = -EINVAL; | 249 | int options, retval = -EINVAL; |
| 245 | 250 | ||
| 246 | switch(cmd) { | 251 | switch (cmd) { |
| 247 | default: | ||
| 248 | return -ENOTTY; | ||
| 249 | |||
| 250 | case WDIOC_GETSUPPORT: | 252 | case WDIOC_GETSUPPORT: |
| 251 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; | 253 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; |
| 252 | 254 | ||
| @@ -254,8 +256,26 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file, | |||
| 254 | case WDIOC_GETBOOTSTATUS: | 256 | case WDIOC_GETBOOTSTATUS: |
| 255 | return put_user(0, p); | 257 | return put_user(0, p); |
| 256 | 258 | ||
| 259 | case WDIOC_SETOPTIONS: | ||
| 260 | if (get_user(options, p)) | ||
| 261 | return -EFAULT; | ||
| 262 | spin_lock(&eurwdt_lock); | ||
| 263 | if (options & WDIOS_DISABLECARD) { | ||
| 264 | eurwdt_disable_timer(); | ||
| 265 | retval = 0; | ||
| 266 | } | ||
| 267 | if (options & WDIOS_ENABLECARD) { | ||
| 268 | eurwdt_activate_timer(); | ||
| 269 | eurwdt_ping(); | ||
| 270 | retval = 0; | ||
| 271 | } | ||
| 272 | spin_unlock(&eurwdt_lock); | ||
| 273 | return retval; | ||
| 274 | |||
| 257 | case WDIOC_KEEPALIVE: | 275 | case WDIOC_KEEPALIVE: |
| 276 | spin_lock(&eurwdt_lock); | ||
| 258 | eurwdt_ping(); | 277 | eurwdt_ping(); |
| 278 | spin_unlock(&eurwdt_lock); | ||
| 259 | return 0; | 279 | return 0; |
| 260 | 280 | ||
| 261 | case WDIOC_SETTIMEOUT: | 281 | case WDIOC_SETTIMEOUT: |
| @@ -266,26 +286,17 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file, | |||
| 266 | if (time < 0 || time > 255) | 286 | if (time < 0 || time > 255) |
| 267 | return -EINVAL; | 287 | return -EINVAL; |
| 268 | 288 | ||
| 289 | spin_lock(&eurwdt_lock); | ||
| 269 | eurwdt_timeout = time; | 290 | eurwdt_timeout = time; |
| 270 | eurwdt_set_timeout(time); | 291 | eurwdt_set_timeout(time); |
| 292 | spin_unlock(&eurwdt_lock); | ||
| 271 | /* Fall */ | 293 | /* Fall */ |
| 272 | 294 | ||
| 273 | case WDIOC_GETTIMEOUT: | 295 | case WDIOC_GETTIMEOUT: |
| 274 | return put_user(eurwdt_timeout, p); | 296 | return put_user(eurwdt_timeout, p); |
| 275 | 297 | ||
| 276 | case WDIOC_SETOPTIONS: | 298 | default: |
| 277 | if (get_user(options, p)) | 299 | return -ENOTTY; |
| 278 | return -EFAULT; | ||
| 279 | if (options & WDIOS_DISABLECARD) { | ||
| 280 | eurwdt_disable_timer(); | ||
| 281 | retval = 0; | ||
| 282 | } | ||
| 283 | if (options & WDIOS_ENABLECARD) { | ||
| 284 | eurwdt_activate_timer(); | ||
| 285 | eurwdt_ping(); | ||
| 286 | retval = 0; | ||
| 287 | } | ||
| 288 | return retval; | ||
| 289 | } | 300 | } |
| 290 | } | 301 | } |
| 291 | 302 | ||
| @@ -322,10 +333,11 @@ static int eurwdt_open(struct inode *inode, struct file *file) | |||
| 322 | 333 | ||
| 323 | static int eurwdt_release(struct inode *inode, struct file *file) | 334 | static int eurwdt_release(struct inode *inode, struct file *file) |
| 324 | { | 335 | { |
| 325 | if (eur_expect_close == 42) { | 336 | if (eur_expect_close == 42) |
| 326 | eurwdt_disable_timer(); | 337 | eurwdt_disable_timer(); |
| 327 | } else { | 338 | else { |
| 328 | printk(KERN_CRIT "eurwdt: Unexpected close, not stopping watchdog!\n"); | 339 | printk(KERN_CRIT |
| 340 | "eurwdt: Unexpected close, not stopping watchdog!\n"); | ||
| 329 | eurwdt_ping(); | 341 | eurwdt_ping(); |
| 330 | } | 342 | } |
| 331 | clear_bit(0, &eurwdt_is_open); | 343 | clear_bit(0, &eurwdt_is_open); |
| @@ -348,10 +360,8 @@ static int eurwdt_release(struct inode *inode, struct file *file) | |||
| 348 | static int eurwdt_notify_sys(struct notifier_block *this, unsigned long code, | 360 | static int eurwdt_notify_sys(struct notifier_block *this, unsigned long code, |
| 349 | void *unused) | 361 | void *unused) |
| 350 | { | 362 | { |
| 351 | if (code == SYS_DOWN || code == SYS_HALT) { | 363 | if (code == SYS_DOWN || code == SYS_HALT) |
| 352 | /* Turn the card off */ | 364 | eurwdt_disable_timer(); /* Turn the card off */ |
| 353 | eurwdt_disable_timer(); | ||
| 354 | } | ||
| 355 | 365 | ||
| 356 | return NOTIFY_DONE; | 366 | return NOTIFY_DONE; |
| 357 | } | 367 | } |
| @@ -362,11 +372,11 @@ static int eurwdt_notify_sys(struct notifier_block *this, unsigned long code, | |||
| 362 | 372 | ||
| 363 | 373 | ||
| 364 | static const struct file_operations eurwdt_fops = { | 374 | static const struct file_operations eurwdt_fops = { |
| 365 | .owner = THIS_MODULE, | 375 | .owner = THIS_MODULE, |
| 366 | .llseek = no_llseek, | 376 | .llseek = no_llseek, |
| 367 | .write = eurwdt_write, | 377 | .write = eurwdt_write, |
| 368 | .ioctl = eurwdt_ioctl, | 378 | .unlocked_ioctl = eurwdt_ioctl, |
| 369 | .open = eurwdt_open, | 379 | .open = eurwdt_open, |
| 370 | .release = eurwdt_release, | 380 | .release = eurwdt_release, |
| 371 | }; | 381 | }; |
| 372 | 382 | ||
| @@ -419,7 +429,7 @@ static int __init eurwdt_init(void) | |||
| 419 | int ret; | 429 | int ret; |
| 420 | 430 | ||
| 421 | ret = request_irq(irq, eurwdt_interrupt, IRQF_DISABLED, "eurwdt", NULL); | 431 | ret = request_irq(irq, eurwdt_interrupt, IRQF_DISABLED, "eurwdt", NULL); |
| 422 | if(ret) { | 432 | if (ret) { |
| 423 | printk(KERN_ERR "eurwdt: IRQ %d is not free.\n", irq); | 433 | printk(KERN_ERR "eurwdt: IRQ %d is not free.\n", irq); |
| 424 | goto out; | 434 | goto out; |
| 425 | } | 435 | } |
| @@ -432,10 +442,13 @@ static int __init eurwdt_init(void) | |||
| 432 | 442 | ||
| 433 | ret = register_reboot_notifier(&eurwdt_notifier); | 443 | ret = register_reboot_notifier(&eurwdt_notifier); |
| 434 | if (ret) { | 444 | if (ret) { |
| 435 | printk(KERN_ERR "eurwdt: can't register reboot notifier (err=%d)\n", ret); | 445 | printk(KERN_ERR |
| 446 | "eurwdt: can't register reboot notifier (err=%d)\n", ret); | ||
| 436 | goto outreg; | 447 | goto outreg; |
| 437 | } | 448 | } |
| 438 | 449 | ||
| 450 | spin_lock_init(&eurwdt_lock); | ||
| 451 | |||
| 439 | ret = misc_register(&eurwdt_miscdev); | 452 | ret = misc_register(&eurwdt_miscdev); |
| 440 | if (ret) { | 453 | if (ret) { |
| 441 | printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n", | 454 | printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n", |
diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c index 30d09cbbad94..614a5c7017b6 100644 --- a/drivers/watchdog/geodewdt.c +++ b/drivers/watchdog/geodewdt.c | |||
| @@ -17,8 +17,8 @@ | |||
| 17 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
| 18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
| 19 | #include <linux/reboot.h> | 19 | #include <linux/reboot.h> |
| 20 | #include <linux/uaccess.h> | ||
| 20 | 21 | ||
| 21 | #include <asm/uaccess.h> | ||
| 22 | #include <asm/geode.h> | 22 | #include <asm/geode.h> |
| 23 | 23 | ||
| 24 | #define GEODEWDT_HZ 500 | 24 | #define GEODEWDT_HZ 500 |
| @@ -77,27 +77,24 @@ static int geodewdt_set_heartbeat(int val) | |||
| 77 | return 0; | 77 | return 0; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | static int | 80 | static int geodewdt_open(struct inode *inode, struct file *file) |
| 81 | geodewdt_open(struct inode *inode, struct file *file) | ||
| 82 | { | 81 | { |
| 83 | if (test_and_set_bit(WDT_FLAGS_OPEN, &wdt_flags)) | 82 | if (test_and_set_bit(WDT_FLAGS_OPEN, &wdt_flags)) |
| 84 | return -EBUSY; | 83 | return -EBUSY; |
| 85 | 84 | ||
| 86 | if (!test_and_clear_bit(WDT_FLAGS_ORPHAN, &wdt_flags)) | 85 | if (!test_and_clear_bit(WDT_FLAGS_ORPHAN, &wdt_flags)) |
| 87 | __module_get(THIS_MODULE); | 86 | __module_get(THIS_MODULE); |
| 88 | 87 | ||
| 89 | geodewdt_ping(); | 88 | geodewdt_ping(); |
| 90 | return nonseekable_open(inode, file); | 89 | return nonseekable_open(inode, file); |
| 91 | } | 90 | } |
| 92 | 91 | ||
| 93 | static int | 92 | static int geodewdt_release(struct inode *inode, struct file *file) |
| 94 | geodewdt_release(struct inode *inode, struct file *file) | ||
| 95 | { | 93 | { |
| 96 | if (safe_close) { | 94 | if (safe_close) { |
| 97 | geodewdt_disable(); | 95 | geodewdt_disable(); |
| 98 | module_put(THIS_MODULE); | 96 | module_put(THIS_MODULE); |
| 99 | } | 97 | } else { |
| 100 | else { | ||
| 101 | printk(KERN_CRIT "Unexpected close - watchdog is not stopping.\n"); | 98 | printk(KERN_CRIT "Unexpected close - watchdog is not stopping.\n"); |
| 102 | geodewdt_ping(); | 99 | geodewdt_ping(); |
| 103 | 100 | ||
| @@ -109,11 +106,10 @@ geodewdt_release(struct inode *inode, struct file *file) | |||
| 109 | return 0; | 106 | return 0; |
| 110 | } | 107 | } |
| 111 | 108 | ||
| 112 | static ssize_t | 109 | static ssize_t geodewdt_write(struct file *file, const char __user *data, |
| 113 | geodewdt_write(struct file *file, const char __user *data, size_t len, | 110 | size_t len, loff_t *ppos) |
| 114 | loff_t *ppos) | ||
| 115 | { | 111 | { |
| 116 | if(len) { | 112 | if (len) { |
| 117 | if (!nowayout) { | 113 | if (!nowayout) { |
| 118 | size_t i; | 114 | size_t i; |
| 119 | safe_close = 0; | 115 | safe_close = 0; |
| @@ -134,9 +130,8 @@ geodewdt_write(struct file *file, const char __user *data, size_t len, | |||
| 134 | return len; | 130 | return len; |
| 135 | } | 131 | } |
| 136 | 132 | ||
| 137 | static int | 133 | static int geodewdt_ioctl(struct inode *inode, struct file *file, |
| 138 | geodewdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 134 | unsigned int cmd, unsigned long arg) |
| 139 | unsigned long arg) | ||
| 140 | { | 135 | { |
| 141 | void __user *argp = (void __user *)arg; | 136 | void __user *argp = (void __user *)arg; |
| 142 | int __user *p = argp; | 137 | int __user *p = argp; |
| @@ -147,9 +142,9 @@ geodewdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
| 147 | | WDIOF_MAGICCLOSE, | 142 | | WDIOF_MAGICCLOSE, |
| 148 | .firmware_version = 1, | 143 | .firmware_version = 1, |
| 149 | .identity = WATCHDOG_NAME, | 144 | .identity = WATCHDOG_NAME, |
| 150 | }; | 145 | }; |
| 151 | 146 | ||
| 152 | switch(cmd) { | 147 | switch (cmd) { |
| 153 | case WDIOC_GETSUPPORT: | 148 | case WDIOC_GETSUPPORT: |
| 154 | return copy_to_user(argp, &ident, | 149 | return copy_to_user(argp, &ident, |
| 155 | sizeof(ident)) ? -EFAULT : 0; | 150 | sizeof(ident)) ? -EFAULT : 0; |
| @@ -159,22 +154,6 @@ geodewdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
| 159 | case WDIOC_GETBOOTSTATUS: | 154 | case WDIOC_GETBOOTSTATUS: |
| 160 | return put_user(0, p); | 155 | return put_user(0, p); |
| 161 | 156 | ||
| 162 | case WDIOC_KEEPALIVE: | ||
| 163 | geodewdt_ping(); | ||
| 164 | return 0; | ||
| 165 | |||
| 166 | case WDIOC_SETTIMEOUT: | ||
| 167 | if (get_user(interval, p)) | ||
| 168 | return -EFAULT; | ||
| 169 | |||
| 170 | if (geodewdt_set_heartbeat(interval)) | ||
| 171 | return -EINVAL; | ||
| 172 | |||
| 173 | /* Fall through */ | ||
| 174 | |||
| 175 | case WDIOC_GETTIMEOUT: | ||
| 176 | return put_user(timeout, p); | ||
| 177 | |||
| 178 | case WDIOC_SETOPTIONS: | 157 | case WDIOC_SETOPTIONS: |
| 179 | { | 158 | { |
| 180 | int options, ret = -EINVAL; | 159 | int options, ret = -EINVAL; |
| @@ -194,6 +173,20 @@ geodewdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
| 194 | 173 | ||
| 195 | return ret; | 174 | return ret; |
| 196 | } | 175 | } |
| 176 | case WDIOC_KEEPALIVE: | ||
| 177 | geodewdt_ping(); | ||
| 178 | return 0; | ||
| 179 | |||
| 180 | case WDIOC_SETTIMEOUT: | ||
| 181 | if (get_user(interval, p)) | ||
| 182 | return -EFAULT; | ||
| 183 | |||
| 184 | if (geodewdt_set_heartbeat(interval)) | ||
| 185 | return -EINVAL; | ||
| 186 | /* Fall through */ | ||
| 187 | case WDIOC_GETTIMEOUT: | ||
| 188 | return put_user(timeout, p); | ||
| 189 | |||
| 197 | default: | 190 | default: |
| 198 | return -ENOTTY; | 191 | return -ENOTTY; |
| 199 | } | 192 | } |
| @@ -202,22 +195,21 @@ geodewdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
| 202 | } | 195 | } |
| 203 | 196 | ||
| 204 | static const struct file_operations geodewdt_fops = { | 197 | static const struct file_operations geodewdt_fops = { |
| 205 | .owner = THIS_MODULE, | 198 | .owner = THIS_MODULE, |
| 206 | .llseek = no_llseek, | 199 | .llseek = no_llseek, |
| 207 | .write = geodewdt_write, | 200 | .write = geodewdt_write, |
| 208 | .ioctl = geodewdt_ioctl, | 201 | .ioctl = geodewdt_ioctl, |
| 209 | .open = geodewdt_open, | 202 | .open = geodewdt_open, |
| 210 | .release = geodewdt_release, | 203 | .release = geodewdt_release, |
| 211 | }; | 204 | }; |
| 212 | 205 | ||
| 213 | static struct miscdevice geodewdt_miscdev = { | 206 | static struct miscdevice geodewdt_miscdev = { |
| 214 | .minor = WATCHDOG_MINOR, | 207 | .minor = WATCHDOG_MINOR, |
| 215 | .name = "watchdog", | 208 | .name = "watchdog", |
| 216 | .fops = &geodewdt_fops | 209 | .fops = &geodewdt_fops, |
| 217 | }; | 210 | }; |
| 218 | 211 | ||
| 219 | static int __devinit | 212 | static int __devinit geodewdt_probe(struct platform_device *dev) |
| 220 | geodewdt_probe(struct platform_device *dev) | ||
| 221 | { | 213 | { |
| 222 | int ret, timer; | 214 | int ret, timer; |
| 223 | 215 | ||
| @@ -248,15 +240,13 @@ geodewdt_probe(struct platform_device *dev) | |||
| 248 | return ret; | 240 | return ret; |
| 249 | } | 241 | } |
| 250 | 242 | ||
| 251 | static int __devexit | 243 | static int __devexit geodewdt_remove(struct platform_device *dev) |
| 252 | geodewdt_remove(struct platform_device *dev) | ||
| 253 | { | 244 | { |
| 254 | misc_deregister(&geodewdt_miscdev); | 245 | misc_deregister(&geodewdt_miscdev); |
| 255 | return 0; | 246 | return 0; |
| 256 | } | 247 | } |
| 257 | 248 | ||
| 258 | static void | 249 | static void geodewdt_shutdown(struct platform_device *dev) |
| 259 | geodewdt_shutdown(struct platform_device *dev) | ||
| 260 | { | 250 | { |
| 261 | geodewdt_disable(); | 251 | geodewdt_disable(); |
| 262 | } | 252 | } |
| @@ -271,8 +261,7 @@ static struct platform_driver geodewdt_driver = { | |||
| 271 | }, | 261 | }, |
| 272 | }; | 262 | }; |
| 273 | 263 | ||
| 274 | static int __init | 264 | static int __init geodewdt_init(void) |
| 275 | geodewdt_init(void) | ||
| 276 | { | 265 | { |
| 277 | int ret; | 266 | int ret; |
| 278 | 267 | ||
| @@ -292,8 +281,7 @@ err: | |||
| 292 | return ret; | 281 | return ret; |
| 293 | } | 282 | } |
| 294 | 283 | ||
| 295 | static void __exit | 284 | static void __exit geodewdt_exit(void) |
| 296 | geodewdt_exit(void) | ||
| 297 | { | 285 | { |
| 298 | platform_device_unregister(geodewdt_platform_device); | 286 | platform_device_unregister(geodewdt_platform_device); |
| 299 | platform_driver_unregister(&geodewdt_driver); | 287 | platform_driver_unregister(&geodewdt_driver); |
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index ccd6c530782d..d039d5f2fd1c 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c | |||
| @@ -39,9 +39,7 @@ | |||
| 39 | #include <linux/string.h> | 39 | #include <linux/string.h> |
| 40 | #include <linux/bootmem.h> | 40 | #include <linux/bootmem.h> |
| 41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
| 42 | #include <asm/dmi.h> | ||
| 43 | #include <asm/desc.h> | 42 | #include <asm/desc.h> |
| 44 | #include <asm/kdebug.h> | ||
| 45 | 43 | ||
| 46 | #define PCI_BIOS32_SD_VALUE 0x5F32335F /* "_32_" */ | 44 | #define PCI_BIOS32_SD_VALUE 0x5F32335F /* "_32_" */ |
| 47 | #define CRU_BIOS_SIGNATURE_VALUE 0x55524324 | 45 | #define CRU_BIOS_SIGNATURE_VALUE 0x55524324 |
| @@ -407,7 +405,7 @@ static int __devinit detect_cru_service(void) | |||
| 407 | dmi_walk(dmi_find_cru); | 405 | dmi_walk(dmi_find_cru); |
| 408 | 406 | ||
| 409 | /* if cru_rom_addr has been set then we found a CRU service */ | 407 | /* if cru_rom_addr has been set then we found a CRU service */ |
| 410 | return ((cru_rom_addr != NULL)? 0: -ENODEV); | 408 | return ((cru_rom_addr != NULL) ? 0: -ENODEV); |
| 411 | } | 409 | } |
| 412 | 410 | ||
| 413 | /* ------------------------------------------------------------------------- */ | 411 | /* ------------------------------------------------------------------------- */ |
| @@ -535,7 +533,7 @@ static ssize_t hpwdt_write(struct file *file, const char __user *data, | |||
| 535 | /* scan to see whether or not we got the magic char. */ | 533 | /* scan to see whether or not we got the magic char. */ |
| 536 | for (i = 0; i != len; i++) { | 534 | for (i = 0; i != len; i++) { |
| 537 | char c; | 535 | char c; |
| 538 | if (get_user(c, data+i)) | 536 | if (get_user(c, data + i)) |
| 539 | return -EFAULT; | 537 | return -EFAULT; |
| 540 | if (c == 'V') | 538 | if (c == 'V') |
| 541 | expect_release = 42; | 539 | expect_release = 42; |
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c index ca44fd9b19bb..c13383f7fcb9 100644 --- a/drivers/watchdog/i6300esb.c +++ b/drivers/watchdog/i6300esb.c | |||
| @@ -9,18 +9,18 @@ | |||
| 9 | * as published by the Free Software Foundation; either version | 9 | * as published by the Free Software Foundation; either version |
| 10 | * 2 of the License, or (at your option) any later version. | 10 | * 2 of the License, or (at your option) any later version. |
| 11 | * | 11 | * |
| 12 | * based on i810-tco.c which is in turn based on softdog.c | 12 | * based on i810-tco.c which is in turn based on softdog.c |
| 13 | * | 13 | * |
| 14 | * The timer is implemented in the following I/O controller hubs: | 14 | * The timer is implemented in the following I/O controller hubs: |
| 15 | * (See the intel documentation on http://developer.intel.com.) | 15 | * (See the intel documentation on http://developer.intel.com.) |
| 16 | * 6300ESB chip : document number 300641-003 | 16 | * 6300ESB chip : document number 300641-003 |
| 17 | * | 17 | * |
| 18 | * 2004YYZZ Ross Biro | 18 | * 2004YYZZ Ross Biro |
| 19 | * Initial version 0.01 | 19 | * Initial version 0.01 |
| 20 | * 2004YYZZ Ross Biro | 20 | * 2004YYZZ Ross Biro |
| 21 | * Version 0.02 | 21 | * Version 0.02 |
| 22 | * 20050210 David Härdeman <david@2gen.com> | 22 | * 20050210 David Härdeman <david@2gen.com> |
| 23 | * Ported driver to kernel 2.6 | 23 | * Ported driver to kernel 2.6 |
| 24 | */ | 24 | */ |
| 25 | 25 | ||
| 26 | /* | 26 | /* |
| @@ -38,9 +38,8 @@ | |||
| 38 | #include <linux/init.h> | 38 | #include <linux/init.h> |
| 39 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
| 40 | #include <linux/ioport.h> | 40 | #include <linux/ioport.h> |
| 41 | 41 | #include <linux/uaccess.h> | |
| 42 | #include <asm/uaccess.h> | 42 | #include <linux/io.h> |
| 43 | #include <asm/io.h> | ||
| 44 | 43 | ||
| 45 | /* Module and version information */ | 44 | /* Module and version information */ |
| 46 | #define ESB_VERSION "0.03" | 45 | #define ESB_VERSION "0.03" |
| @@ -59,17 +58,17 @@ | |||
| 59 | #define ESB_RELOAD_REG BASEADDR + 0x0c /* Reload register */ | 58 | #define ESB_RELOAD_REG BASEADDR + 0x0c /* Reload register */ |
| 60 | 59 | ||
| 61 | /* Lock register bits */ | 60 | /* Lock register bits */ |
| 62 | #define ESB_WDT_FUNC ( 0x01 << 2 ) /* Watchdog functionality */ | 61 | #define ESB_WDT_FUNC (0x01 << 2) /* Watchdog functionality */ |
| 63 | #define ESB_WDT_ENABLE ( 0x01 << 1 ) /* Enable WDT */ | 62 | #define ESB_WDT_ENABLE (0x01 << 1) /* Enable WDT */ |
| 64 | #define ESB_WDT_LOCK ( 0x01 << 0 ) /* Lock (nowayout) */ | 63 | #define ESB_WDT_LOCK (0x01 << 0) /* Lock (nowayout) */ |
| 65 | 64 | ||
| 66 | /* Config register bits */ | 65 | /* Config register bits */ |
| 67 | #define ESB_WDT_REBOOT ( 0x01 << 5 ) /* Enable reboot on timeout */ | 66 | #define ESB_WDT_REBOOT (0x01 << 5) /* Enable reboot on timeout */ |
| 68 | #define ESB_WDT_FREQ ( 0x01 << 2 ) /* Decrement frequency */ | 67 | #define ESB_WDT_FREQ (0x01 << 2) /* Decrement frequency */ |
| 69 | #define ESB_WDT_INTTYPE ( 0x11 << 0 ) /* Interrupt type on timer1 timeout */ | 68 | #define ESB_WDT_INTTYPE (0x11 << 0) /* Interrupt type on timer1 timeout */ |
| 70 | 69 | ||
| 71 | /* Reload register bits */ | 70 | /* Reload register bits */ |
| 72 | #define ESB_WDT_RELOAD ( 0x01 << 8 ) /* prevent timeout */ | 71 | #define ESB_WDT_RELOAD (0x01 << 8) /* prevent timeout */ |
| 73 | 72 | ||
| 74 | /* Magic constants */ | 73 | /* Magic constants */ |
| 75 | #define ESB_UNLOCK1 0x80 /* Step 1 to unlock reset registers */ | 74 | #define ESB_UNLOCK1 0x80 /* Step 1 to unlock reset registers */ |
| @@ -84,14 +83,20 @@ static unsigned short triggered; /* The status of the watchdog upon boot */ | |||
| 84 | static char esb_expect_close; | 83 | static char esb_expect_close; |
| 85 | 84 | ||
| 86 | /* module parameters */ | 85 | /* module parameters */ |
| 87 | #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat (1<heartbeat<2*1023) */ | 86 | /* 30 sec default heartbeat (1 < heartbeat < 2*1023) */ |
| 87 | #define WATCHDOG_HEARTBEAT 30 | ||
| 88 | static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ | 88 | static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ |
| 89 | |||
| 89 | module_param(heartbeat, int, 0); | 90 | module_param(heartbeat, int, 0); |
| 90 | MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (1<heartbeat<2046, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); | 91 | MODULE_PARM_DESC(heartbeat, |
| 92 | "Watchdog heartbeat in seconds. (1<heartbeat<2046, default=" | ||
| 93 | __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); | ||
| 91 | 94 | ||
| 92 | static int nowayout = WATCHDOG_NOWAYOUT; | 95 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 93 | module_param(nowayout, int, 0); | 96 | module_param(nowayout, int, 0); |
| 94 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 97 | MODULE_PARM_DESC(nowayout, |
| 98 | "Watchdog cannot be stopped once started (default=" | ||
| 99 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 95 | 100 | ||
| 96 | /* | 101 | /* |
| 97 | * Some i6300ESB specific functions | 102 | * Some i6300ESB specific functions |
| @@ -103,9 +108,10 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" _ | |||
| 103 | * reload register. After this the appropriate registers can be written | 108 | * reload register. After this the appropriate registers can be written |
| 104 | * to once before they need to be unlocked again. | 109 | * to once before they need to be unlocked again. |
| 105 | */ | 110 | */ |
| 106 | static inline void esb_unlock_registers(void) { | 111 | static inline void esb_unlock_registers(void) |
| 107 | writeb(ESB_UNLOCK1, ESB_RELOAD_REG); | 112 | { |
| 108 | writeb(ESB_UNLOCK2, ESB_RELOAD_REG); | 113 | writeb(ESB_UNLOCK1, ESB_RELOAD_REG); |
| 114 | writeb(ESB_UNLOCK2, ESB_RELOAD_REG); | ||
| 109 | } | 115 | } |
| 110 | 116 | ||
| 111 | static void esb_timer_start(void) | 117 | static void esb_timer_start(void) |
| @@ -114,8 +120,7 @@ static void esb_timer_start(void) | |||
| 114 | 120 | ||
| 115 | /* Enable or Enable + Lock? */ | 121 | /* Enable or Enable + Lock? */ |
| 116 | val = 0x02 | (nowayout ? 0x01 : 0x00); | 122 | val = 0x02 | (nowayout ? 0x01 : 0x00); |
| 117 | 123 | pci_write_config_byte(esb_pci, ESB_LOCK_REG, val); | |
| 118 | pci_write_config_byte(esb_pci, ESB_LOCK_REG, val); | ||
| 119 | } | 124 | } |
| 120 | 125 | ||
| 121 | static int esb_timer_stop(void) | 126 | static int esb_timer_stop(void) |
| @@ -140,7 +145,7 @@ static void esb_timer_keepalive(void) | |||
| 140 | spin_lock(&esb_lock); | 145 | spin_lock(&esb_lock); |
| 141 | esb_unlock_registers(); | 146 | esb_unlock_registers(); |
| 142 | writew(ESB_WDT_RELOAD, ESB_RELOAD_REG); | 147 | writew(ESB_WDT_RELOAD, ESB_RELOAD_REG); |
| 143 | /* FIXME: Do we need to flush anything here? */ | 148 | /* FIXME: Do we need to flush anything here? */ |
| 144 | spin_unlock(&esb_lock); | 149 | spin_unlock(&esb_lock); |
| 145 | } | 150 | } |
| 146 | 151 | ||
| @@ -165,9 +170,9 @@ static int esb_timer_set_heartbeat(int time) | |||
| 165 | 170 | ||
| 166 | /* Write timer 2 */ | 171 | /* Write timer 2 */ |
| 167 | esb_unlock_registers(); | 172 | esb_unlock_registers(); |
| 168 | writel(val, ESB_TIMER2_REG); | 173 | writel(val, ESB_TIMER2_REG); |
| 169 | 174 | ||
| 170 | /* Reload */ | 175 | /* Reload */ |
| 171 | esb_unlock_registers(); | 176 | esb_unlock_registers(); |
| 172 | writew(ESB_WDT_RELOAD, ESB_RELOAD_REG); | 177 | writew(ESB_WDT_RELOAD, ESB_RELOAD_REG); |
| 173 | 178 | ||
| @@ -179,54 +184,55 @@ static int esb_timer_set_heartbeat(int time) | |||
| 179 | return 0; | 184 | return 0; |
| 180 | } | 185 | } |
| 181 | 186 | ||
| 182 | static int esb_timer_read (void) | 187 | static int esb_timer_read(void) |
| 183 | { | 188 | { |
| 184 | u32 count; | 189 | u32 count; |
| 185 | 190 | ||
| 186 | /* This isn't documented, and doesn't take into | 191 | /* This isn't documented, and doesn't take into |
| 187 | * acount which stage is running, but it looks | 192 | * acount which stage is running, but it looks |
| 188 | * like a 20 bit count down, so we might as well report it. | 193 | * like a 20 bit count down, so we might as well report it. |
| 189 | */ | 194 | */ |
| 190 | pci_read_config_dword(esb_pci, 0x64, &count); | 195 | pci_read_config_dword(esb_pci, 0x64, &count); |
| 191 | return (int)count; | 196 | return (int)count; |
| 192 | } | 197 | } |
| 193 | 198 | ||
| 194 | /* | 199 | /* |
| 195 | * /dev/watchdog handling | 200 | * /dev/watchdog handling |
| 196 | */ | 201 | */ |
| 197 | 202 | ||
| 198 | static int esb_open (struct inode *inode, struct file *file) | 203 | static int esb_open(struct inode *inode, struct file *file) |
| 199 | { | 204 | { |
| 200 | /* /dev/watchdog can only be opened once */ | 205 | /* /dev/watchdog can only be opened once */ |
| 201 | if (test_and_set_bit(0, &timer_alive)) | 206 | if (test_and_set_bit(0, &timer_alive)) |
| 202 | return -EBUSY; | 207 | return -EBUSY; |
| 203 | 208 | ||
| 204 | /* Reload and activate timer */ | 209 | /* Reload and activate timer */ |
| 205 | esb_timer_keepalive (); | 210 | esb_timer_keepalive(); |
| 206 | esb_timer_start (); | 211 | esb_timer_start(); |
| 207 | 212 | ||
| 208 | return nonseekable_open(inode, file); | 213 | return nonseekable_open(inode, file); |
| 209 | } | 214 | } |
| 210 | 215 | ||
| 211 | static int esb_release (struct inode *inode, struct file *file) | 216 | static int esb_release(struct inode *inode, struct file *file) |
| 212 | { | 217 | { |
| 213 | /* Shut off the timer. */ | 218 | /* Shut off the timer. */ |
| 214 | if (esb_expect_close == 42) { | 219 | if (esb_expect_close == 42) |
| 215 | esb_timer_stop (); | 220 | esb_timer_stop(); |
| 216 | } else { | 221 | else { |
| 217 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 222 | printk(KERN_CRIT PFX |
| 218 | esb_timer_keepalive (); | 223 | "Unexpected close, not stopping watchdog!\n"); |
| 219 | } | 224 | esb_timer_keepalive(); |
| 220 | clear_bit(0, &timer_alive); | 225 | } |
| 221 | esb_expect_close = 0; | 226 | clear_bit(0, &timer_alive); |
| 222 | return 0; | 227 | esb_expect_close = 0; |
| 228 | return 0; | ||
| 223 | } | 229 | } |
| 224 | 230 | ||
| 225 | static ssize_t esb_write (struct file *file, const char __user *data, | 231 | static ssize_t esb_write(struct file *file, const char __user *data, |
| 226 | size_t len, loff_t * ppos) | 232 | size_t len, loff_t *ppos) |
| 227 | { | 233 | { |
| 228 | /* See if we got the magic character 'V' and reload the timer */ | 234 | /* See if we got the magic character 'V' and reload the timer */ |
| 229 | if (len) { | 235 | if (len) { |
| 230 | if (!nowayout) { | 236 | if (!nowayout) { |
| 231 | size_t i; | 237 | size_t i; |
| 232 | 238 | ||
| @@ -237,7 +243,7 @@ static ssize_t esb_write (struct file *file, const char __user *data, | |||
| 237 | /* scan to see whether or not we got the magic character */ | 243 | /* scan to see whether or not we got the magic character */ |
| 238 | for (i = 0; i != len; i++) { | 244 | for (i = 0; i != len; i++) { |
| 239 | char c; | 245 | char c; |
| 240 | if(get_user(c, data+i)) | 246 | if (get_user(c, data + i)) |
| 241 | return -EFAULT; | 247 | return -EFAULT; |
| 242 | if (c == 'V') | 248 | if (c == 'V') |
| 243 | esb_expect_close = 42; | 249 | esb_expect_close = 42; |
| @@ -245,92 +251,84 @@ static ssize_t esb_write (struct file *file, const char __user *data, | |||
| 245 | } | 251 | } |
| 246 | 252 | ||
| 247 | /* someone wrote to us, we should reload the timer */ | 253 | /* someone wrote to us, we should reload the timer */ |
| 248 | esb_timer_keepalive (); | 254 | esb_timer_keepalive(); |
| 249 | } | 255 | } |
| 250 | return len; | 256 | return len; |
| 251 | } | 257 | } |
| 252 | 258 | ||
| 253 | static int esb_ioctl (struct inode *inode, struct file *file, | 259 | static long esb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 254 | unsigned int cmd, unsigned long arg) | ||
| 255 | { | 260 | { |
| 256 | int new_options, retval = -EINVAL; | 261 | int new_options, retval = -EINVAL; |
| 257 | int new_heartbeat; | 262 | int new_heartbeat; |
| 258 | void __user *argp = (void __user *)arg; | 263 | void __user *argp = (void __user *)arg; |
| 259 | int __user *p = argp; | 264 | int __user *p = argp; |
| 260 | static struct watchdog_info ident = { | 265 | static struct watchdog_info ident = { |
| 261 | .options = WDIOF_SETTIMEOUT | | 266 | .options = WDIOF_SETTIMEOUT | |
| 262 | WDIOF_KEEPALIVEPING | | 267 | WDIOF_KEEPALIVEPING | |
| 263 | WDIOF_MAGICCLOSE, | 268 | WDIOF_MAGICCLOSE, |
| 264 | .firmware_version = 0, | 269 | .firmware_version = 0, |
| 265 | .identity = ESB_MODULE_NAME, | 270 | .identity = ESB_MODULE_NAME, |
| 266 | }; | 271 | }; |
| 267 | 272 | ||
| 268 | switch (cmd) { | 273 | switch (cmd) { |
| 269 | case WDIOC_GETSUPPORT: | 274 | case WDIOC_GETSUPPORT: |
| 270 | return copy_to_user(argp, &ident, | 275 | return copy_to_user(argp, &ident, |
| 271 | sizeof (ident)) ? -EFAULT : 0; | 276 | sizeof(ident)) ? -EFAULT : 0; |
| 272 | |||
| 273 | case WDIOC_GETSTATUS: | ||
| 274 | return put_user (esb_timer_read(), p); | ||
| 275 | |||
| 276 | case WDIOC_GETBOOTSTATUS: | ||
| 277 | return put_user (triggered, p); | ||
| 278 | 277 | ||
| 279 | case WDIOC_KEEPALIVE: | 278 | case WDIOC_GETSTATUS: |
| 280 | esb_timer_keepalive (); | 279 | return put_user(esb_timer_read(), p); |
| 281 | return 0; | ||
| 282 | 280 | ||
| 283 | case WDIOC_SETOPTIONS: | 281 | case WDIOC_GETBOOTSTATUS: |
| 284 | { | 282 | return put_user(triggered, p); |
| 285 | if (get_user (new_options, p)) | ||
| 286 | return -EFAULT; | ||
| 287 | 283 | ||
| 288 | if (new_options & WDIOS_DISABLECARD) { | 284 | case WDIOC_SETOPTIONS: |
| 289 | esb_timer_stop (); | 285 | { |
| 290 | retval = 0; | 286 | if (get_user(new_options, p)) |
| 291 | } | 287 | return -EFAULT; |
| 292 | 288 | ||
| 293 | if (new_options & WDIOS_ENABLECARD) { | 289 | if (new_options & WDIOS_DISABLECARD) { |
| 294 | esb_timer_keepalive (); | 290 | esb_timer_stop(); |
| 295 | esb_timer_start (); | 291 | retval = 0; |
| 296 | retval = 0; | 292 | } |
| 297 | } | ||
| 298 | |||
| 299 | return retval; | ||
| 300 | } | ||
| 301 | |||
| 302 | case WDIOC_SETTIMEOUT: | ||
| 303 | { | ||
| 304 | if (get_user(new_heartbeat, p)) | ||
| 305 | return -EFAULT; | ||
| 306 | |||
| 307 | if (esb_timer_set_heartbeat(new_heartbeat)) | ||
| 308 | return -EINVAL; | ||
| 309 | |||
| 310 | esb_timer_keepalive (); | ||
| 311 | /* Fall */ | ||
| 312 | } | ||
| 313 | |||
| 314 | case WDIOC_GETTIMEOUT: | ||
| 315 | return put_user(heartbeat, p); | ||
| 316 | 293 | ||
| 317 | default: | 294 | if (new_options & WDIOS_ENABLECARD) { |
| 318 | return -ENOTTY; | 295 | esb_timer_keepalive(); |
| 319 | } | 296 | esb_timer_start(); |
| 297 | retval = 0; | ||
| 298 | } | ||
| 299 | return retval; | ||
| 300 | } | ||
| 301 | case WDIOC_KEEPALIVE: | ||
| 302 | esb_timer_keepalive(); | ||
| 303 | return 0; | ||
| 304 | |||
| 305 | case WDIOC_SETTIMEOUT: | ||
| 306 | { | ||
| 307 | if (get_user(new_heartbeat, p)) | ||
| 308 | return -EFAULT; | ||
| 309 | if (esb_timer_set_heartbeat(new_heartbeat)) | ||
| 310 | return -EINVAL; | ||
| 311 | esb_timer_keepalive(); | ||
| 312 | /* Fall */ | ||
| 313 | } | ||
| 314 | case WDIOC_GETTIMEOUT: | ||
| 315 | return put_user(heartbeat, p); | ||
| 316 | default: | ||
| 317 | return -ENOTTY; | ||
| 318 | } | ||
| 320 | } | 319 | } |
| 321 | 320 | ||
| 322 | /* | 321 | /* |
| 323 | * Notify system | 322 | * Notify system |
| 324 | */ | 323 | */ |
| 325 | 324 | ||
| 326 | static int esb_notify_sys (struct notifier_block *this, unsigned long code, void *unused) | 325 | static int esb_notify_sys(struct notifier_block *this, |
| 326 | unsigned long code, void *unused) | ||
| 327 | { | 327 | { |
| 328 | if (code==SYS_DOWN || code==SYS_HALT) { | 328 | if (code == SYS_DOWN || code == SYS_HALT) |
| 329 | /* Turn the WDT off */ | 329 | esb_timer_stop(); /* Turn the WDT off */ |
| 330 | esb_timer_stop (); | ||
| 331 | } | ||
| 332 | 330 | ||
| 333 | return NOTIFY_DONE; | 331 | return NOTIFY_DONE; |
| 334 | } | 332 | } |
| 335 | 333 | ||
| 336 | /* | 334 | /* |
| @@ -338,22 +336,22 @@ static int esb_notify_sys (struct notifier_block *this, unsigned long code, void | |||
| 338 | */ | 336 | */ |
| 339 | 337 | ||
| 340 | static const struct file_operations esb_fops = { | 338 | static const struct file_operations esb_fops = { |
| 341 | .owner = THIS_MODULE, | 339 | .owner = THIS_MODULE, |
| 342 | .llseek = no_llseek, | 340 | .llseek = no_llseek, |
| 343 | .write = esb_write, | 341 | .write = esb_write, |
| 344 | .ioctl = esb_ioctl, | 342 | .unlocked_ioctl = esb_ioctl, |
| 345 | .open = esb_open, | 343 | .open = esb_open, |
| 346 | .release = esb_release, | 344 | .release = esb_release, |
| 347 | }; | 345 | }; |
| 348 | 346 | ||
| 349 | static struct miscdevice esb_miscdev = { | 347 | static struct miscdevice esb_miscdev = { |
| 350 | .minor = WATCHDOG_MINOR, | 348 | .minor = WATCHDOG_MINOR, |
| 351 | .name = "watchdog", | 349 | .name = "watchdog", |
| 352 | .fops = &esb_fops, | 350 | .fops = &esb_fops, |
| 353 | }; | 351 | }; |
| 354 | 352 | ||
| 355 | static struct notifier_block esb_notifier = { | 353 | static struct notifier_block esb_notifier = { |
| 356 | .notifier_call = esb_notify_sys, | 354 | .notifier_call = esb_notify_sys, |
| 357 | }; | 355 | }; |
| 358 | 356 | ||
| 359 | /* | 357 | /* |
| @@ -365,50 +363,44 @@ static struct notifier_block esb_notifier = { | |||
| 365 | * want to register another driver on the same PCI id. | 363 | * want to register another driver on the same PCI id. |
| 366 | */ | 364 | */ |
| 367 | static struct pci_device_id esb_pci_tbl[] = { | 365 | static struct pci_device_id esb_pci_tbl[] = { |
| 368 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), }, | 366 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), }, |
| 369 | { 0, }, /* End of list */ | 367 | { 0, }, /* End of list */ |
| 370 | }; | 368 | }; |
| 371 | MODULE_DEVICE_TABLE (pci, esb_pci_tbl); | 369 | MODULE_DEVICE_TABLE(pci, esb_pci_tbl); |
| 372 | 370 | ||
| 373 | /* | 371 | /* |
| 374 | * Init & exit routines | 372 | * Init & exit routines |
| 375 | */ | 373 | */ |
| 376 | 374 | ||
| 377 | static unsigned char __init esb_getdevice (void) | 375 | static unsigned char __init esb_getdevice(void) |
| 378 | { | 376 | { |
| 379 | u8 val1; | 377 | u8 val1; |
| 380 | unsigned short val2; | 378 | unsigned short val2; |
| 379 | /* | ||
| 380 | * Find the PCI device | ||
| 381 | */ | ||
| 381 | 382 | ||
| 382 | struct pci_dev *dev = NULL; | 383 | esb_pci = pci_get_device(PCI_VENDOR_ID_INTEL, |
| 383 | /* | 384 | PCI_DEVICE_ID_INTEL_ESB_9, NULL); |
| 384 | * Find the PCI device | ||
| 385 | */ | ||
| 386 | |||
| 387 | for_each_pci_dev(dev) { | ||
| 388 | if (pci_match_id(esb_pci_tbl, dev)) { | ||
| 389 | esb_pci = dev; | ||
| 390 | break; | ||
| 391 | } | ||
| 392 | } | ||
| 393 | 385 | ||
| 394 | if (esb_pci) { | 386 | if (esb_pci) { |
| 395 | if (pci_enable_device(esb_pci)) { | 387 | if (pci_enable_device(esb_pci)) { |
| 396 | printk (KERN_ERR PFX "failed to enable device\n"); | 388 | printk(KERN_ERR PFX "failed to enable device\n"); |
| 397 | goto err_devput; | 389 | goto err_devput; |
| 398 | } | 390 | } |
| 399 | 391 | ||
| 400 | if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) { | 392 | if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) { |
| 401 | printk (KERN_ERR PFX "failed to request region\n"); | 393 | printk(KERN_ERR PFX "failed to request region\n"); |
| 402 | goto err_disable; | 394 | goto err_disable; |
| 403 | } | 395 | } |
| 404 | 396 | ||
| 405 | BASEADDR = ioremap(pci_resource_start(esb_pci, 0), | 397 | BASEADDR = ioremap(pci_resource_start(esb_pci, 0), |
| 406 | pci_resource_len(esb_pci, 0)); | 398 | pci_resource_len(esb_pci, 0)); |
| 407 | if (BASEADDR == NULL) { | 399 | if (BASEADDR == NULL) { |
| 408 | /* Something's wrong here, BASEADDR has to be set */ | 400 | /* Something's wrong here, BASEADDR has to be set */ |
| 409 | printk (KERN_ERR PFX "failed to get BASEADDR\n"); | 401 | printk(KERN_ERR PFX "failed to get BASEADDR\n"); |
| 410 | goto err_release; | 402 | goto err_release; |
| 411 | } | 403 | } |
| 412 | 404 | ||
| 413 | /* | 405 | /* |
| 414 | * The watchdog has two timers, it can be setup so that the | 406 | * The watchdog has two timers, it can be setup so that the |
| @@ -425,7 +417,7 @@ static unsigned char __init esb_getdevice (void) | |||
| 425 | /* Check that the WDT isn't already locked */ | 417 | /* Check that the WDT isn't already locked */ |
| 426 | pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val1); | 418 | pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val1); |
| 427 | if (val1 & ESB_WDT_LOCK) | 419 | if (val1 & ESB_WDT_LOCK) |
| 428 | printk (KERN_WARNING PFX "nowayout already set\n"); | 420 | printk(KERN_WARNING PFX "nowayout already set\n"); |
| 429 | 421 | ||
| 430 | /* Set the timer to watchdog mode and disable it for now */ | 422 | /* Set the timer to watchdog mode and disable it for now */ |
| 431 | pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x00); | 423 | pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x00); |
| @@ -452,44 +444,44 @@ err_devput: | |||
| 452 | return 0; | 444 | return 0; |
| 453 | } | 445 | } |
| 454 | 446 | ||
| 455 | static int __init watchdog_init (void) | 447 | static int __init watchdog_init(void) |
| 456 | { | 448 | { |
| 457 | int ret; | 449 | int ret; |
| 458 | 450 | ||
| 459 | /* Check whether or not the hardware watchdog is there */ | 451 | /* Check whether or not the hardware watchdog is there */ |
| 460 | if (!esb_getdevice () || esb_pci == NULL) | 452 | if (!esb_getdevice() || esb_pci == NULL) |
| 461 | return -ENODEV; | 453 | return -ENODEV; |
| 462 | 454 | ||
| 463 | /* Check that the heartbeat value is within it's range ; if not reset to the default */ | 455 | /* Check that the heartbeat value is within it's range; |
| 464 | if (esb_timer_set_heartbeat (heartbeat)) { | 456 | if not reset to the default */ |
| 465 | esb_timer_set_heartbeat (WATCHDOG_HEARTBEAT); | 457 | if (esb_timer_set_heartbeat(heartbeat)) { |
| 466 | printk(KERN_INFO PFX "heartbeat value must be 1<heartbeat<2046, using %d\n", | 458 | esb_timer_set_heartbeat(WATCHDOG_HEARTBEAT); |
| 467 | heartbeat); | 459 | printk(KERN_INFO PFX |
| 468 | } | 460 | "heartbeat value must be 1<heartbeat<2046, using %d\n", |
| 469 | 461 | heartbeat); | |
| 470 | ret = register_reboot_notifier(&esb_notifier); | 462 | } |
| 471 | if (ret != 0) { | 463 | ret = register_reboot_notifier(&esb_notifier); |
| 472 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 464 | if (ret != 0) { |
| 473 | ret); | 465 | printk(KERN_ERR PFX |
| 474 | goto err_unmap; | 466 | "cannot register reboot notifier (err=%d)\n", ret); |
| 475 | } | 467 | goto err_unmap; |
| 476 | 468 | } | |
| 477 | ret = misc_register(&esb_miscdev); | ||
| 478 | if (ret != 0) { | ||
| 479 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | ||
| 480 | WATCHDOG_MINOR, ret); | ||
| 481 | goto err_notifier; | ||
| 482 | } | ||
| 483 | |||
| 484 | esb_timer_stop (); | ||
| 485 | |||
| 486 | printk (KERN_INFO PFX "initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n", | ||
| 487 | BASEADDR, heartbeat, nowayout); | ||
| 488 | 469 | ||
| 489 | return 0; | 470 | ret = misc_register(&esb_miscdev); |
| 471 | if (ret != 0) { | ||
| 472 | printk(KERN_ERR PFX | ||
| 473 | "cannot register miscdev on minor=%d (err=%d)\n", | ||
| 474 | WATCHDOG_MINOR, ret); | ||
| 475 | goto err_notifier; | ||
| 476 | } | ||
| 477 | esb_timer_stop(); | ||
| 478 | printk(KERN_INFO PFX | ||
| 479 | "initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n", | ||
| 480 | BASEADDR, heartbeat, nowayout); | ||
| 481 | return 0; | ||
| 490 | 482 | ||
| 491 | err_notifier: | 483 | err_notifier: |
| 492 | unregister_reboot_notifier(&esb_notifier); | 484 | unregister_reboot_notifier(&esb_notifier); |
| 493 | err_unmap: | 485 | err_unmap: |
| 494 | iounmap(BASEADDR); | 486 | iounmap(BASEADDR); |
| 495 | /* err_release: */ | 487 | /* err_release: */ |
| @@ -498,18 +490,18 @@ err_unmap: | |||
| 498 | pci_disable_device(esb_pci); | 490 | pci_disable_device(esb_pci); |
| 499 | /* err_devput: */ | 491 | /* err_devput: */ |
| 500 | pci_dev_put(esb_pci); | 492 | pci_dev_put(esb_pci); |
| 501 | return ret; | 493 | return ret; |
| 502 | } | 494 | } |
| 503 | 495 | ||
| 504 | static void __exit watchdog_cleanup (void) | 496 | static void __exit watchdog_cleanup(void) |
| 505 | { | 497 | { |
| 506 | /* Stop the timer before we leave */ | 498 | /* Stop the timer before we leave */ |
| 507 | if (!nowayout) | 499 | if (!nowayout) |
| 508 | esb_timer_stop (); | 500 | esb_timer_stop(); |
| 509 | 501 | ||
| 510 | /* Deregister */ | 502 | /* Deregister */ |
| 511 | misc_deregister(&esb_miscdev); | 503 | misc_deregister(&esb_miscdev); |
| 512 | unregister_reboot_notifier(&esb_notifier); | 504 | unregister_reboot_notifier(&esb_notifier); |
| 513 | iounmap(BASEADDR); | 505 | iounmap(BASEADDR); |
| 514 | pci_release_region(esb_pci, 0); | 506 | pci_release_region(esb_pci, 0); |
| 515 | pci_disable_device(esb_pci); | 507 | pci_disable_device(esb_pci); |
diff --git a/drivers/watchdog/iTCO_vendor.h b/drivers/watchdog/iTCO_vendor.h new file mode 100644 index 000000000000..9e27e6422f66 --- /dev/null +++ b/drivers/watchdog/iTCO_vendor.h | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | /* iTCO Vendor Specific Support hooks */ | ||
| 2 | #ifdef CONFIG_ITCO_VENDOR_SUPPORT | ||
| 3 | extern void iTCO_vendor_pre_start(unsigned long, unsigned int); | ||
| 4 | extern void iTCO_vendor_pre_stop(unsigned long); | ||
| 5 | extern void iTCO_vendor_pre_keepalive(unsigned long, unsigned int); | ||
| 6 | extern void iTCO_vendor_pre_set_heartbeat(unsigned int); | ||
| 7 | extern int iTCO_vendor_check_noreboot_on(void); | ||
| 8 | #else | ||
| 9 | #define iTCO_vendor_pre_start(acpibase, heartbeat) {} | ||
| 10 | #define iTCO_vendor_pre_stop(acpibase) {} | ||
| 11 | #define iTCO_vendor_pre_keepalive(acpibase, heartbeat) {} | ||
| 12 | #define iTCO_vendor_pre_set_heartbeat(heartbeat) {} | ||
| 13 | #define iTCO_vendor_check_noreboot_on() 1 | ||
| 14 | /* 1=check noreboot; 0=don't check */ | ||
| 15 | #endif | ||
diff --git a/drivers/watchdog/iTCO_vendor_support.c b/drivers/watchdog/iTCO_vendor_support.c index cafc465f2ae3..ca344a85eb95 100644 --- a/drivers/watchdog/iTCO_vendor_support.c +++ b/drivers/watchdog/iTCO_vendor_support.c | |||
| @@ -18,9 +18,9 @@ | |||
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | /* Module and version information */ | 20 | /* Module and version information */ |
| 21 | #define DRV_NAME "iTCO_vendor_support" | 21 | #define DRV_NAME "iTCO_vendor_support" |
| 22 | #define DRV_VERSION "1.01" | 22 | #define DRV_VERSION "1.01" |
| 23 | #define DRV_RELDATE "11-Nov-2006" | 23 | #define DRV_RELDATE "11-Nov-2006" |
| 24 | #define PFX DRV_NAME ": " | 24 | #define PFX DRV_NAME ": " |
| 25 | 25 | ||
| 26 | /* Includes */ | 26 | /* Includes */ |
| @@ -31,19 +31,22 @@ | |||
| 31 | #include <linux/kernel.h> /* For printk/panic/... */ | 31 | #include <linux/kernel.h> /* For printk/panic/... */ |
| 32 | #include <linux/init.h> /* For __init/__exit/... */ | 32 | #include <linux/init.h> /* For __init/__exit/... */ |
| 33 | #include <linux/ioport.h> /* For io-port access */ | 33 | #include <linux/ioport.h> /* For io-port access */ |
| 34 | #include <linux/io.h> /* For inb/outb/... */ | ||
| 34 | 35 | ||
| 35 | #include <asm/io.h> /* For inb/outb/... */ | 36 | #include "iTCO_vendor.h" |
| 36 | 37 | ||
| 37 | /* iTCO defines */ | 38 | /* iTCO defines */ |
| 38 | #define SMI_EN acpibase + 0x30 /* SMI Control and Enable Register */ | 39 | #define SMI_EN acpibase + 0x30 /* SMI Control and Enable Register */ |
| 39 | #define TCOBASE acpibase + 0x60 /* TCO base address */ | 40 | #define TCOBASE acpibase + 0x60 /* TCO base address */ |
| 40 | #define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ | 41 | #define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ |
| 41 | 42 | ||
| 42 | /* List of vendor support modes */ | 43 | /* List of vendor support modes */ |
| 43 | #define SUPERMICRO_OLD_BOARD 1 /* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */ | 44 | /* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */ |
| 44 | #define SUPERMICRO_NEW_BOARD 2 /* SuperMicro Pentium 4 / Xeon 4 / EMT64T Era Systems */ | 45 | #define SUPERMICRO_OLD_BOARD 1 |
| 46 | /* SuperMicro Pentium 4 / Xeon 4 / EMT64T Era Systems */ | ||
| 47 | #define SUPERMICRO_NEW_BOARD 2 | ||
| 45 | 48 | ||
| 46 | static int vendorsupport = 0; | 49 | static int vendorsupport; |
| 47 | module_param(vendorsupport, int, 0); | 50 | module_param(vendorsupport, int, 0); |
| 48 | MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=0 (none), 1=SuperMicro Pent3, 2=SuperMicro Pent4+"); | 51 | MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=0 (none), 1=SuperMicro Pent3, 2=SuperMicro Pent4+"); |
| 49 | 52 | ||
| @@ -143,34 +146,35 @@ static void supermicro_old_pre_keepalive(unsigned long acpibase) | |||
| 143 | */ | 146 | */ |
| 144 | 147 | ||
| 145 | /* I/O Port's */ | 148 | /* I/O Port's */ |
| 146 | #define SM_REGINDEX 0x2e /* SuperMicro ICH4+ Register Index */ | 149 | #define SM_REGINDEX 0x2e /* SuperMicro ICH4+ Register Index */ |
| 147 | #define SM_DATAIO 0x2f /* SuperMicro ICH4+ Register Data I/O */ | 150 | #define SM_DATAIO 0x2f /* SuperMicro ICH4+ Register Data I/O */ |
| 148 | 151 | ||
| 149 | /* Control Register's */ | 152 | /* Control Register's */ |
| 150 | #define SM_CTLPAGESW 0x07 /* SuperMicro ICH4+ Control Page Switch */ | 153 | #define SM_CTLPAGESW 0x07 /* SuperMicro ICH4+ Control Page Switch */ |
| 151 | #define SM_CTLPAGE 0x08 /* SuperMicro ICH4+ Control Page Num */ | 154 | #define SM_CTLPAGE 0x08 /* SuperMicro ICH4+ Control Page Num */ |
| 152 | 155 | ||
| 153 | #define SM_WATCHENABLE 0x30 /* Watchdog enable: Bit 0: 0=off, 1=on */ | 156 | #define SM_WATCHENABLE 0x30 /* Watchdog enable: Bit 0: 0=off, 1=on */ |
| 154 | 157 | ||
| 155 | #define SM_WATCHPAGE 0x87 /* Watchdog unlock control page */ | 158 | #define SM_WATCHPAGE 0x87 /* Watchdog unlock control page */ |
| 156 | 159 | ||
| 157 | #define SM_ENDWATCH 0xAA /* Watchdog lock control page */ | 160 | #define SM_ENDWATCH 0xAA /* Watchdog lock control page */ |
| 158 | 161 | ||
| 159 | #define SM_COUNTMODE 0xf5 /* Watchdog count mode select */ | 162 | #define SM_COUNTMODE 0xf5 /* Watchdog count mode select */ |
| 160 | /* (Bit 3: 0 = seconds, 1 = minutes */ | 163 | /* (Bit 3: 0 = seconds, 1 = minutes */ |
| 161 | 164 | ||
| 162 | #define SM_WATCHTIMER 0xf6 /* 8-bits, Watchdog timer counter (RW) */ | 165 | #define SM_WATCHTIMER 0xf6 /* 8-bits, Watchdog timer counter (RW) */ |
| 163 | 166 | ||
| 164 | #define SM_RESETCONTROL 0xf7 /* Watchdog reset control */ | 167 | #define SM_RESETCONTROL 0xf7 /* Watchdog reset control */ |
| 165 | /* Bit 6: timer is reset by kbd interrupt */ | 168 | /* Bit 6: timer is reset by kbd interrupt */ |
| 166 | /* Bit 7: timer is reset by mouse interrupt */ | 169 | /* Bit 7: timer is reset by mouse interrupt */ |
| 167 | 170 | ||
| 168 | static void supermicro_new_unlock_watchdog(void) | 171 | static void supermicro_new_unlock_watchdog(void) |
| 169 | { | 172 | { |
| 170 | outb(SM_WATCHPAGE, SM_REGINDEX); /* Write 0x87 to port 0x2e twice */ | 173 | /* Write 0x87 to port 0x2e twice */ |
| 171 | outb(SM_WATCHPAGE, SM_REGINDEX); | 174 | outb(SM_WATCHPAGE, SM_REGINDEX); |
| 172 | 175 | outb(SM_WATCHPAGE, SM_REGINDEX); | |
| 173 | outb(SM_CTLPAGESW, SM_REGINDEX); /* Switch to watchdog control page */ | 176 | /* Switch to watchdog control page */ |
| 177 | outb(SM_CTLPAGESW, SM_REGINDEX); | ||
| 174 | outb(SM_CTLPAGE, SM_DATAIO); | 178 | outb(SM_CTLPAGE, SM_DATAIO); |
| 175 | } | 179 | } |
| 176 | 180 | ||
| @@ -192,7 +196,7 @@ static void supermicro_new_pre_start(unsigned int heartbeat) | |||
| 192 | outb(val, SM_DATAIO); | 196 | outb(val, SM_DATAIO); |
| 193 | 197 | ||
| 194 | /* Write heartbeat interval to WDOG */ | 198 | /* Write heartbeat interval to WDOG */ |
| 195 | outb (SM_WATCHTIMER, SM_REGINDEX); | 199 | outb(SM_WATCHTIMER, SM_REGINDEX); |
| 196 | outb((heartbeat & 255), SM_DATAIO); | 200 | outb((heartbeat & 255), SM_DATAIO); |
| 197 | 201 | ||
| 198 | /* Make sure keyboard/mouse interrupts don't interfere */ | 202 | /* Make sure keyboard/mouse interrupts don't interfere */ |
| @@ -277,7 +281,7 @@ EXPORT_SYMBOL(iTCO_vendor_pre_set_heartbeat); | |||
| 277 | 281 | ||
| 278 | int iTCO_vendor_check_noreboot_on(void) | 282 | int iTCO_vendor_check_noreboot_on(void) |
| 279 | { | 283 | { |
| 280 | switch(vendorsupport) { | 284 | switch (vendorsupport) { |
| 281 | case SUPERMICRO_OLD_BOARD: | 285 | case SUPERMICRO_OLD_BOARD: |
| 282 | return 0; | 286 | return 0; |
| 283 | default: | 287 | default: |
| @@ -288,13 +292,13 @@ EXPORT_SYMBOL(iTCO_vendor_check_noreboot_on); | |||
| 288 | 292 | ||
| 289 | static int __init iTCO_vendor_init_module(void) | 293 | static int __init iTCO_vendor_init_module(void) |
| 290 | { | 294 | { |
| 291 | printk (KERN_INFO PFX "vendor-support=%d\n", vendorsupport); | 295 | printk(KERN_INFO PFX "vendor-support=%d\n", vendorsupport); |
| 292 | return 0; | 296 | return 0; |
| 293 | } | 297 | } |
| 294 | 298 | ||
| 295 | static void __exit iTCO_vendor_exit_module(void) | 299 | static void __exit iTCO_vendor_exit_module(void) |
| 296 | { | 300 | { |
| 297 | printk (KERN_INFO PFX "Module Unloaded\n"); | 301 | printk(KERN_INFO PFX "Module Unloaded\n"); |
| 298 | } | 302 | } |
| 299 | 303 | ||
| 300 | module_init(iTCO_vendor_init_module); | 304 | module_init(iTCO_vendor_init_module); |
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index 95ba985bd341..bfb93bc2ca9f 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c | |||
| @@ -55,9 +55,9 @@ | |||
| 55 | */ | 55 | */ |
| 56 | 56 | ||
| 57 | /* Module and version information */ | 57 | /* Module and version information */ |
| 58 | #define DRV_NAME "iTCO_wdt" | 58 | #define DRV_NAME "iTCO_wdt" |
| 59 | #define DRV_VERSION "1.03" | 59 | #define DRV_VERSION "1.03" |
| 60 | #define DRV_RELDATE "30-Apr-2008" | 60 | #define DRV_RELDATE "30-Apr-2008" |
| 61 | #define PFX DRV_NAME ": " | 61 | #define PFX DRV_NAME ": " |
| 62 | 62 | ||
| 63 | /* Includes */ | 63 | /* Includes */ |
| @@ -66,7 +66,8 @@ | |||
| 66 | #include <linux/types.h> /* For standard types (like size_t) */ | 66 | #include <linux/types.h> /* For standard types (like size_t) */ |
| 67 | #include <linux/errno.h> /* For the -ENODEV/... values */ | 67 | #include <linux/errno.h> /* For the -ENODEV/... values */ |
| 68 | #include <linux/kernel.h> /* For printk/panic/... */ | 68 | #include <linux/kernel.h> /* For printk/panic/... */ |
| 69 | #include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */ | 69 | #include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV |
| 70 | (WATCHDOG_MINOR) */ | ||
| 70 | #include <linux/watchdog.h> /* For the watchdog specific items */ | 71 | #include <linux/watchdog.h> /* For the watchdog specific items */ |
| 71 | #include <linux/init.h> /* For __init/__exit/... */ | 72 | #include <linux/init.h> /* For __init/__exit/... */ |
| 72 | #include <linux/fs.h> /* For file operations */ | 73 | #include <linux/fs.h> /* For file operations */ |
| @@ -74,9 +75,10 @@ | |||
| 74 | #include <linux/pci.h> /* For pci functions */ | 75 | #include <linux/pci.h> /* For pci functions */ |
| 75 | #include <linux/ioport.h> /* For io-port access */ | 76 | #include <linux/ioport.h> /* For io-port access */ |
| 76 | #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ | 77 | #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ |
| 78 | #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ | ||
| 79 | #include <linux/io.h> /* For inb/outb/... */ | ||
| 77 | 80 | ||
| 78 | #include <asm/uaccess.h> /* For copy_to_user/put_user/... */ | 81 | #include "iTCO_vendor.h" |
| 79 | #include <asm/io.h> /* For inb/outb/... */ | ||
| 80 | 82 | ||
| 81 | /* TCO related info */ | 83 | /* TCO related info */ |
| 82 | enum iTCO_chipsets { | 84 | enum iTCO_chipsets { |
| @@ -105,7 +107,7 @@ enum iTCO_chipsets { | |||
| 105 | TCO_ICH9, /* ICH9 */ | 107 | TCO_ICH9, /* ICH9 */ |
| 106 | TCO_ICH9R, /* ICH9R */ | 108 | TCO_ICH9R, /* ICH9R */ |
| 107 | TCO_ICH9DH, /* ICH9DH */ | 109 | TCO_ICH9DH, /* ICH9DH */ |
| 108 | TCO_ICH9DO, /* ICH9DO */ | 110 | TCO_ICH9DO, /* ICH9DO */ |
| 109 | TCO_631XESB, /* 631xESB/632xESB */ | 111 | TCO_631XESB, /* 631xESB/632xESB */ |
| 110 | }; | 112 | }; |
| 111 | 113 | ||
| @@ -140,7 +142,7 @@ static struct { | |||
| 140 | {"ICH9DH", 2}, | 142 | {"ICH9DH", 2}, |
| 141 | {"ICH9DO", 2}, | 143 | {"ICH9DO", 2}, |
| 142 | {"631xESB/632xESB", 2}, | 144 | {"631xESB/632xESB", 2}, |
| 143 | {NULL,0} | 145 | {NULL, 0} |
| 144 | }; | 146 | }; |
| 145 | 147 | ||
| 146 | #define ITCO_PCI_DEVICE(dev, data) \ | 148 | #define ITCO_PCI_DEVICE(dev, data) \ |
| @@ -159,32 +161,32 @@ static struct { | |||
| 159 | * functions that probably will be registered by other drivers. | 161 | * functions that probably will be registered by other drivers. |
| 160 | */ | 162 | */ |
| 161 | static struct pci_device_id iTCO_wdt_pci_tbl[] = { | 163 | static struct pci_device_id iTCO_wdt_pci_tbl[] = { |
| 162 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AA_0, TCO_ICH )}, | 164 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AA_0, TCO_ICH)}, |
| 163 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AB_0, TCO_ICH0 )}, | 165 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AB_0, TCO_ICH0)}, |
| 164 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801BA_0, TCO_ICH2 )}, | 166 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801BA_0, TCO_ICH2)}, |
| 165 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801BA_10, TCO_ICH2M )}, | 167 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801BA_10, TCO_ICH2M)}, |
| 166 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801CA_0, TCO_ICH3 )}, | 168 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801CA_0, TCO_ICH3)}, |
| 167 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801CA_12, TCO_ICH3M )}, | 169 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801CA_12, TCO_ICH3M)}, |
| 168 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801DB_0, TCO_ICH4 )}, | 170 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801DB_0, TCO_ICH4)}, |
| 169 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801DB_12, TCO_ICH4M )}, | 171 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801DB_12, TCO_ICH4M)}, |
| 170 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801E_0, TCO_CICH )}, | 172 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801E_0, TCO_CICH)}, |
| 171 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801EB_0, TCO_ICH5 )}, | 173 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801EB_0, TCO_ICH5)}, |
| 172 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB_1, TCO_6300ESB)}, | 174 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB_1, TCO_6300ESB)}, |
| 173 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_0, TCO_ICH6 )}, | 175 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_0, TCO_ICH6)}, |
| 174 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_1, TCO_ICH6M )}, | 176 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_1, TCO_ICH6M)}, |
| 175 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_2, TCO_ICH6W )}, | 177 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_2, TCO_ICH6W)}, |
| 176 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_0, TCO_ICH7 )}, | 178 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_0, TCO_ICH7)}, |
| 177 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_1, TCO_ICH7M )}, | 179 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_1, TCO_ICH7M)}, |
| 178 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_31, TCO_ICH7MDH)}, | 180 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_31, TCO_ICH7MDH)}, |
| 179 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_0, TCO_ICH8 )}, | 181 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_0, TCO_ICH8)}, |
| 180 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_1, TCO_ICH8ME )}, | 182 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_1, TCO_ICH8ME)}, |
| 181 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_2, TCO_ICH8DH )}, | 183 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_2, TCO_ICH8DH)}, |
| 182 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_3, TCO_ICH8DO )}, | 184 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_3, TCO_ICH8DO)}, |
| 183 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_4, TCO_ICH8M )}, | 185 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_4, TCO_ICH8M)}, |
| 184 | { ITCO_PCI_DEVICE(0x2918, TCO_ICH9 )}, | 186 | { ITCO_PCI_DEVICE(0x2918, TCO_ICH9)}, |
| 185 | { ITCO_PCI_DEVICE(0x2916, TCO_ICH9R )}, | 187 | { ITCO_PCI_DEVICE(0x2916, TCO_ICH9R)}, |
| 186 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_2, TCO_ICH9DH )}, | 188 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_2, TCO_ICH9DH)}, |
| 187 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_4, TCO_ICH9DO )}, | 189 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_4, TCO_ICH9DO)}, |
| 188 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB2_0, TCO_631XESB)}, | 190 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB2_0, TCO_631XESB)}, |
| 189 | { ITCO_PCI_DEVICE(0x2671, TCO_631XESB)}, | 191 | { ITCO_PCI_DEVICE(0x2671, TCO_631XESB)}, |
| 190 | { ITCO_PCI_DEVICE(0x2672, TCO_631XESB)}, | 192 | { ITCO_PCI_DEVICE(0x2672, TCO_631XESB)}, |
| @@ -203,13 +205,15 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = { | |||
| 203 | { ITCO_PCI_DEVICE(0x267f, TCO_631XESB)}, | 205 | { ITCO_PCI_DEVICE(0x267f, TCO_631XESB)}, |
| 204 | { 0, }, /* End of list */ | 206 | { 0, }, /* End of list */ |
| 205 | }; | 207 | }; |
| 206 | MODULE_DEVICE_TABLE (pci, iTCO_wdt_pci_tbl); | 208 | MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); |
| 207 | 209 | ||
| 208 | /* Address definitions for the TCO */ | 210 | /* Address definitions for the TCO */ |
| 209 | #define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60 /* TCO base address */ | 211 | /* TCO base address */ |
| 210 | #define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30 /* SMI Control and Enable Register */ | 212 | #define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60 |
| 213 | /* SMI Control and Enable Register */ | ||
| 214 | #define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30 | ||
| 211 | 215 | ||
| 212 | #define TCO_RLD TCOBASE + 0x00 /* TCO Timer Reload and Current Value */ | 216 | #define TCO_RLD TCOBASE + 0x00 /* TCO Timer Reload and Curr. Value */ |
| 213 | #define TCOv1_TMR TCOBASE + 0x01 /* TCOv1 Timer Initial Value */ | 217 | #define TCOv1_TMR TCOBASE + 0x01 /* TCOv1 Timer Initial Value */ |
| 214 | #define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */ | 218 | #define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */ |
| 215 | #define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */ | 219 | #define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */ |
| @@ -222,15 +226,21 @@ MODULE_DEVICE_TABLE (pci, iTCO_wdt_pci_tbl); | |||
| 222 | /* internal variables */ | 226 | /* internal variables */ |
| 223 | static unsigned long is_active; | 227 | static unsigned long is_active; |
| 224 | static char expect_release; | 228 | static char expect_release; |
| 225 | static struct { /* this is private data for the iTCO_wdt device */ | 229 | static struct { /* this is private data for the iTCO_wdt device */ |
| 226 | unsigned int iTCO_version; /* TCO version/generation */ | 230 | /* TCO version/generation */ |
| 227 | unsigned long ACPIBASE; /* The cards ACPIBASE address (TCOBASE = ACPIBASE+0x60) */ | 231 | unsigned int iTCO_version; |
| 228 | unsigned long __iomem *gcs; /* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2) */ | 232 | /* The cards ACPIBASE address (TCOBASE = ACPIBASE+0x60) */ |
| 229 | spinlock_t io_lock; /* the lock for io operations */ | 233 | unsigned long ACPIBASE; |
| 230 | struct pci_dev *pdev; /* the PCI-device */ | 234 | /* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2)*/ |
| 235 | unsigned long __iomem *gcs; | ||
| 236 | /* the lock for io operations */ | ||
| 237 | spinlock_t io_lock; | ||
| 238 | /* the PCI-device */ | ||
| 239 | struct pci_dev *pdev; | ||
| 231 | } iTCO_wdt_private; | 240 | } iTCO_wdt_private; |
| 232 | 241 | ||
| 233 | static struct platform_device *iTCO_wdt_platform_device; /* the watchdog platform device */ | 242 | /* the watchdog platform device */ |
| 243 | static struct platform_device *iTCO_wdt_platform_device; | ||
| 234 | 244 | ||
| 235 | /* module parameters */ | 245 | /* module parameters */ |
| 236 | #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ | 246 | #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ |
| @@ -240,22 +250,9 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<heartbeat<39 (TCO | |||
| 240 | 250 | ||
| 241 | static int nowayout = WATCHDOG_NOWAYOUT; | 251 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 242 | module_param(nowayout, int, 0); | 252 | module_param(nowayout, int, 0); |
| 243 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 253 | MODULE_PARM_DESC(nowayout, |
| 244 | 254 | "Watchdog cannot be stopped once started (default=" | |
| 245 | /* iTCO Vendor Specific Support hooks */ | 255 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); |
| 246 | #ifdef CONFIG_ITCO_VENDOR_SUPPORT | ||
| 247 | extern void iTCO_vendor_pre_start(unsigned long, unsigned int); | ||
| 248 | extern void iTCO_vendor_pre_stop(unsigned long); | ||
| 249 | extern void iTCO_vendor_pre_keepalive(unsigned long, unsigned int); | ||
| 250 | extern void iTCO_vendor_pre_set_heartbeat(unsigned int); | ||
| 251 | extern int iTCO_vendor_check_noreboot_on(void); | ||
| 252 | #else | ||
| 253 | #define iTCO_vendor_pre_start(acpibase, heartbeat) {} | ||
| 254 | #define iTCO_vendor_pre_stop(acpibase) {} | ||
| 255 | #define iTCO_vendor_pre_keepalive(acpibase,heartbeat) {} | ||
| 256 | #define iTCO_vendor_pre_set_heartbeat(heartbeat) {} | ||
| 257 | #define iTCO_vendor_check_noreboot_on() 1 /* 1=check noreboot; 0=don't check */ | ||
| 258 | #endif | ||
| 259 | 256 | ||
| 260 | /* | 257 | /* |
| 261 | * Some TCO specific functions | 258 | * Some TCO specific functions |
| @@ -369,11 +366,10 @@ static int iTCO_wdt_keepalive(void) | |||
| 369 | iTCO_vendor_pre_keepalive(iTCO_wdt_private.ACPIBASE, heartbeat); | 366 | iTCO_vendor_pre_keepalive(iTCO_wdt_private.ACPIBASE, heartbeat); |
| 370 | 367 | ||
| 371 | /* Reload the timer by writing to the TCO Timer Counter register */ | 368 | /* Reload the timer by writing to the TCO Timer Counter register */ |
| 372 | if (iTCO_wdt_private.iTCO_version == 2) { | 369 | if (iTCO_wdt_private.iTCO_version == 2) |
| 373 | outw(0x01, TCO_RLD); | 370 | outw(0x01, TCO_RLD); |
| 374 | } else if (iTCO_wdt_private.iTCO_version == 1) { | 371 | else if (iTCO_wdt_private.iTCO_version == 1) |
| 375 | outb(0x01, TCO_RLD); | 372 | outb(0x01, TCO_RLD); |
| 376 | } | ||
| 377 | 373 | ||
| 378 | spin_unlock(&iTCO_wdt_private.io_lock); | 374 | spin_unlock(&iTCO_wdt_private.io_lock); |
| 379 | return 0; | 375 | return 0; |
| @@ -425,7 +421,7 @@ static int iTCO_wdt_set_heartbeat(int t) | |||
| 425 | return 0; | 421 | return 0; |
| 426 | } | 422 | } |
| 427 | 423 | ||
| 428 | static int iTCO_wdt_get_timeleft (int *time_left) | 424 | static int iTCO_wdt_get_timeleft(int *time_left) |
| 429 | { | 425 | { |
| 430 | unsigned int val16; | 426 | unsigned int val16; |
| 431 | unsigned char val8; | 427 | unsigned char val8; |
| @@ -454,7 +450,7 @@ static int iTCO_wdt_get_timeleft (int *time_left) | |||
| 454 | * /dev/watchdog handling | 450 | * /dev/watchdog handling |
| 455 | */ | 451 | */ |
| 456 | 452 | ||
| 457 | static int iTCO_wdt_open (struct inode *inode, struct file *file) | 453 | static int iTCO_wdt_open(struct inode *inode, struct file *file) |
| 458 | { | 454 | { |
| 459 | /* /dev/watchdog can only be opened once */ | 455 | /* /dev/watchdog can only be opened once */ |
| 460 | if (test_and_set_bit(0, &is_active)) | 456 | if (test_and_set_bit(0, &is_active)) |
| @@ -468,7 +464,7 @@ static int iTCO_wdt_open (struct inode *inode, struct file *file) | |||
| 468 | return nonseekable_open(inode, file); | 464 | return nonseekable_open(inode, file); |
| 469 | } | 465 | } |
| 470 | 466 | ||
| 471 | static int iTCO_wdt_release (struct inode *inode, struct file *file) | 467 | static int iTCO_wdt_release(struct inode *inode, struct file *file) |
| 472 | { | 468 | { |
| 473 | /* | 469 | /* |
| 474 | * Shut off the timer. | 470 | * Shut off the timer. |
| @@ -476,7 +472,8 @@ static int iTCO_wdt_release (struct inode *inode, struct file *file) | |||
| 476 | if (expect_release == 42) { | 472 | if (expect_release == 42) { |
| 477 | iTCO_wdt_stop(); | 473 | iTCO_wdt_stop(); |
| 478 | } else { | 474 | } else { |
| 479 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 475 | printk(KERN_CRIT PFX |
| 476 | "Unexpected close, not stopping watchdog!\n"); | ||
| 480 | iTCO_wdt_keepalive(); | 477 | iTCO_wdt_keepalive(); |
| 481 | } | 478 | } |
| 482 | clear_bit(0, &is_active); | 479 | clear_bit(0, &is_active); |
| @@ -484,22 +481,23 @@ static int iTCO_wdt_release (struct inode *inode, struct file *file) | |||
| 484 | return 0; | 481 | return 0; |
| 485 | } | 482 | } |
| 486 | 483 | ||
| 487 | static ssize_t iTCO_wdt_write (struct file *file, const char __user *data, | 484 | static ssize_t iTCO_wdt_write(struct file *file, const char __user *data, |
| 488 | size_t len, loff_t * ppos) | 485 | size_t len, loff_t *ppos) |
| 489 | { | 486 | { |
| 490 | /* See if we got the magic character 'V' and reload the timer */ | 487 | /* See if we got the magic character 'V' and reload the timer */ |
| 491 | if (len) { | 488 | if (len) { |
| 492 | if (!nowayout) { | 489 | if (!nowayout) { |
| 493 | size_t i; | 490 | size_t i; |
| 494 | 491 | ||
| 495 | /* note: just in case someone wrote the magic character | 492 | /* note: just in case someone wrote the magic |
| 496 | * five months ago... */ | 493 | character five months ago... */ |
| 497 | expect_release = 0; | 494 | expect_release = 0; |
| 498 | 495 | ||
| 499 | /* scan to see whether or not we got the magic character */ | 496 | /* scan to see whether or not we got the |
| 497 | magic character */ | ||
| 500 | for (i = 0; i != len; i++) { | 498 | for (i = 0; i != len; i++) { |
| 501 | char c; | 499 | char c; |
| 502 | if (get_user(c, data+i)) | 500 | if (get_user(c, data + i)) |
| 503 | return -EFAULT; | 501 | return -EFAULT; |
| 504 | if (c == 'V') | 502 | if (c == 'V') |
| 505 | expect_release = 42; | 503 | expect_release = 42; |
| @@ -512,8 +510,8 @@ static ssize_t iTCO_wdt_write (struct file *file, const char __user *data, | |||
| 512 | return len; | 510 | return len; |
| 513 | } | 511 | } |
| 514 | 512 | ||
| 515 | static int iTCO_wdt_ioctl (struct inode *inode, struct file *file, | 513 | static long iTCO_wdt_ioctl(struct file *file, unsigned int cmd, |
| 516 | unsigned int cmd, unsigned long arg) | 514 | unsigned long arg) |
| 517 | { | 515 | { |
| 518 | int new_options, retval = -EINVAL; | 516 | int new_options, retval = -EINVAL; |
| 519 | int new_heartbeat; | 517 | int new_heartbeat; |
| @@ -528,64 +526,52 @@ static int iTCO_wdt_ioctl (struct inode *inode, struct file *file, | |||
| 528 | }; | 526 | }; |
| 529 | 527 | ||
| 530 | switch (cmd) { | 528 | switch (cmd) { |
| 531 | case WDIOC_GETSUPPORT: | 529 | case WDIOC_GETSUPPORT: |
| 532 | return copy_to_user(argp, &ident, | 530 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; |
| 533 | sizeof (ident)) ? -EFAULT : 0; | 531 | case WDIOC_GETSTATUS: |
| 534 | 532 | case WDIOC_GETBOOTSTATUS: | |
| 535 | case WDIOC_GETSTATUS: | 533 | return put_user(0, p); |
| 536 | case WDIOC_GETBOOTSTATUS: | 534 | |
| 537 | return put_user(0, p); | 535 | case WDIOC_SETOPTIONS: |
| 538 | 536 | { | |
| 539 | case WDIOC_KEEPALIVE: | 537 | if (get_user(new_options, p)) |
| 540 | iTCO_wdt_keepalive(); | 538 | return -EFAULT; |
| 541 | return 0; | 539 | |
| 542 | 540 | if (new_options & WDIOS_DISABLECARD) { | |
| 543 | case WDIOC_SETOPTIONS: | 541 | iTCO_wdt_stop(); |
| 544 | { | 542 | retval = 0; |
| 545 | if (get_user(new_options, p)) | ||
| 546 | return -EFAULT; | ||
| 547 | |||
| 548 | if (new_options & WDIOS_DISABLECARD) { | ||
| 549 | iTCO_wdt_stop(); | ||
| 550 | retval = 0; | ||
| 551 | } | ||
| 552 | |||
| 553 | if (new_options & WDIOS_ENABLECARD) { | ||
| 554 | iTCO_wdt_keepalive(); | ||
| 555 | iTCO_wdt_start(); | ||
| 556 | retval = 0; | ||
| 557 | } | ||
| 558 | |||
| 559 | return retval; | ||
| 560 | } | 543 | } |
| 561 | 544 | if (new_options & WDIOS_ENABLECARD) { | |
| 562 | case WDIOC_SETTIMEOUT: | ||
| 563 | { | ||
| 564 | if (get_user(new_heartbeat, p)) | ||
| 565 | return -EFAULT; | ||
| 566 | |||
| 567 | if (iTCO_wdt_set_heartbeat(new_heartbeat)) | ||
| 568 | return -EINVAL; | ||
| 569 | |||
| 570 | iTCO_wdt_keepalive(); | 545 | iTCO_wdt_keepalive(); |
| 571 | /* Fall */ | 546 | iTCO_wdt_start(); |
| 572 | } | 547 | retval = 0; |
| 573 | |||
| 574 | case WDIOC_GETTIMEOUT: | ||
| 575 | return put_user(heartbeat, p); | ||
| 576 | |||
| 577 | case WDIOC_GETTIMELEFT: | ||
| 578 | { | ||
| 579 | int time_left; | ||
| 580 | |||
| 581 | if (iTCO_wdt_get_timeleft(&time_left)) | ||
| 582 | return -EINVAL; | ||
| 583 | |||
| 584 | return put_user(time_left, p); | ||
| 585 | } | 548 | } |
| 549 | return retval; | ||
| 550 | } | ||
| 551 | case WDIOC_KEEPALIVE: | ||
| 552 | iTCO_wdt_keepalive(); | ||
| 553 | return 0; | ||
| 586 | 554 | ||
| 587 | default: | 555 | case WDIOC_SETTIMEOUT: |
| 588 | return -ENOTTY; | 556 | { |
| 557 | if (get_user(new_heartbeat, p)) | ||
| 558 | return -EFAULT; | ||
| 559 | if (iTCO_wdt_set_heartbeat(new_heartbeat)) | ||
| 560 | return -EINVAL; | ||
| 561 | iTCO_wdt_keepalive(); | ||
| 562 | /* Fall */ | ||
| 563 | } | ||
| 564 | case WDIOC_GETTIMEOUT: | ||
| 565 | return put_user(heartbeat, p); | ||
| 566 | case WDIOC_GETTIMELEFT: | ||
| 567 | { | ||
| 568 | int time_left; | ||
| 569 | if (iTCO_wdt_get_timeleft(&time_left)) | ||
| 570 | return -EINVAL; | ||
| 571 | return put_user(time_left, p); | ||
| 572 | } | ||
| 573 | default: | ||
| 574 | return -ENOTTY; | ||
| 589 | } | 575 | } |
| 590 | } | 576 | } |
| 591 | 577 | ||
| @@ -594,12 +580,12 @@ static int iTCO_wdt_ioctl (struct inode *inode, struct file *file, | |||
| 594 | */ | 580 | */ |
| 595 | 581 | ||
| 596 | static const struct file_operations iTCO_wdt_fops = { | 582 | static const struct file_operations iTCO_wdt_fops = { |
| 597 | .owner = THIS_MODULE, | 583 | .owner = THIS_MODULE, |
| 598 | .llseek = no_llseek, | 584 | .llseek = no_llseek, |
| 599 | .write = iTCO_wdt_write, | 585 | .write = iTCO_wdt_write, |
| 600 | .ioctl = iTCO_wdt_ioctl, | 586 | .unlocked_ioctl = iTCO_wdt_ioctl, |
| 601 | .open = iTCO_wdt_open, | 587 | .open = iTCO_wdt_open, |
| 602 | .release = iTCO_wdt_release, | 588 | .release = iTCO_wdt_release, |
| 603 | }; | 589 | }; |
| 604 | 590 | ||
| 605 | static struct miscdevice iTCO_wdt_miscdev = { | 591 | static struct miscdevice iTCO_wdt_miscdev = { |
| @@ -612,7 +598,8 @@ static struct miscdevice iTCO_wdt_miscdev = { | |||
| 612 | * Init & exit routines | 598 | * Init & exit routines |
| 613 | */ | 599 | */ |
| 614 | 600 | ||
| 615 | static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device_id *ent, struct platform_device *dev) | 601 | static int __devinit iTCO_wdt_init(struct pci_dev *pdev, |
| 602 | const struct pci_device_id *ent, struct platform_device *dev) | ||
| 616 | { | 603 | { |
| 617 | int ret; | 604 | int ret; |
| 618 | u32 base_address; | 605 | u32 base_address; |
| @@ -632,17 +619,19 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device | |||
| 632 | pci_dev_put(pdev); | 619 | pci_dev_put(pdev); |
| 633 | return -ENODEV; | 620 | return -ENODEV; |
| 634 | } | 621 | } |
| 635 | iTCO_wdt_private.iTCO_version = iTCO_chipset_info[ent->driver_data].iTCO_version; | 622 | iTCO_wdt_private.iTCO_version = |
| 623 | iTCO_chipset_info[ent->driver_data].iTCO_version; | ||
| 636 | iTCO_wdt_private.ACPIBASE = base_address; | 624 | iTCO_wdt_private.ACPIBASE = base_address; |
| 637 | iTCO_wdt_private.pdev = pdev; | 625 | iTCO_wdt_private.pdev = pdev; |
| 638 | 626 | ||
| 639 | /* Get the Memory-Mapped GCS register, we need it for the NO_REBOOT flag (TCO v2) */ | 627 | /* Get the Memory-Mapped GCS register, we need it for the |
| 640 | /* To get access to it you have to read RCBA from PCI Config space 0xf0 | 628 | NO_REBOOT flag (TCO v2). To get access to it you have to |
| 641 | and use it as base. GCS = RCBA + ICH6_GCS(0x3410). */ | 629 | read RCBA from PCI Config space 0xf0 and use it as base. |
| 630 | GCS = RCBA + ICH6_GCS(0x3410). */ | ||
| 642 | if (iTCO_wdt_private.iTCO_version == 2) { | 631 | if (iTCO_wdt_private.iTCO_version == 2) { |
| 643 | pci_read_config_dword(pdev, 0xf0, &base_address); | 632 | pci_read_config_dword(pdev, 0xf0, &base_address); |
| 644 | RCBA = base_address & 0xffffc000; | 633 | RCBA = base_address & 0xffffc000; |
| 645 | iTCO_wdt_private.gcs = ioremap((RCBA + 0x3410),4); | 634 | iTCO_wdt_private.gcs = ioremap((RCBA + 0x3410), 4); |
| 646 | } | 635 | } |
| 647 | 636 | ||
| 648 | /* Check chipset's NO_REBOOT bit */ | 637 | /* Check chipset's NO_REBOOT bit */ |
| @@ -657,8 +646,8 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device | |||
| 657 | 646 | ||
| 658 | /* Set the TCO_EN bit in SMI_EN register */ | 647 | /* Set the TCO_EN bit in SMI_EN register */ |
| 659 | if (!request_region(SMI_EN, 4, "iTCO_wdt")) { | 648 | if (!request_region(SMI_EN, 4, "iTCO_wdt")) { |
| 660 | printk(KERN_ERR PFX "I/O address 0x%04lx already in use\n", | 649 | printk(KERN_ERR PFX |
| 661 | SMI_EN ); | 650 | "I/O address 0x%04lx already in use\n", SMI_EN); |
| 662 | ret = -EIO; | 651 | ret = -EIO; |
| 663 | goto out; | 652 | goto out; |
| 664 | } | 653 | } |
| @@ -667,18 +656,20 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device | |||
| 667 | outl(val32, SMI_EN); | 656 | outl(val32, SMI_EN); |
| 668 | release_region(SMI_EN, 4); | 657 | release_region(SMI_EN, 4); |
| 669 | 658 | ||
| 670 | /* The TCO I/O registers reside in a 32-byte range pointed to by the TCOBASE value */ | 659 | /* The TCO I/O registers reside in a 32-byte range pointed to |
| 671 | if (!request_region (TCOBASE, 0x20, "iTCO_wdt")) { | 660 | by the TCOBASE value */ |
| 672 | printk (KERN_ERR PFX "I/O address 0x%04lx already in use\n", | 661 | if (!request_region(TCOBASE, 0x20, "iTCO_wdt")) { |
| 662 | printk(KERN_ERR PFX "I/O address 0x%04lx already in use\n", | ||
| 673 | TCOBASE); | 663 | TCOBASE); |
| 674 | ret = -EIO; | 664 | ret = -EIO; |
| 675 | goto out; | 665 | goto out; |
| 676 | } | 666 | } |
| 677 | 667 | ||
| 678 | printk(KERN_INFO PFX "Found a %s TCO device (Version=%d, TCOBASE=0x%04lx)\n", | 668 | printk(KERN_INFO PFX |
| 679 | iTCO_chipset_info[ent->driver_data].name, | 669 | "Found a %s TCO device (Version=%d, TCOBASE=0x%04lx)\n", |
| 680 | iTCO_chipset_info[ent->driver_data].iTCO_version, | 670 | iTCO_chipset_info[ent->driver_data].name, |
| 681 | TCOBASE); | 671 | iTCO_chipset_info[ent->driver_data].iTCO_version, |
| 672 | TCOBASE); | ||
| 682 | 673 | ||
| 683 | /* Clear out the (probably old) status */ | 674 | /* Clear out the (probably old) status */ |
| 684 | outb(0, TCO1_STS); | 675 | outb(0, TCO1_STS); |
| @@ -687,27 +678,29 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device | |||
| 687 | /* Make sure the watchdog is not running */ | 678 | /* Make sure the watchdog is not running */ |
| 688 | iTCO_wdt_stop(); | 679 | iTCO_wdt_stop(); |
| 689 | 680 | ||
| 690 | /* Check that the heartbeat value is within it's range ; if not reset to the default */ | 681 | /* Check that the heartbeat value is within it's range; |
| 682 | if not reset to the default */ | ||
| 691 | if (iTCO_wdt_set_heartbeat(heartbeat)) { | 683 | if (iTCO_wdt_set_heartbeat(heartbeat)) { |
| 692 | iTCO_wdt_set_heartbeat(WATCHDOG_HEARTBEAT); | 684 | iTCO_wdt_set_heartbeat(WATCHDOG_HEARTBEAT); |
| 693 | printk(KERN_INFO PFX "heartbeat value must be 2<heartbeat<39 (TCO v1) or 613 (TCO v2), using %d\n", | 685 | printk(KERN_INFO PFX "heartbeat value must be 2 < heartbeat < 39 (TCO v1) or 613 (TCO v2), using %d\n", |
| 694 | heartbeat); | 686 | heartbeat); |
| 695 | } | 687 | } |
| 696 | 688 | ||
| 697 | ret = misc_register(&iTCO_wdt_miscdev); | 689 | ret = misc_register(&iTCO_wdt_miscdev); |
| 698 | if (ret != 0) { | 690 | if (ret != 0) { |
| 699 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 691 | printk(KERN_ERR PFX |
| 700 | WATCHDOG_MINOR, ret); | 692 | "cannot register miscdev on minor=%d (err=%d)\n", |
| 693 | WATCHDOG_MINOR, ret); | ||
| 701 | goto unreg_region; | 694 | goto unreg_region; |
| 702 | } | 695 | } |
| 703 | 696 | ||
| 704 | printk (KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n", | 697 | printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n", |
| 705 | heartbeat, nowayout); | 698 | heartbeat, nowayout); |
| 706 | 699 | ||
| 707 | return 0; | 700 | return 0; |
| 708 | 701 | ||
| 709 | unreg_region: | 702 | unreg_region: |
| 710 | release_region (TCOBASE, 0x20); | 703 | release_region(TCOBASE, 0x20); |
| 711 | out: | 704 | out: |
| 712 | if (iTCO_wdt_private.iTCO_version == 2) | 705 | if (iTCO_wdt_private.iTCO_version == 2) |
| 713 | iounmap(iTCO_wdt_private.gcs); | 706 | iounmap(iTCO_wdt_private.gcs); |
| @@ -796,7 +789,8 @@ static int __init iTCO_wdt_init_module(void) | |||
| 796 | if (err) | 789 | if (err) |
| 797 | return err; | 790 | return err; |
| 798 | 791 | ||
| 799 | iTCO_wdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0); | 792 | iTCO_wdt_platform_device = platform_device_register_simple(DRV_NAME, |
| 793 | -1, NULL, 0); | ||
| 800 | if (IS_ERR(iTCO_wdt_platform_device)) { | 794 | if (IS_ERR(iTCO_wdt_platform_device)) { |
| 801 | err = PTR_ERR(iTCO_wdt_platform_device); | 795 | err = PTR_ERR(iTCO_wdt_platform_device); |
| 802 | goto unreg_platform_driver; | 796 | goto unreg_platform_driver; |
diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c index 4b89f401691a..05a28106e8eb 100644 --- a/drivers/watchdog/ib700wdt.c +++ b/drivers/watchdog/ib700wdt.c | |||
| @@ -41,9 +41,9 @@ | |||
| 41 | #include <linux/spinlock.h> | 41 | #include <linux/spinlock.h> |
| 42 | #include <linux/moduleparam.h> | 42 | #include <linux/moduleparam.h> |
| 43 | #include <linux/platform_device.h> | 43 | #include <linux/platform_device.h> |
| 44 | #include <linux/io.h> | ||
| 45 | #include <linux/uaccess.h> | ||
| 44 | 46 | ||
| 45 | #include <asm/io.h> | ||
| 46 | #include <asm/uaccess.h> | ||
| 47 | #include <asm/system.h> | 47 | #include <asm/system.h> |
| 48 | 48 | ||
| 49 | static struct platform_device *ibwdt_platform_device; | 49 | static struct platform_device *ibwdt_platform_device; |
| @@ -120,15 +120,16 @@ static int wd_margin = WD_TIMO; | |||
| 120 | 120 | ||
| 121 | static int nowayout = WATCHDOG_NOWAYOUT; | 121 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 122 | module_param(nowayout, int, 0); | 122 | module_param(nowayout, int, 0); |
| 123 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 123 | MODULE_PARM_DESC(nowayout, |
| 124 | "Watchdog cannot be stopped once started (default=" | ||
| 125 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 124 | 126 | ||
| 125 | 127 | ||
| 126 | /* | 128 | /* |
| 127 | * Watchdog Operations | 129 | * Watchdog Operations |
| 128 | */ | 130 | */ |
| 129 | 131 | ||
| 130 | static void | 132 | static void ibwdt_ping(void) |
| 131 | ibwdt_ping(void) | ||
| 132 | { | 133 | { |
| 133 | spin_lock(&ibwdt_lock); | 134 | spin_lock(&ibwdt_lock); |
| 134 | 135 | ||
| @@ -138,16 +139,14 @@ ibwdt_ping(void) | |||
| 138 | spin_unlock(&ibwdt_lock); | 139 | spin_unlock(&ibwdt_lock); |
| 139 | } | 140 | } |
| 140 | 141 | ||
| 141 | static void | 142 | static void ibwdt_disable(void) |
| 142 | ibwdt_disable(void) | ||
| 143 | { | 143 | { |
| 144 | spin_lock(&ibwdt_lock); | 144 | spin_lock(&ibwdt_lock); |
| 145 | outb_p(0, WDT_STOP); | 145 | outb_p(0, WDT_STOP); |
| 146 | spin_unlock(&ibwdt_lock); | 146 | spin_unlock(&ibwdt_lock); |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | static int | 149 | static int ibwdt_set_heartbeat(int t) |
| 150 | ibwdt_set_heartbeat(int t) | ||
| 151 | { | 150 | { |
| 152 | int i; | 151 | int i; |
| 153 | 152 | ||
| @@ -165,8 +164,8 @@ ibwdt_set_heartbeat(int t) | |||
| 165 | * /dev/watchdog handling | 164 | * /dev/watchdog handling |
| 166 | */ | 165 | */ |
| 167 | 166 | ||
| 168 | static ssize_t | 167 | static ssize_t ibwdt_write(struct file *file, const char __user *buf, |
| 169 | ibwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | 168 | size_t count, loff_t *ppos) |
| 170 | { | 169 | { |
| 171 | if (count) { | 170 | if (count) { |
| 172 | if (!nowayout) { | 171 | if (!nowayout) { |
| @@ -188,77 +187,71 @@ ibwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppo | |||
| 188 | return count; | 187 | return count; |
| 189 | } | 188 | } |
| 190 | 189 | ||
| 191 | static int | 190 | static long ibwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 192 | ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | ||
| 193 | unsigned long arg) | ||
| 194 | { | 191 | { |
| 195 | int new_margin; | 192 | int new_margin; |
| 196 | void __user *argp = (void __user *)arg; | 193 | void __user *argp = (void __user *)arg; |
| 197 | int __user *p = argp; | 194 | int __user *p = argp; |
| 198 | 195 | ||
| 199 | static struct watchdog_info ident = { | 196 | static struct watchdog_info ident = { |
| 200 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, | 197 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
| 198 | | WDIOF_MAGICCLOSE, | ||
| 201 | .firmware_version = 1, | 199 | .firmware_version = 1, |
| 202 | .identity = "IB700 WDT", | 200 | .identity = "IB700 WDT", |
| 203 | }; | 201 | }; |
| 204 | 202 | ||
| 205 | switch (cmd) { | 203 | switch (cmd) { |
| 206 | case WDIOC_GETSUPPORT: | 204 | case WDIOC_GETSUPPORT: |
| 207 | if (copy_to_user(argp, &ident, sizeof(ident))) | 205 | if (copy_to_user(argp, &ident, sizeof(ident))) |
| 208 | return -EFAULT; | 206 | return -EFAULT; |
| 209 | break; | 207 | break; |
| 210 | 208 | ||
| 211 | case WDIOC_GETSTATUS: | 209 | case WDIOC_GETSTATUS: |
| 212 | case WDIOC_GETBOOTSTATUS: | 210 | case WDIOC_GETBOOTSTATUS: |
| 213 | return put_user(0, p); | 211 | return put_user(0, p); |
| 214 | |||
| 215 | case WDIOC_KEEPALIVE: | ||
| 216 | ibwdt_ping(); | ||
| 217 | break; | ||
| 218 | |||
| 219 | case WDIOC_SETTIMEOUT: | ||
| 220 | if (get_user(new_margin, p)) | ||
| 221 | return -EFAULT; | ||
| 222 | if (ibwdt_set_heartbeat(new_margin)) | ||
| 223 | return -EINVAL; | ||
| 224 | ibwdt_ping(); | ||
| 225 | /* Fall */ | ||
| 226 | |||
| 227 | case WDIOC_GETTIMEOUT: | ||
| 228 | return put_user(wd_times[wd_margin], p); | ||
| 229 | 212 | ||
| 230 | case WDIOC_SETOPTIONS: | 213 | case WDIOC_SETOPTIONS: |
| 231 | { | 214 | { |
| 232 | int options, retval = -EINVAL; | 215 | int options, retval = -EINVAL; |
| 233 | 216 | ||
| 234 | if (get_user(options, p)) | 217 | if (get_user(options, p)) |
| 235 | return -EFAULT; | 218 | return -EFAULT; |
| 236 | 219 | ||
| 237 | if (options & WDIOS_DISABLECARD) { | 220 | if (options & WDIOS_DISABLECARD) { |
| 238 | ibwdt_disable(); | 221 | ibwdt_disable(); |
| 239 | retval = 0; | 222 | retval = 0; |
| 240 | } | 223 | } |
| 224 | if (options & WDIOS_ENABLECARD) { | ||
| 225 | ibwdt_ping(); | ||
| 226 | retval = 0; | ||
| 227 | } | ||
| 228 | return retval; | ||
| 229 | } | ||
| 230 | case WDIOC_KEEPALIVE: | ||
| 231 | ibwdt_ping(); | ||
| 232 | break; | ||
| 241 | 233 | ||
| 242 | if (options & WDIOS_ENABLECARD) { | 234 | case WDIOC_SETTIMEOUT: |
| 243 | ibwdt_ping(); | 235 | if (get_user(new_margin, p)) |
| 244 | retval = 0; | 236 | return -EFAULT; |
| 245 | } | 237 | if (ibwdt_set_heartbeat(new_margin)) |
| 238 | return -EINVAL; | ||
| 239 | ibwdt_ping(); | ||
| 240 | /* Fall */ | ||
| 246 | 241 | ||
| 247 | return retval; | 242 | case WDIOC_GETTIMEOUT: |
| 248 | } | 243 | return put_user(wd_times[wd_margin], p); |
| 249 | 244 | ||
| 250 | default: | 245 | default: |
| 251 | return -ENOTTY; | 246 | return -ENOTTY; |
| 252 | } | 247 | } |
| 253 | return 0; | 248 | return 0; |
| 254 | } | 249 | } |
| 255 | 250 | ||
| 256 | static int | 251 | static int ibwdt_open(struct inode *inode, struct file *file) |
| 257 | ibwdt_open(struct inode *inode, struct file *file) | ||
| 258 | { | 252 | { |
| 259 | if (test_and_set_bit(0, &ibwdt_is_open)) { | 253 | if (test_and_set_bit(0, &ibwdt_is_open)) |
| 260 | return -EBUSY; | 254 | return -EBUSY; |
| 261 | } | ||
| 262 | if (nowayout) | 255 | if (nowayout) |
| 263 | __module_get(THIS_MODULE); | 256 | __module_get(THIS_MODULE); |
| 264 | 257 | ||
| @@ -267,13 +260,13 @@ ibwdt_open(struct inode *inode, struct file *file) | |||
| 267 | return nonseekable_open(inode, file); | 260 | return nonseekable_open(inode, file); |
| 268 | } | 261 | } |
| 269 | 262 | ||
| 270 | static int | 263 | static int ibwdt_close(struct inode *inode, struct file *file) |
| 271 | ibwdt_close(struct inode *inode, struct file *file) | ||
| 272 | { | 264 | { |
| 273 | if (expect_close == 42) { | 265 | if (expect_close == 42) { |
| 274 | ibwdt_disable(); | 266 | ibwdt_disable(); |
| 275 | } else { | 267 | } else { |
| 276 | printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n"); | 268 | printk(KERN_CRIT PFX |
| 269 | "WDT device closed unexpectedly. WDT will not stop!\n"); | ||
| 277 | ibwdt_ping(); | 270 | ibwdt_ping(); |
| 278 | } | 271 | } |
| 279 | clear_bit(0, &ibwdt_is_open); | 272 | clear_bit(0, &ibwdt_is_open); |
| @@ -289,7 +282,7 @@ static const struct file_operations ibwdt_fops = { | |||
| 289 | .owner = THIS_MODULE, | 282 | .owner = THIS_MODULE, |
| 290 | .llseek = no_llseek, | 283 | .llseek = no_llseek, |
| 291 | .write = ibwdt_write, | 284 | .write = ibwdt_write, |
| 292 | .ioctl = ibwdt_ioctl, | 285 | .unlocked_ioctl = ibwdt_ioctl, |
| 293 | .open = ibwdt_open, | 286 | .open = ibwdt_open, |
| 294 | .release = ibwdt_close, | 287 | .release = ibwdt_close, |
| 295 | }; | 288 | }; |
| @@ -310,21 +303,23 @@ static int __devinit ibwdt_probe(struct platform_device *dev) | |||
| 310 | 303 | ||
| 311 | #if WDT_START != WDT_STOP | 304 | #if WDT_START != WDT_STOP |
| 312 | if (!request_region(WDT_STOP, 1, "IB700 WDT")) { | 305 | if (!request_region(WDT_STOP, 1, "IB700 WDT")) { |
| 313 | printk (KERN_ERR PFX "STOP method I/O %X is not available.\n", WDT_STOP); | 306 | printk(KERN_ERR PFX "STOP method I/O %X is not available.\n", |
| 307 | WDT_STOP); | ||
| 314 | res = -EIO; | 308 | res = -EIO; |
| 315 | goto out_nostopreg; | 309 | goto out_nostopreg; |
| 316 | } | 310 | } |
| 317 | #endif | 311 | #endif |
| 318 | 312 | ||
| 319 | if (!request_region(WDT_START, 1, "IB700 WDT")) { | 313 | if (!request_region(WDT_START, 1, "IB700 WDT")) { |
| 320 | printk (KERN_ERR PFX "START method I/O %X is not available.\n", WDT_START); | 314 | printk(KERN_ERR PFX "START method I/O %X is not available.\n", |
| 315 | WDT_START); | ||
| 321 | res = -EIO; | 316 | res = -EIO; |
| 322 | goto out_nostartreg; | 317 | goto out_nostartreg; |
| 323 | } | 318 | } |
| 324 | 319 | ||
| 325 | res = misc_register(&ibwdt_miscdev); | 320 | res = misc_register(&ibwdt_miscdev); |
| 326 | if (res) { | 321 | if (res) { |
| 327 | printk (KERN_ERR PFX "failed to register misc device\n"); | 322 | printk(KERN_ERR PFX "failed to register misc device\n"); |
| 328 | goto out_nomisc; | 323 | goto out_nomisc; |
| 329 | } | 324 | } |
| 330 | return 0; | 325 | return 0; |
| @@ -342,9 +337,9 @@ out_nostopreg: | |||
| 342 | static int __devexit ibwdt_remove(struct platform_device *dev) | 337 | static int __devexit ibwdt_remove(struct platform_device *dev) |
| 343 | { | 338 | { |
| 344 | misc_deregister(&ibwdt_miscdev); | 339 | misc_deregister(&ibwdt_miscdev); |
| 345 | release_region(WDT_START,1); | 340 | release_region(WDT_START, 1); |
| 346 | #if WDT_START != WDT_STOP | 341 | #if WDT_START != WDT_STOP |
| 347 | release_region(WDT_STOP,1); | 342 | release_region(WDT_STOP, 1); |
| 348 | #endif | 343 | #endif |
| 349 | return 0; | 344 | return 0; |
| 350 | } | 345 | } |
| @@ -369,13 +364,15 @@ static int __init ibwdt_init(void) | |||
| 369 | { | 364 | { |
| 370 | int err; | 365 | int err; |
| 371 | 366 | ||
| 372 | printk(KERN_INFO PFX "WDT driver for IB700 single board computer initialising.\n"); | 367 | printk(KERN_INFO PFX |
| 368 | "WDT driver for IB700 single board computer initialising.\n"); | ||
| 373 | 369 | ||
| 374 | err = platform_driver_register(&ibwdt_driver); | 370 | err = platform_driver_register(&ibwdt_driver); |
| 375 | if (err) | 371 | if (err) |
| 376 | return err; | 372 | return err; |
| 377 | 373 | ||
| 378 | ibwdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0); | 374 | ibwdt_platform_device = platform_device_register_simple(DRV_NAME, |
| 375 | -1, NULL, 0); | ||
| 379 | if (IS_ERR(ibwdt_platform_device)) { | 376 | if (IS_ERR(ibwdt_platform_device)) { |
| 380 | err = PTR_ERR(ibwdt_platform_device); | 377 | err = PTR_ERR(ibwdt_platform_device); |
| 381 | goto unreg_platform_driver; | 378 | goto unreg_platform_driver; |
diff --git a/drivers/watchdog/ibmasr.c b/drivers/watchdog/ibmasr.c index 94155f6136c2..b82405cfb4cd 100644 --- a/drivers/watchdog/ibmasr.c +++ b/drivers/watchdog/ibmasr.c | |||
| @@ -19,9 +19,8 @@ | |||
| 19 | #include <linux/miscdevice.h> | 19 | #include <linux/miscdevice.h> |
| 20 | #include <linux/watchdog.h> | 20 | #include <linux/watchdog.h> |
| 21 | #include <linux/dmi.h> | 21 | #include <linux/dmi.h> |
| 22 | 22 | #include <linux/io.h> | |
| 23 | #include <asm/io.h> | 23 | #include <linux/uaccess.h> |
| 24 | #include <asm/uaccess.h> | ||
| 25 | 24 | ||
| 26 | 25 | ||
| 27 | enum { | 26 | enum { |
| @@ -70,10 +69,13 @@ static char asr_expect_close; | |||
| 70 | static unsigned int asr_type, asr_base, asr_length; | 69 | static unsigned int asr_type, asr_base, asr_length; |
| 71 | static unsigned int asr_read_addr, asr_write_addr; | 70 | static unsigned int asr_read_addr, asr_write_addr; |
| 72 | static unsigned char asr_toggle_mask, asr_disable_mask; | 71 | static unsigned char asr_toggle_mask, asr_disable_mask; |
| 72 | static spinlock_t asr_lock; | ||
| 73 | 73 | ||
| 74 | static void asr_toggle(void) | 74 | static void __asr_toggle(void) |
| 75 | { | 75 | { |
| 76 | unsigned char reg = inb(asr_read_addr); | 76 | unsigned char reg; |
| 77 | |||
| 78 | reg = inb(asr_read_addr); | ||
| 77 | 79 | ||
| 78 | outb(reg & ~asr_toggle_mask, asr_write_addr); | 80 | outb(reg & ~asr_toggle_mask, asr_write_addr); |
| 79 | reg = inb(asr_read_addr); | 81 | reg = inb(asr_read_addr); |
| @@ -83,12 +85,21 @@ static void asr_toggle(void) | |||
| 83 | 85 | ||
| 84 | outb(reg & ~asr_toggle_mask, asr_write_addr); | 86 | outb(reg & ~asr_toggle_mask, asr_write_addr); |
| 85 | reg = inb(asr_read_addr); | 87 | reg = inb(asr_read_addr); |
| 88 | spin_unlock(&asr_lock); | ||
| 89 | } | ||
| 90 | |||
| 91 | static void asr_toggle(void) | ||
| 92 | { | ||
| 93 | spin_lock(&asr_lock); | ||
| 94 | __asr_toggle(); | ||
| 95 | spin_unlock(&asr_lock); | ||
| 86 | } | 96 | } |
| 87 | 97 | ||
| 88 | static void asr_enable(void) | 98 | static void asr_enable(void) |
| 89 | { | 99 | { |
| 90 | unsigned char reg; | 100 | unsigned char reg; |
| 91 | 101 | ||
| 102 | spin_lock(&asr_lock); | ||
| 92 | if (asr_type == ASMTYPE_TOPAZ) { | 103 | if (asr_type == ASMTYPE_TOPAZ) { |
| 93 | /* asr_write_addr == asr_read_addr */ | 104 | /* asr_write_addr == asr_read_addr */ |
| 94 | reg = inb(asr_read_addr); | 105 | reg = inb(asr_read_addr); |
| @@ -99,17 +110,21 @@ static void asr_enable(void) | |||
| 99 | * First make sure the hardware timer is reset by toggling | 110 | * First make sure the hardware timer is reset by toggling |
| 100 | * ASR hardware timer line. | 111 | * ASR hardware timer line. |
| 101 | */ | 112 | */ |
| 102 | asr_toggle(); | 113 | __asr_toggle(); |
| 103 | 114 | ||
| 104 | reg = inb(asr_read_addr); | 115 | reg = inb(asr_read_addr); |
| 105 | outb(reg & ~asr_disable_mask, asr_write_addr); | 116 | outb(reg & ~asr_disable_mask, asr_write_addr); |
| 106 | } | 117 | } |
| 107 | reg = inb(asr_read_addr); | 118 | reg = inb(asr_read_addr); |
| 119 | spin_unlock(&asr_lock); | ||
| 108 | } | 120 | } |
| 109 | 121 | ||
| 110 | static void asr_disable(void) | 122 | static void asr_disable(void) |
| 111 | { | 123 | { |
| 112 | unsigned char reg = inb(asr_read_addr); | 124 | unsigned char reg; |
| 125 | |||
| 126 | spin_lock(&asr_lock); | ||
| 127 | reg = inb(asr_read_addr); | ||
| 113 | 128 | ||
| 114 | if (asr_type == ASMTYPE_TOPAZ) | 129 | if (asr_type == ASMTYPE_TOPAZ) |
| 115 | /* asr_write_addr == asr_read_addr */ | 130 | /* asr_write_addr == asr_read_addr */ |
| @@ -122,6 +137,7 @@ static void asr_disable(void) | |||
| 122 | outb(reg | asr_disable_mask, asr_write_addr); | 137 | outb(reg | asr_disable_mask, asr_write_addr); |
| 123 | } | 138 | } |
| 124 | reg = inb(asr_read_addr); | 139 | reg = inb(asr_read_addr); |
| 140 | spin_unlock(&asr_lock); | ||
| 125 | } | 141 | } |
| 126 | 142 | ||
| 127 | static int __init asr_get_base_address(void) | 143 | static int __init asr_get_base_address(void) |
| @@ -133,7 +149,8 @@ static int __init asr_get_base_address(void) | |||
| 133 | 149 | ||
| 134 | switch (asr_type) { | 150 | switch (asr_type) { |
| 135 | case ASMTYPE_TOPAZ: | 151 | case ASMTYPE_TOPAZ: |
| 136 | /* SELECT SuperIO CHIP FOR QUERYING (WRITE 0x07 TO BOTH 0x2E and 0x2F) */ | 152 | /* SELECT SuperIO CHIP FOR QUERYING |
| 153 | (WRITE 0x07 TO BOTH 0x2E and 0x2F) */ | ||
| 137 | outb(0x07, 0x2e); | 154 | outb(0x07, 0x2e); |
| 138 | outb(0x07, 0x2f); | 155 | outb(0x07, 0x2f); |
| 139 | 156 | ||
| @@ -154,14 +171,26 @@ static int __init asr_get_base_address(void) | |||
| 154 | 171 | ||
| 155 | case ASMTYPE_JASPER: | 172 | case ASMTYPE_JASPER: |
| 156 | type = "Jaspers "; | 173 | type = "Jaspers "; |
| 157 | 174 | #if 0 | |
| 158 | /* FIXME: need to use pci_config_lock here, but it's not exported */ | 175 | u32 r; |
| 176 | /* Suggested fix */ | ||
| 177 | pdev = pci_get_bus_and_slot(0, DEVFN(0x1f, 0)); | ||
| 178 | if (pdev == NULL) | ||
| 179 | return -ENODEV; | ||
| 180 | pci_read_config_dword(pdev, 0x58, &r); | ||
| 181 | asr_base = r & 0xFFFE; | ||
| 182 | pci_dev_put(pdev); | ||
| 183 | #else | ||
| 184 | /* FIXME: need to use pci_config_lock here, | ||
| 185 | but it's not exported */ | ||
| 159 | 186 | ||
| 160 | /* spin_lock_irqsave(&pci_config_lock, flags);*/ | 187 | /* spin_lock_irqsave(&pci_config_lock, flags);*/ |
| 161 | 188 | ||
| 162 | /* Select the SuperIO chip in the PCI I/O port register */ | 189 | /* Select the SuperIO chip in the PCI I/O port register */ |
| 163 | outl(0x8000f858, 0xcf8); | 190 | outl(0x8000f858, 0xcf8); |
| 164 | 191 | ||
| 192 | /* BUS 0, Slot 1F, fnc 0, offset 58 */ | ||
| 193 | |||
| 165 | /* | 194 | /* |
| 166 | * Read the base address for the SuperIO chip. | 195 | * Read the base address for the SuperIO chip. |
| 167 | * Only the lower 16 bits are valid, but the address is word | 196 | * Only the lower 16 bits are valid, but the address is word |
| @@ -170,7 +199,7 @@ static int __init asr_get_base_address(void) | |||
| 170 | asr_base = inl(0xcfc) & 0xfffe; | 199 | asr_base = inl(0xcfc) & 0xfffe; |
| 171 | 200 | ||
| 172 | /* spin_unlock_irqrestore(&pci_config_lock, flags);*/ | 201 | /* spin_unlock_irqrestore(&pci_config_lock, flags);*/ |
| 173 | 202 | #endif | |
| 174 | asr_read_addr = asr_write_addr = | 203 | asr_read_addr = asr_write_addr = |
| 175 | asr_base + JASPER_ASR_REG_OFFSET; | 204 | asr_base + JASPER_ASR_REG_OFFSET; |
| 176 | asr_toggle_mask = JASPER_ASR_TOGGLE_MASK; | 205 | asr_toggle_mask = JASPER_ASR_TOGGLE_MASK; |
| @@ -241,66 +270,57 @@ static ssize_t asr_write(struct file *file, const char __user *buf, | |||
| 241 | return count; | 270 | return count; |
| 242 | } | 271 | } |
| 243 | 272 | ||
| 244 | static int asr_ioctl(struct inode *inode, struct file *file, | 273 | static long asr_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 245 | unsigned int cmd, unsigned long arg) | ||
| 246 | { | 274 | { |
| 247 | static const struct watchdog_info ident = { | 275 | static const struct watchdog_info ident = { |
| 248 | .options = WDIOF_KEEPALIVEPING | | 276 | .options = WDIOF_KEEPALIVEPING | |
| 249 | WDIOF_MAGICCLOSE, | 277 | WDIOF_MAGICCLOSE, |
| 250 | .identity = "IBM ASR" | 278 | .identity = "IBM ASR", |
| 251 | }; | 279 | }; |
| 252 | void __user *argp = (void __user *)arg; | 280 | void __user *argp = (void __user *)arg; |
| 253 | int __user *p = argp; | 281 | int __user *p = argp; |
| 254 | int heartbeat; | 282 | int heartbeat; |
| 255 | 283 | ||
| 256 | switch (cmd) { | 284 | switch (cmd) { |
| 257 | case WDIOC_GETSUPPORT: | 285 | case WDIOC_GETSUPPORT: |
| 258 | return copy_to_user(argp, &ident, sizeof(ident)) ? | 286 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; |
| 259 | -EFAULT : 0; | 287 | case WDIOC_GETSTATUS: |
| 260 | 288 | case WDIOC_GETBOOTSTATUS: | |
| 261 | case WDIOC_GETSTATUS: | 289 | return put_user(0, p); |
| 262 | case WDIOC_GETBOOTSTATUS: | 290 | case WDIOC_SETOPTIONS: |
| 263 | return put_user(0, p); | 291 | { |
| 264 | 292 | int new_options, retval = -EINVAL; | |
| 265 | case WDIOC_KEEPALIVE: | 293 | if (get_user(new_options, p)) |
| 294 | return -EFAULT; | ||
| 295 | if (new_options & WDIOS_DISABLECARD) { | ||
| 296 | asr_disable(); | ||
| 297 | retval = 0; | ||
| 298 | } | ||
| 299 | if (new_options & WDIOS_ENABLECARD) { | ||
| 300 | asr_enable(); | ||
| 266 | asr_toggle(); | 301 | asr_toggle(); |
| 267 | return 0; | 302 | retval = 0; |
| 268 | |||
| 269 | /* | ||
| 270 | * The hardware has a fixed timeout value, so no WDIOC_SETTIMEOUT | ||
| 271 | * and WDIOC_GETTIMEOUT always returns 256. | ||
| 272 | */ | ||
| 273 | case WDIOC_GETTIMEOUT: | ||
| 274 | heartbeat = 256; | ||
| 275 | return put_user(heartbeat, p); | ||
| 276 | |||
| 277 | case WDIOC_SETOPTIONS: { | ||
| 278 | int new_options, retval = -EINVAL; | ||
| 279 | |||
| 280 | if (get_user(new_options, p)) | ||
| 281 | return -EFAULT; | ||
| 282 | |||
| 283 | if (new_options & WDIOS_DISABLECARD) { | ||
| 284 | asr_disable(); | ||
| 285 | retval = 0; | ||
| 286 | } | ||
| 287 | |||
| 288 | if (new_options & WDIOS_ENABLECARD) { | ||
| 289 | asr_enable(); | ||
| 290 | asr_toggle(); | ||
| 291 | retval = 0; | ||
| 292 | } | ||
| 293 | |||
| 294 | return retval; | ||
| 295 | } | 303 | } |
| 304 | return retval; | ||
| 305 | } | ||
| 306 | case WDIOC_KEEPALIVE: | ||
| 307 | asr_toggle(); | ||
| 308 | return 0; | ||
| 309 | /* | ||
| 310 | * The hardware has a fixed timeout value, so no WDIOC_SETTIMEOUT | ||
| 311 | * and WDIOC_GETTIMEOUT always returns 256. | ||
| 312 | */ | ||
| 313 | case WDIOC_GETTIMEOUT: | ||
| 314 | heartbeat = 256; | ||
| 315 | return put_user(heartbeat, p); | ||
| 316 | default: | ||
| 317 | return -ENOTTY; | ||
| 296 | } | 318 | } |
| 297 | |||
| 298 | return -ENOTTY; | ||
| 299 | } | 319 | } |
| 300 | 320 | ||
| 301 | static int asr_open(struct inode *inode, struct file *file) | 321 | static int asr_open(struct inode *inode, struct file *file) |
| 302 | { | 322 | { |
| 303 | if(test_and_set_bit(0, &asr_is_open)) | 323 | if (test_and_set_bit(0, &asr_is_open)) |
| 304 | return -EBUSY; | 324 | return -EBUSY; |
| 305 | 325 | ||
| 306 | asr_toggle(); | 326 | asr_toggle(); |
| @@ -314,7 +334,8 @@ static int asr_release(struct inode *inode, struct file *file) | |||
| 314 | if (asr_expect_close == 42) | 334 | if (asr_expect_close == 42) |
| 315 | asr_disable(); | 335 | asr_disable(); |
| 316 | else { | 336 | else { |
| 317 | printk(KERN_CRIT PFX "unexpected close, not stopping watchdog!\n"); | 337 | printk(KERN_CRIT PFX |
| 338 | "unexpected close, not stopping watchdog!\n"); | ||
| 318 | asr_toggle(); | 339 | asr_toggle(); |
| 319 | } | 340 | } |
| 320 | clear_bit(0, &asr_is_open); | 341 | clear_bit(0, &asr_is_open); |
| @@ -323,12 +344,12 @@ static int asr_release(struct inode *inode, struct file *file) | |||
| 323 | } | 344 | } |
| 324 | 345 | ||
| 325 | static const struct file_operations asr_fops = { | 346 | static const struct file_operations asr_fops = { |
| 326 | .owner = THIS_MODULE, | 347 | .owner = THIS_MODULE, |
| 327 | .llseek = no_llseek, | 348 | .llseek = no_llseek, |
| 328 | .write = asr_write, | 349 | .write = asr_write, |
| 329 | .ioctl = asr_ioctl, | 350 | .unlocked_ioctl = asr_ioctl, |
| 330 | .open = asr_open, | 351 | .open = asr_open, |
| 331 | .release = asr_release, | 352 | .release = asr_release, |
| 332 | }; | 353 | }; |
| 333 | 354 | ||
| 334 | static struct miscdevice asr_miscdev = { | 355 | static struct miscdevice asr_miscdev = { |
| @@ -367,6 +388,8 @@ static int __init ibmasr_init(void) | |||
| 367 | if (!asr_type) | 388 | if (!asr_type) |
| 368 | return -ENODEV; | 389 | return -ENODEV; |
| 369 | 390 | ||
| 391 | spin_lock_init(&asr_lock); | ||
| 392 | |||
| 370 | rc = asr_get_base_address(); | 393 | rc = asr_get_base_address(); |
| 371 | if (rc) | 394 | if (rc) |
| 372 | return rc; | 395 | return rc; |
| @@ -395,7 +418,9 @@ module_init(ibmasr_init); | |||
| 395 | module_exit(ibmasr_exit); | 418 | module_exit(ibmasr_exit); |
| 396 | 419 | ||
| 397 | module_param(nowayout, int, 0); | 420 | module_param(nowayout, int, 0); |
| 398 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 421 | MODULE_PARM_DESC(nowayout, |
| 422 | "Watchdog cannot be stopped once started (default=" | ||
| 423 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 399 | 424 | ||
| 400 | MODULE_DESCRIPTION("IBM Automatic Server Restart driver"); | 425 | MODULE_DESCRIPTION("IBM Automatic Server Restart driver"); |
| 401 | MODULE_AUTHOR("Andrey Panin"); | 426 | MODULE_AUTHOR("Andrey Panin"); |
diff --git a/drivers/watchdog/indydog.c b/drivers/watchdog/indydog.c index 788245bdaa7f..73c9e7992feb 100644 --- a/drivers/watchdog/indydog.c +++ b/drivers/watchdog/indydog.c | |||
| @@ -1,7 +1,8 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * IndyDog 0.3 A Hardware Watchdog Device for SGI IP22 | 2 | * IndyDog 0.3 A Hardware Watchdog Device for SGI IP22 |
| 3 | * | 3 | * |
| 4 | * (c) Copyright 2002 Guido Guenther <agx@sigxcpu.org>, All Rights Reserved. | 4 | * (c) Copyright 2002 Guido Guenther <agx@sigxcpu.org>, |
| 5 | * All Rights Reserved. | ||
| 5 | * | 6 | * |
| 6 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU General Public License | 8 | * modify it under the terms of the GNU General Public License |
| @@ -22,32 +23,42 @@ | |||
| 22 | #include <linux/notifier.h> | 23 | #include <linux/notifier.h> |
| 23 | #include <linux/reboot.h> | 24 | #include <linux/reboot.h> |
| 24 | #include <linux/init.h> | 25 | #include <linux/init.h> |
| 25 | #include <asm/uaccess.h> | 26 | #include <linux/uaccess.h> |
| 26 | #include <asm/sgi/mc.h> | 27 | #include <asm/sgi/mc.h> |
| 27 | 28 | ||
| 28 | #define PFX "indydog: " | 29 | #define PFX "indydog: " |
| 29 | static int indydog_alive; | 30 | static unsigned long indydog_alive; |
| 31 | static spinlock_t indydog_lock; | ||
| 30 | 32 | ||
| 31 | #define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ | 33 | #define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ |
| 32 | 34 | ||
| 33 | static int nowayout = WATCHDOG_NOWAYOUT; | 35 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 34 | module_param(nowayout, int, 0); | 36 | module_param(nowayout, int, 0); |
| 35 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 37 | MODULE_PARM_DESC(nowayout, |
| 38 | "Watchdog cannot be stopped once started (default=" | ||
| 39 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 36 | 40 | ||
| 37 | static void indydog_start(void) | 41 | static void indydog_start(void) |
| 38 | { | 42 | { |
| 39 | u32 mc_ctrl0 = sgimc->cpuctrl0; | 43 | u32 mc_ctrl0; |
| 40 | 44 | ||
| 45 | spin_lock(&indydog_lock); | ||
| 46 | mc_ctrl0 = sgimc->cpuctrl0; | ||
| 41 | mc_ctrl0 = sgimc->cpuctrl0 | SGIMC_CCTRL0_WDOG; | 47 | mc_ctrl0 = sgimc->cpuctrl0 | SGIMC_CCTRL0_WDOG; |
| 42 | sgimc->cpuctrl0 = mc_ctrl0; | 48 | sgimc->cpuctrl0 = mc_ctrl0; |
| 49 | spin_unlock(&indydog_lock); | ||
| 43 | } | 50 | } |
| 44 | 51 | ||
| 45 | static void indydog_stop(void) | 52 | static void indydog_stop(void) |
| 46 | { | 53 | { |
| 47 | u32 mc_ctrl0 = sgimc->cpuctrl0; | 54 | u32 mc_ctrl0; |
| 48 | 55 | ||
| 56 | spin_lock(&indydog_lock); | ||
| 57 | |||
| 58 | mc_ctrl0 = sgimc->cpuctrl0; | ||
| 49 | mc_ctrl0 &= ~SGIMC_CCTRL0_WDOG; | 59 | mc_ctrl0 &= ~SGIMC_CCTRL0_WDOG; |
| 50 | sgimc->cpuctrl0 = mc_ctrl0; | 60 | sgimc->cpuctrl0 = mc_ctrl0; |
| 61 | spin_unlock(&indydog_lock); | ||
| 51 | 62 | ||
| 52 | printk(KERN_INFO PFX "Stopped watchdog timer.\n"); | 63 | printk(KERN_INFO PFX "Stopped watchdog timer.\n"); |
| 53 | } | 64 | } |
| @@ -62,7 +73,7 @@ static void indydog_ping(void) | |||
| 62 | */ | 73 | */ |
| 63 | static int indydog_open(struct inode *inode, struct file *file) | 74 | static int indydog_open(struct inode *inode, struct file *file) |
| 64 | { | 75 | { |
| 65 | if (indydog_alive) | 76 | if (test_and_set_bit(0, &indydog_alive)) |
| 66 | return -EBUSY; | 77 | return -EBUSY; |
| 67 | 78 | ||
| 68 | if (nowayout) | 79 | if (nowayout) |
| @@ -84,23 +95,21 @@ static int indydog_release(struct inode *inode, struct file *file) | |||
| 84 | * Lock it in if it's a module and we defined ...NOWAYOUT */ | 95 | * Lock it in if it's a module and we defined ...NOWAYOUT */ |
| 85 | if (!nowayout) | 96 | if (!nowayout) |
| 86 | indydog_stop(); /* Turn the WDT off */ | 97 | indydog_stop(); /* Turn the WDT off */ |
| 87 | 98 | clear_bit(0, &indydog_alive); | |
| 88 | indydog_alive = 0; | ||
| 89 | |||
| 90 | return 0; | 99 | return 0; |
| 91 | } | 100 | } |
| 92 | 101 | ||
| 93 | static ssize_t indydog_write(struct file *file, const char *data, size_t len, loff_t *ppos) | 102 | static ssize_t indydog_write(struct file *file, const char *data, |
| 103 | size_t len, loff_t *ppos) | ||
| 94 | { | 104 | { |
| 95 | /* Refresh the timer. */ | 105 | /* Refresh the timer. */ |
| 96 | if (len) { | 106 | if (len) |
| 97 | indydog_ping(); | 107 | indydog_ping(); |
| 98 | } | ||
| 99 | return len; | 108 | return len; |
| 100 | } | 109 | } |
| 101 | 110 | ||
| 102 | static int indydog_ioctl(struct inode *inode, struct file *file, | 111 | static long indydog_ioctl(struct file *file, unsigned int cmd, |
| 103 | unsigned int cmd, unsigned long arg) | 112 | unsigned long arg) |
| 104 | { | 113 | { |
| 105 | int options, retval = -EINVAL; | 114 | int options, retval = -EINVAL; |
| 106 | static struct watchdog_info ident = { | 115 | static struct watchdog_info ident = { |
| @@ -111,42 +120,40 @@ static int indydog_ioctl(struct inode *inode, struct file *file, | |||
| 111 | }; | 120 | }; |
| 112 | 121 | ||
| 113 | switch (cmd) { | 122 | switch (cmd) { |
| 114 | default: | 123 | case WDIOC_GETSUPPORT: |
| 115 | return -ENOTTY; | 124 | if (copy_to_user((struct watchdog_info *)arg, |
| 116 | case WDIOC_GETSUPPORT: | 125 | &ident, sizeof(ident))) |
| 117 | if (copy_to_user((struct watchdog_info *)arg, | 126 | return -EFAULT; |
| 118 | &ident, sizeof(ident))) | 127 | return 0; |
| 119 | return -EFAULT; | 128 | case WDIOC_GETSTATUS: |
| 120 | return 0; | 129 | case WDIOC_GETBOOTSTATUS: |
| 121 | case WDIOC_GETSTATUS: | 130 | return put_user(0, (int *)arg); |
| 122 | case WDIOC_GETBOOTSTATUS: | 131 | case WDIOC_SETOPTIONS: |
| 123 | return put_user(0,(int *)arg); | 132 | { |
| 124 | case WDIOC_KEEPALIVE: | 133 | if (get_user(options, (int *)arg)) |
| 125 | indydog_ping(); | 134 | return -EFAULT; |
| 126 | return 0; | 135 | if (options & WDIOS_DISABLECARD) { |
| 127 | case WDIOC_GETTIMEOUT: | 136 | indydog_stop(); |
| 128 | return put_user(WATCHDOG_TIMEOUT,(int *)arg); | 137 | retval = 0; |
| 129 | case WDIOC_SETOPTIONS: | ||
| 130 | { | ||
| 131 | if (get_user(options, (int *)arg)) | ||
| 132 | return -EFAULT; | ||
| 133 | |||
| 134 | if (options & WDIOS_DISABLECARD) { | ||
| 135 | indydog_stop(); | ||
| 136 | retval = 0; | ||
| 137 | } | ||
| 138 | |||
| 139 | if (options & WDIOS_ENABLECARD) { | ||
| 140 | indydog_start(); | ||
| 141 | retval = 0; | ||
| 142 | } | ||
| 143 | |||
| 144 | return retval; | ||
| 145 | } | 138 | } |
| 139 | if (options & WDIOS_ENABLECARD) { | ||
| 140 | indydog_start(); | ||
| 141 | retval = 0; | ||
| 142 | } | ||
| 143 | return retval; | ||
| 144 | } | ||
| 145 | case WDIOC_KEEPALIVE: | ||
| 146 | indydog_ping(); | ||
| 147 | return 0; | ||
| 148 | case WDIOC_GETTIMEOUT: | ||
| 149 | return put_user(WATCHDOG_TIMEOUT, (int *)arg); | ||
| 150 | default: | ||
| 151 | return -ENOTTY; | ||
| 146 | } | 152 | } |
| 147 | } | 153 | } |
| 148 | 154 | ||
| 149 | static int indydog_notify_sys(struct notifier_block *this, unsigned long code, void *unused) | 155 | static int indydog_notify_sys(struct notifier_block *this, |
| 156 | unsigned long code, void *unused) | ||
| 150 | { | 157 | { |
| 151 | if (code == SYS_DOWN || code == SYS_HALT) | 158 | if (code == SYS_DOWN || code == SYS_HALT) |
| 152 | indydog_stop(); /* Turn the WDT off */ | 159 | indydog_stop(); /* Turn the WDT off */ |
| @@ -158,7 +165,7 @@ static const struct file_operations indydog_fops = { | |||
| 158 | .owner = THIS_MODULE, | 165 | .owner = THIS_MODULE, |
| 159 | .llseek = no_llseek, | 166 | .llseek = no_llseek, |
| 160 | .write = indydog_write, | 167 | .write = indydog_write, |
| 161 | .ioctl = indydog_ioctl, | 168 | .unlocked_ioctl = indydog_ioctl, |
| 162 | .open = indydog_open, | 169 | .open = indydog_open, |
| 163 | .release = indydog_release, | 170 | .release = indydog_release, |
| 164 | }; | 171 | }; |
| @@ -180,17 +187,20 @@ static int __init watchdog_init(void) | |||
| 180 | { | 187 | { |
| 181 | int ret; | 188 | int ret; |
| 182 | 189 | ||
| 190 | spin_lock_init(&indydog_lock); | ||
| 191 | |||
| 183 | ret = register_reboot_notifier(&indydog_notifier); | 192 | ret = register_reboot_notifier(&indydog_notifier); |
| 184 | if (ret) { | 193 | if (ret) { |
| 185 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 194 | printk(KERN_ERR PFX |
| 186 | ret); | 195 | "cannot register reboot notifier (err=%d)\n", ret); |
| 187 | return ret; | 196 | return ret; |
| 188 | } | 197 | } |
| 189 | 198 | ||
| 190 | ret = misc_register(&indydog_miscdev); | 199 | ret = misc_register(&indydog_miscdev); |
| 191 | if (ret) { | 200 | if (ret) { |
| 192 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 201 | printk(KERN_ERR PFX |
| 193 | WATCHDOG_MINOR, ret); | 202 | "cannot register miscdev on minor=%d (err=%d)\n", |
| 203 | WATCHDOG_MINOR, ret); | ||
| 194 | unregister_reboot_notifier(&indydog_notifier); | 204 | unregister_reboot_notifier(&indydog_notifier); |
| 195 | return ret; | 205 | return ret; |
| 196 | } | 206 | } |
diff --git a/drivers/watchdog/iop_wdt.c b/drivers/watchdog/iop_wdt.c index 1946dd06d815..96eb2cbe5874 100644 --- a/drivers/watchdog/iop_wdt.c +++ b/drivers/watchdog/iop_wdt.c | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | static int nowayout = WATCHDOG_NOWAYOUT; | 37 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 38 | static unsigned long wdt_status; | 38 | static unsigned long wdt_status; |
| 39 | static unsigned long boot_status; | 39 | static unsigned long boot_status; |
| 40 | static spinlock_t wdt_lock; | ||
| 40 | 41 | ||
| 41 | #define WDT_IN_USE 0 | 42 | #define WDT_IN_USE 0 |
| 42 | #define WDT_OK_TO_CLOSE 1 | 43 | #define WDT_OK_TO_CLOSE 1 |
| @@ -68,8 +69,10 @@ static void wdt_enable(void) | |||
| 68 | /* Arm and enable the Timer to starting counting down from 0xFFFF.FFFF | 69 | /* Arm and enable the Timer to starting counting down from 0xFFFF.FFFF |
| 69 | * Takes approx. 10.7s to timeout | 70 | * Takes approx. 10.7s to timeout |
| 70 | */ | 71 | */ |
| 72 | spin_lock(&wdt_lock); | ||
| 71 | write_wdtcr(IOP_WDTCR_EN_ARM); | 73 | write_wdtcr(IOP_WDTCR_EN_ARM); |
| 72 | write_wdtcr(IOP_WDTCR_EN); | 74 | write_wdtcr(IOP_WDTCR_EN); |
| 75 | spin_unlock(&wdt_lock); | ||
| 73 | } | 76 | } |
| 74 | 77 | ||
| 75 | /* returns 0 if the timer was successfully disabled */ | 78 | /* returns 0 if the timer was successfully disabled */ |
| @@ -77,9 +80,11 @@ static int wdt_disable(void) | |||
| 77 | { | 80 | { |
| 78 | /* Stop Counting */ | 81 | /* Stop Counting */ |
| 79 | if (wdt_supports_disable()) { | 82 | if (wdt_supports_disable()) { |
| 83 | spin_lock(&wdt_lock); | ||
| 80 | write_wdtcr(IOP_WDTCR_DIS_ARM); | 84 | write_wdtcr(IOP_WDTCR_DIS_ARM); |
| 81 | write_wdtcr(IOP_WDTCR_DIS); | 85 | write_wdtcr(IOP_WDTCR_DIS); |
| 82 | clear_bit(WDT_ENABLED, &wdt_status); | 86 | clear_bit(WDT_ENABLED, &wdt_status); |
| 87 | spin_unlock(&wdt_lock); | ||
| 83 | printk(KERN_INFO "WATCHDOG: Disabled\n"); | 88 | printk(KERN_INFO "WATCHDOG: Disabled\n"); |
| 84 | return 0; | 89 | return 0; |
| 85 | } else | 90 | } else |
| @@ -92,16 +97,12 @@ static int iop_wdt_open(struct inode *inode, struct file *file) | |||
| 92 | return -EBUSY; | 97 | return -EBUSY; |
| 93 | 98 | ||
| 94 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | 99 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); |
| 95 | |||
| 96 | wdt_enable(); | 100 | wdt_enable(); |
| 97 | |||
| 98 | set_bit(WDT_ENABLED, &wdt_status); | 101 | set_bit(WDT_ENABLED, &wdt_status); |
| 99 | |||
| 100 | return nonseekable_open(inode, file); | 102 | return nonseekable_open(inode, file); |
| 101 | } | 103 | } |
| 102 | 104 | ||
| 103 | static ssize_t | 105 | static ssize_t iop_wdt_write(struct file *file, const char *data, size_t len, |
| 104 | iop_wdt_write(struct file *file, const char *data, size_t len, | ||
| 105 | loff_t *ppos) | 106 | loff_t *ppos) |
| 106 | { | 107 | { |
| 107 | if (len) { | 108 | if (len) { |
| @@ -121,46 +122,35 @@ iop_wdt_write(struct file *file, const char *data, size_t len, | |||
| 121 | } | 122 | } |
| 122 | wdt_enable(); | 123 | wdt_enable(); |
| 123 | } | 124 | } |
| 124 | |||
| 125 | return len; | 125 | return len; |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | static struct watchdog_info ident = { | 128 | static const struct watchdog_info ident = { |
| 129 | .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, | 129 | .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, |
| 130 | .identity = "iop watchdog", | 130 | .identity = "iop watchdog", |
| 131 | }; | 131 | }; |
| 132 | 132 | ||
| 133 | static int | 133 | static long iop_wdt_ioctl(struct file *file, |
| 134 | iop_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 134 | unsigned int cmd, unsigned long arg) |
| 135 | unsigned long arg) | ||
| 136 | { | 135 | { |
| 137 | int options; | 136 | int options; |
| 138 | int ret = -ENOTTY; | 137 | int ret = -ENOTTY; |
| 138 | int __user *argp = (int __user *)arg; | ||
| 139 | 139 | ||
| 140 | switch (cmd) { | 140 | switch (cmd) { |
| 141 | case WDIOC_GETSUPPORT: | 141 | case WDIOC_GETSUPPORT: |
| 142 | if (copy_to_user | 142 | if (copy_to_user(argp, &ident, sizeof ident)) |
| 143 | ((struct watchdog_info *)arg, &ident, sizeof ident)) | ||
| 144 | ret = -EFAULT; | 143 | ret = -EFAULT; |
| 145 | else | 144 | else |
| 146 | ret = 0; | 145 | ret = 0; |
| 147 | break; | 146 | break; |
| 148 | 147 | ||
| 149 | case WDIOC_GETSTATUS: | 148 | case WDIOC_GETSTATUS: |
| 150 | ret = put_user(0, (int *)arg); | 149 | ret = put_user(0, argp); |
| 151 | break; | 150 | break; |
| 152 | 151 | ||
| 153 | case WDIOC_GETBOOTSTATUS: | 152 | case WDIOC_GETBOOTSTATUS: |
| 154 | ret = put_user(boot_status, (int *)arg); | 153 | ret = put_user(boot_status, argp); |
| 155 | break; | ||
| 156 | |||
| 157 | case WDIOC_GETTIMEOUT: | ||
| 158 | ret = put_user(iop_watchdog_timeout(), (int *)arg); | ||
| 159 | break; | ||
| 160 | |||
| 161 | case WDIOC_KEEPALIVE: | ||
| 162 | wdt_enable(); | ||
| 163 | ret = 0; | ||
| 164 | break; | 154 | break; |
| 165 | 155 | ||
| 166 | case WDIOC_SETOPTIONS: | 156 | case WDIOC_SETOPTIONS: |
| @@ -177,14 +167,21 @@ iop_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
| 177 | } else | 167 | } else |
| 178 | ret = 0; | 168 | ret = 0; |
| 179 | } | 169 | } |
| 180 | |||
| 181 | if (options & WDIOS_ENABLECARD) { | 170 | if (options & WDIOS_ENABLECARD) { |
| 182 | wdt_enable(); | 171 | wdt_enable(); |
| 183 | ret = 0; | 172 | ret = 0; |
| 184 | } | 173 | } |
| 185 | break; | 174 | break; |
| 186 | } | ||
| 187 | 175 | ||
| 176 | case WDIOC_KEEPALIVE: | ||
| 177 | wdt_enable(); | ||
| 178 | ret = 0; | ||
| 179 | break; | ||
| 180 | |||
| 181 | case WDIOC_GETTIMEOUT: | ||
| 182 | ret = put_user(iop_watchdog_timeout(), argp); | ||
| 183 | break; | ||
| 184 | } | ||
| 188 | return ret; | 185 | return ret; |
| 189 | } | 186 | } |
| 190 | 187 | ||
| @@ -214,7 +211,7 @@ static const struct file_operations iop_wdt_fops = { | |||
| 214 | .owner = THIS_MODULE, | 211 | .owner = THIS_MODULE, |
| 215 | .llseek = no_llseek, | 212 | .llseek = no_llseek, |
| 216 | .write = iop_wdt_write, | 213 | .write = iop_wdt_write, |
| 217 | .ioctl = iop_wdt_ioctl, | 214 | .unlocked_ioctl = iop_wdt_ioctl, |
| 218 | .open = iop_wdt_open, | 215 | .open = iop_wdt_open, |
| 219 | .release = iop_wdt_release, | 216 | .release = iop_wdt_release, |
| 220 | }; | 217 | }; |
| @@ -229,10 +226,8 @@ static int __init iop_wdt_init(void) | |||
| 229 | { | 226 | { |
| 230 | int ret; | 227 | int ret; |
| 231 | 228 | ||
| 232 | ret = misc_register(&iop_wdt_miscdev); | 229 | spin_lock_init(&wdt_lock); |
| 233 | if (ret == 0) | 230 | |
| 234 | printk("iop watchdog timer: timeout %lu sec\n", | ||
| 235 | iop_watchdog_timeout()); | ||
| 236 | 231 | ||
| 237 | /* check if the reset was caused by the watchdog timer */ | 232 | /* check if the reset was caused by the watchdog timer */ |
| 238 | boot_status = (read_rcsr() & IOP_RCSR_WDT) ? WDIOF_CARDRESET : 0; | 233 | boot_status = (read_rcsr() & IOP_RCSR_WDT) ? WDIOF_CARDRESET : 0; |
| @@ -242,6 +237,13 @@ static int __init iop_wdt_init(void) | |||
| 242 | */ | 237 | */ |
| 243 | write_wdtsr(IOP13XX_WDTCR_IB_RESET); | 238 | write_wdtsr(IOP13XX_WDTCR_IB_RESET); |
| 244 | 239 | ||
| 240 | /* Register after we have the device set up so we cannot race | ||
| 241 | with an open */ | ||
| 242 | ret = misc_register(&iop_wdt_miscdev); | ||
| 243 | if (ret == 0) | ||
| 244 | printk(KERN_INFO "iop watchdog timer: timeout %lu sec\n", | ||
| 245 | iop_watchdog_timeout()); | ||
| 246 | |||
| 245 | return ret; | 247 | return ret; |
| 246 | } | 248 | } |
| 247 | 249 | ||
diff --git a/drivers/watchdog/it8712f_wdt.c b/drivers/watchdog/it8712f_wdt.c index 51bfd5721833..2270ee07c01b 100644 --- a/drivers/watchdog/it8712f_wdt.c +++ b/drivers/watchdog/it8712f_wdt.c | |||
| @@ -221,7 +221,7 @@ static ssize_t it8712f_wdt_write(struct file *file, const char __user *data, | |||
| 221 | expect_close = 0; | 221 | expect_close = 0; |
| 222 | for (i = 0; i < len; ++i) { | 222 | for (i = 0; i < len; ++i) { |
| 223 | char c; | 223 | char c; |
| 224 | if (get_user(c, data+i)) | 224 | if (get_user(c, data + i)) |
| 225 | return -EFAULT; | 225 | return -EFAULT; |
| 226 | if (c == 'V') | 226 | if (c == 'V') |
| 227 | expect_close = 42; | 227 | expect_close = 42; |
| @@ -244,8 +244,6 @@ static long it8712f_wdt_ioctl(struct file *file, unsigned int cmd, | |||
| 244 | int value; | 244 | int value; |
| 245 | 245 | ||
| 246 | switch (cmd) { | 246 | switch (cmd) { |
| 247 | default: | ||
| 248 | return -ENOTTY; | ||
| 249 | case WDIOC_GETSUPPORT: | 247 | case WDIOC_GETSUPPORT: |
| 250 | if (copy_to_user(argp, &ident, sizeof(ident))) | 248 | if (copy_to_user(argp, &ident, sizeof(ident))) |
| 251 | return -EFAULT; | 249 | return -EFAULT; |
| @@ -284,6 +282,8 @@ static long it8712f_wdt_ioctl(struct file *file, unsigned int cmd, | |||
| 284 | if (put_user(margin, p)) | 282 | if (put_user(margin, p)) |
| 285 | return -EFAULT; | 283 | return -EFAULT; |
| 286 | return 0; | 284 | return 0; |
| 285 | default: | ||
| 286 | return -ENOTTY; | ||
| 287 | } | 287 | } |
| 288 | } | 288 | } |
| 289 | 289 | ||
diff --git a/drivers/watchdog/ixp2000_wdt.c b/drivers/watchdog/ixp2000_wdt.c index 4226dae7d260..4f4b35a20d84 100644 --- a/drivers/watchdog/ixp2000_wdt.c +++ b/drivers/watchdog/ixp2000_wdt.c | |||
| @@ -25,42 +25,44 @@ | |||
| 25 | #include <linux/watchdog.h> | 25 | #include <linux/watchdog.h> |
| 26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
| 27 | #include <linux/bitops.h> | 27 | #include <linux/bitops.h> |
| 28 | 28 | #include <linux/uaccess.h> | |
| 29 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
| 30 | #include <asm/uaccess.h> | ||
| 31 | 30 | ||
| 32 | static int nowayout = WATCHDOG_NOWAYOUT; | 31 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 33 | static unsigned int heartbeat = 60; /* (secs) Default is 1 minute */ | 32 | static unsigned int heartbeat = 60; /* (secs) Default is 1 minute */ |
| 34 | static unsigned long wdt_status; | 33 | static unsigned long wdt_status; |
| 34 | static spinlock_t wdt_lock; | ||
| 35 | 35 | ||
| 36 | #define WDT_IN_USE 0 | 36 | #define WDT_IN_USE 0 |
| 37 | #define WDT_OK_TO_CLOSE 1 | 37 | #define WDT_OK_TO_CLOSE 1 |
| 38 | 38 | ||
| 39 | static unsigned long wdt_tick_rate; | 39 | static unsigned long wdt_tick_rate; |
| 40 | 40 | ||
| 41 | static void | 41 | static void wdt_enable(void) |
| 42 | wdt_enable(void) | ||
| 43 | { | 42 | { |
| 43 | spin_lock(&wdt_lock); | ||
| 44 | ixp2000_reg_write(IXP2000_RESET0, *(IXP2000_RESET0) | WDT_RESET_ENABLE); | 44 | ixp2000_reg_write(IXP2000_RESET0, *(IXP2000_RESET0) | WDT_RESET_ENABLE); |
| 45 | ixp2000_reg_write(IXP2000_TWDE, WDT_ENABLE); | 45 | ixp2000_reg_write(IXP2000_TWDE, WDT_ENABLE); |
| 46 | ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate); | 46 | ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate); |
| 47 | ixp2000_reg_write(IXP2000_T4_CTL, TIMER_DIVIDER_256 | TIMER_ENABLE); | 47 | ixp2000_reg_write(IXP2000_T4_CTL, TIMER_DIVIDER_256 | TIMER_ENABLE); |
| 48 | spin_unlock(&wdt_lock); | ||
| 48 | } | 49 | } |
| 49 | 50 | ||
| 50 | static void | 51 | static void wdt_disable(void) |
| 51 | wdt_disable(void) | ||
| 52 | { | 52 | { |
| 53 | spin_lock(&wdt_lock); | ||
| 53 | ixp2000_reg_write(IXP2000_T4_CTL, 0); | 54 | ixp2000_reg_write(IXP2000_T4_CTL, 0); |
| 55 | spin_unlock(&wdt_lock); | ||
| 54 | } | 56 | } |
| 55 | 57 | ||
| 56 | static void | 58 | static void wdt_keepalive(void) |
| 57 | wdt_keepalive(void) | ||
| 58 | { | 59 | { |
| 60 | spin_lock(&wdt_lock); | ||
| 59 | ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate); | 61 | ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate); |
| 62 | spin_unlock(&wdt_lock); | ||
| 60 | } | 63 | } |
| 61 | 64 | ||
| 62 | static int | 65 | static int ixp2000_wdt_open(struct inode *inode, struct file *file) |
| 63 | ixp2000_wdt_open(struct inode *inode, struct file *file) | ||
| 64 | { | 66 | { |
| 65 | if (test_and_set_bit(WDT_IN_USE, &wdt_status)) | 67 | if (test_and_set_bit(WDT_IN_USE, &wdt_status)) |
| 66 | return -EBUSY; | 68 | return -EBUSY; |
| @@ -72,8 +74,8 @@ ixp2000_wdt_open(struct inode *inode, struct file *file) | |||
| 72 | return nonseekable_open(inode, file); | 74 | return nonseekable_open(inode, file); |
| 73 | } | 75 | } |
| 74 | 76 | ||
| 75 | static ssize_t | 77 | static ssize_t ixp2000_wdt_write(struct file *file, const char *data, |
| 76 | ixp2000_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) | 78 | size_t len, loff_t *ppos) |
| 77 | { | 79 | { |
| 78 | if (len) { | 80 | if (len) { |
| 79 | if (!nowayout) { | 81 | if (!nowayout) { |
| @@ -103,9 +105,8 @@ static struct watchdog_info ident = { | |||
| 103 | .identity = "IXP2000 Watchdog", | 105 | .identity = "IXP2000 Watchdog", |
| 104 | }; | 106 | }; |
| 105 | 107 | ||
| 106 | static int | 108 | static long ixp2000_wdt_ioctl(struct file *file, unsigned int cmd, |
| 107 | ixp2000_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 109 | unsigned long arg) |
| 108 | unsigned long arg) | ||
| 109 | { | 110 | { |
| 110 | int ret = -ENOTTY; | 111 | int ret = -ENOTTY; |
| 111 | int time; | 112 | int time; |
| @@ -124,6 +125,11 @@ ixp2000_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
| 124 | ret = put_user(0, (int *)arg); | 125 | ret = put_user(0, (int *)arg); |
| 125 | break; | 126 | break; |
| 126 | 127 | ||
| 128 | case WDIOC_KEEPALIVE: | ||
| 129 | wdt_enable(); | ||
| 130 | ret = 0; | ||
| 131 | break; | ||
| 132 | |||
| 127 | case WDIOC_SETTIMEOUT: | 133 | case WDIOC_SETTIMEOUT: |
| 128 | ret = get_user(time, (int *)arg); | 134 | ret = get_user(time, (int *)arg); |
| 129 | if (ret) | 135 | if (ret) |
| @@ -141,26 +147,18 @@ ixp2000_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
| 141 | case WDIOC_GETTIMEOUT: | 147 | case WDIOC_GETTIMEOUT: |
| 142 | ret = put_user(heartbeat, (int *)arg); | 148 | ret = put_user(heartbeat, (int *)arg); |
| 143 | break; | 149 | break; |
| 144 | |||
| 145 | case WDIOC_KEEPALIVE: | ||
| 146 | wdt_enable(); | ||
| 147 | ret = 0; | ||
| 148 | break; | ||
| 149 | } | 150 | } |
| 150 | 151 | ||
| 151 | return ret; | 152 | return ret; |
| 152 | } | 153 | } |
| 153 | 154 | ||
| 154 | static int | 155 | static int ixp2000_wdt_release(struct inode *inode, struct file *file) |
| 155 | ixp2000_wdt_release(struct inode *inode, struct file *file) | ||
| 156 | { | 156 | { |
| 157 | if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) { | 157 | if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) |
| 158 | wdt_disable(); | 158 | wdt_disable(); |
| 159 | } else { | 159 | else |
| 160 | printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " | 160 | printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " |
| 161 | "timer will not stop\n"); | 161 | "timer will not stop\n"); |
| 162 | } | ||
| 163 | |||
| 164 | clear_bit(WDT_IN_USE, &wdt_status); | 162 | clear_bit(WDT_IN_USE, &wdt_status); |
| 165 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | 163 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); |
| 166 | 164 | ||
| @@ -168,18 +166,16 @@ ixp2000_wdt_release(struct inode *inode, struct file *file) | |||
| 168 | } | 166 | } |
| 169 | 167 | ||
| 170 | 168 | ||
| 171 | static const struct file_operations ixp2000_wdt_fops = | 169 | static const struct file_operations ixp2000_wdt_fops = { |
| 172 | { | ||
| 173 | .owner = THIS_MODULE, | 170 | .owner = THIS_MODULE, |
| 174 | .llseek = no_llseek, | 171 | .llseek = no_llseek, |
| 175 | .write = ixp2000_wdt_write, | 172 | .write = ixp2000_wdt_write, |
| 176 | .ioctl = ixp2000_wdt_ioctl, | 173 | .unlocked_ioctl = ixp2000_wdt_ioctl, |
| 177 | .open = ixp2000_wdt_open, | 174 | .open = ixp2000_wdt_open, |
| 178 | .release = ixp2000_wdt_release, | 175 | .release = ixp2000_wdt_release, |
| 179 | }; | 176 | }; |
| 180 | 177 | ||
| 181 | static struct miscdevice ixp2000_wdt_miscdev = | 178 | static struct miscdevice ixp2000_wdt_miscdev = { |
| 182 | { | ||
| 183 | .minor = WATCHDOG_MINOR, | 179 | .minor = WATCHDOG_MINOR, |
| 184 | .name = "watchdog", | 180 | .name = "watchdog", |
| 185 | .fops = &ixp2000_wdt_fops, | 181 | .fops = &ixp2000_wdt_fops, |
| @@ -191,9 +187,8 @@ static int __init ixp2000_wdt_init(void) | |||
| 191 | printk(KERN_INFO "Unable to use IXP2000 watchdog due to IXP2800 erratum #25.\n"); | 187 | printk(KERN_INFO "Unable to use IXP2000 watchdog due to IXP2800 erratum #25.\n"); |
| 192 | return -EIO; | 188 | return -EIO; |
| 193 | } | 189 | } |
| 194 | |||
| 195 | wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256; | 190 | wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256; |
| 196 | 191 | spin_lock_init(&wdt_lock); | |
| 197 | return misc_register(&ixp2000_wdt_miscdev); | 192 | return misc_register(&ixp2000_wdt_miscdev); |
| 198 | } | 193 | } |
| 199 | 194 | ||
diff --git a/drivers/watchdog/ixp4xx_wdt.c b/drivers/watchdog/ixp4xx_wdt.c index 2313fad0dbb1..41264a5f1731 100644 --- a/drivers/watchdog/ixp4xx_wdt.c +++ b/drivers/watchdog/ixp4xx_wdt.c | |||
| @@ -22,48 +22,47 @@ | |||
| 22 | #include <linux/watchdog.h> | 22 | #include <linux/watchdog.h> |
| 23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
| 24 | #include <linux/bitops.h> | 24 | #include <linux/bitops.h> |
| 25 | 25 | #include <linux/uaccess.h> | |
| 26 | #include <mach/hardware.h> | 26 | #include <mach/hardware.h> |
| 27 | #include <asm/uaccess.h> | ||
| 28 | 27 | ||
| 29 | static int nowayout = WATCHDOG_NOWAYOUT; | 28 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 30 | static int heartbeat = 60; /* (secs) Default is 1 minute */ | 29 | static int heartbeat = 60; /* (secs) Default is 1 minute */ |
| 31 | static unsigned long wdt_status; | 30 | static unsigned long wdt_status; |
| 32 | static unsigned long boot_status; | 31 | static unsigned long boot_status; |
| 32 | static spin_lock_t wdt_lock; | ||
| 33 | 33 | ||
| 34 | #define WDT_TICK_RATE (IXP4XX_PERIPHERAL_BUS_CLOCK * 1000000UL) | 34 | #define WDT_TICK_RATE (IXP4XX_PERIPHERAL_BUS_CLOCK * 1000000UL) |
| 35 | 35 | ||
| 36 | #define WDT_IN_USE 0 | 36 | #define WDT_IN_USE 0 |
| 37 | #define WDT_OK_TO_CLOSE 1 | 37 | #define WDT_OK_TO_CLOSE 1 |
| 38 | 38 | ||
| 39 | static void | 39 | static void wdt_enable(void) |
| 40 | wdt_enable(void) | ||
| 41 | { | 40 | { |
| 41 | spin_lock(&wdt_lock); | ||
| 42 | *IXP4XX_OSWK = IXP4XX_WDT_KEY; | 42 | *IXP4XX_OSWK = IXP4XX_WDT_KEY; |
| 43 | *IXP4XX_OSWE = 0; | 43 | *IXP4XX_OSWE = 0; |
| 44 | *IXP4XX_OSWT = WDT_TICK_RATE * heartbeat; | 44 | *IXP4XX_OSWT = WDT_TICK_RATE * heartbeat; |
| 45 | *IXP4XX_OSWE = IXP4XX_WDT_COUNT_ENABLE | IXP4XX_WDT_RESET_ENABLE; | 45 | *IXP4XX_OSWE = IXP4XX_WDT_COUNT_ENABLE | IXP4XX_WDT_RESET_ENABLE; |
| 46 | *IXP4XX_OSWK = 0; | 46 | *IXP4XX_OSWK = 0; |
| 47 | spin_unlock(&wdt_lock); | ||
| 47 | } | 48 | } |
| 48 | 49 | ||
| 49 | static void | 50 | static void wdt_disable(void) |
| 50 | wdt_disable(void) | ||
| 51 | { | 51 | { |
| 52 | spin_lock(&wdt_lock); | ||
| 52 | *IXP4XX_OSWK = IXP4XX_WDT_KEY; | 53 | *IXP4XX_OSWK = IXP4XX_WDT_KEY; |
| 53 | *IXP4XX_OSWE = 0; | 54 | *IXP4XX_OSWE = 0; |
| 54 | *IXP4XX_OSWK = 0; | 55 | *IXP4XX_OSWK = 0; |
| 56 | spin_unlock(&wdt_lock); | ||
| 55 | } | 57 | } |
| 56 | 58 | ||
| 57 | static int | 59 | static int ixp4xx_wdt_open(struct inode *inode, struct file *file) |
| 58 | ixp4xx_wdt_open(struct inode *inode, struct file *file) | ||
| 59 | { | 60 | { |
| 60 | if (test_and_set_bit(WDT_IN_USE, &wdt_status)) | 61 | if (test_and_set_bit(WDT_IN_USE, &wdt_status)) |
| 61 | return -EBUSY; | 62 | return -EBUSY; |
| 62 | 63 | ||
| 63 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | 64 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); |
| 64 | |||
| 65 | wdt_enable(); | 65 | wdt_enable(); |
| 66 | |||
| 67 | return nonseekable_open(inode, file); | 66 | return nonseekable_open(inode, file); |
| 68 | } | 67 | } |
| 69 | 68 | ||
| @@ -87,7 +86,6 @@ ixp4xx_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) | |||
| 87 | } | 86 | } |
| 88 | wdt_enable(); | 87 | wdt_enable(); |
| 89 | } | 88 | } |
| 90 | |||
| 91 | return len; | 89 | return len; |
| 92 | } | 90 | } |
| 93 | 91 | ||
| @@ -98,9 +96,8 @@ static struct watchdog_info ident = { | |||
| 98 | }; | 96 | }; |
| 99 | 97 | ||
| 100 | 98 | ||
| 101 | static int | 99 | static long ixp4xx_wdt_ioctl(struct file *file, unsigned int cmd, |
| 102 | ixp4xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 100 | unsigned long arg) |
| 103 | unsigned long arg) | ||
| 104 | { | 101 | { |
| 105 | int ret = -ENOTTY; | 102 | int ret = -ENOTTY; |
| 106 | int time; | 103 | int time; |
| @@ -119,6 +116,11 @@ ixp4xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
| 119 | ret = put_user(boot_status, (int *)arg); | 116 | ret = put_user(boot_status, (int *)arg); |
| 120 | break; | 117 | break; |
| 121 | 118 | ||
| 119 | case WDIOC_KEEPALIVE: | ||
| 120 | wdt_enable(); | ||
| 121 | ret = 0; | ||
| 122 | break; | ||
| 123 | |||
| 122 | case WDIOC_SETTIMEOUT: | 124 | case WDIOC_SETTIMEOUT: |
| 123 | ret = get_user(time, (int *)arg); | 125 | ret = get_user(time, (int *)arg); |
| 124 | if (ret) | 126 | if (ret) |
| @@ -136,25 +138,17 @@ ixp4xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
| 136 | case WDIOC_GETTIMEOUT: | 138 | case WDIOC_GETTIMEOUT: |
| 137 | ret = put_user(heartbeat, (int *)arg); | 139 | ret = put_user(heartbeat, (int *)arg); |
| 138 | break; | 140 | break; |
| 139 | |||
| 140 | case WDIOC_KEEPALIVE: | ||
| 141 | wdt_enable(); | ||
| 142 | ret = 0; | ||
| 143 | break; | ||
| 144 | } | 141 | } |
| 145 | return ret; | 142 | return ret; |
| 146 | } | 143 | } |
| 147 | 144 | ||
| 148 | static int | 145 | static int ixp4xx_wdt_release(struct inode *inode, struct file *file) |
| 149 | ixp4xx_wdt_release(struct inode *inode, struct file *file) | ||
| 150 | { | 146 | { |
| 151 | if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) { | 147 | if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) |
| 152 | wdt_disable(); | 148 | wdt_disable(); |
| 153 | } else { | 149 | else |
| 154 | printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " | 150 | printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " |
| 155 | "timer will not stop\n"); | 151 | "timer will not stop\n"); |
| 156 | } | ||
| 157 | |||
| 158 | clear_bit(WDT_IN_USE, &wdt_status); | 152 | clear_bit(WDT_IN_USE, &wdt_status); |
| 159 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | 153 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); |
| 160 | 154 | ||
| @@ -162,18 +156,16 @@ ixp4xx_wdt_release(struct inode *inode, struct file *file) | |||
| 162 | } | 156 | } |
| 163 | 157 | ||
| 164 | 158 | ||
| 165 | static const struct file_operations ixp4xx_wdt_fops = | 159 | static const struct file_operations ixp4xx_wdt_fops = { |
| 166 | { | ||
| 167 | .owner = THIS_MODULE, | 160 | .owner = THIS_MODULE, |
| 168 | .llseek = no_llseek, | 161 | .llseek = no_llseek, |
| 169 | .write = ixp4xx_wdt_write, | 162 | .write = ixp4xx_wdt_write, |
| 170 | .ioctl = ixp4xx_wdt_ioctl, | 163 | .unlocked_ioctl = ixp4xx_wdt_ioctl, |
| 171 | .open = ixp4xx_wdt_open, | 164 | .open = ixp4xx_wdt_open, |
| 172 | .release = ixp4xx_wdt_release, | 165 | .release = ixp4xx_wdt_release, |
| 173 | }; | 166 | }; |
| 174 | 167 | ||
| 175 | static struct miscdevice ixp4xx_wdt_miscdev = | 168 | static struct miscdevice ixp4xx_wdt_miscdev = { |
| 176 | { | ||
| 177 | .minor = WATCHDOG_MINOR, | 169 | .minor = WATCHDOG_MINOR, |
| 178 | .name = "watchdog", | 170 | .name = "watchdog", |
| 179 | .fops = &ixp4xx_wdt_fops, | 171 | .fops = &ixp4xx_wdt_fops, |
| @@ -186,19 +178,18 @@ static int __init ixp4xx_wdt_init(void) | |||
| 186 | 178 | ||
| 187 | asm("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(processor_id) :); | 179 | asm("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(processor_id) :); |
| 188 | if (!(processor_id & 0xf) && !cpu_is_ixp46x()) { | 180 | if (!(processor_id & 0xf) && !cpu_is_ixp46x()) { |
| 189 | printk("IXP4XXX Watchdog: Rev. A0 IXP42x CPU detected - " | 181 | printk(KERN_ERR "IXP4XXX Watchdog: Rev. A0 IXP42x CPU detected" |
| 190 | "watchdog disabled\n"); | 182 | " - watchdog disabled\n"); |
| 191 | 183 | ||
| 192 | return -ENODEV; | 184 | return -ENODEV; |
| 193 | } | 185 | } |
| 194 | 186 | spin_lock_init(&wdt_lock); | |
| 195 | ret = misc_register(&ixp4xx_wdt_miscdev); | ||
| 196 | if (ret == 0) | ||
| 197 | printk("IXP4xx Watchdog Timer: heartbeat %d sec\n", heartbeat); | ||
| 198 | |||
| 199 | boot_status = (*IXP4XX_OSST & IXP4XX_OSST_TIMER_WARM_RESET) ? | 187 | boot_status = (*IXP4XX_OSST & IXP4XX_OSST_TIMER_WARM_RESET) ? |
| 200 | WDIOF_CARDRESET : 0; | 188 | WDIOF_CARDRESET : 0; |
| 201 | 189 | ret = misc_register(&ixp4xx_wdt_miscdev); | |
| 190 | if (ret == 0) | ||
| 191 | printk(KERN_INFO "IXP4xx Watchdog Timer: heartbeat %d sec\n", | ||
| 192 | heartbeat); | ||
| 202 | return ret; | 193 | return ret; |
| 203 | } | 194 | } |
| 204 | 195 | ||
diff --git a/drivers/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c index d21a6407fe21..0b798fdaa378 100644 --- a/drivers/watchdog/ks8695_wdt.c +++ b/drivers/watchdog/ks8695_wdt.c | |||
| @@ -19,11 +19,10 @@ | |||
| 19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
| 20 | #include <linux/types.h> | 20 | #include <linux/types.h> |
| 21 | #include <linux/watchdog.h> | 21 | #include <linux/watchdog.h> |
| 22 | #include <asm/io.h> | 22 | #include <linux/io.h> |
| 23 | #include <asm/uaccess.h> | 23 | #include <linux/uaccess.h> |
| 24 | #include <mach/regs-timer.h> | 24 | #include <mach/regs-timer.h> |
| 25 | 25 | ||
| 26 | |||
| 27 | #define WDT_DEFAULT_TIME 5 /* seconds */ | 26 | #define WDT_DEFAULT_TIME 5 /* seconds */ |
| 28 | #define WDT_MAX_TIME 171 /* seconds */ | 27 | #define WDT_MAX_TIME 171 /* seconds */ |
| 29 | 28 | ||
| @@ -31,38 +30,44 @@ static int wdt_time = WDT_DEFAULT_TIME; | |||
| 31 | static int nowayout = WATCHDOG_NOWAYOUT; | 30 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 32 | 31 | ||
| 33 | module_param(wdt_time, int, 0); | 32 | module_param(wdt_time, int, 0); |
| 34 | MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")"); | 33 | MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default=" |
| 34 | __MODULE_STRING(WDT_DEFAULT_TIME) ")"); | ||
| 35 | 35 | ||
| 36 | #ifdef CONFIG_WATCHDOG_NOWAYOUT | 36 | #ifdef CONFIG_WATCHDOG_NOWAYOUT |
| 37 | module_param(nowayout, int, 0); | 37 | module_param(nowayout, int, 0); |
| 38 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 38 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" |
| 39 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 39 | #endif | 40 | #endif |
| 40 | 41 | ||
| 41 | 42 | ||
| 42 | static unsigned long ks8695wdt_busy; | 43 | static unsigned long ks8695wdt_busy; |
| 44 | static spinlock_t ks8695_lock; | ||
| 43 | 45 | ||
| 44 | /* ......................................................................... */ | 46 | /* ......................................................................... */ |
| 45 | 47 | ||
| 46 | /* | 48 | /* |
| 47 | * Disable the watchdog. | 49 | * Disable the watchdog. |
| 48 | */ | 50 | */ |
| 49 | static void inline ks8695_wdt_stop(void) | 51 | static inline void ks8695_wdt_stop(void) |
| 50 | { | 52 | { |
| 51 | unsigned long tmcon; | 53 | unsigned long tmcon; |
| 52 | 54 | ||
| 55 | spin_lock(&ks8695_lock); | ||
| 53 | /* disable timer0 */ | 56 | /* disable timer0 */ |
| 54 | tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); | 57 | tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); |
| 55 | __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); | 58 | __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); |
| 59 | spin_unlock(&ks8695_lock); | ||
| 56 | } | 60 | } |
| 57 | 61 | ||
| 58 | /* | 62 | /* |
| 59 | * Enable and reset the watchdog. | 63 | * Enable and reset the watchdog. |
| 60 | */ | 64 | */ |
| 61 | static void inline ks8695_wdt_start(void) | 65 | static inline void ks8695_wdt_start(void) |
| 62 | { | 66 | { |
| 63 | unsigned long tmcon; | 67 | unsigned long tmcon; |
| 64 | unsigned long tval = wdt_time * CLOCK_TICK_RATE; | 68 | unsigned long tval = wdt_time * CLOCK_TICK_RATE; |
| 65 | 69 | ||
| 70 | spin_lock(&ks8695_lock); | ||
| 66 | /* disable timer0 */ | 71 | /* disable timer0 */ |
| 67 | tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); | 72 | tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); |
| 68 | __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); | 73 | __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); |
| @@ -73,19 +78,22 @@ static void inline ks8695_wdt_start(void) | |||
| 73 | /* re-enable timer0 */ | 78 | /* re-enable timer0 */ |
| 74 | tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); | 79 | tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); |
| 75 | __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); | 80 | __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); |
| 81 | spin_unlock(&ks8695_lock); | ||
| 76 | } | 82 | } |
| 77 | 83 | ||
| 78 | /* | 84 | /* |
| 79 | * Reload the watchdog timer. (ie, pat the watchdog) | 85 | * Reload the watchdog timer. (ie, pat the watchdog) |
| 80 | */ | 86 | */ |
| 81 | static void inline ks8695_wdt_reload(void) | 87 | static inline void ks8695_wdt_reload(void) |
| 82 | { | 88 | { |
| 83 | unsigned long tmcon; | 89 | unsigned long tmcon; |
| 84 | 90 | ||
| 91 | spin_lock(&ks8695_lock); | ||
| 85 | /* disable, then re-enable timer0 */ | 92 | /* disable, then re-enable timer0 */ |
| 86 | tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); | 93 | tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); |
| 87 | __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); | 94 | __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); |
| 88 | __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); | 95 | __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); |
| 96 | spin_unlock(&ks8695_lock); | ||
| 89 | } | 97 | } |
| 90 | 98 | ||
| 91 | /* | 99 | /* |
| @@ -102,7 +110,8 @@ static int ks8695_wdt_settimeout(int new_time) | |||
| 102 | if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) | 110 | if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) |
| 103 | return -EINVAL; | 111 | return -EINVAL; |
| 104 | 112 | ||
| 105 | /* Set new watchdog time. It will be used when ks8695_wdt_start() is called. */ | 113 | /* Set new watchdog time. It will be used when |
| 114 | ks8695_wdt_start() is called. */ | ||
| 106 | wdt_time = new_time; | 115 | wdt_time = new_time; |
| 107 | return 0; | 116 | return 0; |
| 108 | } | 117 | } |
| @@ -128,9 +137,9 @@ static int ks8695_wdt_open(struct inode *inode, struct file *file) | |||
| 128 | */ | 137 | */ |
| 129 | static int ks8695_wdt_close(struct inode *inode, struct file *file) | 138 | static int ks8695_wdt_close(struct inode *inode, struct file *file) |
| 130 | { | 139 | { |
| 140 | /* Disable the watchdog when file is closed */ | ||
| 131 | if (!nowayout) | 141 | if (!nowayout) |
| 132 | ks8695_wdt_stop(); /* Disable the watchdog when file is closed */ | 142 | ks8695_wdt_stop(); |
| 133 | |||
| 134 | clear_bit(0, &ks8695wdt_busy); | 143 | clear_bit(0, &ks8695wdt_busy); |
| 135 | return 0; | 144 | return 0; |
| 136 | } | 145 | } |
| @@ -143,60 +152,52 @@ static struct watchdog_info ks8695_wdt_info = { | |||
| 143 | /* | 152 | /* |
| 144 | * Handle commands from user-space. | 153 | * Handle commands from user-space. |
| 145 | */ | 154 | */ |
| 146 | static int ks8695_wdt_ioctl(struct inode *inode, struct file *file, | 155 | static long ks8695_wdt_ioctl(struct file *file, unsigned int cmd, |
| 147 | unsigned int cmd, unsigned long arg) | 156 | unsigned long arg) |
| 148 | { | 157 | { |
| 149 | void __user *argp = (void __user *)arg; | 158 | void __user *argp = (void __user *)arg; |
| 150 | int __user *p = argp; | 159 | int __user *p = argp; |
| 151 | int new_value; | 160 | int new_value; |
| 152 | 161 | ||
| 153 | switch(cmd) { | 162 | switch (cmd) { |
| 154 | case WDIOC_KEEPALIVE: | 163 | case WDIOC_GETSUPPORT: |
| 155 | ks8695_wdt_reload(); /* pat the watchdog */ | 164 | return copy_to_user(argp, &ks8695_wdt_info, |
| 156 | return 0; | 165 | sizeof(ks8695_wdt_info)) ? -EFAULT : 0; |
| 157 | 166 | case WDIOC_GETSTATUS: | |
| 158 | case WDIOC_GETSUPPORT: | 167 | case WDIOC_GETBOOTSTATUS: |
| 159 | return copy_to_user(argp, &ks8695_wdt_info, sizeof(ks8695_wdt_info)) ? -EFAULT : 0; | 168 | return put_user(0, p); |
| 160 | 169 | case WDIOC_SETOPTIONS: | |
| 161 | case WDIOC_SETTIMEOUT: | 170 | if (get_user(new_value, p)) |
| 162 | if (get_user(new_value, p)) | 171 | return -EFAULT; |
| 163 | return -EFAULT; | 172 | if (new_value & WDIOS_DISABLECARD) |
| 164 | 173 | ks8695_wdt_stop(); | |
| 165 | if (ks8695_wdt_settimeout(new_value)) | 174 | if (new_value & WDIOS_ENABLECARD) |
| 166 | return -EINVAL; | ||
| 167 | |||
| 168 | /* Enable new time value */ | ||
| 169 | ks8695_wdt_start(); | 175 | ks8695_wdt_start(); |
| 170 | 176 | return 0; | |
| 171 | /* Return current value */ | 177 | case WDIOC_KEEPALIVE: |
| 172 | return put_user(wdt_time, p); | 178 | ks8695_wdt_reload(); /* pat the watchdog */ |
| 173 | 179 | return 0; | |
| 174 | case WDIOC_GETTIMEOUT: | 180 | case WDIOC_SETTIMEOUT: |
| 175 | return put_user(wdt_time, p); | 181 | if (get_user(new_value, p)) |
| 176 | 182 | return -EFAULT; | |
| 177 | case WDIOC_GETSTATUS: | 183 | if (ks8695_wdt_settimeout(new_value)) |
| 178 | case WDIOC_GETBOOTSTATUS: | 184 | return -EINVAL; |
| 179 | return put_user(0, p); | 185 | /* Enable new time value */ |
| 180 | 186 | ks8695_wdt_start(); | |
| 181 | case WDIOC_SETOPTIONS: | 187 | /* Return current value */ |
| 182 | if (get_user(new_value, p)) | 188 | return put_user(wdt_time, p); |
| 183 | return -EFAULT; | 189 | case WDIOC_GETTIMEOUT: |
| 184 | 190 | return put_user(wdt_time, p); | |
| 185 | if (new_value & WDIOS_DISABLECARD) | 191 | default: |
| 186 | ks8695_wdt_stop(); | 192 | return -ENOTTY; |
| 187 | if (new_value & WDIOS_ENABLECARD) | ||
| 188 | ks8695_wdt_start(); | ||
| 189 | return 0; | ||
| 190 | |||
| 191 | default: | ||
| 192 | return -ENOTTY; | ||
| 193 | } | 193 | } |
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | /* | 196 | /* |
| 197 | * Pat the watchdog whenever device is written to. | 197 | * Pat the watchdog whenever device is written to. |
| 198 | */ | 198 | */ |
| 199 | static ssize_t ks8695_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) | 199 | static ssize_t ks8695_wdt_write(struct file *file, const char *data, |
| 200 | size_t len, loff_t *ppos) | ||
| 200 | { | 201 | { |
| 201 | ks8695_wdt_reload(); /* pat the watchdog */ | 202 | ks8695_wdt_reload(); /* pat the watchdog */ |
| 202 | return len; | 203 | return len; |
| @@ -207,7 +208,7 @@ static ssize_t ks8695_wdt_write(struct file *file, const char *data, size_t len, | |||
| 207 | static const struct file_operations ks8695wdt_fops = { | 208 | static const struct file_operations ks8695wdt_fops = { |
| 208 | .owner = THIS_MODULE, | 209 | .owner = THIS_MODULE, |
| 209 | .llseek = no_llseek, | 210 | .llseek = no_llseek, |
| 210 | .ioctl = ks8695_wdt_ioctl, | 211 | .unlocked_ioctl = ks8695_wdt_ioctl, |
| 211 | .open = ks8695_wdt_open, | 212 | .open = ks8695_wdt_open, |
| 212 | .release = ks8695_wdt_close, | 213 | .release = ks8695_wdt_close, |
| 213 | .write = ks8695_wdt_write, | 214 | .write = ks8695_wdt_write, |
| @@ -231,7 +232,8 @@ static int __init ks8695wdt_probe(struct platform_device *pdev) | |||
| 231 | if (res) | 232 | if (res) |
| 232 | return res; | 233 | return res; |
| 233 | 234 | ||
| 234 | printk("KS8695 Watchdog Timer enabled (%d seconds%s)\n", wdt_time, nowayout ? ", nowayout" : ""); | 235 | printk(KERN_INFO "KS8695 Watchdog Timer enabled (%d seconds%s)\n", |
| 236 | wdt_time, nowayout ? ", nowayout" : ""); | ||
| 235 | return 0; | 237 | return 0; |
| 236 | } | 238 | } |
| 237 | 239 | ||
| @@ -285,12 +287,14 @@ static struct platform_driver ks8695wdt_driver = { | |||
| 285 | 287 | ||
| 286 | static int __init ks8695_wdt_init(void) | 288 | static int __init ks8695_wdt_init(void) |
| 287 | { | 289 | { |
| 288 | /* Check that the heartbeat value is within range; if not reset to the default */ | 290 | spin_lock_init(&ks8695_lock); |
| 291 | /* Check that the heartbeat value is within range; | ||
| 292 | if not reset to the default */ | ||
| 289 | if (ks8695_wdt_settimeout(wdt_time)) { | 293 | if (ks8695_wdt_settimeout(wdt_time)) { |
| 290 | ks8695_wdt_settimeout(WDT_DEFAULT_TIME); | 294 | ks8695_wdt_settimeout(WDT_DEFAULT_TIME); |
| 291 | pr_info("ks8695_wdt: wdt_time value must be 1 <= wdt_time <= %i, using %d\n", wdt_time, WDT_MAX_TIME); | 295 | pr_info("ks8695_wdt: wdt_time value must be 1 <= wdt_time <= %i, using %d\n", |
| 296 | wdt_time, WDT_MAX_TIME); | ||
| 292 | } | 297 | } |
| 293 | |||
| 294 | return platform_driver_register(&ks8695wdt_driver); | 298 | return platform_driver_register(&ks8695wdt_driver); |
| 295 | } | 299 | } |
| 296 | 300 | ||
diff --git a/drivers/watchdog/machzwd.c b/drivers/watchdog/machzwd.c index 6905135a776c..2dfc27559bf7 100644 --- a/drivers/watchdog/machzwd.c +++ b/drivers/watchdog/machzwd.c | |||
| @@ -40,9 +40,9 @@ | |||
| 40 | #include <linux/notifier.h> | 40 | #include <linux/notifier.h> |
| 41 | #include <linux/reboot.h> | 41 | #include <linux/reboot.h> |
| 42 | #include <linux/init.h> | 42 | #include <linux/init.h> |
| 43 | #include <linux/io.h> | ||
| 44 | #include <linux/uaccess.h> | ||
| 43 | 45 | ||
| 44 | #include <asm/io.h> | ||
| 45 | #include <asm/uaccess.h> | ||
| 46 | #include <asm/system.h> | 46 | #include <asm/system.h> |
| 47 | 47 | ||
| 48 | /* ports */ | 48 | /* ports */ |
| @@ -95,7 +95,9 @@ MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | |||
| 95 | 95 | ||
| 96 | static int nowayout = WATCHDOG_NOWAYOUT; | 96 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 97 | module_param(nowayout, int, 0); | 97 | module_param(nowayout, int, 0); |
| 98 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 98 | MODULE_PARM_DESC(nowayout, |
| 99 | "Watchdog cannot be stopped once started (default=" | ||
| 100 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 99 | 101 | ||
| 100 | #define PFX "machzwd" | 102 | #define PFX "machzwd" |
| 101 | 103 | ||
| @@ -114,7 +116,7 @@ static struct watchdog_info zf_info = { | |||
| 114 | * 3 = GEN_SCI | 116 | * 3 = GEN_SCI |
| 115 | * defaults to GEN_RESET (0) | 117 | * defaults to GEN_RESET (0) |
| 116 | */ | 118 | */ |
| 117 | static int action = 0; | 119 | static int action; |
| 118 | module_param(action, int, 0); | 120 | module_param(action, int, 0); |
| 119 | MODULE_PARM_DESC(action, "after watchdog resets, generate: 0 = RESET(*) 1 = SMI 2 = NMI 3 = SCI"); | 121 | MODULE_PARM_DESC(action, "after watchdog resets, generate: 0 = RESET(*) 1 = SMI 2 = NMI 3 = SCI"); |
| 120 | 122 | ||
| @@ -123,10 +125,9 @@ static void zf_ping(unsigned long data); | |||
| 123 | static int zf_action = GEN_RESET; | 125 | static int zf_action = GEN_RESET; |
| 124 | static unsigned long zf_is_open; | 126 | static unsigned long zf_is_open; |
| 125 | static char zf_expect_close; | 127 | static char zf_expect_close; |
| 126 | static DEFINE_SPINLOCK(zf_lock); | ||
| 127 | static DEFINE_SPINLOCK(zf_port_lock); | 128 | static DEFINE_SPINLOCK(zf_port_lock); |
| 128 | static DEFINE_TIMER(zf_timer, zf_ping, 0, 0); | 129 | static DEFINE_TIMER(zf_timer, zf_ping, 0, 0); |
| 129 | static unsigned long next_heartbeat = 0; | 130 | static unsigned long next_heartbeat; |
| 130 | 131 | ||
| 131 | 132 | ||
| 132 | /* timeout for user land heart beat (10 seconds) */ | 133 | /* timeout for user land heart beat (10 seconds) */ |
| @@ -171,13 +172,13 @@ static inline void zf_set_control(unsigned short new) | |||
| 171 | 172 | ||
| 172 | static inline void zf_set_timer(unsigned short new, unsigned char n) | 173 | static inline void zf_set_timer(unsigned short new, unsigned char n) |
| 173 | { | 174 | { |
| 174 | switch(n){ | 175 | switch (n) { |
| 175 | case WD1: | 176 | case WD1: |
| 176 | zf_writew(COUNTER_1, new); | 177 | zf_writew(COUNTER_1, new); |
| 177 | case WD2: | 178 | case WD2: |
| 178 | zf_writeb(COUNTER_2, new > 0xff ? 0xff : new); | 179 | zf_writeb(COUNTER_2, new > 0xff ? 0xff : new); |
| 179 | default: | 180 | default: |
| 180 | return; | 181 | return; |
| 181 | } | 182 | } |
| 182 | } | 183 | } |
| 183 | 184 | ||
| @@ -241,10 +242,8 @@ static void zf_ping(unsigned long data) | |||
| 241 | 242 | ||
| 242 | zf_writeb(COUNTER_2, 0xff); | 243 | zf_writeb(COUNTER_2, 0xff); |
| 243 | 244 | ||
| 244 | if(time_before(jiffies, next_heartbeat)){ | 245 | if (time_before(jiffies, next_heartbeat)) { |
| 245 | |||
| 246 | dprintk("time_before: %ld\n", next_heartbeat - jiffies); | 246 | dprintk("time_before: %ld\n", next_heartbeat - jiffies); |
| 247 | |||
| 248 | /* | 247 | /* |
| 249 | * reset event is activated by transition from 0 to 1 on | 248 | * reset event is activated by transition from 0 to 1 on |
| 250 | * RESET_WD1 bit and we assume that it is already zero... | 249 | * RESET_WD1 bit and we assume that it is already zero... |
| @@ -261,24 +260,21 @@ static void zf_ping(unsigned long data) | |||
| 261 | spin_unlock_irqrestore(&zf_port_lock, flags); | 260 | spin_unlock_irqrestore(&zf_port_lock, flags); |
| 262 | 261 | ||
| 263 | mod_timer(&zf_timer, jiffies + ZF_HW_TIMEO); | 262 | mod_timer(&zf_timer, jiffies + ZF_HW_TIMEO); |
| 264 | }else{ | 263 | } else |
| 265 | printk(KERN_CRIT PFX ": I will reset your machine\n"); | 264 | printk(KERN_CRIT PFX ": I will reset your machine\n"); |
| 266 | } | ||
| 267 | } | 265 | } |
| 268 | 266 | ||
| 269 | static ssize_t zf_write(struct file *file, const char __user *buf, size_t count, | 267 | static ssize_t zf_write(struct file *file, const char __user *buf, size_t count, |
| 270 | loff_t *ppos) | 268 | loff_t *ppos) |
| 271 | { | 269 | { |
| 272 | /* See if we got the magic character */ | 270 | /* See if we got the magic character */ |
| 273 | if(count){ | 271 | if (count) { |
| 274 | |||
| 275 | /* | 272 | /* |
| 276 | * no need to check for close confirmation | 273 | * no need to check for close confirmation |
| 277 | * no way to disable watchdog ;) | 274 | * no way to disable watchdog ;) |
| 278 | */ | 275 | */ |
| 279 | if (!nowayout) { | 276 | if (!nowayout) { |
| 280 | size_t ofs; | 277 | size_t ofs; |
| 281 | |||
| 282 | /* | 278 | /* |
| 283 | * note: just in case someone wrote the magic character | 279 | * note: just in case someone wrote the magic character |
| 284 | * five months ago... | 280 | * five months ago... |
| @@ -286,11 +282,11 @@ static ssize_t zf_write(struct file *file, const char __user *buf, size_t count, | |||
| 286 | zf_expect_close = 0; | 282 | zf_expect_close = 0; |
| 287 | 283 | ||
| 288 | /* now scan */ | 284 | /* now scan */ |
| 289 | for (ofs = 0; ofs != count; ofs++){ | 285 | for (ofs = 0; ofs != count; ofs++) { |
| 290 | char c; | 286 | char c; |
| 291 | if (get_user(c, buf + ofs)) | 287 | if (get_user(c, buf + ofs)) |
| 292 | return -EFAULT; | 288 | return -EFAULT; |
| 293 | if (c == 'V'){ | 289 | if (c == 'V') { |
| 294 | zf_expect_close = 42; | 290 | zf_expect_close = 42; |
| 295 | dprintk("zf_expect_close = 42\n"); | 291 | dprintk("zf_expect_close = 42\n"); |
| 296 | } | 292 | } |
| @@ -303,14 +299,11 @@ static ssize_t zf_write(struct file *file, const char __user *buf, size_t count, | |||
| 303 | */ | 299 | */ |
| 304 | next_heartbeat = jiffies + ZF_USER_TIMEO; | 300 | next_heartbeat = jiffies + ZF_USER_TIMEO; |
| 305 | dprintk("user ping at %ld\n", jiffies); | 301 | dprintk("user ping at %ld\n", jiffies); |
| 306 | |||
| 307 | } | 302 | } |
| 308 | |||
| 309 | return count; | 303 | return count; |
| 310 | } | 304 | } |
| 311 | 305 | ||
| 312 | static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 306 | static long zf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 313 | unsigned long arg) | ||
| 314 | { | 307 | { |
| 315 | void __user *argp = (void __user *)arg; | 308 | void __user *argp = (void __user *)arg; |
| 316 | int __user *p = argp; | 309 | int __user *p = argp; |
| @@ -319,55 +312,38 @@ static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
| 319 | if (copy_to_user(argp, &zf_info, sizeof(zf_info))) | 312 | if (copy_to_user(argp, &zf_info, sizeof(zf_info))) |
| 320 | return -EFAULT; | 313 | return -EFAULT; |
| 321 | break; | 314 | break; |
| 322 | |||
| 323 | case WDIOC_GETSTATUS: | 315 | case WDIOC_GETSTATUS: |
| 324 | case WDIOC_GETBOOTSTATUS: | 316 | case WDIOC_GETBOOTSTATUS: |
| 325 | return put_user(0, p); | 317 | return put_user(0, p); |
| 326 | |||
| 327 | case WDIOC_KEEPALIVE: | 318 | case WDIOC_KEEPALIVE: |
| 328 | zf_ping(0); | 319 | zf_ping(0); |
| 329 | break; | 320 | break; |
| 330 | |||
| 331 | default: | 321 | default: |
| 332 | return -ENOTTY; | 322 | return -ENOTTY; |
| 333 | } | 323 | } |
| 334 | |||
| 335 | return 0; | 324 | return 0; |
| 336 | } | 325 | } |
| 337 | 326 | ||
| 338 | static int zf_open(struct inode *inode, struct file *file) | 327 | static int zf_open(struct inode *inode, struct file *file) |
| 339 | { | 328 | { |
| 340 | spin_lock(&zf_lock); | 329 | if (test_and_set_bit(0, &zf_is_open)) |
| 341 | if(test_and_set_bit(0, &zf_is_open)) { | ||
| 342 | spin_unlock(&zf_lock); | ||
| 343 | return -EBUSY; | 330 | return -EBUSY; |
| 344 | } | ||
| 345 | |||
| 346 | if (nowayout) | 331 | if (nowayout) |
| 347 | __module_get(THIS_MODULE); | 332 | __module_get(THIS_MODULE); |
| 348 | |||
| 349 | spin_unlock(&zf_lock); | ||
| 350 | |||
| 351 | zf_timer_on(); | 333 | zf_timer_on(); |
| 352 | |||
| 353 | return nonseekable_open(inode, file); | 334 | return nonseekable_open(inode, file); |
| 354 | } | 335 | } |
| 355 | 336 | ||
| 356 | static int zf_close(struct inode *inode, struct file *file) | 337 | static int zf_close(struct inode *inode, struct file *file) |
| 357 | { | 338 | { |
| 358 | if(zf_expect_close == 42){ | 339 | if (zf_expect_close == 42) |
| 359 | zf_timer_off(); | 340 | zf_timer_off(); |
| 360 | } else { | 341 | else { |
| 361 | del_timer(&zf_timer); | 342 | del_timer(&zf_timer); |
| 362 | printk(KERN_ERR PFX ": device file closed unexpectedly. Will not stop the WDT!\n"); | 343 | printk(KERN_ERR PFX ": device file closed unexpectedly. Will not stop the WDT!\n"); |
| 363 | } | 344 | } |
| 364 | |||
| 365 | spin_lock(&zf_lock); | ||
| 366 | clear_bit(0, &zf_is_open); | 345 | clear_bit(0, &zf_is_open); |
| 367 | spin_unlock(&zf_lock); | ||
| 368 | |||
| 369 | zf_expect_close = 0; | 346 | zf_expect_close = 0; |
| 370 | |||
| 371 | return 0; | 347 | return 0; |
| 372 | } | 348 | } |
| 373 | 349 | ||
| @@ -378,23 +354,18 @@ static int zf_close(struct inode *inode, struct file *file) | |||
| 378 | static int zf_notify_sys(struct notifier_block *this, unsigned long code, | 354 | static int zf_notify_sys(struct notifier_block *this, unsigned long code, |
| 379 | void *unused) | 355 | void *unused) |
| 380 | { | 356 | { |
| 381 | if(code == SYS_DOWN || code == SYS_HALT){ | 357 | if (code == SYS_DOWN || code == SYS_HALT) |
| 382 | zf_timer_off(); | 358 | zf_timer_off(); |
| 383 | } | ||
| 384 | |||
| 385 | return NOTIFY_DONE; | 359 | return NOTIFY_DONE; |
| 386 | } | 360 | } |
| 387 | 361 | ||
| 388 | |||
| 389 | |||
| 390 | |||
| 391 | static const struct file_operations zf_fops = { | 362 | static const struct file_operations zf_fops = { |
| 392 | .owner = THIS_MODULE, | 363 | .owner = THIS_MODULE, |
| 393 | .llseek = no_llseek, | 364 | .llseek = no_llseek, |
| 394 | .write = zf_write, | 365 | .write = zf_write, |
| 395 | .ioctl = zf_ioctl, | 366 | .unlocked_ioctl = zf_ioctl, |
| 396 | .open = zf_open, | 367 | .open = zf_open, |
| 397 | .release = zf_close, | 368 | .release = zf_close, |
| 398 | }; | 369 | }; |
| 399 | 370 | ||
| 400 | static struct miscdevice zf_miscdev = { | 371 | static struct miscdevice zf_miscdev = { |
| @@ -402,7 +373,7 @@ static struct miscdevice zf_miscdev = { | |||
| 402 | .name = "watchdog", | 373 | .name = "watchdog", |
| 403 | .fops = &zf_fops, | 374 | .fops = &zf_fops, |
| 404 | }; | 375 | }; |
| 405 | 376 | ||
| 406 | 377 | ||
| 407 | /* | 378 | /* |
| 408 | * The device needs to learn about soft shutdowns in order to | 379 | * The device needs to learn about soft shutdowns in order to |
| @@ -423,22 +394,23 @@ static int __init zf_init(void) | |||
| 423 | { | 394 | { |
| 424 | int ret; | 395 | int ret; |
| 425 | 396 | ||
| 426 | printk(KERN_INFO PFX ": MachZ ZF-Logic Watchdog driver initializing.\n"); | 397 | printk(KERN_INFO PFX |
| 398 | ": MachZ ZF-Logic Watchdog driver initializing.\n"); | ||
| 427 | 399 | ||
| 428 | ret = zf_get_ZFL_version(); | 400 | ret = zf_get_ZFL_version(); |
| 429 | if ((!ret) || (ret == 0xffff)) { | 401 | if (!ret || ret == 0xffff) { |
| 430 | printk(KERN_WARNING PFX ": no ZF-Logic found\n"); | 402 | printk(KERN_WARNING PFX ": no ZF-Logic found\n"); |
| 431 | return -ENODEV; | 403 | return -ENODEV; |
| 432 | } | 404 | } |
| 433 | 405 | ||
| 434 | if((action <= 3) && (action >= 0)){ | 406 | if (action <= 3 && action >= 0) |
| 435 | zf_action = zf_action>>action; | 407 | zf_action = zf_action >> action; |
| 436 | } else | 408 | else |
| 437 | action = 0; | 409 | action = 0; |
| 438 | 410 | ||
| 439 | zf_show_action(action); | 411 | zf_show_action(action); |
| 440 | 412 | ||
| 441 | if(!request_region(ZF_IOBASE, 3, "MachZ ZFL WDT")){ | 413 | if (!request_region(ZF_IOBASE, 3, "MachZ ZFL WDT")) { |
| 442 | printk(KERN_ERR "cannot reserve I/O ports at %d\n", | 414 | printk(KERN_ERR "cannot reserve I/O ports at %d\n", |
| 443 | ZF_IOBASE); | 415 | ZF_IOBASE); |
| 444 | ret = -EBUSY; | 416 | ret = -EBUSY; |
| @@ -446,14 +418,14 @@ static int __init zf_init(void) | |||
| 446 | } | 418 | } |
| 447 | 419 | ||
| 448 | ret = register_reboot_notifier(&zf_notifier); | 420 | ret = register_reboot_notifier(&zf_notifier); |
| 449 | if(ret){ | 421 | if (ret) { |
| 450 | printk(KERN_ERR "can't register reboot notifier (err=%d)\n", | 422 | printk(KERN_ERR "can't register reboot notifier (err=%d)\n", |
| 451 | ret); | 423 | ret); |
| 452 | goto no_reboot; | 424 | goto no_reboot; |
| 453 | } | 425 | } |
| 454 | 426 | ||
| 455 | ret = misc_register(&zf_miscdev); | 427 | ret = misc_register(&zf_miscdev); |
| 456 | if (ret){ | 428 | if (ret) { |
| 457 | printk(KERN_ERR "can't misc_register on minor=%d\n", | 429 | printk(KERN_ERR "can't misc_register on minor=%d\n", |
| 458 | WATCHDOG_MINOR); | 430 | WATCHDOG_MINOR); |
| 459 | goto no_misc; | 431 | goto no_misc; |
diff --git a/drivers/watchdog/mixcomwd.c b/drivers/watchdog/mixcomwd.c index 1adf1d56027d..407b025cb104 100644 --- a/drivers/watchdog/mixcomwd.c +++ b/drivers/watchdog/mixcomwd.c | |||
| @@ -29,7 +29,8 @@ | |||
| 29 | * - support for one more type board | 29 | * - support for one more type board |
| 30 | * | 30 | * |
| 31 | * Version 0.5 (2001/12/14) Matt Domsch <Matt_Domsch@dell.com> | 31 | * Version 0.5 (2001/12/14) Matt Domsch <Matt_Domsch@dell.com> |
| 32 | * - added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT | 32 | * - added nowayout module option to override |
| 33 | * CONFIG_WATCHDOG_NOWAYOUT | ||
| 33 | * | 34 | * |
| 34 | * Version 0.6 (2002/04/12): Rob Radez <rob@osinvestor.com> | 35 | * Version 0.6 (2002/04/12): Rob Radez <rob@osinvestor.com> |
| 35 | * - make mixcomwd_opened unsigned, | 36 | * - make mixcomwd_opened unsigned, |
| @@ -53,8 +54,8 @@ | |||
| 53 | #include <linux/init.h> | 54 | #include <linux/init.h> |
| 54 | #include <linux/jiffies.h> | 55 | #include <linux/jiffies.h> |
| 55 | #include <linux/timer.h> | 56 | #include <linux/timer.h> |
| 56 | #include <asm/uaccess.h> | 57 | #include <linux/uaccess.h> |
| 57 | #include <asm/io.h> | 58 | #include <linux/io.h> |
| 58 | 59 | ||
| 59 | /* | 60 | /* |
| 60 | * We have two types of cards that can be probed: | 61 | * We have two types of cards that can be probed: |
| @@ -108,18 +109,19 @@ static char expect_close; | |||
| 108 | 109 | ||
| 109 | static int nowayout = WATCHDOG_NOWAYOUT; | 110 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 110 | module_param(nowayout, int, 0); | 111 | module_param(nowayout, int, 0); |
| 111 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 112 | MODULE_PARM_DESC(nowayout, |
| 113 | "Watchdog cannot be stopped once started (default=" | ||
| 114 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 112 | 115 | ||
| 113 | static void mixcomwd_ping(void) | 116 | static void mixcomwd_ping(void) |
| 114 | { | 117 | { |
| 115 | outb_p(55,watchdog_port); | 118 | outb_p(55, watchdog_port); |
| 116 | return; | 119 | return; |
| 117 | } | 120 | } |
| 118 | 121 | ||
| 119 | static void mixcomwd_timerfun(unsigned long d) | 122 | static void mixcomwd_timerfun(unsigned long d) |
| 120 | { | 123 | { |
| 121 | mixcomwd_ping(); | 124 | mixcomwd_ping(); |
| 122 | |||
| 123 | mod_timer(&mixcomwd_timer, jiffies + 5 * HZ); | 125 | mod_timer(&mixcomwd_timer, jiffies + 5 * HZ); |
| 124 | } | 126 | } |
| 125 | 127 | ||
| @@ -129,22 +131,22 @@ static void mixcomwd_timerfun(unsigned long d) | |||
| 129 | 131 | ||
| 130 | static int mixcomwd_open(struct inode *inode, struct file *file) | 132 | static int mixcomwd_open(struct inode *inode, struct file *file) |
| 131 | { | 133 | { |
| 132 | if(test_and_set_bit(0,&mixcomwd_opened)) { | 134 | if (test_and_set_bit(0, &mixcomwd_opened)) |
| 133 | return -EBUSY; | 135 | return -EBUSY; |
| 134 | } | 136 | |
| 135 | mixcomwd_ping(); | 137 | mixcomwd_ping(); |
| 136 | 138 | ||
| 137 | if (nowayout) { | 139 | if (nowayout) |
| 138 | /* | 140 | /* |
| 139 | * fops_get() code via open() has already done | 141 | * fops_get() code via open() has already done |
| 140 | * a try_module_get() so it is safe to do the | 142 | * a try_module_get() so it is safe to do the |
| 141 | * __module_get(). | 143 | * __module_get(). |
| 142 | */ | 144 | */ |
| 143 | __module_get(THIS_MODULE); | 145 | __module_get(THIS_MODULE); |
| 144 | } else { | 146 | else { |
| 145 | if(mixcomwd_timer_alive) { | 147 | if (mixcomwd_timer_alive) { |
| 146 | del_timer(&mixcomwd_timer); | 148 | del_timer(&mixcomwd_timer); |
| 147 | mixcomwd_timer_alive=0; | 149 | mixcomwd_timer_alive = 0; |
| 148 | } | 150 | } |
| 149 | } | 151 | } |
| 150 | return nonseekable_open(inode, file); | 152 | return nonseekable_open(inode, file); |
| @@ -153,26 +155,27 @@ static int mixcomwd_open(struct inode *inode, struct file *file) | |||
| 153 | static int mixcomwd_release(struct inode *inode, struct file *file) | 155 | static int mixcomwd_release(struct inode *inode, struct file *file) |
| 154 | { | 156 | { |
| 155 | if (expect_close == 42) { | 157 | if (expect_close == 42) { |
| 156 | if(mixcomwd_timer_alive) { | 158 | if (mixcomwd_timer_alive) { |
| 157 | printk(KERN_ERR PFX "release called while internal timer alive"); | 159 | printk(KERN_ERR PFX |
| 160 | "release called while internal timer alive"); | ||
| 158 | return -EBUSY; | 161 | return -EBUSY; |
| 159 | } | 162 | } |
| 160 | mixcomwd_timer_alive=1; | 163 | mixcomwd_timer_alive = 1; |
| 161 | mod_timer(&mixcomwd_timer, jiffies + 5 * HZ); | 164 | mod_timer(&mixcomwd_timer, jiffies + 5 * HZ); |
| 162 | } else { | 165 | } else |
| 163 | printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n"); | 166 | printk(KERN_CRIT PFX |
| 164 | } | 167 | "WDT device closed unexpectedly. WDT will not stop!\n"); |
| 165 | 168 | ||
| 166 | clear_bit(0,&mixcomwd_opened); | 169 | clear_bit(0, &mixcomwd_opened); |
| 167 | expect_close=0; | 170 | expect_close = 0; |
| 168 | return 0; | 171 | return 0; |
| 169 | } | 172 | } |
| 170 | 173 | ||
| 171 | 174 | ||
| 172 | static ssize_t mixcomwd_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) | 175 | static ssize_t mixcomwd_write(struct file *file, const char __user *data, |
| 176 | size_t len, loff_t *ppos) | ||
| 173 | { | 177 | { |
| 174 | if(len) | 178 | if (len) { |
| 175 | { | ||
| 176 | if (!nowayout) { | 179 | if (!nowayout) { |
| 177 | size_t i; | 180 | size_t i; |
| 178 | 181 | ||
| @@ -192,8 +195,8 @@ static ssize_t mixcomwd_write(struct file *file, const char __user *data, size_t | |||
| 192 | return len; | 195 | return len; |
| 193 | } | 196 | } |
| 194 | 197 | ||
| 195 | static int mixcomwd_ioctl(struct inode *inode, struct file *file, | 198 | static long mixcomwd_ioctl(struct file *file, |
| 196 | unsigned int cmd, unsigned long arg) | 199 | unsigned int cmd, unsigned long arg) |
| 197 | { | 200 | { |
| 198 | void __user *argp = (void __user *)arg; | 201 | void __user *argp = (void __user *)arg; |
| 199 | int __user *p = argp; | 202 | int __user *p = argp; |
| @@ -204,32 +207,23 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file, | |||
| 204 | .identity = "MixCOM watchdog", | 207 | .identity = "MixCOM watchdog", |
| 205 | }; | 208 | }; |
| 206 | 209 | ||
| 207 | switch(cmd) | 210 | switch (cmd) { |
| 208 | { | 211 | case WDIOC_GETSUPPORT: |
| 209 | case WDIOC_GETSTATUS: | 212 | if (copy_to_user(argp, &ident, sizeof(ident))) |
| 210 | status=mixcomwd_opened; | 213 | return -EFAULT; |
| 211 | if (!nowayout) { | 214 | break; |
| 212 | status|=mixcomwd_timer_alive; | 215 | case WDIOC_GETSTATUS: |
| 213 | } | 216 | status = mixcomwd_opened; |
| 214 | if (copy_to_user(p, &status, sizeof(int))) { | 217 | if (!nowayout) |
| 215 | return -EFAULT; | 218 | status |= mixcomwd_timer_alive; |
| 216 | } | 219 | return put_user(status, p); |
| 217 | break; | 220 | case WDIOC_GETBOOTSTATUS: |
| 218 | case WDIOC_GETBOOTSTATUS: | 221 | return put_user(0, p); |
| 219 | if (copy_to_user(p, &status, sizeof(int))) { | 222 | case WDIOC_KEEPALIVE: |
| 220 | return -EFAULT; | 223 | mixcomwd_ping(); |
| 221 | } | 224 | break; |
| 222 | break; | 225 | default: |
| 223 | case WDIOC_GETSUPPORT: | 226 | return -ENOTTY; |
| 224 | if (copy_to_user(argp, &ident, sizeof(ident))) { | ||
| 225 | return -EFAULT; | ||
| 226 | } | ||
| 227 | break; | ||
| 228 | case WDIOC_KEEPALIVE: | ||
| 229 | mixcomwd_ping(); | ||
| 230 | break; | ||
| 231 | default: | ||
| 232 | return -ENOTTY; | ||
| 233 | } | 227 | } |
| 234 | return 0; | 228 | return 0; |
| 235 | } | 229 | } |
| @@ -238,7 +232,7 @@ static const struct file_operations mixcomwd_fops = { | |||
| 238 | .owner = THIS_MODULE, | 232 | .owner = THIS_MODULE, |
| 239 | .llseek = no_llseek, | 233 | .llseek = no_llseek, |
| 240 | .write = mixcomwd_write, | 234 | .write = mixcomwd_write, |
| 241 | .ioctl = mixcomwd_ioctl, | 235 | .unlocked_ioctl = mixcomwd_ioctl, |
| 242 | .open = mixcomwd_open, | 236 | .open = mixcomwd_open, |
| 243 | .release = mixcomwd_release, | 237 | .release = mixcomwd_release, |
| 244 | }; | 238 | }; |
| @@ -253,15 +247,14 @@ static int __init checkcard(int port, int card_id) | |||
| 253 | { | 247 | { |
| 254 | int id; | 248 | int id; |
| 255 | 249 | ||
| 256 | if (!request_region(port, 1, "MixCOM watchdog")) { | 250 | if (!request_region(port, 1, "MixCOM watchdog")) |
| 257 | return 0; | 251 | return 0; |
| 258 | } | ||
| 259 | 252 | ||
| 260 | id=inb_p(port); | 253 | id = inb_p(port); |
| 261 | if (card_id==MIXCOM_ID) | 254 | if (card_id == MIXCOM_ID) |
| 262 | id &= 0x3f; | 255 | id &= 0x3f; |
| 263 | 256 | ||
| 264 | if (id!=card_id) { | 257 | if (id != card_id) { |
| 265 | release_region(port, 1); | 258 | release_region(port, 1); |
| 266 | return 0; | 259 | return 0; |
| 267 | } | 260 | } |
| @@ -270,9 +263,7 @@ static int __init checkcard(int port, int card_id) | |||
| 270 | 263 | ||
| 271 | static int __init mixcomwd_init(void) | 264 | static int __init mixcomwd_init(void) |
| 272 | { | 265 | { |
| 273 | int i; | 266 | int i, ret, found = 0; |
| 274 | int ret; | ||
| 275 | int found=0; | ||
| 276 | 267 | ||
| 277 | for (i = 0; !found && mixcomwd_io_info[i].ioport != 0; i++) { | 268 | for (i = 0; !found && mixcomwd_io_info[i].ioport != 0; i++) { |
| 278 | if (checkcard(mixcomwd_io_info[i].ioport, | 269 | if (checkcard(mixcomwd_io_info[i].ioport, |
| @@ -283,20 +274,22 @@ static int __init mixcomwd_init(void) | |||
| 283 | } | 274 | } |
| 284 | 275 | ||
| 285 | if (!found) { | 276 | if (!found) { |
| 286 | printk(KERN_ERR PFX "No card detected, or port not available.\n"); | 277 | printk(KERN_ERR PFX |
| 278 | "No card detected, or port not available.\n"); | ||
| 287 | return -ENODEV; | 279 | return -ENODEV; |
| 288 | } | 280 | } |
| 289 | 281 | ||
| 290 | ret = misc_register(&mixcomwd_miscdev); | 282 | ret = misc_register(&mixcomwd_miscdev); |
| 291 | if (ret) | 283 | if (ret) { |
| 292 | { | 284 | printk(KERN_ERR PFX |
| 293 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 285 | "cannot register miscdev on minor=%d (err=%d)\n", |
| 294 | WATCHDOG_MINOR, ret); | 286 | WATCHDOG_MINOR, ret); |
| 295 | goto error_misc_register_watchdog; | 287 | goto error_misc_register_watchdog; |
| 296 | } | 288 | } |
| 297 | 289 | ||
| 298 | printk(KERN_INFO "MixCOM watchdog driver v%s, watchdog port at 0x%3x\n", | 290 | printk(KERN_INFO |
| 299 | VERSION, watchdog_port); | 291 | "MixCOM watchdog driver v%s, watchdog port at 0x%3x\n", |
| 292 | VERSION, watchdog_port); | ||
| 300 | 293 | ||
| 301 | return 0; | 294 | return 0; |
| 302 | 295 | ||
| @@ -309,15 +302,15 @@ error_misc_register_watchdog: | |||
| 309 | static void __exit mixcomwd_exit(void) | 302 | static void __exit mixcomwd_exit(void) |
| 310 | { | 303 | { |
| 311 | if (!nowayout) { | 304 | if (!nowayout) { |
| 312 | if(mixcomwd_timer_alive) { | 305 | if (mixcomwd_timer_alive) { |
| 313 | printk(KERN_WARNING PFX "I quit now, hardware will" | 306 | printk(KERN_WARNING PFX "I quit now, hardware will" |
| 314 | " probably reboot!\n"); | 307 | " probably reboot!\n"); |
| 315 | del_timer_sync(&mixcomwd_timer); | 308 | del_timer_sync(&mixcomwd_timer); |
| 316 | mixcomwd_timer_alive=0; | 309 | mixcomwd_timer_alive = 0; |
| 317 | } | 310 | } |
| 318 | } | 311 | } |
| 319 | misc_deregister(&mixcomwd_miscdev); | 312 | misc_deregister(&mixcomwd_miscdev); |
| 320 | release_region(watchdog_port,1); | 313 | release_region(watchdog_port, 1); |
| 321 | } | 314 | } |
| 322 | 315 | ||
| 323 | module_init(mixcomwd_init); | 316 | module_init(mixcomwd_init); |
diff --git a/drivers/watchdog/mpc5200_wdt.c b/drivers/watchdog/mpc5200_wdt.c index 77c1c2ae2cc2..db91892558f2 100644 --- a/drivers/watchdog/mpc5200_wdt.c +++ b/drivers/watchdog/mpc5200_wdt.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | #include <linux/io.h> | 5 | #include <linux/io.h> |
| 6 | #include <linux/spinlock.h> | 6 | #include <linux/spinlock.h> |
| 7 | #include <linux/of_platform.h> | 7 | #include <linux/of_platform.h> |
| 8 | #include <asm/uaccess.h> | 8 | #include <linux/uaccess.h> |
| 9 | #include <asm/mpc52xx.h> | 9 | #include <asm/mpc52xx.h> |
| 10 | 10 | ||
| 11 | 11 | ||
| @@ -57,7 +57,8 @@ static int mpc5200_wdt_start(struct mpc5200_wdt *wdt) | |||
| 57 | /* set timeout, with maximum prescaler */ | 57 | /* set timeout, with maximum prescaler */ |
| 58 | out_be32(&wdt->regs->count, 0x0 | wdt->count); | 58 | out_be32(&wdt->regs->count, 0x0 | wdt->count); |
| 59 | /* enable watchdog */ | 59 | /* enable watchdog */ |
| 60 | out_be32(&wdt->regs->mode, GPT_MODE_CE | GPT_MODE_WDT | GPT_MODE_MS_TIMER); | 60 | out_be32(&wdt->regs->mode, GPT_MODE_CE | GPT_MODE_WDT | |
| 61 | GPT_MODE_MS_TIMER); | ||
| 61 | spin_unlock(&wdt->io_lock); | 62 | spin_unlock(&wdt->io_lock); |
| 62 | 63 | ||
| 63 | return 0; | 64 | return 0; |
| @@ -66,7 +67,8 @@ static int mpc5200_wdt_ping(struct mpc5200_wdt *wdt) | |||
| 66 | { | 67 | { |
| 67 | spin_lock(&wdt->io_lock); | 68 | spin_lock(&wdt->io_lock); |
| 68 | /* writing A5 to OCPW resets the watchdog */ | 69 | /* writing A5 to OCPW resets the watchdog */ |
| 69 | out_be32(&wdt->regs->mode, 0xA5000000 | (0xffffff & in_be32(&wdt->regs->mode))); | 70 | out_be32(&wdt->regs->mode, 0xA5000000 | |
| 71 | (0xffffff & in_be32(&wdt->regs->mode))); | ||
| 70 | spin_unlock(&wdt->io_lock); | 72 | spin_unlock(&wdt->io_lock); |
| 71 | return 0; | 73 | return 0; |
| 72 | } | 74 | } |
| @@ -92,8 +94,8 @@ static struct watchdog_info mpc5200_wdt_info = { | |||
| 92 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | 94 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, |
| 93 | .identity = "mpc5200 watchdog on GPT0", | 95 | .identity = "mpc5200 watchdog on GPT0", |
| 94 | }; | 96 | }; |
| 95 | static int mpc5200_wdt_ioctl(struct inode *inode, struct file *file, | 97 | static long mpc5200_wdt_ioctl(struct file *file, unsigned int cmd, |
| 96 | unsigned int cmd, unsigned long arg) | 98 | unsigned long arg) |
| 97 | { | 99 | { |
| 98 | struct mpc5200_wdt *wdt = file->private_data; | 100 | struct mpc5200_wdt *wdt = file->private_data; |
| 99 | int __user *data = (int __user *)arg; | 101 | int __user *data = (int __user *)arg; |
| @@ -103,7 +105,7 @@ static int mpc5200_wdt_ioctl(struct inode *inode, struct file *file, | |||
| 103 | switch (cmd) { | 105 | switch (cmd) { |
| 104 | case WDIOC_GETSUPPORT: | 106 | case WDIOC_GETSUPPORT: |
| 105 | ret = copy_to_user(data, &mpc5200_wdt_info, | 107 | ret = copy_to_user(data, &mpc5200_wdt_info, |
| 106 | sizeof(mpc5200_wdt_info)); | 108 | sizeof(mpc5200_wdt_info)); |
| 107 | if (ret) | 109 | if (ret) |
| 108 | ret = -EFAULT; | 110 | ret = -EFAULT; |
| 109 | break; | 111 | break; |
| @@ -135,6 +137,7 @@ static int mpc5200_wdt_ioctl(struct inode *inode, struct file *file, | |||
| 135 | } | 137 | } |
| 136 | return ret; | 138 | return ret; |
| 137 | } | 139 | } |
| 140 | |||
| 138 | static int mpc5200_wdt_open(struct inode *inode, struct file *file) | 141 | static int mpc5200_wdt_open(struct inode *inode, struct file *file) |
| 139 | { | 142 | { |
| 140 | /* /dev/watchdog can only be opened once */ | 143 | /* /dev/watchdog can only be opened once */ |
| @@ -161,13 +164,14 @@ static int mpc5200_wdt_release(struct inode *inode, struct file *file) | |||
| 161 | static const struct file_operations mpc5200_wdt_fops = { | 164 | static const struct file_operations mpc5200_wdt_fops = { |
| 162 | .owner = THIS_MODULE, | 165 | .owner = THIS_MODULE, |
| 163 | .write = mpc5200_wdt_write, | 166 | .write = mpc5200_wdt_write, |
| 164 | .ioctl = mpc5200_wdt_ioctl, | 167 | .unlocked_ioctl = mpc5200_wdt_ioctl, |
| 165 | .open = mpc5200_wdt_open, | 168 | .open = mpc5200_wdt_open, |
| 166 | .release = mpc5200_wdt_release, | 169 | .release = mpc5200_wdt_release, |
| 167 | }; | 170 | }; |
| 168 | 171 | ||
| 169 | /* module operations */ | 172 | /* module operations */ |
| 170 | static int mpc5200_wdt_probe(struct of_device *op, const struct of_device_id *match) | 173 | static int mpc5200_wdt_probe(struct of_device *op, |
| 174 | const struct of_device_id *match) | ||
| 171 | { | 175 | { |
| 172 | struct mpc5200_wdt *wdt; | 176 | struct mpc5200_wdt *wdt; |
| 173 | int err; | 177 | int err; |
| @@ -215,9 +219,9 @@ static int mpc5200_wdt_probe(struct of_device *op, const struct of_device_id *ma | |||
| 215 | return 0; | 219 | return 0; |
| 216 | 220 | ||
| 217 | iounmap(wdt->regs); | 221 | iounmap(wdt->regs); |
| 218 | out_release: | 222 | out_release: |
| 219 | release_mem_region(wdt->mem.start, size); | 223 | release_mem_region(wdt->mem.start, size); |
| 220 | out_free: | 224 | out_free: |
| 221 | kfree(wdt); | 225 | kfree(wdt); |
| 222 | return err; | 226 | return err; |
| 223 | } | 227 | } |
diff --git a/drivers/watchdog/mpc83xx_wdt.c b/drivers/watchdog/mpc83xx_wdt.c deleted file mode 100644 index b16c5cd972eb..000000000000 --- a/drivers/watchdog/mpc83xx_wdt.c +++ /dev/null | |||
| @@ -1,230 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * mpc83xx_wdt.c - MPC83xx watchdog userspace interface | ||
| 3 | * | ||
| 4 | * Authors: Dave Updegraff <dave@cray.org> | ||
| 5 | * Kumar Gala <galak@kernel.crashing.org> | ||
| 6 | * Attribution: from 83xx_wst: Florian Schirmer <jolt@tuxbox.org> | ||
| 7 | * ..and from sc520_wdt | ||
| 8 | * | ||
| 9 | * Note: it appears that you can only actually ENABLE or DISABLE the thing | ||
| 10 | * once after POR. Once enabled, you cannot disable, and vice versa. | ||
| 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 | |||
| 18 | #include <linux/fs.h> | ||
| 19 | #include <linux/init.h> | ||
| 20 | #include <linux/kernel.h> | ||
| 21 | #include <linux/miscdevice.h> | ||
| 22 | #include <linux/platform_device.h> | ||
| 23 | #include <linux/module.h> | ||
| 24 | #include <linux/watchdog.h> | ||
| 25 | #include <asm/io.h> | ||
| 26 | #include <asm/uaccess.h> | ||
| 27 | |||
| 28 | struct mpc83xx_wdt { | ||
| 29 | __be32 res0; | ||
| 30 | __be32 swcrr; /* System watchdog control register */ | ||
| 31 | #define SWCRR_SWTC 0xFFFF0000 /* Software Watchdog Time Count. */ | ||
| 32 | #define SWCRR_SWEN 0x00000004 /* Watchdog Enable bit. */ | ||
| 33 | #define SWCRR_SWRI 0x00000002 /* Software Watchdog Reset/Interrupt Select bit.*/ | ||
| 34 | #define SWCRR_SWPR 0x00000001 /* Software Watchdog Counter Prescale bit. */ | ||
| 35 | __be32 swcnr; /* System watchdog count register */ | ||
| 36 | u8 res1[2]; | ||
| 37 | __be16 swsrr; /* System watchdog service register */ | ||
| 38 | u8 res2[0xF0]; | ||
| 39 | }; | ||
| 40 | |||
| 41 | static struct mpc83xx_wdt __iomem *wd_base; | ||
| 42 | |||
| 43 | static u16 timeout = 0xffff; | ||
| 44 | module_param(timeout, ushort, 0); | ||
| 45 | MODULE_PARM_DESC(timeout, "Watchdog timeout in ticks. (0<timeout<65536, default=65535"); | ||
| 46 | |||
| 47 | static int reset = 1; | ||
| 48 | module_param(reset, bool, 0); | ||
| 49 | MODULE_PARM_DESC(reset, "Watchdog Interrupt/Reset Mode. 0 = interrupt, 1 = reset"); | ||
| 50 | |||
| 51 | /* | ||
| 52 | * We always prescale, but if someone really doesn't want to they can set this | ||
| 53 | * to 0 | ||
| 54 | */ | ||
| 55 | static int prescale = 1; | ||
| 56 | static unsigned int timeout_sec; | ||
| 57 | |||
| 58 | static unsigned long wdt_is_open; | ||
| 59 | static DEFINE_SPINLOCK(wdt_spinlock); | ||
| 60 | |||
| 61 | static void mpc83xx_wdt_keepalive(void) | ||
| 62 | { | ||
| 63 | /* Ping the WDT */ | ||
| 64 | spin_lock(&wdt_spinlock); | ||
| 65 | out_be16(&wd_base->swsrr, 0x556c); | ||
| 66 | out_be16(&wd_base->swsrr, 0xaa39); | ||
| 67 | spin_unlock(&wdt_spinlock); | ||
| 68 | } | ||
| 69 | |||
| 70 | static ssize_t mpc83xx_wdt_write(struct file *file, const char __user *buf, | ||
| 71 | size_t count, loff_t *ppos) | ||
| 72 | { | ||
| 73 | if (count) | ||
| 74 | mpc83xx_wdt_keepalive(); | ||
| 75 | return count; | ||
| 76 | } | ||
| 77 | |||
| 78 | static int mpc83xx_wdt_open(struct inode *inode, struct file *file) | ||
| 79 | { | ||
| 80 | u32 tmp = SWCRR_SWEN; | ||
| 81 | if (test_and_set_bit(0, &wdt_is_open)) | ||
| 82 | return -EBUSY; | ||
| 83 | |||
| 84 | /* Once we start the watchdog we can't stop it */ | ||
| 85 | __module_get(THIS_MODULE); | ||
| 86 | |||
| 87 | /* Good, fire up the show */ | ||
| 88 | if (prescale) | ||
| 89 | tmp |= SWCRR_SWPR; | ||
| 90 | if (reset) | ||
| 91 | tmp |= SWCRR_SWRI; | ||
| 92 | |||
| 93 | tmp |= timeout << 16; | ||
| 94 | |||
| 95 | out_be32(&wd_base->swcrr, tmp); | ||
| 96 | |||
| 97 | return nonseekable_open(inode, file); | ||
| 98 | } | ||
| 99 | |||
| 100 | static int mpc83xx_wdt_release(struct inode *inode, struct file *file) | ||
| 101 | { | ||
| 102 | printk(KERN_CRIT "Unexpected close, not stopping watchdog!\n"); | ||
| 103 | mpc83xx_wdt_keepalive(); | ||
| 104 | clear_bit(0, &wdt_is_open); | ||
| 105 | return 0; | ||
| 106 | } | ||
| 107 | |||
| 108 | static int mpc83xx_wdt_ioctl(struct inode *inode, struct file *file, | ||
| 109 | unsigned int cmd, unsigned long arg) | ||
| 110 | { | ||
| 111 | void __user *argp = (void __user *)arg; | ||
| 112 | int __user *p = argp; | ||
| 113 | static struct watchdog_info ident = { | ||
| 114 | .options = WDIOF_KEEPALIVEPING, | ||
| 115 | .firmware_version = 1, | ||
| 116 | .identity = "MPC83xx", | ||
| 117 | }; | ||
| 118 | |||
| 119 | switch (cmd) { | ||
| 120 | case WDIOC_GETSUPPORT: | ||
| 121 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; | ||
| 122 | case WDIOC_GETSTATUS: | ||
| 123 | case WDIOC_GETBOOTSTATUS: | ||
| 124 | return put_user(0, p); | ||
| 125 | case WDIOC_KEEPALIVE: | ||
| 126 | mpc83xx_wdt_keepalive(); | ||
| 127 | return 0; | ||
| 128 | case WDIOC_GETTIMEOUT: | ||
| 129 | return put_user(timeout_sec, p); | ||
| 130 | default: | ||
| 131 | return -ENOTTY; | ||
| 132 | } | ||
| 133 | } | ||
| 134 | |||
| 135 | static const struct file_operations mpc83xx_wdt_fops = { | ||
| 136 | .owner = THIS_MODULE, | ||
| 137 | .llseek = no_llseek, | ||
| 138 | .write = mpc83xx_wdt_write, | ||
| 139 | .ioctl = mpc83xx_wdt_ioctl, | ||
| 140 | .open = mpc83xx_wdt_open, | ||
| 141 | .release = mpc83xx_wdt_release, | ||
| 142 | }; | ||
| 143 | |||
| 144 | static struct miscdevice mpc83xx_wdt_miscdev = { | ||
| 145 | .minor = WATCHDOG_MINOR, | ||
| 146 | .name = "watchdog", | ||
| 147 | .fops = &mpc83xx_wdt_fops, | ||
| 148 | }; | ||
| 149 | |||
| 150 | static int __devinit mpc83xx_wdt_probe(struct platform_device *dev) | ||
| 151 | { | ||
| 152 | struct resource *r; | ||
| 153 | int ret; | ||
| 154 | unsigned int *freq = dev->dev.platform_data; | ||
| 155 | |||
| 156 | /* get a pointer to the register memory */ | ||
| 157 | r = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
| 158 | |||
| 159 | if (!r) { | ||
| 160 | ret = -ENODEV; | ||
| 161 | goto err_out; | ||
| 162 | } | ||
| 163 | |||
| 164 | wd_base = ioremap(r->start, sizeof (struct mpc83xx_wdt)); | ||
| 165 | |||
| 166 | if (wd_base == NULL) { | ||
| 167 | ret = -ENOMEM; | ||
| 168 | goto err_out; | ||
| 169 | } | ||
| 170 | |||
| 171 | ret = misc_register(&mpc83xx_wdt_miscdev); | ||
| 172 | if (ret) { | ||
| 173 | printk(KERN_ERR "cannot register miscdev on minor=%d " | ||
| 174 | "(err=%d)\n", | ||
| 175 | WATCHDOG_MINOR, ret); | ||
| 176 | goto err_unmap; | ||
| 177 | } | ||
| 178 | |||
| 179 | /* Calculate the timeout in seconds */ | ||
| 180 | if (prescale) | ||
| 181 | timeout_sec = (timeout * 0x10000) / (*freq); | ||
| 182 | else | ||
| 183 | timeout_sec = timeout / (*freq); | ||
| 184 | |||
| 185 | printk(KERN_INFO "WDT driver for MPC83xx initialized. " | ||
| 186 | "mode:%s timeout=%d (%d seconds)\n", | ||
| 187 | reset ? "reset":"interrupt", timeout, timeout_sec); | ||
| 188 | return 0; | ||
| 189 | |||
| 190 | err_unmap: | ||
| 191 | iounmap(wd_base); | ||
| 192 | err_out: | ||
| 193 | return ret; | ||
| 194 | } | ||
| 195 | |||
| 196 | static int __devexit mpc83xx_wdt_remove(struct platform_device *dev) | ||
| 197 | { | ||
| 198 | misc_deregister(&mpc83xx_wdt_miscdev); | ||
| 199 | iounmap(wd_base); | ||
| 200 | |||
| 201 | return 0; | ||
| 202 | } | ||
| 203 | |||
| 204 | static struct platform_driver mpc83xx_wdt_driver = { | ||
| 205 | .probe = mpc83xx_wdt_probe, | ||
| 206 | .remove = __devexit_p(mpc83xx_wdt_remove), | ||
| 207 | .driver = { | ||
| 208 | .name = "mpc83xx_wdt", | ||
| 209 | .owner = THIS_MODULE, | ||
| 210 | }, | ||
| 211 | }; | ||
| 212 | |||
| 213 | static int __init mpc83xx_wdt_init(void) | ||
| 214 | { | ||
| 215 | return platform_driver_register(&mpc83xx_wdt_driver); | ||
| 216 | } | ||
| 217 | |||
| 218 | static void __exit mpc83xx_wdt_exit(void) | ||
| 219 | { | ||
| 220 | platform_driver_unregister(&mpc83xx_wdt_driver); | ||
| 221 | } | ||
| 222 | |||
| 223 | module_init(mpc83xx_wdt_init); | ||
| 224 | module_exit(mpc83xx_wdt_exit); | ||
| 225 | |||
| 226 | MODULE_AUTHOR("Dave Updegraff, Kumar Gala"); | ||
| 227 | MODULE_DESCRIPTION("Driver for watchdog timer in MPC83xx uProcessor"); | ||
| 228 | MODULE_LICENSE("GPL"); | ||
| 229 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | ||
| 230 | MODULE_ALIAS("platform:mpc83xx_wdt"); | ||
diff --git a/drivers/watchdog/mpc8xx_wdt.c b/drivers/watchdog/mpc8xx_wdt.c index 85b5734403a5..1336425acf20 100644 --- a/drivers/watchdog/mpc8xx_wdt.c +++ b/drivers/watchdog/mpc8xx_wdt.c | |||
| @@ -16,36 +16,35 @@ | |||
| 16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 17 | #include <linux/watchdog.h> | 17 | #include <linux/watchdog.h> |
| 18 | #include <asm/8xx_immap.h> | 18 | #include <asm/8xx_immap.h> |
| 19 | #include <asm/uaccess.h> | 19 | #include <linux/uaccess.h> |
| 20 | #include <asm/io.h> | 20 | #include <linux/io.h> |
| 21 | #include <syslib/m8xx_wdt.h> | 21 | #include <syslib/m8xx_wdt.h> |
| 22 | 22 | ||
| 23 | static unsigned long wdt_opened; | 23 | static unsigned long wdt_opened; |
| 24 | static int wdt_status; | 24 | static int wdt_status; |
| 25 | static spinlock_t wdt_lock; | ||
| 25 | 26 | ||
| 26 | static void mpc8xx_wdt_handler_disable(void) | 27 | static void mpc8xx_wdt_handler_disable(void) |
| 27 | { | 28 | { |
| 28 | volatile uint __iomem *piscr; | 29 | volatile uint __iomem *piscr; |
| 29 | piscr = (uint *)&((immap_t*)IMAP_ADDR)->im_sit.sit_piscr; | 30 | piscr = (uint *)&((immap_t *)IMAP_ADDR)->im_sit.sit_piscr; |
| 30 | 31 | ||
| 31 | if (!m8xx_has_internal_rtc) | 32 | if (!m8xx_has_internal_rtc) |
| 32 | m8xx_wdt_stop_timer(); | 33 | m8xx_wdt_stop_timer(); |
| 33 | else | 34 | else |
| 34 | out_be32(piscr, in_be32(piscr) & ~(PISCR_PIE | PISCR_PTE)); | 35 | out_be32(piscr, in_be32(piscr) & ~(PISCR_PIE | PISCR_PTE)); |
| 35 | |||
| 36 | printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler deactivated\n"); | 36 | printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler deactivated\n"); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | static void mpc8xx_wdt_handler_enable(void) | 39 | static void mpc8xx_wdt_handler_enable(void) |
| 40 | { | 40 | { |
| 41 | volatile uint __iomem *piscr; | 41 | volatile uint __iomem *piscr; |
| 42 | piscr = (uint *)&((immap_t*)IMAP_ADDR)->im_sit.sit_piscr; | 42 | piscr = (uint *)&((immap_t *)IMAP_ADDR)->im_sit.sit_piscr; |
| 43 | 43 | ||
| 44 | if (!m8xx_has_internal_rtc) | 44 | if (!m8xx_has_internal_rtc) |
| 45 | m8xx_wdt_install_timer(); | 45 | m8xx_wdt_install_timer(); |
| 46 | else | 46 | else |
| 47 | out_be32(piscr, in_be32(piscr) | PISCR_PIE | PISCR_PTE); | 47 | out_be32(piscr, in_be32(piscr) | PISCR_PIE | PISCR_PTE); |
| 48 | |||
| 49 | printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler activated\n"); | 48 | printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler activated\n"); |
| 50 | } | 49 | } |
| 51 | 50 | ||
| @@ -53,37 +52,34 @@ static int mpc8xx_wdt_open(struct inode *inode, struct file *file) | |||
| 53 | { | 52 | { |
| 54 | if (test_and_set_bit(0, &wdt_opened)) | 53 | if (test_and_set_bit(0, &wdt_opened)) |
| 55 | return -EBUSY; | 54 | return -EBUSY; |
| 56 | |||
| 57 | m8xx_wdt_reset(); | 55 | m8xx_wdt_reset(); |
| 58 | mpc8xx_wdt_handler_disable(); | 56 | mpc8xx_wdt_handler_disable(); |
| 59 | |||
| 60 | return nonseekable_open(inode, file); | 57 | return nonseekable_open(inode, file); |
| 61 | } | 58 | } |
| 62 | 59 | ||
| 63 | static int mpc8xx_wdt_release(struct inode *inode, struct file *file) | 60 | static int mpc8xx_wdt_release(struct inode *inode, struct file *file) |
| 64 | { | 61 | { |
| 65 | m8xx_wdt_reset(); | 62 | m8xx_wdt_reset(); |
| 66 | |||
| 67 | #if !defined(CONFIG_WATCHDOG_NOWAYOUT) | 63 | #if !defined(CONFIG_WATCHDOG_NOWAYOUT) |
| 68 | mpc8xx_wdt_handler_enable(); | 64 | mpc8xx_wdt_handler_enable(); |
| 69 | #endif | 65 | #endif |
| 70 | |||
| 71 | clear_bit(0, &wdt_opened); | 66 | clear_bit(0, &wdt_opened); |
| 72 | |||
| 73 | return 0; | 67 | return 0; |
| 74 | } | 68 | } |
| 75 | 69 | ||
| 76 | static ssize_t mpc8xx_wdt_write(struct file *file, const char *data, size_t len, | 70 | static ssize_t mpc8xx_wdt_write(struct file *file, const char *data, |
| 77 | loff_t * ppos) | 71 | size_t len, loff_t *ppos) |
| 78 | { | 72 | { |
| 79 | if (len) | 73 | if (len) { |
| 74 | spin_lock(&wdt_lock); | ||
| 80 | m8xx_wdt_reset(); | 75 | m8xx_wdt_reset(); |
| 81 | 76 | spin_unlock(&wdt_lock); | |
| 77 | } | ||
| 82 | return len; | 78 | return len; |
| 83 | } | 79 | } |
| 84 | 80 | ||
| 85 | static int mpc8xx_wdt_ioctl(struct inode *inode, struct file *file, | 81 | static long mpc8xx_wdt_ioctl(struct file *file, |
| 86 | unsigned int cmd, unsigned long arg) | 82 | unsigned int cmd, unsigned long arg) |
| 87 | { | 83 | { |
| 88 | int timeout; | 84 | int timeout; |
| 89 | static struct watchdog_info info = { | 85 | static struct watchdog_info info = { |
| @@ -112,15 +108,19 @@ static int mpc8xx_wdt_ioctl(struct inode *inode, struct file *file, | |||
| 112 | return -EOPNOTSUPP; | 108 | return -EOPNOTSUPP; |
| 113 | 109 | ||
| 114 | case WDIOC_KEEPALIVE: | 110 | case WDIOC_KEEPALIVE: |
| 111 | spin_lock(&wdt_lock); | ||
| 115 | m8xx_wdt_reset(); | 112 | m8xx_wdt_reset(); |
| 116 | wdt_status |= WDIOF_KEEPALIVEPING; | 113 | wdt_status |= WDIOF_KEEPALIVEPING; |
| 114 | spin_unlock(&wdt_lock); | ||
| 117 | break; | 115 | break; |
| 118 | 116 | ||
| 119 | case WDIOC_SETTIMEOUT: | 117 | case WDIOC_SETTIMEOUT: |
| 120 | return -EOPNOTSUPP; | 118 | return -EOPNOTSUPP; |
| 121 | 119 | ||
| 122 | case WDIOC_GETTIMEOUT: | 120 | case WDIOC_GETTIMEOUT: |
| 121 | spin_lock(&wdt_lock); | ||
| 123 | timeout = m8xx_wdt_get_timeout(); | 122 | timeout = m8xx_wdt_get_timeout(); |
| 123 | spin_unlock(&wdt_lock); | ||
| 124 | if (put_user(timeout, (int *)arg)) | 124 | if (put_user(timeout, (int *)arg)) |
| 125 | return -EFAULT; | 125 | return -EFAULT; |
| 126 | break; | 126 | break; |
| @@ -136,7 +136,7 @@ static const struct file_operations mpc8xx_wdt_fops = { | |||
| 136 | .owner = THIS_MODULE, | 136 | .owner = THIS_MODULE, |
| 137 | .llseek = no_llseek, | 137 | .llseek = no_llseek, |
| 138 | .write = mpc8xx_wdt_write, | 138 | .write = mpc8xx_wdt_write, |
| 139 | .ioctl = mpc8xx_wdt_ioctl, | 139 | .unlocked_ioctl = mpc8xx_wdt_ioctl, |
| 140 | .open = mpc8xx_wdt_open, | 140 | .open = mpc8xx_wdt_open, |
| 141 | .release = mpc8xx_wdt_release, | 141 | .release = mpc8xx_wdt_release, |
| 142 | }; | 142 | }; |
| @@ -149,6 +149,7 @@ static struct miscdevice mpc8xx_wdt_miscdev = { | |||
| 149 | 149 | ||
| 150 | static int __init mpc8xx_wdt_init(void) | 150 | static int __init mpc8xx_wdt_init(void) |
| 151 | { | 151 | { |
| 152 | spin_lock_init(&wdt_lock); | ||
| 152 | return misc_register(&mpc8xx_wdt_miscdev); | 153 | return misc_register(&mpc8xx_wdt_miscdev); |
| 153 | } | 154 | } |
| 154 | 155 | ||
diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c new file mode 100644 index 000000000000..f2094960e662 --- /dev/null +++ b/drivers/watchdog/mpc8xxx_wdt.c | |||
| @@ -0,0 +1,316 @@ | |||
| 1 | /* | ||
| 2 | * mpc8xxx_wdt.c - MPC8xx/MPC83xx/MPC86xx watchdog userspace interface | ||
| 3 | * | ||
| 4 | * Authors: Dave Updegraff <dave@cray.org> | ||
| 5 | * Kumar Gala <galak@kernel.crashing.org> | ||
| 6 | * Attribution: from 83xx_wst: Florian Schirmer <jolt@tuxbox.org> | ||
| 7 | * ..and from sc520_wdt | ||
| 8 | * Copyright (c) 2008 MontaVista Software, Inc. | ||
| 9 | * Anton Vorontsov <avorontsov@ru.mvista.com> | ||
| 10 | * | ||
| 11 | * Note: it appears that you can only actually ENABLE or DISABLE the thing | ||
| 12 | * once after POR. Once enabled, you cannot disable, and vice versa. | ||
| 13 | * | ||
| 14 | * This program is free software; you can redistribute it and/or modify it | ||
| 15 | * under the terms of the GNU General Public License as published by the | ||
| 16 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 17 | * option) any later version. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/fs.h> | ||
| 21 | #include <linux/init.h> | ||
| 22 | #include <linux/kernel.h> | ||
| 23 | #include <linux/timer.h> | ||
| 24 | #include <linux/miscdevice.h> | ||
| 25 | #include <linux/of_platform.h> | ||
| 26 | #include <linux/module.h> | ||
| 27 | #include <linux/watchdog.h> | ||
| 28 | #include <linux/io.h> | ||
| 29 | #include <linux/uaccess.h> | ||
| 30 | #include <sysdev/fsl_soc.h> | ||
| 31 | |||
| 32 | struct mpc8xxx_wdt { | ||
| 33 | __be32 res0; | ||
| 34 | __be32 swcrr; /* System watchdog control register */ | ||
| 35 | #define SWCRR_SWTC 0xFFFF0000 /* Software Watchdog Time Count. */ | ||
| 36 | #define SWCRR_SWEN 0x00000004 /* Watchdog Enable bit. */ | ||
| 37 | #define SWCRR_SWRI 0x00000002 /* Software Watchdog Reset/Interrupt Select bit.*/ | ||
| 38 | #define SWCRR_SWPR 0x00000001 /* Software Watchdog Counter Prescale bit. */ | ||
| 39 | __be32 swcnr; /* System watchdog count register */ | ||
| 40 | u8 res1[2]; | ||
| 41 | __be16 swsrr; /* System watchdog service register */ | ||
| 42 | u8 res2[0xF0]; | ||
| 43 | }; | ||
| 44 | |||
| 45 | struct mpc8xxx_wdt_type { | ||
| 46 | int prescaler; | ||
| 47 | bool hw_enabled; | ||
| 48 | }; | ||
| 49 | |||
| 50 | static struct mpc8xxx_wdt __iomem *wd_base; | ||
| 51 | |||
| 52 | static u16 timeout = 0xffff; | ||
| 53 | module_param(timeout, ushort, 0); | ||
| 54 | MODULE_PARM_DESC(timeout, | ||
| 55 | "Watchdog timeout in ticks. (0<timeout<65536, default=65535"); | ||
| 56 | |||
| 57 | static int reset = 1; | ||
| 58 | module_param(reset, bool, 0); | ||
| 59 | MODULE_PARM_DESC(reset, | ||
| 60 | "Watchdog Interrupt/Reset Mode. 0 = interrupt, 1 = reset"); | ||
| 61 | |||
| 62 | static int nowayout = WATCHDOG_NOWAYOUT; | ||
| 63 | module_param(nowayout, int, 0); | ||
| 64 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " | ||
| 65 | "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 66 | |||
| 67 | /* | ||
| 68 | * We always prescale, but if someone really doesn't want to they can set this | ||
| 69 | * to 0 | ||
| 70 | */ | ||
| 71 | static int prescale = 1; | ||
| 72 | static unsigned int timeout_sec; | ||
| 73 | |||
| 74 | static unsigned long wdt_is_open; | ||
| 75 | static DEFINE_SPINLOCK(wdt_spinlock); | ||
| 76 | |||
| 77 | static void mpc8xxx_wdt_keepalive(void) | ||
| 78 | { | ||
| 79 | /* Ping the WDT */ | ||
| 80 | spin_lock(&wdt_spinlock); | ||
| 81 | out_be16(&wd_base->swsrr, 0x556c); | ||
| 82 | out_be16(&wd_base->swsrr, 0xaa39); | ||
| 83 | spin_unlock(&wdt_spinlock); | ||
| 84 | } | ||
| 85 | |||
| 86 | static void mpc8xxx_wdt_timer_ping(unsigned long arg); | ||
| 87 | static DEFINE_TIMER(wdt_timer, mpc8xxx_wdt_timer_ping, 0, 0); | ||
| 88 | |||
| 89 | static void mpc8xxx_wdt_timer_ping(unsigned long arg) | ||
| 90 | { | ||
| 91 | mpc8xxx_wdt_keepalive(); | ||
| 92 | /* We're pinging it twice faster than needed, just to be sure. */ | ||
| 93 | mod_timer(&wdt_timer, jiffies + HZ * timeout_sec / 2); | ||
| 94 | } | ||
| 95 | |||
| 96 | static void mpc8xxx_wdt_pr_warn(const char *msg) | ||
| 97 | { | ||
| 98 | pr_crit("mpc8xxx_wdt: %s, expect the %s soon!\n", msg, | ||
| 99 | reset ? "reset" : "machine check exception"); | ||
| 100 | } | ||
| 101 | |||
| 102 | static ssize_t mpc8xxx_wdt_write(struct file *file, const char __user *buf, | ||
| 103 | size_t count, loff_t *ppos) | ||
| 104 | { | ||
| 105 | if (count) | ||
| 106 | mpc8xxx_wdt_keepalive(); | ||
| 107 | return count; | ||
| 108 | } | ||
| 109 | |||
| 110 | static int mpc8xxx_wdt_open(struct inode *inode, struct file *file) | ||
| 111 | { | ||
| 112 | u32 tmp = SWCRR_SWEN; | ||
| 113 | if (test_and_set_bit(0, &wdt_is_open)) | ||
| 114 | return -EBUSY; | ||
| 115 | |||
| 116 | /* Once we start the watchdog we can't stop it */ | ||
| 117 | if (nowayout) | ||
| 118 | __module_get(THIS_MODULE); | ||
| 119 | |||
| 120 | /* Good, fire up the show */ | ||
| 121 | if (prescale) | ||
| 122 | tmp |= SWCRR_SWPR; | ||
| 123 | if (reset) | ||
| 124 | tmp |= SWCRR_SWRI; | ||
| 125 | |||
| 126 | tmp |= timeout << 16; | ||
| 127 | |||
| 128 | out_be32(&wd_base->swcrr, tmp); | ||
| 129 | |||
| 130 | del_timer_sync(&wdt_timer); | ||
| 131 | |||
| 132 | return nonseekable_open(inode, file); | ||
| 133 | } | ||
| 134 | |||
| 135 | static int mpc8xxx_wdt_release(struct inode *inode, struct file *file) | ||
| 136 | { | ||
| 137 | if (!nowayout) | ||
| 138 | mpc8xxx_wdt_timer_ping(0); | ||
| 139 | else | ||
| 140 | mpc8xxx_wdt_pr_warn("watchdog closed"); | ||
| 141 | clear_bit(0, &wdt_is_open); | ||
| 142 | return 0; | ||
| 143 | } | ||
| 144 | |||
| 145 | static long mpc8xxx_wdt_ioctl(struct file *file, unsigned int cmd, | ||
| 146 | unsigned long arg) | ||
| 147 | { | ||
| 148 | void __user *argp = (void __user *)arg; | ||
| 149 | int __user *p = argp; | ||
| 150 | static struct watchdog_info ident = { | ||
| 151 | .options = WDIOF_KEEPALIVEPING, | ||
| 152 | .firmware_version = 1, | ||
| 153 | .identity = "MPC8xxx", | ||
| 154 | }; | ||
| 155 | |||
| 156 | switch (cmd) { | ||
| 157 | case WDIOC_GETSUPPORT: | ||
| 158 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; | ||
| 159 | case WDIOC_GETSTATUS: | ||
| 160 | case WDIOC_GETBOOTSTATUS: | ||
| 161 | return put_user(0, p); | ||
| 162 | case WDIOC_KEEPALIVE: | ||
| 163 | mpc8xxx_wdt_keepalive(); | ||
| 164 | return 0; | ||
| 165 | case WDIOC_GETTIMEOUT: | ||
| 166 | return put_user(timeout_sec, p); | ||
| 167 | default: | ||
| 168 | return -ENOTTY; | ||
| 169 | } | ||
| 170 | } | ||
| 171 | |||
| 172 | static const struct file_operations mpc8xxx_wdt_fops = { | ||
| 173 | .owner = THIS_MODULE, | ||
| 174 | .llseek = no_llseek, | ||
| 175 | .write = mpc8xxx_wdt_write, | ||
| 176 | .unlocked_ioctl = mpc8xxx_wdt_ioctl, | ||
| 177 | .open = mpc8xxx_wdt_open, | ||
| 178 | .release = mpc8xxx_wdt_release, | ||
| 179 | }; | ||
| 180 | |||
| 181 | static struct miscdevice mpc8xxx_wdt_miscdev = { | ||
| 182 | .minor = WATCHDOG_MINOR, | ||
| 183 | .name = "watchdog", | ||
| 184 | .fops = &mpc8xxx_wdt_fops, | ||
| 185 | }; | ||
| 186 | |||
| 187 | static int __devinit mpc8xxx_wdt_probe(struct of_device *ofdev, | ||
| 188 | const struct of_device_id *match) | ||
| 189 | { | ||
| 190 | int ret; | ||
| 191 | struct device_node *np = ofdev->node; | ||
| 192 | struct mpc8xxx_wdt_type *wdt_type = match->data; | ||
| 193 | u32 freq = fsl_get_sys_freq(); | ||
| 194 | bool enabled; | ||
| 195 | |||
| 196 | if (!freq || freq == -1) | ||
| 197 | return -EINVAL; | ||
| 198 | |||
| 199 | wd_base = of_iomap(np, 0); | ||
| 200 | if (!wd_base) | ||
| 201 | return -ENOMEM; | ||
| 202 | |||
| 203 | enabled = in_be32(&wd_base->swcrr) & SWCRR_SWEN; | ||
| 204 | if (!enabled && wdt_type->hw_enabled) { | ||
| 205 | pr_info("mpc8xxx_wdt: could not be enabled in software\n"); | ||
| 206 | ret = -ENOSYS; | ||
| 207 | goto err_unmap; | ||
| 208 | } | ||
| 209 | |||
| 210 | /* Calculate the timeout in seconds */ | ||
| 211 | if (prescale) | ||
| 212 | timeout_sec = (timeout * wdt_type->prescaler) / freq; | ||
| 213 | else | ||
| 214 | timeout_sec = timeout / freq; | ||
| 215 | |||
| 216 | pr_info("WDT driver for MPC8xxx initialized. mode:%s timeout=%d " | ||
| 217 | "(%d seconds)\n", reset ? "reset" : "interrupt", timeout, | ||
| 218 | timeout_sec); | ||
| 219 | |||
| 220 | /* | ||
| 221 | * If the watchdog was previously enabled or we're running on | ||
| 222 | * MPC8xxx, we should ping the wdt from the kernel until the | ||
| 223 | * userspace handles it. | ||
| 224 | */ | ||
| 225 | if (enabled) | ||
| 226 | mpc8xxx_wdt_timer_ping(0); | ||
| 227 | return 0; | ||
| 228 | err_unmap: | ||
| 229 | iounmap(wd_base); | ||
| 230 | wd_base = NULL; | ||
| 231 | return ret; | ||
| 232 | } | ||
| 233 | |||
| 234 | static int __devexit mpc8xxx_wdt_remove(struct of_device *ofdev) | ||
| 235 | { | ||
| 236 | mpc8xxx_wdt_pr_warn("watchdog removed"); | ||
| 237 | del_timer_sync(&wdt_timer); | ||
| 238 | misc_deregister(&mpc8xxx_wdt_miscdev); | ||
| 239 | iounmap(wd_base); | ||
| 240 | |||
| 241 | return 0; | ||
| 242 | } | ||
| 243 | |||
| 244 | static const struct of_device_id mpc8xxx_wdt_match[] = { | ||
| 245 | { | ||
| 246 | .compatible = "mpc83xx_wdt", | ||
| 247 | .data = &(struct mpc8xxx_wdt_type) { | ||
| 248 | .prescaler = 0x10000, | ||
| 249 | }, | ||
| 250 | }, | ||
| 251 | { | ||
| 252 | .compatible = "fsl,mpc8610-wdt", | ||
| 253 | .data = &(struct mpc8xxx_wdt_type) { | ||
| 254 | .prescaler = 0x10000, | ||
| 255 | .hw_enabled = true, | ||
| 256 | }, | ||
| 257 | }, | ||
| 258 | { | ||
| 259 | .compatible = "fsl,mpc823-wdt", | ||
| 260 | .data = &(struct mpc8xxx_wdt_type) { | ||
| 261 | .prescaler = 0x800, | ||
| 262 | }, | ||
| 263 | }, | ||
| 264 | {}, | ||
| 265 | }; | ||
| 266 | MODULE_DEVICE_TABLE(of, mpc8xxx_wdt_match); | ||
| 267 | |||
| 268 | static struct of_platform_driver mpc8xxx_wdt_driver = { | ||
| 269 | .match_table = mpc8xxx_wdt_match, | ||
| 270 | .probe = mpc8xxx_wdt_probe, | ||
| 271 | .remove = __devexit_p(mpc8xxx_wdt_remove), | ||
| 272 | .driver = { | ||
| 273 | .name = "mpc8xxx_wdt", | ||
| 274 | .owner = THIS_MODULE, | ||
| 275 | }, | ||
| 276 | }; | ||
| 277 | |||
| 278 | /* | ||
| 279 | * We do wdt initialization in two steps: arch_initcall probes the wdt | ||
| 280 | * very early to start pinging the watchdog (misc devices are not yet | ||
| 281 | * available), and later module_init() just registers the misc device. | ||
| 282 | */ | ||
| 283 | static int __init mpc8xxx_wdt_init_late(void) | ||
| 284 | { | ||
| 285 | int ret; | ||
| 286 | |||
| 287 | if (!wd_base) | ||
| 288 | return -ENODEV; | ||
| 289 | |||
| 290 | ret = misc_register(&mpc8xxx_wdt_miscdev); | ||
| 291 | if (ret) { | ||
| 292 | pr_err("cannot register miscdev on minor=%d (err=%d)\n", | ||
| 293 | WATCHDOG_MINOR, ret); | ||
| 294 | return ret; | ||
| 295 | } | ||
| 296 | return 0; | ||
| 297 | } | ||
| 298 | module_init(mpc8xxx_wdt_init_late); | ||
| 299 | |||
| 300 | static int __init mpc8xxx_wdt_init(void) | ||
| 301 | { | ||
| 302 | return of_register_platform_driver(&mpc8xxx_wdt_driver); | ||
| 303 | } | ||
| 304 | arch_initcall(mpc8xxx_wdt_init); | ||
| 305 | |||
| 306 | static void __exit mpc8xxx_wdt_exit(void) | ||
| 307 | { | ||
| 308 | of_unregister_platform_driver(&mpc8xxx_wdt_driver); | ||
| 309 | } | ||
| 310 | module_exit(mpc8xxx_wdt_exit); | ||
| 311 | |||
| 312 | MODULE_AUTHOR("Dave Updegraff, Kumar Gala"); | ||
| 313 | MODULE_DESCRIPTION("Driver for watchdog timer in MPC8xx/MPC83xx/MPC86xx " | ||
| 314 | "uProcessors"); | ||
| 315 | MODULE_LICENSE("GPL"); | ||
| 316 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | ||
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c index 009573b81496..2a9bfa81f9d6 100644 --- a/drivers/watchdog/mpcore_wdt.c +++ b/drivers/watchdog/mpcore_wdt.c | |||
| @@ -29,9 +29,9 @@ | |||
| 29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
| 30 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
| 31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
| 32 | #include <linux/uaccess.h> | ||
| 32 | 33 | ||
| 33 | #include <asm/hardware/arm_twd.h> | 34 | #include <asm/hardware/arm_twd.h> |
| 34 | #include <asm/uaccess.h> | ||
| 35 | 35 | ||
| 36 | struct mpcore_wdt { | 36 | struct mpcore_wdt { |
| 37 | unsigned long timer_alive; | 37 | unsigned long timer_alive; |
| @@ -43,17 +43,20 @@ struct mpcore_wdt { | |||
| 43 | }; | 43 | }; |
| 44 | 44 | ||
| 45 | static struct platform_device *mpcore_wdt_dev; | 45 | static struct platform_device *mpcore_wdt_dev; |
| 46 | |||
| 47 | extern unsigned int mpcore_timer_rate; | 46 | extern unsigned int mpcore_timer_rate; |
| 48 | 47 | ||
| 49 | #define TIMER_MARGIN 60 | 48 | #define TIMER_MARGIN 60 |
| 50 | static int mpcore_margin = TIMER_MARGIN; | 49 | static int mpcore_margin = TIMER_MARGIN; |
| 51 | module_param(mpcore_margin, int, 0); | 50 | module_param(mpcore_margin, int, 0); |
| 52 | MODULE_PARM_DESC(mpcore_margin, "MPcore timer margin in seconds. (0<mpcore_margin<65536, default=" __MODULE_STRING(TIMER_MARGIN) ")"); | 51 | MODULE_PARM_DESC(mpcore_margin, |
| 52 | "MPcore timer margin in seconds. (0 < mpcore_margin < 65536, default=" | ||
| 53 | __MODULE_STRING(TIMER_MARGIN) ")"); | ||
| 53 | 54 | ||
| 54 | static int nowayout = WATCHDOG_NOWAYOUT; | 55 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 55 | module_param(nowayout, int, 0); | 56 | module_param(nowayout, int, 0); |
| 56 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 57 | MODULE_PARM_DESC(nowayout, |
| 58 | "Watchdog cannot be stopped once started (default=" | ||
| 59 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 57 | 60 | ||
| 58 | #define ONLY_TESTING 0 | 61 | #define ONLY_TESTING 0 |
| 59 | static int mpcore_noboot = ONLY_TESTING; | 62 | static int mpcore_noboot = ONLY_TESTING; |
| @@ -70,14 +73,12 @@ static irqreturn_t mpcore_wdt_fire(int irq, void *arg) | |||
| 70 | 73 | ||
| 71 | /* Check it really was our interrupt */ | 74 | /* Check it really was our interrupt */ |
| 72 | if (readl(wdt->base + TWD_WDOG_INTSTAT)) { | 75 | if (readl(wdt->base + TWD_WDOG_INTSTAT)) { |
| 73 | dev_printk(KERN_CRIT, wdt->dev, "Triggered - Reboot ignored.\n"); | 76 | dev_printk(KERN_CRIT, wdt->dev, |
| 74 | 77 | "Triggered - Reboot ignored.\n"); | |
| 75 | /* Clear the interrupt on the watchdog */ | 78 | /* Clear the interrupt on the watchdog */ |
| 76 | writel(1, wdt->base + TWD_WDOG_INTSTAT); | 79 | writel(1, wdt->base + TWD_WDOG_INTSTAT); |
| 77 | |||
| 78 | return IRQ_HANDLED; | 80 | return IRQ_HANDLED; |
| 79 | } | 81 | } |
| 80 | |||
| 81 | return IRQ_NONE; | 82 | return IRQ_NONE; |
| 82 | } | 83 | } |
| 83 | 84 | ||
| @@ -96,22 +97,26 @@ static void mpcore_wdt_keepalive(struct mpcore_wdt *wdt) | |||
| 96 | count = (mpcore_timer_rate / 256) * mpcore_margin; | 97 | count = (mpcore_timer_rate / 256) * mpcore_margin; |
| 97 | 98 | ||
| 98 | /* Reload the counter */ | 99 | /* Reload the counter */ |
| 100 | spin_lock(&wdt_lock); | ||
| 99 | writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD); | 101 | writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD); |
| 100 | |||
| 101 | wdt->perturb = wdt->perturb ? 0 : 1; | 102 | wdt->perturb = wdt->perturb ? 0 : 1; |
| 103 | spin_unlock(&wdt_lock); | ||
| 102 | } | 104 | } |
| 103 | 105 | ||
| 104 | static void mpcore_wdt_stop(struct mpcore_wdt *wdt) | 106 | static void mpcore_wdt_stop(struct mpcore_wdt *wdt) |
| 105 | { | 107 | { |
| 108 | spin_lock(&wdt_lock); | ||
| 106 | writel(0x12345678, wdt->base + TWD_WDOG_DISABLE); | 109 | writel(0x12345678, wdt->base + TWD_WDOG_DISABLE); |
| 107 | writel(0x87654321, wdt->base + TWD_WDOG_DISABLE); | 110 | writel(0x87654321, wdt->base + TWD_WDOG_DISABLE); |
| 108 | writel(0x0, wdt->base + TWD_WDOG_CONTROL); | 111 | writel(0x0, wdt->base + TWD_WDOG_CONTROL); |
| 112 | spin_unlock(&wdt_lock); | ||
| 109 | } | 113 | } |
| 110 | 114 | ||
| 111 | static void mpcore_wdt_start(struct mpcore_wdt *wdt) | 115 | static void mpcore_wdt_start(struct mpcore_wdt *wdt) |
| 112 | { | 116 | { |
| 113 | dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n"); | 117 | dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n"); |
| 114 | 118 | ||
| 119 | spin_lock(&wdt_lock); | ||
| 115 | /* This loads the count register but does NOT start the count yet */ | 120 | /* This loads the count register but does NOT start the count yet */ |
| 116 | mpcore_wdt_keepalive(wdt); | 121 | mpcore_wdt_keepalive(wdt); |
| 117 | 122 | ||
| @@ -122,6 +127,7 @@ static void mpcore_wdt_start(struct mpcore_wdt *wdt) | |||
| 122 | /* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */ | 127 | /* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */ |
| 123 | writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL); | 128 | writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL); |
| 124 | } | 129 | } |
| 130 | spin_unlock(&wdt_lock); | ||
| 125 | } | 131 | } |
| 126 | 132 | ||
| 127 | static int mpcore_wdt_set_heartbeat(int t) | 133 | static int mpcore_wdt_set_heartbeat(int t) |
| @@ -164,10 +170,11 @@ static int mpcore_wdt_release(struct inode *inode, struct file *file) | |||
| 164 | * Shut off the timer. | 170 | * Shut off the timer. |
| 165 | * Lock it in if it's a module and we set nowayout | 171 | * Lock it in if it's a module and we set nowayout |
| 166 | */ | 172 | */ |
| 167 | if (wdt->expect_close == 42) { | 173 | if (wdt->expect_close == 42) |
| 168 | mpcore_wdt_stop(wdt); | 174 | mpcore_wdt_stop(wdt); |
| 169 | } else { | 175 | else { |
| 170 | dev_printk(KERN_CRIT, wdt->dev, "unexpected close, not stopping watchdog!\n"); | 176 | dev_printk(KERN_CRIT, wdt->dev, |
| 177 | "unexpected close, not stopping watchdog!\n"); | ||
| 171 | mpcore_wdt_keepalive(wdt); | 178 | mpcore_wdt_keepalive(wdt); |
| 172 | } | 179 | } |
| 173 | clear_bit(0, &wdt->timer_alive); | 180 | clear_bit(0, &wdt->timer_alive); |
| @@ -175,7 +182,8 @@ static int mpcore_wdt_release(struct inode *inode, struct file *file) | |||
| 175 | return 0; | 182 | return 0; |
| 176 | } | 183 | } |
| 177 | 184 | ||
| 178 | static ssize_t mpcore_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) | 185 | static ssize_t mpcore_wdt_write(struct file *file, const char *data, |
| 186 | size_t len, loff_t *ppos) | ||
| 179 | { | 187 | { |
| 180 | struct mpcore_wdt *wdt = file->private_data; | 188 | struct mpcore_wdt *wdt = file->private_data; |
| 181 | 189 | ||
| @@ -210,8 +218,8 @@ static struct watchdog_info ident = { | |||
| 210 | .identity = "MPcore Watchdog", | 218 | .identity = "MPcore Watchdog", |
| 211 | }; | 219 | }; |
| 212 | 220 | ||
| 213 | static int mpcore_wdt_ioctl(struct inode *inode, struct file *file, | 221 | static long mpcore_wdt_ioctl(struct file *file, unsigned int cmd, |
| 214 | unsigned int cmd, unsigned long arg) | 222 | unsigned long arg) |
| 215 | { | 223 | { |
| 216 | struct mpcore_wdt *wdt = file->private_data; | 224 | struct mpcore_wdt *wdt = file->private_data; |
| 217 | int ret; | 225 | int ret; |
| @@ -235,6 +243,12 @@ static int mpcore_wdt_ioctl(struct inode *inode, struct file *file, | |||
| 235 | ret = 0; | 243 | ret = 0; |
| 236 | break; | 244 | break; |
| 237 | 245 | ||
| 246 | case WDIOC_GETSTATUS: | ||
| 247 | case WDIOC_GETBOOTSTATUS: | ||
| 248 | uarg.i = 0; | ||
| 249 | ret = 0; | ||
| 250 | break; | ||
| 251 | |||
| 238 | case WDIOC_SETOPTIONS: | 252 | case WDIOC_SETOPTIONS: |
| 239 | ret = -EINVAL; | 253 | ret = -EINVAL; |
| 240 | if (uarg.i & WDIOS_DISABLECARD) { | 254 | if (uarg.i & WDIOS_DISABLECARD) { |
| @@ -247,12 +261,6 @@ static int mpcore_wdt_ioctl(struct inode *inode, struct file *file, | |||
| 247 | } | 261 | } |
| 248 | break; | 262 | break; |
| 249 | 263 | ||
| 250 | case WDIOC_GETSTATUS: | ||
| 251 | case WDIOC_GETBOOTSTATUS: | ||
| 252 | uarg.i = 0; | ||
| 253 | ret = 0; | ||
| 254 | break; | ||
| 255 | |||
| 256 | case WDIOC_KEEPALIVE: | 264 | case WDIOC_KEEPALIVE: |
| 257 | mpcore_wdt_keepalive(wdt); | 265 | mpcore_wdt_keepalive(wdt); |
| 258 | ret = 0; | 266 | ret = 0; |
| @@ -301,7 +309,7 @@ static const struct file_operations mpcore_wdt_fops = { | |||
| 301 | .owner = THIS_MODULE, | 309 | .owner = THIS_MODULE, |
| 302 | .llseek = no_llseek, | 310 | .llseek = no_llseek, |
| 303 | .write = mpcore_wdt_write, | 311 | .write = mpcore_wdt_write, |
| 304 | .ioctl = mpcore_wdt_ioctl, | 312 | .unlocked_ioctl = mpcore_wdt_ioctl, |
| 305 | .open = mpcore_wdt_open, | 313 | .open = mpcore_wdt_open, |
| 306 | .release = mpcore_wdt_release, | 314 | .release = mpcore_wdt_release, |
| 307 | }; | 315 | }; |
| @@ -349,14 +357,17 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev) | |||
| 349 | mpcore_wdt_miscdev.parent = &dev->dev; | 357 | mpcore_wdt_miscdev.parent = &dev->dev; |
| 350 | ret = misc_register(&mpcore_wdt_miscdev); | 358 | ret = misc_register(&mpcore_wdt_miscdev); |
| 351 | if (ret) { | 359 | if (ret) { |
| 352 | dev_printk(KERN_ERR, _dev, "cannot register miscdev on minor=%d (err=%d)\n", | 360 | dev_printk(KERN_ERR, _dev, |
| 353 | WATCHDOG_MINOR, ret); | 361 | "cannot register miscdev on minor=%d (err=%d)\n", |
| 362 | WATCHDOG_MINOR, ret); | ||
| 354 | goto err_misc; | 363 | goto err_misc; |
| 355 | } | 364 | } |
| 356 | 365 | ||
| 357 | ret = request_irq(wdt->irq, mpcore_wdt_fire, IRQF_DISABLED, "mpcore_wdt", wdt); | 366 | ret = request_irq(wdt->irq, mpcore_wdt_fire, IRQF_DISABLED, |
| 367 | "mpcore_wdt", wdt); | ||
| 358 | if (ret) { | 368 | if (ret) { |
| 359 | dev_printk(KERN_ERR, _dev, "cannot register IRQ%d for watchdog\n", wdt->irq); | 369 | dev_printk(KERN_ERR, _dev, |
| 370 | "cannot register IRQ%d for watchdog\n", wdt->irq); | ||
| 360 | goto err_irq; | 371 | goto err_irq; |
| 361 | } | 372 | } |
| 362 | 373 | ||
| @@ -366,13 +377,13 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev) | |||
| 366 | 377 | ||
| 367 | return 0; | 378 | return 0; |
| 368 | 379 | ||
| 369 | err_irq: | 380 | err_irq: |
| 370 | misc_deregister(&mpcore_wdt_miscdev); | 381 | misc_deregister(&mpcore_wdt_miscdev); |
| 371 | err_misc: | 382 | err_misc: |
| 372 | iounmap(wdt->base); | 383 | iounmap(wdt->base); |
| 373 | err_free: | 384 | err_free: |
| 374 | kfree(wdt); | 385 | kfree(wdt); |
| 375 | err_out: | 386 | err_out: |
| 376 | return ret; | 387 | return ret; |
| 377 | } | 388 | } |
| 378 | 389 | ||
| @@ -415,7 +426,7 @@ static int __init mpcore_wdt_init(void) | |||
| 415 | */ | 426 | */ |
| 416 | if (mpcore_wdt_set_heartbeat(mpcore_margin)) { | 427 | if (mpcore_wdt_set_heartbeat(mpcore_margin)) { |
| 417 | mpcore_wdt_set_heartbeat(TIMER_MARGIN); | 428 | mpcore_wdt_set_heartbeat(TIMER_MARGIN); |
| 418 | printk(KERN_INFO "mpcore_margin value must be 0<mpcore_margin<65536, using %d\n", | 429 | printk(KERN_INFO "mpcore_margin value must be 0 < mpcore_margin < 65536, using %d\n", |
| 419 | TIMER_MARGIN); | 430 | TIMER_MARGIN); |
| 420 | } | 431 | } |
| 421 | 432 | ||
diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c index a8e67383784e..b4b7b0a4c119 100644 --- a/drivers/watchdog/mtx-1_wdt.c +++ b/drivers/watchdog/mtx-1_wdt.c | |||
| @@ -1,7 +1,8 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Driver for the MTX-1 Watchdog. | 2 | * Driver for the MTX-1 Watchdog. |
| 3 | * | 3 | * |
| 4 | * (C) Copyright 2005 4G Systems <info@4g-systems.biz>, All Rights Reserved. | 4 | * (C) Copyright 2005 4G Systems <info@4g-systems.biz>, |
| 5 | * All Rights Reserved. | ||
| 5 | * http://www.4g-systems.biz | 6 | * http://www.4g-systems.biz |
| 6 | * | 7 | * |
| 7 | * (C) Copyright 2007 OpenWrt.org, Florian Fainelli <florian@openwrt.org> | 8 | * (C) Copyright 2007 OpenWrt.org, Florian Fainelli <florian@openwrt.org> |
| @@ -46,12 +47,11 @@ | |||
| 46 | #include <linux/jiffies.h> | 47 | #include <linux/jiffies.h> |
| 47 | #include <linux/watchdog.h> | 48 | #include <linux/watchdog.h> |
| 48 | #include <linux/platform_device.h> | 49 | #include <linux/platform_device.h> |
| 49 | 50 | #include <linux/io.h> | |
| 50 | #include <asm/io.h> | 51 | #include <linux/uaccess.h> |
| 51 | #include <asm/uaccess.h> | 52 | #include <linux/gpio.h> |
| 52 | 53 | ||
| 53 | #include <asm/mach-au1x00/au1000.h> | 54 | #include <asm/mach-au1x00/au1000.h> |
| 54 | #include <asm/gpio.h> | ||
| 55 | 55 | ||
| 56 | #define MTX1_WDT_INTERVAL (5 * HZ) | 56 | #define MTX1_WDT_INTERVAL (5 * HZ) |
| 57 | 57 | ||
| @@ -59,6 +59,7 @@ static int ticks = 100 * HZ; | |||
| 59 | 59 | ||
| 60 | static struct { | 60 | static struct { |
| 61 | struct completion stop; | 61 | struct completion stop; |
| 62 | spinlock_t lock; | ||
| 62 | int running; | 63 | int running; |
| 63 | struct timer_list timer; | 64 | struct timer_list timer; |
| 64 | int queue; | 65 | int queue; |
| @@ -71,6 +72,7 @@ static void mtx1_wdt_trigger(unsigned long unused) | |||
| 71 | { | 72 | { |
| 72 | u32 tmp; | 73 | u32 tmp; |
| 73 | 74 | ||
| 75 | spin_lock(&mtx1_wdt_device.lock); | ||
| 74 | if (mtx1_wdt_device.running) | 76 | if (mtx1_wdt_device.running) |
| 75 | ticks--; | 77 | ticks--; |
| 76 | /* | 78 | /* |
| @@ -79,13 +81,13 @@ static void mtx1_wdt_trigger(unsigned long unused) | |||
| 79 | tmp = au_readl(GPIO2_DIR); | 81 | tmp = au_readl(GPIO2_DIR); |
| 80 | tmp = (tmp & ~(1 << mtx1_wdt_device.gpio)) | | 82 | tmp = (tmp & ~(1 << mtx1_wdt_device.gpio)) | |
| 81 | ((~tmp) & (1 << mtx1_wdt_device.gpio)); | 83 | ((~tmp) & (1 << mtx1_wdt_device.gpio)); |
| 82 | au_writel (tmp, GPIO2_DIR); | 84 | au_writel(tmp, GPIO2_DIR); |
| 83 | 85 | ||
| 84 | if (mtx1_wdt_device.queue && ticks) | 86 | if (mtx1_wdt_device.queue && ticks) |
| 85 | mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL); | 87 | mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL); |
| 86 | else { | 88 | else |
| 87 | complete(&mtx1_wdt_device.stop); | 89 | complete(&mtx1_wdt_device.stop); |
| 88 | } | 90 | spin_unlock(&mtx1_wdt_device.lock); |
| 89 | } | 91 | } |
| 90 | 92 | ||
| 91 | static void mtx1_wdt_reset(void) | 93 | static void mtx1_wdt_reset(void) |
| @@ -96,23 +98,25 @@ static void mtx1_wdt_reset(void) | |||
| 96 | 98 | ||
| 97 | static void mtx1_wdt_start(void) | 99 | static void mtx1_wdt_start(void) |
| 98 | { | 100 | { |
| 101 | spin_lock_irqsave(&mtx1_wdt_device.lock, flags); | ||
| 99 | if (!mtx1_wdt_device.queue) { | 102 | if (!mtx1_wdt_device.queue) { |
| 100 | mtx1_wdt_device.queue = 1; | 103 | mtx1_wdt_device.queue = 1; |
| 101 | gpio_set_value(mtx1_wdt_device.gpio, 1); | 104 | gpio_set_value(mtx1_wdt_device.gpio, 1); |
| 102 | mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL); | 105 | mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL); |
| 103 | } | 106 | } |
| 104 | mtx1_wdt_device.running++; | 107 | mtx1_wdt_device.running++; |
| 108 | spin_unlock_irqrestore(&mtx1_wdt_device.lock, flags); | ||
| 105 | } | 109 | } |
| 106 | 110 | ||
| 107 | static int mtx1_wdt_stop(void) | 111 | static int mtx1_wdt_stop(void) |
| 108 | { | 112 | { |
| 113 | spin_lock_irqsave(&mtx1_wdt_device.lock, flags); | ||
| 109 | if (mtx1_wdt_device.queue) { | 114 | if (mtx1_wdt_device.queue) { |
| 110 | mtx1_wdt_device.queue = 0; | 115 | mtx1_wdt_device.queue = 0; |
| 111 | gpio_set_value(mtx1_wdt_device.gpio, 0); | 116 | gpio_set_value(mtx1_wdt_device.gpio, 0); |
| 112 | } | 117 | } |
| 113 | |||
| 114 | ticks = mtx1_wdt_device.default_ticks; | 118 | ticks = mtx1_wdt_device.default_ticks; |
| 115 | 119 | spin_unlock_irqrestore(&mtx1_wdt_device.lock, flags); | |
| 116 | return 0; | 120 | return 0; |
| 117 | } | 121 | } |
| 118 | 122 | ||
| @@ -122,7 +126,6 @@ static int mtx1_wdt_open(struct inode *inode, struct file *file) | |||
| 122 | { | 126 | { |
| 123 | if (test_and_set_bit(0, &mtx1_wdt_device.inuse)) | 127 | if (test_and_set_bit(0, &mtx1_wdt_device.inuse)) |
| 124 | return -EBUSY; | 128 | return -EBUSY; |
| 125 | |||
| 126 | return nonseekable_open(inode, file); | 129 | return nonseekable_open(inode, file); |
| 127 | } | 130 | } |
| 128 | 131 | ||
| @@ -133,54 +136,51 @@ static int mtx1_wdt_release(struct inode *inode, struct file *file) | |||
| 133 | return 0; | 136 | return 0; |
| 134 | } | 137 | } |
| 135 | 138 | ||
| 136 | static int mtx1_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 139 | static long mtx1_wdt_ioctl(struct file *file, unsigned int cmd, |
| 140 | unsigned long arg) | ||
| 137 | { | 141 | { |
| 138 | void __user *argp = (void __user *)arg; | 142 | void __user *argp = (void __user *)arg; |
| 143 | int __user *p = (int __user *)argp; | ||
| 139 | unsigned int value; | 144 | unsigned int value; |
| 140 | static struct watchdog_info ident = | 145 | static const struct watchdog_info ident = { |
| 141 | { | ||
| 142 | .options = WDIOF_CARDRESET, | 146 | .options = WDIOF_CARDRESET, |
| 143 | .identity = "MTX-1 WDT", | 147 | .identity = "MTX-1 WDT", |
| 144 | }; | 148 | }; |
| 145 | 149 | ||
| 146 | switch(cmd) { | 150 | switch (cmd) { |
| 147 | case WDIOC_KEEPALIVE: | 151 | case WDIOC_GETSUPPORT: |
| 148 | mtx1_wdt_reset(); | 152 | if (copy_to_user(argp, &ident, sizeof(ident))) |
| 149 | break; | 153 | return -EFAULT; |
| 150 | case WDIOC_GETSTATUS: | 154 | break; |
| 151 | case WDIOC_GETBOOTSTATUS: | 155 | case WDIOC_GETSTATUS: |
| 152 | if ( copy_to_user(argp, &value, sizeof(int)) ) | 156 | case WDIOC_GETBOOTSTATUS: |
| 153 | return -EFAULT; | 157 | put_user(0, p); |
| 154 | break; | 158 | break; |
| 155 | case WDIOC_GETSUPPORT: | 159 | case WDIOC_SETOPTIONS: |
| 156 | if ( copy_to_user(argp, &ident, sizeof(ident)) ) | 160 | if (get_user(value, p)) |
| 157 | return -EFAULT; | 161 | return -EFAULT; |
| 158 | break; | 162 | if (value & WDIOS_ENABLECARD) |
| 159 | case WDIOC_SETOPTIONS: | 163 | mtx1_wdt_start(); |
| 160 | if ( copy_from_user(&value, argp, sizeof(int)) ) | 164 | else if (value & WDIOS_DISABLECARD) |
| 161 | return -EFAULT; | 165 | mtx1_wdt_stop(); |
| 162 | switch(value) { | 166 | else |
| 163 | case WDIOS_ENABLECARD: | 167 | return -EINVAL; |
| 164 | mtx1_wdt_start(); | 168 | return 0; |
| 165 | break; | 169 | case WDIOC_KEEPALIVE: |
| 166 | case WDIOS_DISABLECARD: | 170 | mtx1_wdt_reset(); |
| 167 | return mtx1_wdt_stop(); | 171 | break; |
| 168 | default: | 172 | default: |
| 169 | return -EINVAL; | 173 | return -ENOTTY; |
| 170 | } | ||
| 171 | break; | ||
| 172 | default: | ||
| 173 | return -ENOTTY; | ||
| 174 | } | 174 | } |
| 175 | return 0; | 175 | return 0; |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | 178 | ||
| 179 | static ssize_t mtx1_wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos) | 179 | static ssize_t mtx1_wdt_write(struct file *file, const char *buf, |
| 180 | size_t count, loff_t *ppos) | ||
| 180 | { | 181 | { |
| 181 | if (!count) | 182 | if (!count) |
| 182 | return -EIO; | 183 | return -EIO; |
| 183 | |||
| 184 | mtx1_wdt_reset(); | 184 | mtx1_wdt_reset(); |
| 185 | return count; | 185 | return count; |
| 186 | } | 186 | } |
| @@ -188,17 +188,17 @@ static ssize_t mtx1_wdt_write(struct file *file, const char *buf, size_t count, | |||
| 188 | static const struct file_operations mtx1_wdt_fops = { | 188 | static const struct file_operations mtx1_wdt_fops = { |
| 189 | .owner = THIS_MODULE, | 189 | .owner = THIS_MODULE, |
| 190 | .llseek = no_llseek, | 190 | .llseek = no_llseek, |
| 191 | .ioctl = mtx1_wdt_ioctl, | 191 | .unlocked_ioctl = mtx1_wdt_ioctl, |
| 192 | .open = mtx1_wdt_open, | 192 | .open = mtx1_wdt_open, |
| 193 | .write = mtx1_wdt_write, | 193 | .write = mtx1_wdt_write, |
| 194 | .release = mtx1_wdt_release | 194 | .release = mtx1_wdt_release, |
| 195 | }; | 195 | }; |
| 196 | 196 | ||
| 197 | 197 | ||
| 198 | static struct miscdevice mtx1_wdt_misc = { | 198 | static struct miscdevice mtx1_wdt_misc = { |
| 199 | .minor = WATCHDOG_MINOR, | 199 | .minor = WATCHDOG_MINOR, |
| 200 | .name = "watchdog", | 200 | .name = "watchdog", |
| 201 | .fops = &mtx1_wdt_fops | 201 | .fops = &mtx1_wdt_fops, |
| 202 | }; | 202 | }; |
| 203 | 203 | ||
| 204 | 204 | ||
| @@ -208,29 +208,26 @@ static int mtx1_wdt_probe(struct platform_device *pdev) | |||
| 208 | 208 | ||
| 209 | mtx1_wdt_device.gpio = pdev->resource[0].start; | 209 | mtx1_wdt_device.gpio = pdev->resource[0].start; |
| 210 | 210 | ||
| 211 | if ((ret = misc_register(&mtx1_wdt_misc)) < 0) { | 211 | spin_lock_init(&mtx1_wdt_device.lock); |
| 212 | printk(KERN_ERR " mtx-1_wdt : failed to register\n"); | ||
| 213 | return ret; | ||
| 214 | } | ||
| 215 | |||
| 216 | init_completion(&mtx1_wdt_device.stop); | 212 | init_completion(&mtx1_wdt_device.stop); |
| 217 | mtx1_wdt_device.queue = 0; | 213 | mtx1_wdt_device.queue = 0; |
| 218 | |||
| 219 | clear_bit(0, &mtx1_wdt_device.inuse); | 214 | clear_bit(0, &mtx1_wdt_device.inuse); |
| 220 | |||
| 221 | setup_timer(&mtx1_wdt_device.timer, mtx1_wdt_trigger, 0L); | 215 | setup_timer(&mtx1_wdt_device.timer, mtx1_wdt_trigger, 0L); |
| 222 | |||
| 223 | mtx1_wdt_device.default_ticks = ticks; | 216 | mtx1_wdt_device.default_ticks = ticks; |
| 224 | 217 | ||
| 218 | ret = misc_register(&mtx1_wdt_misc); | ||
| 219 | if (ret < 0) { | ||
| 220 | printk(KERN_ERR " mtx-1_wdt : failed to register\n"); | ||
| 221 | return ret; | ||
| 222 | } | ||
| 225 | mtx1_wdt_start(); | 223 | mtx1_wdt_start(); |
| 226 | |||
| 227 | printk(KERN_INFO "MTX-1 Watchdog driver\n"); | 224 | printk(KERN_INFO "MTX-1 Watchdog driver\n"); |
| 228 | |||
| 229 | return 0; | 225 | return 0; |
| 230 | } | 226 | } |
| 231 | 227 | ||
| 232 | static int mtx1_wdt_remove(struct platform_device *pdev) | 228 | static int mtx1_wdt_remove(struct platform_device *pdev) |
| 233 | { | 229 | { |
| 230 | /* FIXME: do we need to lock this test ? */ | ||
| 234 | if (mtx1_wdt_device.queue) { | 231 | if (mtx1_wdt_device.queue) { |
| 235 | mtx1_wdt_device.queue = 0; | 232 | mtx1_wdt_device.queue = 0; |
| 236 | wait_for_completion(&mtx1_wdt_device.stop); | 233 | wait_for_completion(&mtx1_wdt_device.stop); |
diff --git a/drivers/watchdog/mv64x60_wdt.c b/drivers/watchdog/mv64x60_wdt.c index b59ca3273967..acf589dc057c 100644 --- a/drivers/watchdog/mv64x60_wdt.c +++ b/drivers/watchdog/mv64x60_wdt.c | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | * and services the watchdog. | 8 | * and services the watchdog. |
| 9 | * | 9 | * |
| 10 | * Derived from mpc8xx_wdt.c, with the following copyright. | 10 | * Derived from mpc8xx_wdt.c, with the following copyright. |
| 11 | * | 11 | * |
| 12 | * 2002 (c) Florian Schirmer <jolt@tuxbox.org> This file is licensed under | 12 | * 2002 (c) Florian Schirmer <jolt@tuxbox.org> This file is licensed under |
| 13 | * the terms of the GNU General Public License version 2. This program | 13 | * the terms of the GNU General Public License version 2. This program |
| 14 | * is licensed "as is" without any warranty of any kind, whether express | 14 | * is licensed "as is" without any warranty of any kind, whether express |
| @@ -22,10 +22,9 @@ | |||
| 22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
| 23 | #include <linux/watchdog.h> | 23 | #include <linux/watchdog.h> |
| 24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
| 25 | |||
| 26 | #include <linux/mv643xx.h> | 25 | #include <linux/mv643xx.h> |
| 27 | #include <asm/uaccess.h> | 26 | #include <linux/uaccess.h> |
| 28 | #include <asm/io.h> | 27 | #include <linux/io.h> |
| 29 | 28 | ||
| 30 | #define MV64x60_WDT_WDC_OFFSET 0 | 29 | #define MV64x60_WDT_WDC_OFFSET 0 |
| 31 | 30 | ||
| @@ -61,7 +60,9 @@ static DEFINE_SPINLOCK(mv64x60_wdt_spinlock); | |||
| 61 | 60 | ||
| 62 | static int nowayout = WATCHDOG_NOWAYOUT; | 61 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 63 | module_param(nowayout, int, 0); | 62 | module_param(nowayout, int, 0); |
| 64 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 63 | MODULE_PARM_DESC(nowayout, |
| 64 | "Watchdog cannot be stopped once started (default=" | ||
| 65 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 65 | 66 | ||
| 66 | static int mv64x60_wdt_toggle_wdc(int enabled_predicate, int field_shift) | 67 | static int mv64x60_wdt_toggle_wdc(int enabled_predicate, int field_shift) |
| 67 | { | 68 | { |
| @@ -150,7 +151,7 @@ static int mv64x60_wdt_release(struct inode *inode, struct file *file) | |||
| 150 | } | 151 | } |
| 151 | 152 | ||
| 152 | static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data, | 153 | static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data, |
| 153 | size_t len, loff_t * ppos) | 154 | size_t len, loff_t *ppos) |
| 154 | { | 155 | { |
| 155 | if (len) { | 156 | if (len) { |
| 156 | if (!nowayout) { | 157 | if (!nowayout) { |
| @@ -160,7 +161,7 @@ static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data, | |||
| 160 | 161 | ||
| 161 | for (i = 0; i != len; i++) { | 162 | for (i = 0; i != len; i++) { |
| 162 | char c; | 163 | char c; |
| 163 | if(get_user(c, data + i)) | 164 | if (get_user(c, data + i)) |
| 164 | return -EFAULT; | 165 | return -EFAULT; |
| 165 | if (c == 'V') | 166 | if (c == 'V') |
| 166 | expect_close = 42; | 167 | expect_close = 42; |
| @@ -172,8 +173,8 @@ static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data, | |||
| 172 | return len; | 173 | return len; |
| 173 | } | 174 | } |
| 174 | 175 | ||
| 175 | static int mv64x60_wdt_ioctl(struct inode *inode, struct file *file, | 176 | static long mv64x60_wdt_ioctl(struct file *file, |
| 176 | unsigned int cmd, unsigned long arg) | 177 | unsigned int cmd, unsigned long arg) |
| 177 | { | 178 | { |
| 178 | int timeout; | 179 | int timeout; |
| 179 | int options; | 180 | int options; |
| @@ -240,7 +241,7 @@ static const struct file_operations mv64x60_wdt_fops = { | |||
| 240 | .owner = THIS_MODULE, | 241 | .owner = THIS_MODULE, |
| 241 | .llseek = no_llseek, | 242 | .llseek = no_llseek, |
| 242 | .write = mv64x60_wdt_write, | 243 | .write = mv64x60_wdt_write, |
| 243 | .ioctl = mv64x60_wdt_ioctl, | 244 | .unlocked_ioctl = mv64x60_wdt_ioctl, |
| 244 | .open = mv64x60_wdt_open, | 245 | .open = mv64x60_wdt_open, |
| 245 | .release = mv64x60_wdt_release, | 246 | .release = mv64x60_wdt_release, |
| 246 | }; | 247 | }; |
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c index 74a10d50607b..3a11dadfd8e7 100644 --- a/drivers/watchdog/omap_wdt.c +++ b/drivers/watchdog/omap_wdt.c | |||
| @@ -40,11 +40,9 @@ | |||
| 40 | #include <linux/moduleparam.h> | 40 | #include <linux/moduleparam.h> |
| 41 | #include <linux/clk.h> | 41 | #include <linux/clk.h> |
| 42 | #include <linux/bitops.h> | 42 | #include <linux/bitops.h> |
| 43 | 43 | #include <linux/io.h> | |
| 44 | #include <asm/io.h> | 44 | #include <linux/uaccess.h> |
| 45 | #include <asm/uaccess.h> | ||
| 46 | #include <mach/hardware.h> | 45 | #include <mach/hardware.h> |
| 47 | |||
| 48 | #include <mach/prcm.h> | 46 | #include <mach/prcm.h> |
| 49 | 47 | ||
| 50 | #include "omap_wdt.h" | 48 | #include "omap_wdt.h" |
| @@ -54,11 +52,12 @@ module_param(timer_margin, uint, 0); | |||
| 54 | MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)"); | 52 | MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)"); |
| 55 | 53 | ||
| 56 | static int omap_wdt_users; | 54 | static int omap_wdt_users; |
| 57 | static struct clk *armwdt_ck = NULL; | 55 | static struct clk *armwdt_ck; |
| 58 | static struct clk *mpu_wdt_ick = NULL; | 56 | static struct clk *mpu_wdt_ick; |
| 59 | static struct clk *mpu_wdt_fck = NULL; | 57 | static struct clk *mpu_wdt_fck; |
| 60 | 58 | ||
| 61 | static unsigned int wdt_trgr_pattern = 0x1234; | 59 | static unsigned int wdt_trgr_pattern = 0x1234; |
| 60 | static spinlock_t wdt_lock; | ||
| 62 | 61 | ||
| 63 | static void omap_wdt_ping(void) | 62 | static void omap_wdt_ping(void) |
| 64 | { | 63 | { |
| @@ -174,30 +173,29 @@ static int omap_wdt_release(struct inode *inode, struct file *file) | |||
| 174 | return 0; | 173 | return 0; |
| 175 | } | 174 | } |
| 176 | 175 | ||
| 177 | static ssize_t | 176 | static ssize_t omap_wdt_write(struct file *file, const char __user *data, |
| 178 | omap_wdt_write(struct file *file, const char __user *data, | ||
| 179 | size_t len, loff_t *ppos) | 177 | size_t len, loff_t *ppos) |
| 180 | { | 178 | { |
| 181 | /* Refresh LOAD_TIME. */ | 179 | /* Refresh LOAD_TIME. */ |
| 182 | if (len) | 180 | if (len) { |
| 181 | spin_lock(&wdt_lock); | ||
| 183 | omap_wdt_ping(); | 182 | omap_wdt_ping(); |
| 183 | spin_unlock(&wdt_lock); | ||
| 184 | } | ||
| 184 | return len; | 185 | return len; |
| 185 | } | 186 | } |
| 186 | 187 | ||
| 187 | static int | 188 | static long omap_wdt_ioctl(struct file *file, unsigned int cmd, |
| 188 | omap_wdt_ioctl(struct inode *inode, struct file *file, | 189 | unsigned long arg) |
| 189 | unsigned int cmd, unsigned long arg) | ||
| 190 | { | 190 | { |
| 191 | int new_margin; | 191 | int new_margin; |
| 192 | static struct watchdog_info ident = { | 192 | static const struct watchdog_info ident = { |
| 193 | .identity = "OMAP Watchdog", | 193 | .identity = "OMAP Watchdog", |
| 194 | .options = WDIOF_SETTIMEOUT, | 194 | .options = WDIOF_SETTIMEOUT, |
| 195 | .firmware_version = 0, | 195 | .firmware_version = 0, |
| 196 | }; | 196 | }; |
| 197 | 197 | ||
| 198 | switch (cmd) { | 198 | switch (cmd) { |
| 199 | default: | ||
| 200 | return -ENOTTY; | ||
| 201 | case WDIOC_GETSUPPORT: | 199 | case WDIOC_GETSUPPORT: |
| 202 | return copy_to_user((struct watchdog_info __user *)arg, &ident, | 200 | return copy_to_user((struct watchdog_info __user *)arg, &ident, |
| 203 | sizeof(ident)); | 201 | sizeof(ident)); |
| @@ -211,28 +209,34 @@ omap_wdt_ioctl(struct inode *inode, struct file *file, | |||
| 211 | return put_user(omap_prcm_get_reset_sources(), | 209 | return put_user(omap_prcm_get_reset_sources(), |
| 212 | (int __user *)arg); | 210 | (int __user *)arg); |
| 213 | case WDIOC_KEEPALIVE: | 211 | case WDIOC_KEEPALIVE: |
| 212 | spin_lock(&wdt_lock); | ||
| 214 | omap_wdt_ping(); | 213 | omap_wdt_ping(); |
| 214 | spin_unlock(&wdt_lock); | ||
| 215 | return 0; | 215 | return 0; |
| 216 | case WDIOC_SETTIMEOUT: | 216 | case WDIOC_SETTIMEOUT: |
| 217 | if (get_user(new_margin, (int __user *)arg)) | 217 | if (get_user(new_margin, (int __user *)arg)) |
| 218 | return -EFAULT; | 218 | return -EFAULT; |
| 219 | omap_wdt_adjust_timeout(new_margin); | 219 | omap_wdt_adjust_timeout(new_margin); |
| 220 | 220 | ||
| 221 | spin_lock(&wdt_lock); | ||
| 221 | omap_wdt_disable(); | 222 | omap_wdt_disable(); |
| 222 | omap_wdt_set_timeout(); | 223 | omap_wdt_set_timeout(); |
| 223 | omap_wdt_enable(); | 224 | omap_wdt_enable(); |
| 224 | 225 | ||
| 225 | omap_wdt_ping(); | 226 | omap_wdt_ping(); |
| 227 | spin_unlock(&wdt_lock); | ||
| 226 | /* Fall */ | 228 | /* Fall */ |
| 227 | case WDIOC_GETTIMEOUT: | 229 | case WDIOC_GETTIMEOUT: |
| 228 | return put_user(timer_margin, (int __user *)arg); | 230 | return put_user(timer_margin, (int __user *)arg); |
| 231 | default: | ||
| 232 | return -ENOTTY; | ||
| 229 | } | 233 | } |
| 230 | } | 234 | } |
| 231 | 235 | ||
| 232 | static const struct file_operations omap_wdt_fops = { | 236 | static const struct file_operations omap_wdt_fops = { |
| 233 | .owner = THIS_MODULE, | 237 | .owner = THIS_MODULE, |
| 234 | .write = omap_wdt_write, | 238 | .write = omap_wdt_write, |
| 235 | .ioctl = omap_wdt_ioctl, | 239 | .unlocked_ioctl = omap_wdt_ioctl, |
| 236 | .open = omap_wdt_open, | 240 | .open = omap_wdt_open, |
| 237 | .release = omap_wdt_release, | 241 | .release = omap_wdt_release, |
| 238 | }; | 242 | }; |
| @@ -240,7 +244,7 @@ static const struct file_operations omap_wdt_fops = { | |||
| 240 | static struct miscdevice omap_wdt_miscdev = { | 244 | static struct miscdevice omap_wdt_miscdev = { |
| 241 | .minor = WATCHDOG_MINOR, | 245 | .minor = WATCHDOG_MINOR, |
| 242 | .name = "watchdog", | 246 | .name = "watchdog", |
| 243 | .fops = &omap_wdt_fops | 247 | .fops = &omap_wdt_fops, |
| 244 | }; | 248 | }; |
| 245 | 249 | ||
| 246 | static int __init omap_wdt_probe(struct platform_device *pdev) | 250 | static int __init omap_wdt_probe(struct platform_device *pdev) |
| @@ -373,6 +377,7 @@ static struct platform_driver omap_wdt_driver = { | |||
| 373 | 377 | ||
| 374 | static int __init omap_wdt_init(void) | 378 | static int __init omap_wdt_init(void) |
| 375 | { | 379 | { |
| 380 | spin_lock_init(&wdt_lock); | ||
| 376 | return platform_driver_register(&omap_wdt_driver); | 381 | return platform_driver_register(&omap_wdt_driver); |
| 377 | } | 382 | } |
| 378 | 383 | ||
diff --git a/drivers/watchdog/pc87413_wdt.c b/drivers/watchdog/pc87413_wdt.c index 15e4f8887a9e..e91ada72da1d 100644 --- a/drivers/watchdog/pc87413_wdt.c +++ b/drivers/watchdog/pc87413_wdt.c | |||
| @@ -31,14 +31,14 @@ | |||
| 31 | #include <linux/spinlock.h> | 31 | #include <linux/spinlock.h> |
| 32 | #include <linux/moduleparam.h> | 32 | #include <linux/moduleparam.h> |
| 33 | #include <linux/version.h> | 33 | #include <linux/version.h> |
| 34 | #include <linux/io.h> | ||
| 35 | #include <linux/uaccess.h> | ||
| 34 | 36 | ||
| 35 | #include <asm/io.h> | ||
| 36 | #include <asm/uaccess.h> | ||
| 37 | #include <asm/system.h> | 37 | #include <asm/system.h> |
| 38 | 38 | ||
| 39 | /* #define DEBUG 1 */ | 39 | /* #define DEBUG 1 */ |
| 40 | 40 | ||
| 41 | #define DEFAULT_TIMEOUT 1 /* 1 minute */ | 41 | #define DEFAULT_TIMEOUT 1 /* 1 minute */ |
| 42 | #define MAX_TIMEOUT 255 | 42 | #define MAX_TIMEOUT 255 |
| 43 | 43 | ||
| 44 | #define VERSION "1.1" | 44 | #define VERSION "1.1" |
| @@ -46,22 +46,22 @@ | |||
| 46 | #define PFX MODNAME ": " | 46 | #define PFX MODNAME ": " |
| 47 | #define DPFX MODNAME " - DEBUG: " | 47 | #define DPFX MODNAME " - DEBUG: " |
| 48 | 48 | ||
| 49 | #define WDT_INDEX_IO_PORT (io+0) /* I/O port base (index register) */ | 49 | #define WDT_INDEX_IO_PORT (io+0) /* I/O port base (index register) */ |
| 50 | #define WDT_DATA_IO_PORT (WDT_INDEX_IO_PORT+1) | 50 | #define WDT_DATA_IO_PORT (WDT_INDEX_IO_PORT+1) |
| 51 | #define SWC_LDN 0x04 | 51 | #define SWC_LDN 0x04 |
| 52 | #define SIOCFG2 0x22 /* Serial IO register */ | 52 | #define SIOCFG2 0x22 /* Serial IO register */ |
| 53 | #define WDCTL 0x10 /* Watchdog-Timer-Controll-Register */ | 53 | #define WDCTL 0x10 /* Watchdog-Timer-Controll-Register */ |
| 54 | #define WDTO 0x11 /* Watchdog timeout register */ | 54 | #define WDTO 0x11 /* Watchdog timeout register */ |
| 55 | #define WDCFG 0x12 /* Watchdog config register */ | 55 | #define WDCFG 0x12 /* Watchdog config register */ |
| 56 | 56 | ||
| 57 | static int io = 0x2E; /* Address used on Portwell Boards */ | 57 | static int io = 0x2E; /* Address used on Portwell Boards */ |
| 58 | 58 | ||
| 59 | static int timeout = DEFAULT_TIMEOUT; /* timeout value */ | 59 | static int timeout = DEFAULT_TIMEOUT; /* timeout value */ |
| 60 | static unsigned long timer_enabled = 0; /* is the timer enabled? */ | 60 | static unsigned long timer_enabled; /* is the timer enabled? */ |
| 61 | 61 | ||
| 62 | static char expect_close; /* is the close expected? */ | 62 | static char expect_close; /* is the close expected? */ |
| 63 | 63 | ||
| 64 | static DEFINE_SPINLOCK(io_lock);/* to guard the watchdog from io races */ | 64 | static DEFINE_SPINLOCK(io_lock); /* to guard us from io races */ |
| 65 | 65 | ||
| 66 | static int nowayout = WATCHDOG_NOWAYOUT; | 66 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 67 | 67 | ||
| @@ -69,7 +69,7 @@ static int nowayout = WATCHDOG_NOWAYOUT; | |||
| 69 | 69 | ||
| 70 | /* Select pins for Watchdog output */ | 70 | /* Select pins for Watchdog output */ |
| 71 | 71 | ||
| 72 | static inline void pc87413_select_wdt_out (void) | 72 | static inline void pc87413_select_wdt_out(void) |
| 73 | { | 73 | { |
| 74 | unsigned int cr_data = 0; | 74 | unsigned int cr_data = 0; |
| 75 | 75 | ||
| @@ -77,7 +77,7 @@ static inline void pc87413_select_wdt_out (void) | |||
| 77 | 77 | ||
| 78 | outb_p(SIOCFG2, WDT_INDEX_IO_PORT); | 78 | outb_p(SIOCFG2, WDT_INDEX_IO_PORT); |
| 79 | 79 | ||
| 80 | cr_data = inb (WDT_DATA_IO_PORT); | 80 | cr_data = inb(WDT_DATA_IO_PORT); |
| 81 | 81 | ||
| 82 | cr_data |= 0x80; /* Set Bit7 to 1*/ | 82 | cr_data |= 0x80; /* Set Bit7 to 1*/ |
| 83 | outb_p(SIOCFG2, WDT_INDEX_IO_PORT); | 83 | outb_p(SIOCFG2, WDT_INDEX_IO_PORT); |
| @@ -85,8 +85,9 @@ static inline void pc87413_select_wdt_out (void) | |||
| 85 | outb_p(cr_data, WDT_DATA_IO_PORT); | 85 | outb_p(cr_data, WDT_DATA_IO_PORT); |
| 86 | 86 | ||
| 87 | #ifdef DEBUG | 87 | #ifdef DEBUG |
| 88 | printk(KERN_INFO DPFX "Select multiple pin,pin55,as WDT output:" | 88 | printk(KERN_INFO DPFX |
| 89 | " Bit7 to 1: %d\n", cr_data); | 89 | "Select multiple pin,pin55,as WDT output: Bit7 to 1: %d\n", |
| 90 | cr_data); | ||
| 90 | #endif | 91 | #endif |
| 91 | } | 92 | } |
| 92 | 93 | ||
| @@ -94,18 +95,18 @@ static inline void pc87413_select_wdt_out (void) | |||
| 94 | 95 | ||
| 95 | static inline void pc87413_enable_swc(void) | 96 | static inline void pc87413_enable_swc(void) |
| 96 | { | 97 | { |
| 97 | unsigned int cr_data=0; | 98 | unsigned int cr_data = 0; |
| 98 | 99 | ||
| 99 | /* Step 2: Enable SWC functions */ | 100 | /* Step 2: Enable SWC functions */ |
| 100 | 101 | ||
| 101 | outb_p(0x07, WDT_INDEX_IO_PORT); /* Point SWC_LDN (LDN=4) */ | 102 | outb_p(0x07, WDT_INDEX_IO_PORT); /* Point SWC_LDN (LDN=4) */ |
| 102 | outb_p(SWC_LDN, WDT_DATA_IO_PORT); | 103 | outb_p(SWC_LDN, WDT_DATA_IO_PORT); |
| 103 | 104 | ||
| 104 | outb_p(0x30, WDT_INDEX_IO_PORT); /* Read Index 0x30 First */ | 105 | outb_p(0x30, WDT_INDEX_IO_PORT); /* Read Index 0x30 First */ |
| 105 | cr_data = inb(WDT_DATA_IO_PORT); | 106 | cr_data = inb(WDT_DATA_IO_PORT); |
| 106 | cr_data |= 0x01; /* Set Bit0 to 1 */ | 107 | cr_data |= 0x01; /* Set Bit0 to 1 */ |
| 107 | outb_p(0x30, WDT_INDEX_IO_PORT); | 108 | outb_p(0x30, WDT_INDEX_IO_PORT); |
| 108 | outb_p(cr_data, WDT_DATA_IO_PORT); /* Index0x30_bit0P1 */ | 109 | outb_p(cr_data, WDT_DATA_IO_PORT); /* Index0x30_bit0P1 */ |
| 109 | 110 | ||
| 110 | #ifdef DEBUG | 111 | #ifdef DEBUG |
| 111 | printk(KERN_INFO DPFX "pc87413 - Enable SWC functions\n"); | 112 | printk(KERN_INFO DPFX "pc87413 - Enable SWC functions\n"); |
| @@ -121,20 +122,19 @@ static inline unsigned int pc87413_get_swc_base(void) | |||
| 121 | 122 | ||
| 122 | /* Step 3: Read SWC I/O Base Address */ | 123 | /* Step 3: Read SWC I/O Base Address */ |
| 123 | 124 | ||
| 124 | outb_p(0x60, WDT_INDEX_IO_PORT); /* Read Index 0x60 */ | 125 | outb_p(0x60, WDT_INDEX_IO_PORT); /* Read Index 0x60 */ |
| 125 | addr_h = inb(WDT_DATA_IO_PORT); | 126 | addr_h = inb(WDT_DATA_IO_PORT); |
| 126 | 127 | ||
| 127 | outb_p(0x61, WDT_INDEX_IO_PORT); /* Read Index 0x61 */ | 128 | outb_p(0x61, WDT_INDEX_IO_PORT); /* Read Index 0x61 */ |
| 128 | 129 | ||
| 129 | addr_l = inb(WDT_DATA_IO_PORT); | 130 | addr_l = inb(WDT_DATA_IO_PORT); |
| 130 | 131 | ||
| 131 | swc_base_addr = (addr_h << 8) + addr_l; | 132 | swc_base_addr = (addr_h << 8) + addr_l; |
| 132 | |||
| 133 | #ifdef DEBUG | 133 | #ifdef DEBUG |
| 134 | printk(KERN_INFO DPFX "Read SWC I/O Base Address: low %d, high %d," | 134 | printk(KERN_INFO DPFX |
| 135 | " res %d\n", addr_l, addr_h, swc_base_addr); | 135 | "Read SWC I/O Base Address: low %d, high %d, res %d\n", |
| 136 | addr_l, addr_h, swc_base_addr); | ||
| 136 | #endif | 137 | #endif |
| 137 | |||
| 138 | return swc_base_addr; | 138 | return swc_base_addr; |
| 139 | } | 139 | } |
| 140 | 140 | ||
| @@ -143,9 +143,7 @@ static inline unsigned int pc87413_get_swc_base(void) | |||
| 143 | static inline void pc87413_swc_bank3(unsigned int swc_base_addr) | 143 | static inline void pc87413_swc_bank3(unsigned int swc_base_addr) |
| 144 | { | 144 | { |
| 145 | /* Step 4: Select Bank3 of SWC */ | 145 | /* Step 4: Select Bank3 of SWC */ |
| 146 | |||
| 147 | outb_p(inb(swc_base_addr + 0x0f) | 0x03, swc_base_addr + 0x0f); | 146 | outb_p(inb(swc_base_addr + 0x0f) | 0x03, swc_base_addr + 0x0f); |
| 148 | |||
| 149 | #ifdef DEBUG | 147 | #ifdef DEBUG |
| 150 | printk(KERN_INFO DPFX "Select Bank3 of SWC\n"); | 148 | printk(KERN_INFO DPFX "Select Bank3 of SWC\n"); |
| 151 | #endif | 149 | #endif |
| @@ -157,9 +155,7 @@ static inline void pc87413_programm_wdto(unsigned int swc_base_addr, | |||
| 157 | char pc87413_time) | 155 | char pc87413_time) |
| 158 | { | 156 | { |
| 159 | /* Step 5: Programm WDTO, Twd. */ | 157 | /* Step 5: Programm WDTO, Twd. */ |
| 160 | |||
| 161 | outb_p(pc87413_time, swc_base_addr + WDTO); | 158 | outb_p(pc87413_time, swc_base_addr + WDTO); |
| 162 | |||
| 163 | #ifdef DEBUG | 159 | #ifdef DEBUG |
| 164 | printk(KERN_INFO DPFX "Set WDTO to %d minutes\n", pc87413_time); | 160 | printk(KERN_INFO DPFX "Set WDTO to %d minutes\n", pc87413_time); |
| 165 | #endif | 161 | #endif |
| @@ -170,9 +166,7 @@ static inline void pc87413_programm_wdto(unsigned int swc_base_addr, | |||
| 170 | static inline void pc87413_enable_wden(unsigned int swc_base_addr) | 166 | static inline void pc87413_enable_wden(unsigned int swc_base_addr) |
| 171 | { | 167 | { |
| 172 | /* Step 6: Enable WDEN */ | 168 | /* Step 6: Enable WDEN */ |
| 173 | 169 | outb_p(inb(swc_base_addr + WDCTL) | 0x01, swc_base_addr + WDCTL); | |
| 174 | outb_p(inb (swc_base_addr + WDCTL) | 0x01, swc_base_addr + WDCTL); | ||
| 175 | |||
| 176 | #ifdef DEBUG | 170 | #ifdef DEBUG |
| 177 | printk(KERN_INFO DPFX "Enable WDEN\n"); | 171 | printk(KERN_INFO DPFX "Enable WDEN\n"); |
| 178 | #endif | 172 | #endif |
| @@ -182,9 +176,7 @@ static inline void pc87413_enable_wden(unsigned int swc_base_addr) | |||
| 182 | static inline void pc87413_enable_sw_wd_tren(unsigned int swc_base_addr) | 176 | static inline void pc87413_enable_sw_wd_tren(unsigned int swc_base_addr) |
| 183 | { | 177 | { |
| 184 | /* Enable SW_WD_TREN */ | 178 | /* Enable SW_WD_TREN */ |
| 185 | 179 | outb_p(inb(swc_base_addr + WDCFG) | 0x80, swc_base_addr + WDCFG); | |
| 186 | outb_p(inb (swc_base_addr + WDCFG) | 0x80, swc_base_addr + WDCFG); | ||
| 187 | |||
| 188 | #ifdef DEBUG | 180 | #ifdef DEBUG |
| 189 | printk(KERN_INFO DPFX "Enable SW_WD_TREN\n"); | 181 | printk(KERN_INFO DPFX "Enable SW_WD_TREN\n"); |
| 190 | #endif | 182 | #endif |
| @@ -195,9 +187,7 @@ static inline void pc87413_enable_sw_wd_tren(unsigned int swc_base_addr) | |||
| 195 | static inline void pc87413_disable_sw_wd_tren(unsigned int swc_base_addr) | 187 | static inline void pc87413_disable_sw_wd_tren(unsigned int swc_base_addr) |
| 196 | { | 188 | { |
| 197 | /* Disable SW_WD_TREN */ | 189 | /* Disable SW_WD_TREN */ |
| 198 | 190 | outb_p(inb(swc_base_addr + WDCFG) & 0x7f, swc_base_addr + WDCFG); | |
| 199 | outb_p(inb (swc_base_addr + WDCFG) & 0x7f, swc_base_addr + WDCFG); | ||
| 200 | |||
| 201 | #ifdef DEBUG | 191 | #ifdef DEBUG |
| 202 | printk(KERN_INFO DPFX "pc87413 - Disable SW_WD_TREN\n"); | 192 | printk(KERN_INFO DPFX "pc87413 - Disable SW_WD_TREN\n"); |
| 203 | #endif | 193 | #endif |
| @@ -208,9 +198,7 @@ static inline void pc87413_disable_sw_wd_tren(unsigned int swc_base_addr) | |||
| 208 | static inline void pc87413_enable_sw_wd_trg(unsigned int swc_base_addr) | 198 | static inline void pc87413_enable_sw_wd_trg(unsigned int swc_base_addr) |
| 209 | { | 199 | { |
| 210 | /* Enable SW_WD_TRG */ | 200 | /* Enable SW_WD_TRG */ |
| 211 | 201 | outb_p(inb(swc_base_addr + WDCTL) | 0x80, swc_base_addr + WDCTL); | |
| 212 | outb_p(inb (swc_base_addr + WDCTL) | 0x80, swc_base_addr + WDCTL); | ||
| 213 | |||
| 214 | #ifdef DEBUG | 202 | #ifdef DEBUG |
| 215 | printk(KERN_INFO DPFX "pc87413 - Enable SW_WD_TRG\n"); | 203 | printk(KERN_INFO DPFX "pc87413 - Enable SW_WD_TRG\n"); |
| 216 | #endif | 204 | #endif |
| @@ -221,9 +209,7 @@ static inline void pc87413_enable_sw_wd_trg(unsigned int swc_base_addr) | |||
| 221 | static inline void pc87413_disable_sw_wd_trg(unsigned int swc_base_addr) | 209 | static inline void pc87413_disable_sw_wd_trg(unsigned int swc_base_addr) |
| 222 | { | 210 | { |
| 223 | /* Disable SW_WD_TRG */ | 211 | /* Disable SW_WD_TRG */ |
| 224 | 212 | outb_p(inb(swc_base_addr + WDCTL) & 0x7f, swc_base_addr + WDCTL); | |
| 225 | outb_p(inb (swc_base_addr + WDCTL) & 0x7f, swc_base_addr + WDCTL); | ||
| 226 | |||
| 227 | #ifdef DEBUG | 213 | #ifdef DEBUG |
| 228 | printk(KERN_INFO DPFX "Disable SW_WD_TRG\n"); | 214 | printk(KERN_INFO DPFX "Disable SW_WD_TRG\n"); |
| 229 | #endif | 215 | #endif |
| @@ -314,8 +300,8 @@ static int pc87413_open(struct inode *inode, struct file *file) | |||
| 314 | /* Reload and activate timer */ | 300 | /* Reload and activate timer */ |
| 315 | pc87413_refresh(); | 301 | pc87413_refresh(); |
| 316 | 302 | ||
| 317 | printk(KERN_INFO MODNAME "Watchdog enabled. Timeout set to" | 303 | printk(KERN_INFO MODNAME |
| 318 | " %d minute(s).\n", timeout); | 304 | "Watchdog enabled. Timeout set to %d minute(s).\n", timeout); |
| 319 | 305 | ||
| 320 | return nonseekable_open(inode, file); | 306 | return nonseekable_open(inode, file); |
| 321 | } | 307 | } |
| @@ -338,17 +324,15 @@ static int pc87413_release(struct inode *inode, struct file *file) | |||
| 338 | 324 | ||
| 339 | if (expect_close == 42) { | 325 | if (expect_close == 42) { |
| 340 | pc87413_disable(); | 326 | pc87413_disable(); |
| 341 | printk(KERN_INFO MODNAME "Watchdog disabled," | 327 | printk(KERN_INFO MODNAME |
| 342 | " sleeping again...\n"); | 328 | "Watchdog disabled, sleeping again...\n"); |
| 343 | } else { | 329 | } else { |
| 344 | printk(KERN_CRIT MODNAME "Unexpected close, not stopping" | 330 | printk(KERN_CRIT MODNAME |
| 345 | " watchdog!\n"); | 331 | "Unexpected close, not stopping watchdog!\n"); |
| 346 | pc87413_refresh(); | 332 | pc87413_refresh(); |
| 347 | } | 333 | } |
| 348 | |||
| 349 | clear_bit(0, &timer_enabled); | 334 | clear_bit(0, &timer_enabled); |
| 350 | expect_close = 0; | 335 | expect_close = 0; |
| 351 | |||
| 352 | return 0; | 336 | return 0; |
| 353 | } | 337 | } |
| 354 | 338 | ||
| @@ -386,10 +370,11 @@ static ssize_t pc87413_write(struct file *file, const char __user *data, | |||
| 386 | /* reset expect flag */ | 370 | /* reset expect flag */ |
| 387 | expect_close = 0; | 371 | expect_close = 0; |
| 388 | 372 | ||
| 389 | /* scan to see whether or not we got the magic character */ | 373 | /* scan to see whether or not we got the |
| 374 | magic character */ | ||
| 390 | for (i = 0; i != len; i++) { | 375 | for (i = 0; i != len; i++) { |
| 391 | char c; | 376 | char c; |
| 392 | if (get_user(c, data+i)) | 377 | if (get_user(c, data + i)) |
| 393 | return -EFAULT; | 378 | return -EFAULT; |
| 394 | if (c == 'V') | 379 | if (c == 'V') |
| 395 | expect_close = 42; | 380 | expect_close = 42; |
| @@ -404,7 +389,6 @@ static ssize_t pc87413_write(struct file *file, const char __user *data, | |||
| 404 | 389 | ||
| 405 | /** | 390 | /** |
| 406 | * pc87413_ioctl: | 391 | * pc87413_ioctl: |
| 407 | * @inode: inode of the device | ||
| 408 | * @file: file handle to the device | 392 | * @file: file handle to the device |
| 409 | * @cmd: watchdog command | 393 | * @cmd: watchdog command |
| 410 | * @arg: argument pointer | 394 | * @arg: argument pointer |
| @@ -414,8 +398,8 @@ static ssize_t pc87413_write(struct file *file, const char __user *data, | |||
| 414 | * querying capabilities and current status. | 398 | * querying capabilities and current status. |
| 415 | */ | 399 | */ |
| 416 | 400 | ||
| 417 | static int pc87413_ioctl(struct inode *inode, struct file *file, | 401 | static long pc87413_ioctl(struct file *file, unsigned int cmd, |
| 418 | unsigned int cmd, unsigned long arg) | 402 | unsigned long arg) |
| 419 | { | 403 | { |
| 420 | int new_timeout; | 404 | int new_timeout; |
| 421 | 405 | ||
| @@ -426,75 +410,58 @@ static int pc87413_ioctl(struct inode *inode, struct file *file, | |||
| 426 | 410 | ||
| 427 | static struct watchdog_info ident = { | 411 | static struct watchdog_info ident = { |
| 428 | .options = WDIOF_KEEPALIVEPING | | 412 | .options = WDIOF_KEEPALIVEPING | |
| 429 | WDIOF_SETTIMEOUT | | 413 | WDIOF_SETTIMEOUT | |
| 430 | WDIOF_MAGICCLOSE, | 414 | WDIOF_MAGICCLOSE, |
| 431 | .firmware_version = 1, | 415 | .firmware_version = 1, |
| 432 | .identity = "PC87413(HF/F) watchdog" | 416 | .identity = "PC87413(HF/F) watchdog", |
| 433 | }; | 417 | }; |
| 434 | 418 | ||
| 435 | uarg.i = (int __user *)arg; | 419 | uarg.i = (int __user *)arg; |
| 436 | 420 | ||
| 437 | switch(cmd) { | 421 | switch (cmd) { |
| 438 | default: | 422 | case WDIOC_GETSUPPORT: |
| 439 | return -ENOTTY; | 423 | return copy_to_user(uarg.ident, &ident, |
| 440 | 424 | sizeof(ident)) ? -EFAULT : 0; | |
| 441 | case WDIOC_GETSUPPORT: | 425 | case WDIOC_GETSTATUS: |
| 442 | return copy_to_user(uarg.ident, &ident, | 426 | return put_user(pc87413_status(), uarg.i); |
| 443 | sizeof(ident)) ? -EFAULT : 0; | 427 | case WDIOC_GETBOOTSTATUS: |
| 444 | 428 | return put_user(0, uarg.i); | |
| 445 | case WDIOC_GETSTATUS: | 429 | case WDIOC_SETOPTIONS: |
| 446 | return put_user(pc87413_status(), uarg.i); | 430 | { |
| 447 | 431 | int options, retval = -EINVAL; | |
| 448 | case WDIOC_GETBOOTSTATUS: | 432 | if (get_user(options, uarg.i)) |
| 449 | return put_user(0, uarg.i); | 433 | return -EFAULT; |
| 450 | 434 | if (options & WDIOS_DISABLECARD) { | |
| 451 | case WDIOC_KEEPALIVE: | 435 | pc87413_disable(); |
| 452 | pc87413_refresh(); | 436 | retval = 0; |
| 437 | } | ||
| 438 | if (options & WDIOS_ENABLECARD) { | ||
| 439 | pc87413_enable(); | ||
| 440 | retval = 0; | ||
| 441 | } | ||
| 442 | return retval; | ||
| 443 | } | ||
| 444 | case WDIOC_KEEPALIVE: | ||
| 445 | pc87413_refresh(); | ||
| 453 | #ifdef DEBUG | 446 | #ifdef DEBUG |
| 454 | printk(KERN_INFO DPFX "keepalive\n"); | 447 | printk(KERN_INFO DPFX "keepalive\n"); |
| 455 | #endif | 448 | #endif |
| 456 | return 0; | 449 | return 0; |
| 457 | 450 | case WDIOC_SETTIMEOUT: | |
| 458 | case WDIOC_SETTIMEOUT: | 451 | if (get_user(new_timeout, uarg.i)) |
| 459 | if (get_user(new_timeout, uarg.i)) | 452 | return -EFAULT; |
| 460 | return -EFAULT; | 453 | /* the API states this is given in secs */ |
| 461 | 454 | new_timeout /= 60; | |
| 462 | // the API states this is given in secs | 455 | if (new_timeout < 0 || new_timeout > MAX_TIMEOUT) |
| 463 | new_timeout /= 60; | 456 | return -EINVAL; |
| 464 | 457 | timeout = new_timeout; | |
| 465 | if (new_timeout < 0 || new_timeout > MAX_TIMEOUT) | 458 | pc87413_refresh(); |
| 466 | return -EINVAL; | 459 | /* fall through and return the new timeout... */ |
| 467 | 460 | case WDIOC_GETTIMEOUT: | |
| 468 | timeout = new_timeout; | 461 | new_timeout = timeout * 60; |
| 469 | pc87413_refresh(); | 462 | return put_user(new_timeout, uarg.i); |
| 470 | 463 | default: | |
| 471 | // fall through and return the new timeout... | 464 | return -ENOTTY; |
| 472 | |||
| 473 | case WDIOC_GETTIMEOUT: | ||
| 474 | |||
| 475 | new_timeout = timeout * 60; | ||
| 476 | |||
| 477 | return put_user(new_timeout, uarg.i); | ||
| 478 | |||
| 479 | case WDIOC_SETOPTIONS: | ||
| 480 | { | ||
| 481 | int options, retval = -EINVAL; | ||
| 482 | |||
| 483 | if (get_user(options, uarg.i)) | ||
| 484 | return -EFAULT; | ||
| 485 | |||
| 486 | if (options & WDIOS_DISABLECARD) { | ||
| 487 | pc87413_disable(); | ||
| 488 | retval = 0; | ||
| 489 | } | ||
| 490 | |||
| 491 | if (options & WDIOS_ENABLECARD) { | ||
| 492 | pc87413_enable(); | ||
| 493 | retval = 0; | ||
| 494 | } | ||
| 495 | |||
| 496 | return retval; | ||
| 497 | } | ||
| 498 | } | 465 | } |
| 499 | } | 466 | } |
| 500 | 467 | ||
| @@ -517,10 +484,8 @@ static int pc87413_notify_sys(struct notifier_block *this, | |||
| 517 | void *unused) | 484 | void *unused) |
| 518 | { | 485 | { |
| 519 | if (code == SYS_DOWN || code == SYS_HALT) | 486 | if (code == SYS_DOWN || code == SYS_HALT) |
| 520 | { | ||
| 521 | /* Turn the card off */ | 487 | /* Turn the card off */ |
| 522 | pc87413_disable(); | 488 | pc87413_disable(); |
| 523 | } | ||
| 524 | return NOTIFY_DONE; | 489 | return NOTIFY_DONE; |
| 525 | } | 490 | } |
| 526 | 491 | ||
| @@ -530,21 +495,19 @@ static const struct file_operations pc87413_fops = { | |||
| 530 | .owner = THIS_MODULE, | 495 | .owner = THIS_MODULE, |
| 531 | .llseek = no_llseek, | 496 | .llseek = no_llseek, |
| 532 | .write = pc87413_write, | 497 | .write = pc87413_write, |
| 533 | .ioctl = pc87413_ioctl, | 498 | .unlocked_ioctl = pc87413_ioctl, |
| 534 | .open = pc87413_open, | 499 | .open = pc87413_open, |
| 535 | .release = pc87413_release, | 500 | .release = pc87413_release, |
| 536 | }; | 501 | }; |
| 537 | 502 | ||
| 538 | static struct notifier_block pc87413_notifier = | 503 | static struct notifier_block pc87413_notifier = { |
| 539 | { | ||
| 540 | .notifier_call = pc87413_notify_sys, | 504 | .notifier_call = pc87413_notify_sys, |
| 541 | }; | 505 | }; |
| 542 | 506 | ||
| 543 | static struct miscdevice pc87413_miscdev= | 507 | static struct miscdevice pc87413_miscdev = { |
| 544 | { | ||
| 545 | .minor = WATCHDOG_MINOR, | 508 | .minor = WATCHDOG_MINOR, |
| 546 | .name = "watchdog", | 509 | .name = "watchdog", |
| 547 | .fops = &pc87413_fops | 510 | .fops = &pc87413_fops, |
| 548 | }; | 511 | }; |
| 549 | 512 | ||
| 550 | /* -- Module init functions -------------------------------------*/ | 513 | /* -- Module init functions -------------------------------------*/ |
| @@ -561,29 +524,26 @@ static int __init pc87413_init(void) | |||
| 561 | { | 524 | { |
| 562 | int ret; | 525 | int ret; |
| 563 | 526 | ||
| 564 | printk(KERN_INFO PFX "Version " VERSION " at io 0x%X\n", WDT_INDEX_IO_PORT); | 527 | printk(KERN_INFO PFX "Version " VERSION " at io 0x%X\n", |
| 528 | WDT_INDEX_IO_PORT); | ||
| 565 | 529 | ||
| 566 | /* request_region(io, 2, "pc87413"); */ | 530 | /* request_region(io, 2, "pc87413"); */ |
| 567 | 531 | ||
| 568 | ret = register_reboot_notifier(&pc87413_notifier); | 532 | ret = register_reboot_notifier(&pc87413_notifier); |
| 569 | if (ret != 0) { | 533 | if (ret != 0) { |
| 570 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 534 | printk(KERN_ERR PFX |
| 571 | ret); | 535 | "cannot register reboot notifier (err=%d)\n", ret); |
| 572 | } | 536 | } |
| 573 | 537 | ||
| 574 | ret = misc_register(&pc87413_miscdev); | 538 | ret = misc_register(&pc87413_miscdev); |
| 575 | |||
| 576 | if (ret != 0) { | 539 | if (ret != 0) { |
| 577 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 540 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", |
| 578 | WATCHDOG_MINOR, ret); | 541 | WATCHDOG_MINOR, ret); |
| 579 | unregister_reboot_notifier(&pc87413_notifier); | 542 | unregister_reboot_notifier(&pc87413_notifier); |
| 580 | return ret; | 543 | return ret; |
| 581 | } | 544 | } |
| 582 | |||
| 583 | printk(KERN_INFO PFX "initialized. timeout=%d min \n", timeout); | 545 | printk(KERN_INFO PFX "initialized. timeout=%d min \n", timeout); |
| 584 | |||
| 585 | pc87413_enable(); | 546 | pc87413_enable(); |
| 586 | |||
| 587 | return 0; | 547 | return 0; |
| 588 | } | 548 | } |
| 589 | 549 | ||
| @@ -600,17 +560,16 @@ static int __init pc87413_init(void) | |||
| 600 | static void __exit pc87413_exit(void) | 560 | static void __exit pc87413_exit(void) |
| 601 | { | 561 | { |
| 602 | /* Stop the timer before we leave */ | 562 | /* Stop the timer before we leave */ |
| 603 | if (!nowayout) | 563 | if (!nowayout) { |
| 604 | { | ||
| 605 | pc87413_disable(); | 564 | pc87413_disable(); |
| 606 | printk(KERN_INFO MODNAME "Watchdog disabled.\n"); | 565 | printk(KERN_INFO MODNAME "Watchdog disabled.\n"); |
| 607 | } | 566 | } |
| 608 | 567 | ||
| 609 | misc_deregister(&pc87413_miscdev); | 568 | misc_deregister(&pc87413_miscdev); |
| 610 | unregister_reboot_notifier(&pc87413_notifier); | 569 | unregister_reboot_notifier(&pc87413_notifier); |
| 611 | /* release_region(io,2); */ | 570 | /* release_region(io, 2); */ |
| 612 | 571 | ||
| 613 | printk(MODNAME " watchdog component driver removed.\n"); | 572 | printk(KERN_INFO MODNAME " watchdog component driver removed.\n"); |
| 614 | } | 573 | } |
| 615 | 574 | ||
| 616 | module_init(pc87413_init); | 575 | module_init(pc87413_init); |
| @@ -626,8 +585,12 @@ module_param(io, int, 0); | |||
| 626 | MODULE_PARM_DESC(io, MODNAME " I/O port (default: " __MODULE_STRING(io) ")."); | 585 | MODULE_PARM_DESC(io, MODNAME " I/O port (default: " __MODULE_STRING(io) ")."); |
| 627 | 586 | ||
| 628 | module_param(timeout, int, 0); | 587 | module_param(timeout, int, 0); |
| 629 | MODULE_PARM_DESC(timeout, "Watchdog timeout in minutes (default=" __MODULE_STRING(timeout) ")."); | 588 | MODULE_PARM_DESC(timeout, |
| 589 | "Watchdog timeout in minutes (default=" | ||
| 590 | __MODULE_STRING(timeout) ")."); | ||
| 630 | 591 | ||
| 631 | module_param(nowayout, int, 0); | 592 | module_param(nowayout, int, 0); |
| 632 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 593 | MODULE_PARM_DESC(nowayout, |
| 594 | "Watchdog cannot be stopped once started (default=" | ||
| 595 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 633 | 596 | ||
diff --git a/drivers/watchdog/pcwd.c b/drivers/watchdog/pcwd.c index 7b41434fac8c..3b0ddc7fcf3f 100644 --- a/drivers/watchdog/pcwd.c +++ b/drivers/watchdog/pcwd.c | |||
| @@ -40,13 +40,15 @@ | |||
| 40 | * fairly useless proc entry. | 40 | * fairly useless proc entry. |
| 41 | * 990610 removed said useless proc code for the merge <alan> | 41 | * 990610 removed said useless proc code for the merge <alan> |
| 42 | * 000403 Removed last traces of proc code. <davej> | 42 | * 000403 Removed last traces of proc code. <davej> |
| 43 | * 011214 Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT <Matt_Domsch@dell.com> | 43 | * 011214 Added nowayout module option to override |
| 44 | * CONFIG_WATCHDOG_NOWAYOUT <Matt_Domsch@dell.com> | ||
| 44 | * Added timeout module option to override default | 45 | * Added timeout module option to override default |
| 45 | */ | 46 | */ |
| 46 | 47 | ||
| 47 | /* | 48 | /* |
| 48 | * A bells and whistles driver is available from http://www.pcwd.de/ | 49 | * A bells and whistles driver is available from http://www.pcwd.de/ |
| 49 | * More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/ | 50 | * More info available at http://www.berkprod.com/ or |
| 51 | * http://www.pcwatchdog.com/ | ||
| 50 | */ | 52 | */ |
| 51 | 53 | ||
| 52 | #include <linux/module.h> /* For module specific items */ | 54 | #include <linux/module.h> /* For module specific items */ |
| @@ -65,9 +67,8 @@ | |||
| 65 | #include <linux/isa.h> /* For isa devices */ | 67 | #include <linux/isa.h> /* For isa devices */ |
| 66 | #include <linux/ioport.h> /* For io-port access */ | 68 | #include <linux/ioport.h> /* For io-port access */ |
| 67 | #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ | 69 | #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ |
| 68 | 70 | #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ | |
| 69 | #include <asm/uaccess.h> /* For copy_to_user/put_user/... */ | 71 | #include <linux/io.h> /* For inb/outb/... */ |
| 70 | #include <asm/io.h> /* For inb/outb/... */ | ||
| 71 | 72 | ||
| 72 | /* Module and version information */ | 73 | /* Module and version information */ |
| 73 | #define WATCHDOG_VERSION "1.20" | 74 | #define WATCHDOG_VERSION "1.20" |
| @@ -111,14 +112,16 @@ static int pcwd_ioports[] = { 0x270, 0x350, 0x370, 0x000 }; | |||
| 111 | #define WD_REVC_WTRP 0x01 /* Watchdog Trip status */ | 112 | #define WD_REVC_WTRP 0x01 /* Watchdog Trip status */ |
| 112 | #define WD_REVC_HRBT 0x02 /* Watchdog Heartbeat */ | 113 | #define WD_REVC_HRBT 0x02 /* Watchdog Heartbeat */ |
| 113 | #define WD_REVC_TTRP 0x04 /* Temperature Trip status */ | 114 | #define WD_REVC_TTRP 0x04 /* Temperature Trip status */ |
| 114 | #define WD_REVC_RL2A 0x08 /* Relay 2 activated by on-board processor */ | 115 | #define WD_REVC_RL2A 0x08 /* Relay 2 activated by |
| 116 | on-board processor */ | ||
| 115 | #define WD_REVC_RL1A 0x10 /* Relay 1 active */ | 117 | #define WD_REVC_RL1A 0x10 /* Relay 1 active */ |
| 116 | #define WD_REVC_R2DS 0x40 /* Relay 2 disable */ | 118 | #define WD_REVC_R2DS 0x40 /* Relay 2 disable */ |
| 117 | #define WD_REVC_RLY2 0x80 /* Relay 2 activated? */ | 119 | #define WD_REVC_RLY2 0x80 /* Relay 2 activated? */ |
| 118 | /* Port 2 : Control Status #2 */ | 120 | /* Port 2 : Control Status #2 */ |
| 119 | #define WD_WDIS 0x10 /* Watchdog Disabled */ | 121 | #define WD_WDIS 0x10 /* Watchdog Disabled */ |
| 120 | #define WD_ENTP 0x20 /* Watchdog Enable Temperature Trip */ | 122 | #define WD_ENTP 0x20 /* Watchdog Enable Temperature Trip */ |
| 121 | #define WD_SSEL 0x40 /* Watchdog Switch Select (1:SW1 <-> 0:SW2) */ | 123 | #define WD_SSEL 0x40 /* Watchdog Switch Select |
| 124 | (1:SW1 <-> 0:SW2) */ | ||
| 122 | #define WD_WCMD 0x80 /* Watchdog Command Mode */ | 125 | #define WD_WCMD 0x80 /* Watchdog Command Mode */ |
| 123 | 126 | ||
| 124 | /* max. time we give an ISA watchdog card to process a command */ | 127 | /* max. time we give an ISA watchdog card to process a command */ |
| @@ -142,7 +145,7 @@ static int pcwd_ioports[] = { 0x270, 0x350, 0x370, 0x000 }; | |||
| 142 | #define CMD_ISA_RESET_RELAYS 0x0D | 145 | #define CMD_ISA_RESET_RELAYS 0x0D |
| 143 | 146 | ||
| 144 | /* Watchdog's Dip Switch heartbeat values */ | 147 | /* Watchdog's Dip Switch heartbeat values */ |
| 145 | static const int heartbeat_tbl [] = { | 148 | static const int heartbeat_tbl[] = { |
| 146 | 20, /* OFF-OFF-OFF = 20 Sec */ | 149 | 20, /* OFF-OFF-OFF = 20 Sec */ |
| 147 | 40, /* OFF-OFF-ON = 40 Sec */ | 150 | 40, /* OFF-OFF-ON = 40 Sec */ |
| 148 | 60, /* OFF-ON-OFF = 1 Min */ | 151 | 60, /* OFF-ON-OFF = 1 Min */ |
| @@ -168,11 +171,15 @@ static int cards_found; | |||
| 168 | static atomic_t open_allowed = ATOMIC_INIT(1); | 171 | static atomic_t open_allowed = ATOMIC_INIT(1); |
| 169 | static char expect_close; | 172 | static char expect_close; |
| 170 | static int temp_panic; | 173 | static int temp_panic; |
| 171 | static struct { /* this is private data for each ISA-PC watchdog card */ | 174 | |
| 175 | /* this is private data for each ISA-PC watchdog card */ | ||
| 176 | static struct { | ||
| 172 | char fw_ver_str[6]; /* The cards firmware version */ | 177 | char fw_ver_str[6]; /* The cards firmware version */ |
| 173 | int revision; /* The card's revision */ | 178 | int revision; /* The card's revision */ |
| 174 | int supports_temp; /* Wether or not the card has a temperature device */ | 179 | int supports_temp; /* Whether or not the card has |
| 175 | int command_mode; /* Wether or not the card is in command mode */ | 180 | a temperature device */ |
| 181 | int command_mode; /* Whether or not the card is in | ||
| 182 | command mode */ | ||
| 176 | int boot_status; /* The card's boot status */ | 183 | int boot_status; /* The card's boot status */ |
| 177 | int io_addr; /* The cards I/O address */ | 184 | int io_addr; /* The cards I/O address */ |
| 178 | spinlock_t io_lock; /* the lock for io operations */ | 185 | spinlock_t io_lock; /* the lock for io operations */ |
| @@ -186,16 +193,20 @@ static struct { /* this is private data for each ISA-PC watchdog card */ | |||
| 186 | #define DEBUG 2 /* print fancy stuff too */ | 193 | #define DEBUG 2 /* print fancy stuff too */ |
| 187 | static int debug = QUIET; | 194 | static int debug = QUIET; |
| 188 | module_param(debug, int, 0); | 195 | module_param(debug, int, 0); |
| 189 | MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)"); | 196 | MODULE_PARM_DESC(debug, |
| 197 | "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)"); | ||
| 190 | 198 | ||
| 191 | #define WATCHDOG_HEARTBEAT 0 /* default heartbeat = delay-time from dip-switches */ | 199 | /* default heartbeat = delay-time from dip-switches */ |
| 200 | #define WATCHDOG_HEARTBEAT 0 | ||
| 192 | static int heartbeat = WATCHDOG_HEARTBEAT; | 201 | static int heartbeat = WATCHDOG_HEARTBEAT; |
| 193 | module_param(heartbeat, int, 0); | 202 | module_param(heartbeat, int, 0); |
| 194 | MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<=heartbeat<=7200 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); | 203 | MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2 <= heartbeat <= 7200 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); |
| 195 | 204 | ||
| 196 | static int nowayout = WATCHDOG_NOWAYOUT; | 205 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 197 | module_param(nowayout, int, 0); | 206 | module_param(nowayout, int, 0); |
| 198 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 207 | MODULE_PARM_DESC(nowayout, |
| 208 | "Watchdog cannot be stopped once started (default=" | ||
| 209 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 199 | 210 | ||
| 200 | /* | 211 | /* |
| 201 | * Internal functions | 212 | * Internal functions |
| @@ -224,7 +235,7 @@ static int send_isa_command(int cmd) | |||
| 224 | if (port0 == last_port0) | 235 | if (port0 == last_port0) |
| 225 | break; /* Data is stable */ | 236 | break; /* Data is stable */ |
| 226 | 237 | ||
| 227 | udelay (250); | 238 | udelay(250); |
| 228 | } | 239 | } |
| 229 | 240 | ||
| 230 | if (debug >= DEBUG) | 241 | if (debug >= DEBUG) |
| @@ -236,7 +247,7 @@ static int send_isa_command(int cmd) | |||
| 236 | 247 | ||
| 237 | static int set_command_mode(void) | 248 | static int set_command_mode(void) |
| 238 | { | 249 | { |
| 239 | int i, found=0, count=0; | 250 | int i, found = 0, count = 0; |
| 240 | 251 | ||
| 241 | /* Set the card into command mode */ | 252 | /* Set the card into command mode */ |
| 242 | spin_lock(&pcwd_private.io_lock); | 253 | spin_lock(&pcwd_private.io_lock); |
| @@ -261,7 +272,7 @@ static int set_command_mode(void) | |||
| 261 | printk(KERN_DEBUG PFX "command_mode=%d\n", | 272 | printk(KERN_DEBUG PFX "command_mode=%d\n", |
| 262 | pcwd_private.command_mode); | 273 | pcwd_private.command_mode); |
| 263 | 274 | ||
| 264 | return(found); | 275 | return found; |
| 265 | } | 276 | } |
| 266 | 277 | ||
| 267 | static void unset_command_mode(void) | 278 | static void unset_command_mode(void) |
| @@ -296,7 +307,8 @@ static inline void pcwd_get_firmware(void) | |||
| 296 | ten = send_isa_command(CMD_ISA_VERSION_TENTH); | 307 | ten = send_isa_command(CMD_ISA_VERSION_TENTH); |
| 297 | hund = send_isa_command(CMD_ISA_VERSION_HUNDRETH); | 308 | hund = send_isa_command(CMD_ISA_VERSION_HUNDRETH); |
| 298 | minor = send_isa_command(CMD_ISA_VERSION_MINOR); | 309 | minor = send_isa_command(CMD_ISA_VERSION_MINOR); |
| 299 | sprintf(pcwd_private.fw_ver_str, "%c.%c%c%c", one, ten, hund, minor); | 310 | sprintf(pcwd_private.fw_ver_str, "%c.%c%c%c", |
| 311 | one, ten, hund, minor); | ||
| 300 | } | 312 | } |
| 301 | unset_command_mode(); | 313 | unset_command_mode(); |
| 302 | 314 | ||
| @@ -305,7 +317,7 @@ static inline void pcwd_get_firmware(void) | |||
| 305 | 317 | ||
| 306 | static inline int pcwd_get_option_switches(void) | 318 | static inline int pcwd_get_option_switches(void) |
| 307 | { | 319 | { |
| 308 | int option_switches=0; | 320 | int option_switches = 0; |
| 309 | 321 | ||
| 310 | if (set_command_mode()) { | 322 | if (set_command_mode()) { |
| 311 | /* Get switch settings */ | 323 | /* Get switch settings */ |
| @@ -313,7 +325,7 @@ static inline int pcwd_get_option_switches(void) | |||
| 313 | } | 325 | } |
| 314 | 326 | ||
| 315 | unset_command_mode(); | 327 | unset_command_mode(); |
| 316 | return(option_switches); | 328 | return option_switches; |
| 317 | } | 329 | } |
| 318 | 330 | ||
| 319 | static void pcwd_show_card_info(void) | 331 | static void pcwd_show_card_info(void) |
| @@ -322,7 +334,9 @@ static void pcwd_show_card_info(void) | |||
| 322 | 334 | ||
| 323 | /* Get some extra info from the hardware (in command/debug/diag mode) */ | 335 | /* Get some extra info from the hardware (in command/debug/diag mode) */ |
| 324 | if (pcwd_private.revision == PCWD_REVISION_A) | 336 | if (pcwd_private.revision == PCWD_REVISION_A) |
| 325 | printk(KERN_INFO PFX "ISA-PC Watchdog (REV.A) detected at port 0x%04x\n", pcwd_private.io_addr); | 337 | printk(KERN_INFO PFX |
| 338 | "ISA-PC Watchdog (REV.A) detected at port 0x%04x\n", | ||
| 339 | pcwd_private.io_addr); | ||
| 326 | else if (pcwd_private.revision == PCWD_REVISION_C) { | 340 | else if (pcwd_private.revision == PCWD_REVISION_C) { |
| 327 | pcwd_get_firmware(); | 341 | pcwd_get_firmware(); |
| 328 | printk(KERN_INFO PFX "ISA-PC Watchdog (REV.C) detected at port 0x%04x (Firmware version: %s)\n", | 342 | printk(KERN_INFO PFX "ISA-PC Watchdog (REV.C) detected at port 0x%04x (Firmware version: %s)\n", |
| @@ -347,12 +361,15 @@ static void pcwd_show_card_info(void) | |||
| 347 | printk(KERN_INFO PFX "Previous reboot was caused by the card\n"); | 361 | printk(KERN_INFO PFX "Previous reboot was caused by the card\n"); |
| 348 | 362 | ||
| 349 | if (pcwd_private.boot_status & WDIOF_OVERHEAT) { | 363 | if (pcwd_private.boot_status & WDIOF_OVERHEAT) { |
| 350 | printk(KERN_EMERG PFX "Card senses a CPU Overheat. Panicking!\n"); | 364 | printk(KERN_EMERG PFX |
| 351 | printk(KERN_EMERG PFX "CPU Overheat\n"); | 365 | "Card senses a CPU Overheat. Panicking!\n"); |
| 366 | printk(KERN_EMERG PFX | ||
| 367 | "CPU Overheat\n"); | ||
| 352 | } | 368 | } |
| 353 | 369 | ||
| 354 | if (pcwd_private.boot_status == 0) | 370 | if (pcwd_private.boot_status == 0) |
| 355 | printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n"); | 371 | printk(KERN_INFO PFX |
| 372 | "No previous trip detected - Cold boot or reset\n"); | ||
| 356 | } | 373 | } |
| 357 | 374 | ||
| 358 | static void pcwd_timer_ping(unsigned long data) | 375 | static void pcwd_timer_ping(unsigned long data) |
| @@ -361,11 +378,12 @@ static void pcwd_timer_ping(unsigned long data) | |||
| 361 | 378 | ||
| 362 | /* If we got a heartbeat pulse within the WDT_INTERVAL | 379 | /* If we got a heartbeat pulse within the WDT_INTERVAL |
| 363 | * we agree to ping the WDT */ | 380 | * we agree to ping the WDT */ |
| 364 | if(time_before(jiffies, pcwd_private.next_heartbeat)) { | 381 | if (time_before(jiffies, pcwd_private.next_heartbeat)) { |
| 365 | /* Ping the watchdog */ | 382 | /* Ping the watchdog */ |
| 366 | spin_lock(&pcwd_private.io_lock); | 383 | spin_lock(&pcwd_private.io_lock); |
| 367 | if (pcwd_private.revision == PCWD_REVISION_A) { | 384 | if (pcwd_private.revision == PCWD_REVISION_A) { |
| 368 | /* Rev A cards are reset by setting the WD_WDRST bit in register 1 */ | 385 | /* Rev A cards are reset by setting the |
| 386 | WD_WDRST bit in register 1 */ | ||
| 369 | wdrst_stat = inb_p(pcwd_private.io_addr); | 387 | wdrst_stat = inb_p(pcwd_private.io_addr); |
| 370 | wdrst_stat &= 0x0F; | 388 | wdrst_stat &= 0x0F; |
| 371 | wdrst_stat |= WD_WDRST; | 389 | wdrst_stat |= WD_WDRST; |
| @@ -381,7 +399,8 @@ static void pcwd_timer_ping(unsigned long data) | |||
| 381 | 399 | ||
| 382 | spin_unlock(&pcwd_private.io_lock); | 400 | spin_unlock(&pcwd_private.io_lock); |
| 383 | } else { | 401 | } else { |
| 384 | printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); | 402 | printk(KERN_WARNING PFX |
| 403 | "Heartbeat lost! Will not ping the watchdog\n"); | ||
| 385 | } | 404 | } |
| 386 | } | 405 | } |
| 387 | 406 | ||
| @@ -454,7 +473,7 @@ static int pcwd_keepalive(void) | |||
| 454 | 473 | ||
| 455 | static int pcwd_set_heartbeat(int t) | 474 | static int pcwd_set_heartbeat(int t) |
| 456 | { | 475 | { |
| 457 | if ((t < 2) || (t > 7200)) /* arbitrary upper limit */ | 476 | if (t < 2 || t > 7200) /* arbitrary upper limit */ |
| 458 | return -EINVAL; | 477 | return -EINVAL; |
| 459 | 478 | ||
| 460 | heartbeat = t; | 479 | heartbeat = t; |
| @@ -470,7 +489,7 @@ static int pcwd_get_status(int *status) | |||
| 470 | { | 489 | { |
| 471 | int control_status; | 490 | int control_status; |
| 472 | 491 | ||
| 473 | *status=0; | 492 | *status = 0; |
| 474 | spin_lock(&pcwd_private.io_lock); | 493 | spin_lock(&pcwd_private.io_lock); |
| 475 | if (pcwd_private.revision == PCWD_REVISION_A) | 494 | if (pcwd_private.revision == PCWD_REVISION_A) |
| 476 | /* Rev A cards return status information from | 495 | /* Rev A cards return status information from |
| @@ -494,9 +513,9 @@ static int pcwd_get_status(int *status) | |||
| 494 | if (control_status & WD_T110) { | 513 | if (control_status & WD_T110) { |
| 495 | *status |= WDIOF_OVERHEAT; | 514 | *status |= WDIOF_OVERHEAT; |
| 496 | if (temp_panic) { | 515 | if (temp_panic) { |
| 497 | printk(KERN_INFO PFX "Temperature overheat trip!\n"); | 516 | printk(KERN_INFO PFX |
| 517 | "Temperature overheat trip!\n"); | ||
| 498 | kernel_power_off(); | 518 | kernel_power_off(); |
| 499 | /* or should we just do a: panic(PFX "Temperature overheat trip!\n"); */ | ||
| 500 | } | 519 | } |
| 501 | } | 520 | } |
| 502 | } else { | 521 | } else { |
| @@ -506,9 +525,9 @@ static int pcwd_get_status(int *status) | |||
| 506 | if (control_status & WD_REVC_TTRP) { | 525 | if (control_status & WD_REVC_TTRP) { |
| 507 | *status |= WDIOF_OVERHEAT; | 526 | *status |= WDIOF_OVERHEAT; |
| 508 | if (temp_panic) { | 527 | if (temp_panic) { |
| 509 | printk(KERN_INFO PFX "Temperature overheat trip!\n"); | 528 | printk(KERN_INFO PFX |
| 529 | "Temperature overheat trip!\n"); | ||
| 510 | kernel_power_off(); | 530 | kernel_power_off(); |
| 511 | /* or should we just do a: panic(PFX "Temperature overheat trip!\n"); */ | ||
| 512 | } | 531 | } |
| 513 | } | 532 | } |
| 514 | } | 533 | } |
| @@ -524,18 +543,21 @@ static int pcwd_clear_status(void) | |||
| 524 | spin_lock(&pcwd_private.io_lock); | 543 | spin_lock(&pcwd_private.io_lock); |
| 525 | 544 | ||
| 526 | if (debug >= VERBOSE) | 545 | if (debug >= VERBOSE) |
| 527 | printk(KERN_INFO PFX "clearing watchdog trip status\n"); | 546 | printk(KERN_INFO PFX |
| 547 | "clearing watchdog trip status\n"); | ||
| 528 | 548 | ||
| 529 | control_status = inb_p(pcwd_private.io_addr + 1); | 549 | control_status = inb_p(pcwd_private.io_addr + 1); |
| 530 | 550 | ||
| 531 | if (debug >= DEBUG) { | 551 | if (debug >= DEBUG) { |
| 532 | printk(KERN_DEBUG PFX "status was: 0x%02x\n", control_status); | 552 | printk(KERN_DEBUG PFX "status was: 0x%02x\n", |
| 553 | control_status); | ||
| 533 | printk(KERN_DEBUG PFX "sending: 0x%02x\n", | 554 | printk(KERN_DEBUG PFX "sending: 0x%02x\n", |
| 534 | (control_status & WD_REVC_R2DS)); | 555 | (control_status & WD_REVC_R2DS)); |
| 535 | } | 556 | } |
| 536 | 557 | ||
| 537 | /* clear reset status & Keep Relay 2 disable state as it is */ | 558 | /* clear reset status & Keep Relay 2 disable state as it is */ |
| 538 | outb_p((control_status & WD_REVC_R2DS), pcwd_private.io_addr + 1); | 559 | outb_p((control_status & WD_REVC_R2DS), |
| 560 | pcwd_private.io_addr + 1); | ||
| 539 | 561 | ||
| 540 | spin_unlock(&pcwd_private.io_lock); | 562 | spin_unlock(&pcwd_private.io_lock); |
| 541 | } | 563 | } |
| @@ -572,8 +594,7 @@ static int pcwd_get_temperature(int *temperature) | |||
| 572 | * /dev/watchdog handling | 594 | * /dev/watchdog handling |
| 573 | */ | 595 | */ |
| 574 | 596 | ||
| 575 | static int pcwd_ioctl(struct inode *inode, struct file *file, | 597 | static long pcwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 576 | unsigned int cmd, unsigned long arg) | ||
| 577 | { | 598 | { |
| 578 | int rv; | 599 | int rv; |
| 579 | int status; | 600 | int status; |
| @@ -590,12 +611,9 @@ static int pcwd_ioctl(struct inode *inode, struct file *file, | |||
| 590 | .identity = "PCWD", | 611 | .identity = "PCWD", |
| 591 | }; | 612 | }; |
| 592 | 613 | ||
| 593 | switch(cmd) { | 614 | switch (cmd) { |
| 594 | default: | ||
| 595 | return -ENOTTY; | ||
| 596 | |||
| 597 | case WDIOC_GETSUPPORT: | 615 | case WDIOC_GETSUPPORT: |
| 598 | if(copy_to_user(argp, &ident, sizeof(ident))) | 616 | if (copy_to_user(argp, &ident, sizeof(ident))) |
| 599 | return -EFAULT; | 617 | return -EFAULT; |
| 600 | return 0; | 618 | return 0; |
| 601 | 619 | ||
| @@ -613,25 +631,22 @@ static int pcwd_ioctl(struct inode *inode, struct file *file, | |||
| 613 | return put_user(temperature, argp); | 631 | return put_user(temperature, argp); |
| 614 | 632 | ||
| 615 | case WDIOC_SETOPTIONS: | 633 | case WDIOC_SETOPTIONS: |
| 616 | if (pcwd_private.revision == PCWD_REVISION_C) | 634 | if (pcwd_private.revision == PCWD_REVISION_C) { |
| 617 | { | 635 | if (get_user(rv, argp)) |
| 618 | if(copy_from_user(&rv, argp, sizeof(int))) | ||
| 619 | return -EFAULT; | 636 | return -EFAULT; |
| 620 | 637 | ||
| 621 | if (rv & WDIOS_DISABLECARD) | 638 | if (rv & WDIOS_DISABLECARD) { |
| 622 | { | 639 | status = pcwd_stop(); |
| 623 | return pcwd_stop(); | 640 | if (status < 0) |
| 641 | return status; | ||
| 624 | } | 642 | } |
| 625 | 643 | if (rv & WDIOS_ENABLECARD) { | |
| 626 | if (rv & WDIOS_ENABLECARD) | 644 | status = pcwd_start(); |
| 627 | { | 645 | if (status < 0) |
| 628 | return pcwd_start(); | 646 | return status; |
| 629 | } | 647 | } |
| 630 | |||
| 631 | if (rv & WDIOS_TEMPPANIC) | 648 | if (rv & WDIOS_TEMPPANIC) |
| 632 | { | ||
| 633 | temp_panic = 1; | 649 | temp_panic = 1; |
| 634 | } | ||
| 635 | } | 650 | } |
| 636 | return -EINVAL; | 651 | return -EINVAL; |
| 637 | 652 | ||
| @@ -651,6 +666,9 @@ static int pcwd_ioctl(struct inode *inode, struct file *file, | |||
| 651 | 666 | ||
| 652 | case WDIOC_GETTIMEOUT: | 667 | case WDIOC_GETTIMEOUT: |
| 653 | return put_user(heartbeat, argp); | 668 | return put_user(heartbeat, argp); |
| 669 | |||
| 670 | default: | ||
| 671 | return -ENOTTY; | ||
| 654 | } | 672 | } |
| 655 | 673 | ||
| 656 | return 0; | 674 | return 0; |
| @@ -682,16 +700,10 @@ static ssize_t pcwd_write(struct file *file, const char __user *buf, size_t len, | |||
| 682 | 700 | ||
| 683 | static int pcwd_open(struct inode *inode, struct file *file) | 701 | static int pcwd_open(struct inode *inode, struct file *file) |
| 684 | { | 702 | { |
| 685 | if (!atomic_dec_and_test(&open_allowed) ) { | 703 | if (test_and_set_bit(0, &open_allowed)) |
| 686 | if (debug >= VERBOSE) | ||
| 687 | printk(KERN_ERR PFX "Attempt to open already opened device.\n"); | ||
| 688 | atomic_inc( &open_allowed ); | ||
| 689 | return -EBUSY; | 704 | return -EBUSY; |
| 690 | } | ||
| 691 | |||
| 692 | if (nowayout) | 705 | if (nowayout) |
| 693 | __module_get(THIS_MODULE); | 706 | __module_get(THIS_MODULE); |
| 694 | |||
| 695 | /* Activate */ | 707 | /* Activate */ |
| 696 | pcwd_start(); | 708 | pcwd_start(); |
| 697 | pcwd_keepalive(); | 709 | pcwd_keepalive(); |
| @@ -700,14 +712,15 @@ static int pcwd_open(struct inode *inode, struct file *file) | |||
| 700 | 712 | ||
| 701 | static int pcwd_close(struct inode *inode, struct file *file) | 713 | static int pcwd_close(struct inode *inode, struct file *file) |
| 702 | { | 714 | { |
| 703 | if (expect_close == 42) { | 715 | if (expect_close == 42) |
| 704 | pcwd_stop(); | 716 | pcwd_stop(); |
| 705 | } else { | 717 | else { |
| 706 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 718 | printk(KERN_CRIT PFX |
| 719 | "Unexpected close, not stopping watchdog!\n"); | ||
| 707 | pcwd_keepalive(); | 720 | pcwd_keepalive(); |
| 708 | } | 721 | } |
| 709 | expect_close = 0; | 722 | expect_close = 0; |
| 710 | atomic_inc( &open_allowed ); | 723 | clear_bit(0, &open_allowed); |
| 711 | return 0; | 724 | return 0; |
| 712 | } | 725 | } |
| 713 | 726 | ||
| @@ -750,7 +763,7 @@ static const struct file_operations pcwd_fops = { | |||
| 750 | .owner = THIS_MODULE, | 763 | .owner = THIS_MODULE, |
| 751 | .llseek = no_llseek, | 764 | .llseek = no_llseek, |
| 752 | .write = pcwd_write, | 765 | .write = pcwd_write, |
| 753 | .ioctl = pcwd_ioctl, | 766 | .unlocked_ioctl = pcwd_ioctl, |
| 754 | .open = pcwd_open, | 767 | .open = pcwd_open, |
| 755 | .release = pcwd_close, | 768 | .release = pcwd_close, |
| 756 | }; | 769 | }; |
| @@ -788,7 +801,7 @@ static inline int get_revision(void) | |||
| 788 | * presumes a floating bus reads as 0xff. */ | 801 | * presumes a floating bus reads as 0xff. */ |
| 789 | if ((inb(pcwd_private.io_addr + 2) == 0xFF) || | 802 | if ((inb(pcwd_private.io_addr + 2) == 0xFF) || |
| 790 | (inb(pcwd_private.io_addr + 3) == 0xFF)) | 803 | (inb(pcwd_private.io_addr + 3) == 0xFF)) |
| 791 | r=PCWD_REVISION_A; | 804 | r = PCWD_REVISION_A; |
| 792 | spin_unlock(&pcwd_private.io_lock); | 805 | spin_unlock(&pcwd_private.io_lock); |
| 793 | 806 | ||
| 794 | return r; | 807 | return r; |
| @@ -803,7 +816,7 @@ static inline int get_revision(void) | |||
| 803 | */ | 816 | */ |
| 804 | static int __devinit pcwd_isa_match(struct device *dev, unsigned int id) | 817 | static int __devinit pcwd_isa_match(struct device *dev, unsigned int id) |
| 805 | { | 818 | { |
| 806 | int base_addr=pcwd_ioports[id]; | 819 | int base_addr = pcwd_ioports[id]; |
| 807 | int port0, last_port0; /* Reg 0, in case it's REV A */ | 820 | int port0, last_port0; /* Reg 0, in case it's REV A */ |
| 808 | int port1, last_port1; /* Register 1 for REV C cards */ | 821 | int port1, last_port1; /* Register 1 for REV C cards */ |
| 809 | int i; | 822 | int i; |
| @@ -813,7 +826,7 @@ static int __devinit pcwd_isa_match(struct device *dev, unsigned int id) | |||
| 813 | printk(KERN_DEBUG PFX "pcwd_isa_match id=%d\n", | 826 | printk(KERN_DEBUG PFX "pcwd_isa_match id=%d\n", |
| 814 | id); | 827 | id); |
| 815 | 828 | ||
| 816 | if (!request_region (base_addr, 4, "PCWD")) { | 829 | if (!request_region(base_addr, 4, "PCWD")) { |
| 817 | printk(KERN_INFO PFX "Port 0x%04x unavailable\n", base_addr); | 830 | printk(KERN_INFO PFX "Port 0x%04x unavailable\n", base_addr); |
| 818 | return 0; | 831 | return 0; |
| 819 | } | 832 | } |
| @@ -842,7 +855,7 @@ static int __devinit pcwd_isa_match(struct device *dev, unsigned int id) | |||
| 842 | } | 855 | } |
| 843 | } | 856 | } |
| 844 | } | 857 | } |
| 845 | release_region (base_addr, 4); | 858 | release_region(base_addr, 4); |
| 846 | 859 | ||
| 847 | return retval; | 860 | return retval; |
| 848 | } | 861 | } |
| @@ -857,7 +870,8 @@ static int __devinit pcwd_isa_probe(struct device *dev, unsigned int id) | |||
| 857 | 870 | ||
| 858 | cards_found++; | 871 | cards_found++; |
| 859 | if (cards_found == 1) | 872 | if (cards_found == 1) |
| 860 | printk(KERN_INFO PFX "v%s Ken Hollis (kenji@bitgate.com)\n", WD_VER); | 873 | printk(KERN_INFO PFX "v%s Ken Hollis (kenji@bitgate.com)\n", |
| 874 | WD_VER); | ||
| 861 | 875 | ||
| 862 | if (cards_found > 1) { | 876 | if (cards_found > 1) { |
| 863 | printk(KERN_ERR PFX "This driver only supports 1 device\n"); | 877 | printk(KERN_ERR PFX "This driver only supports 1 device\n"); |
| @@ -875,10 +889,11 @@ static int __devinit pcwd_isa_probe(struct device *dev, unsigned int id) | |||
| 875 | /* Check card's revision */ | 889 | /* Check card's revision */ |
| 876 | pcwd_private.revision = get_revision(); | 890 | pcwd_private.revision = get_revision(); |
| 877 | 891 | ||
| 878 | if (!request_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4, "PCWD")) { | 892 | if (!request_region(pcwd_private.io_addr, |
| 893 | (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4, "PCWD")) { | ||
| 879 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", | 894 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", |
| 880 | pcwd_private.io_addr); | 895 | pcwd_private.io_addr); |
| 881 | ret=-EIO; | 896 | ret = -EIO; |
| 882 | goto error_request_region; | 897 | goto error_request_region; |
| 883 | } | 898 | } |
| 884 | 899 | ||
| @@ -908,26 +923,30 @@ static int __devinit pcwd_isa_probe(struct device *dev, unsigned int id) | |||
| 908 | if (heartbeat == 0) | 923 | if (heartbeat == 0) |
| 909 | heartbeat = heartbeat_tbl[(pcwd_get_option_switches() & 0x07)]; | 924 | heartbeat = heartbeat_tbl[(pcwd_get_option_switches() & 0x07)]; |
| 910 | 925 | ||
| 911 | /* Check that the heartbeat value is within it's range ; if not reset to the default */ | 926 | /* Check that the heartbeat value is within it's range; |
| 927 | if not reset to the default */ | ||
| 912 | if (pcwd_set_heartbeat(heartbeat)) { | 928 | if (pcwd_set_heartbeat(heartbeat)) { |
| 913 | pcwd_set_heartbeat(WATCHDOG_HEARTBEAT); | 929 | pcwd_set_heartbeat(WATCHDOG_HEARTBEAT); |
| 914 | printk(KERN_INFO PFX "heartbeat value must be 2<=heartbeat<=7200, using %d\n", | 930 | printk(KERN_INFO PFX |
| 915 | WATCHDOG_HEARTBEAT); | 931 | "heartbeat value must be 2 <= heartbeat <= 7200, using %d\n", |
| 932 | WATCHDOG_HEARTBEAT); | ||
| 916 | } | 933 | } |
| 917 | 934 | ||
| 918 | if (pcwd_private.supports_temp) { | 935 | if (pcwd_private.supports_temp) { |
| 919 | ret = misc_register(&temp_miscdev); | 936 | ret = misc_register(&temp_miscdev); |
| 920 | if (ret) { | 937 | if (ret) { |
| 921 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 938 | printk(KERN_ERR PFX |
| 922 | TEMP_MINOR, ret); | 939 | "cannot register miscdev on minor=%d (err=%d)\n", |
| 940 | TEMP_MINOR, ret); | ||
| 923 | goto error_misc_register_temp; | 941 | goto error_misc_register_temp; |
| 924 | } | 942 | } |
| 925 | } | 943 | } |
| 926 | 944 | ||
| 927 | ret = misc_register(&pcwd_miscdev); | 945 | ret = misc_register(&pcwd_miscdev); |
| 928 | if (ret) { | 946 | if (ret) { |
| 929 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 947 | printk(KERN_ERR PFX |
| 930 | WATCHDOG_MINOR, ret); | 948 | "cannot register miscdev on minor=%d (err=%d)\n", |
| 949 | WATCHDOG_MINOR, ret); | ||
| 931 | goto error_misc_register_watchdog; | 950 | goto error_misc_register_watchdog; |
| 932 | } | 951 | } |
| 933 | 952 | ||
| @@ -940,7 +959,8 @@ error_misc_register_watchdog: | |||
| 940 | if (pcwd_private.supports_temp) | 959 | if (pcwd_private.supports_temp) |
| 941 | misc_deregister(&temp_miscdev); | 960 | misc_deregister(&temp_miscdev); |
| 942 | error_misc_register_temp: | 961 | error_misc_register_temp: |
| 943 | release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); | 962 | release_region(pcwd_private.io_addr, |
| 963 | (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); | ||
| 944 | error_request_region: | 964 | error_request_region: |
| 945 | pcwd_private.io_addr = 0x0000; | 965 | pcwd_private.io_addr = 0x0000; |
| 946 | cards_found--; | 966 | cards_found--; |
| @@ -964,7 +984,8 @@ static int __devexit pcwd_isa_remove(struct device *dev, unsigned int id) | |||
| 964 | misc_deregister(&pcwd_miscdev); | 984 | misc_deregister(&pcwd_miscdev); |
| 965 | if (pcwd_private.supports_temp) | 985 | if (pcwd_private.supports_temp) |
| 966 | misc_deregister(&temp_miscdev); | 986 | misc_deregister(&temp_miscdev); |
| 967 | release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); | 987 | release_region(pcwd_private.io_addr, |
| 988 | (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); | ||
| 968 | pcwd_private.io_addr = 0x0000; | 989 | pcwd_private.io_addr = 0x0000; |
| 969 | cards_found--; | 990 | cards_found--; |
| 970 | 991 | ||
diff --git a/drivers/watchdog/pcwd_pci.c b/drivers/watchdog/pcwd_pci.c index 61a89e959642..90eb1d4271d7 100644 --- a/drivers/watchdog/pcwd_pci.c +++ b/drivers/watchdog/pcwd_pci.c | |||
| @@ -46,9 +46,8 @@ | |||
| 46 | #include <linux/pci.h> /* For pci functions */ | 46 | #include <linux/pci.h> /* For pci functions */ |
| 47 | #include <linux/ioport.h> /* For io-port access */ | 47 | #include <linux/ioport.h> /* For io-port access */ |
| 48 | #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ | 48 | #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ |
| 49 | 49 | #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ | |
| 50 | #include <asm/uaccess.h> /* For copy_to_user/put_user/... */ | 50 | #include <linux/io.h> /* For inb/outb/... */ |
| 51 | #include <asm/io.h> /* For inb/outb/... */ | ||
| 52 | 51 | ||
| 53 | /* Module and version information */ | 52 | /* Module and version information */ |
| 54 | #define WATCHDOG_VERSION "1.03" | 53 | #define WATCHDOG_VERSION "1.03" |
| @@ -97,7 +96,7 @@ | |||
| 97 | #define CMD_GET_CLEAR_RESET_COUNT 0x84 | 96 | #define CMD_GET_CLEAR_RESET_COUNT 0x84 |
| 98 | 97 | ||
| 99 | /* Watchdog's Dip Switch heartbeat values */ | 98 | /* Watchdog's Dip Switch heartbeat values */ |
| 100 | static const int heartbeat_tbl [] = { | 99 | static const int heartbeat_tbl[] = { |
| 101 | 5, /* OFF-OFF-OFF = 5 Sec */ | 100 | 5, /* OFF-OFF-OFF = 5 Sec */ |
| 102 | 10, /* OFF-OFF-ON = 10 Sec */ | 101 | 10, /* OFF-OFF-ON = 10 Sec */ |
| 103 | 30, /* OFF-ON-OFF = 30 Sec */ | 102 | 30, /* OFF-ON-OFF = 30 Sec */ |
| @@ -220,11 +219,10 @@ static void pcipcwd_show_card_info(void) | |||
| 220 | int option_switches; | 219 | int option_switches; |
| 221 | 220 | ||
| 222 | got_fw_rev = send_command(CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor); | 221 | got_fw_rev = send_command(CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor); |
| 223 | if (got_fw_rev) { | 222 | if (got_fw_rev) |
| 224 | sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor); | 223 | sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor); |
| 225 | } else { | 224 | else |
| 226 | sprintf(fw_ver_str, "<card no answer>"); | 225 | sprintf(fw_ver_str, "<card no answer>"); |
| 227 | } | ||
| 228 | 226 | ||
| 229 | /* Get switch settings */ | 227 | /* Get switch settings */ |
| 230 | option_switches = pcipcwd_get_option_switches(); | 228 | option_switches = pcipcwd_get_option_switches(); |
| @@ -331,7 +329,7 @@ static int pcipcwd_get_status(int *status) | |||
| 331 | { | 329 | { |
| 332 | int control_status; | 330 | int control_status; |
| 333 | 331 | ||
| 334 | *status=0; | 332 | *status = 0; |
| 335 | control_status = inb_p(pcipcwd_private.io_addr + 1); | 333 | control_status = inb_p(pcipcwd_private.io_addr + 1); |
| 336 | if (control_status & WD_PCI_WTRP) | 334 | if (control_status & WD_PCI_WTRP) |
| 337 | *status |= WDIOF_CARDRESET; | 335 | *status |= WDIOF_CARDRESET; |
| @@ -369,8 +367,8 @@ static int pcipcwd_clear_status(void) | |||
| 369 | outb_p((control_status & WD_PCI_R2DS) | WD_PCI_WTRP, pcipcwd_private.io_addr + 1); | 367 | outb_p((control_status & WD_PCI_R2DS) | WD_PCI_WTRP, pcipcwd_private.io_addr + 1); |
| 370 | 368 | ||
| 371 | /* clear reset counter */ | 369 | /* clear reset counter */ |
| 372 | msb=0; | 370 | msb = 0; |
| 373 | reset_counter=0xff; | 371 | reset_counter = 0xff; |
| 374 | send_command(CMD_GET_CLEAR_RESET_COUNT, &msb, &reset_counter); | 372 | send_command(CMD_GET_CLEAR_RESET_COUNT, &msb, &reset_counter); |
| 375 | 373 | ||
| 376 | if (debug >= DEBUG) { | 374 | if (debug >= DEBUG) { |
| @@ -442,7 +440,7 @@ static ssize_t pcipcwd_write(struct file *file, const char __user *data, | |||
| 442 | /* scan to see whether or not we got the magic character */ | 440 | /* scan to see whether or not we got the magic character */ |
| 443 | for (i = 0; i != len; i++) { | 441 | for (i = 0; i != len; i++) { |
| 444 | char c; | 442 | char c; |
| 445 | if(get_user(c, data+i)) | 443 | if (get_user(c, data + i)) |
| 446 | return -EFAULT; | 444 | return -EFAULT; |
| 447 | if (c == 'V') | 445 | if (c == 'V') |
| 448 | expect_release = 42; | 446 | expect_release = 42; |
| @@ -455,8 +453,8 @@ static ssize_t pcipcwd_write(struct file *file, const char __user *data, | |||
| 455 | return len; | 453 | return len; |
| 456 | } | 454 | } |
| 457 | 455 | ||
| 458 | static int pcipcwd_ioctl(struct inode *inode, struct file *file, | 456 | static long pcipcwd_ioctl(struct file *file, unsigned int cmd, |
| 459 | unsigned int cmd, unsigned long arg) | 457 | unsigned long arg) |
| 460 | { | 458 | { |
| 461 | void __user *argp = (void __user *)arg; | 459 | void __user *argp = (void __user *)arg; |
| 462 | int __user *p = argp; | 460 | int __user *p = argp; |
| @@ -471,92 +469,89 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file, | |||
| 471 | }; | 469 | }; |
| 472 | 470 | ||
| 473 | switch (cmd) { | 471 | switch (cmd) { |
| 474 | case WDIOC_GETSUPPORT: | 472 | case WDIOC_GETSUPPORT: |
| 475 | return copy_to_user(argp, &ident, | 473 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; |
| 476 | sizeof (ident)) ? -EFAULT : 0; | 474 | |
| 475 | case WDIOC_GETSTATUS: | ||
| 476 | { | ||
| 477 | int status; | ||
| 478 | pcipcwd_get_status(&status); | ||
| 479 | return put_user(status, p); | ||
| 480 | } | ||
| 477 | 481 | ||
| 478 | case WDIOC_GETSTATUS: | 482 | case WDIOC_GETBOOTSTATUS: |
| 479 | { | 483 | return put_user(pcipcwd_private.boot_status, p); |
| 480 | int status; | ||
| 481 | 484 | ||
| 482 | pcipcwd_get_status(&status); | 485 | case WDIOC_GETTEMP: |
| 486 | { | ||
| 487 | int temperature; | ||
| 483 | 488 | ||
| 484 | return put_user(status, p); | 489 | if (pcipcwd_get_temperature(&temperature)) |
| 485 | } | 490 | return -EFAULT; |
| 486 | 491 | ||
| 487 | case WDIOC_GETBOOTSTATUS: | 492 | return put_user(temperature, p); |
| 488 | return put_user(pcipcwd_private.boot_status, p); | 493 | } |
| 489 | 494 | ||
| 490 | case WDIOC_GETTEMP: | 495 | case WDIOC_SETOPTIONS: |
| 491 | { | 496 | { |
| 492 | int temperature; | 497 | int new_options, retval = -EINVAL; |
| 493 | 498 | ||
| 494 | if (pcipcwd_get_temperature(&temperature)) | 499 | if (get_user(new_options, p)) |
| 495 | return -EFAULT; | 500 | return -EFAULT; |
| 496 | 501 | ||
| 497 | return put_user(temperature, p); | 502 | if (new_options & WDIOS_DISABLECARD) { |
| 503 | if (pcipcwd_stop()) | ||
| 504 | return -EIO; | ||
| 505 | retval = 0; | ||
| 498 | } | 506 | } |
| 499 | 507 | ||
| 500 | case WDIOC_KEEPALIVE: | 508 | if (new_options & WDIOS_ENABLECARD) { |
| 501 | pcipcwd_keepalive(); | 509 | if (pcipcwd_start()) |
| 502 | return 0; | 510 | return -EIO; |
| 503 | 511 | retval = 0; | |
| 504 | case WDIOC_SETOPTIONS: | 512 | } |
| 505 | { | ||
| 506 | int new_options, retval = -EINVAL; | ||
| 507 | |||
| 508 | if (get_user (new_options, p)) | ||
| 509 | return -EFAULT; | ||
| 510 | |||
| 511 | if (new_options & WDIOS_DISABLECARD) { | ||
| 512 | if (pcipcwd_stop()) | ||
| 513 | return -EIO; | ||
| 514 | retval = 0; | ||
| 515 | } | ||
| 516 | 513 | ||
| 517 | if (new_options & WDIOS_ENABLECARD) { | 514 | if (new_options & WDIOS_TEMPPANIC) { |
| 518 | if (pcipcwd_start()) | 515 | temp_panic = 1; |
| 519 | return -EIO; | 516 | retval = 0; |
| 520 | retval = 0; | 517 | } |
| 521 | } | ||
| 522 | 518 | ||
| 523 | if (new_options & WDIOS_TEMPPANIC) { | 519 | return retval; |
| 524 | temp_panic = 1; | 520 | } |
| 525 | retval = 0; | ||
| 526 | } | ||
| 527 | 521 | ||
| 528 | return retval; | 522 | case WDIOC_KEEPALIVE: |
| 529 | } | 523 | pcipcwd_keepalive(); |
| 524 | return 0; | ||
| 530 | 525 | ||
| 531 | case WDIOC_SETTIMEOUT: | 526 | case WDIOC_SETTIMEOUT: |
| 532 | { | 527 | { |
| 533 | int new_heartbeat; | 528 | int new_heartbeat; |
| 534 | 529 | ||
| 535 | if (get_user(new_heartbeat, p)) | 530 | if (get_user(new_heartbeat, p)) |
| 536 | return -EFAULT; | 531 | return -EFAULT; |
| 537 | 532 | ||
| 538 | if (pcipcwd_set_heartbeat(new_heartbeat)) | 533 | if (pcipcwd_set_heartbeat(new_heartbeat)) |
| 539 | return -EINVAL; | 534 | return -EINVAL; |
| 540 | 535 | ||
| 541 | pcipcwd_keepalive(); | 536 | pcipcwd_keepalive(); |
| 542 | /* Fall */ | 537 | /* Fall */ |
| 543 | } | 538 | } |
| 544 | 539 | ||
| 545 | case WDIOC_GETTIMEOUT: | 540 | case WDIOC_GETTIMEOUT: |
| 546 | return put_user(heartbeat, p); | 541 | return put_user(heartbeat, p); |
| 547 | 542 | ||
| 548 | case WDIOC_GETTIMELEFT: | 543 | case WDIOC_GETTIMELEFT: |
| 549 | { | 544 | { |
| 550 | int time_left; | 545 | int time_left; |
| 551 | 546 | ||
| 552 | if (pcipcwd_get_timeleft(&time_left)) | 547 | if (pcipcwd_get_timeleft(&time_left)) |
| 553 | return -EFAULT; | 548 | return -EFAULT; |
| 554 | 549 | ||
| 555 | return put_user(time_left, p); | 550 | return put_user(time_left, p); |
| 556 | } | 551 | } |
| 557 | 552 | ||
| 558 | default: | 553 | default: |
| 559 | return -ENOTTY; | 554 | return -ENOTTY; |
| 560 | } | 555 | } |
| 561 | } | 556 | } |
| 562 | 557 | ||
| @@ -603,7 +598,7 @@ static ssize_t pcipcwd_temp_read(struct file *file, char __user *data, | |||
| 603 | if (pcipcwd_get_temperature(&temperature)) | 598 | if (pcipcwd_get_temperature(&temperature)) |
| 604 | return -EFAULT; | 599 | return -EFAULT; |
| 605 | 600 | ||
| 606 | if (copy_to_user (data, &temperature, 1)) | 601 | if (copy_to_user(data, &temperature, 1)) |
| 607 | return -EFAULT; | 602 | return -EFAULT; |
| 608 | 603 | ||
| 609 | return 1; | 604 | return 1; |
| @@ -628,10 +623,8 @@ static int pcipcwd_temp_release(struct inode *inode, struct file *file) | |||
| 628 | 623 | ||
| 629 | static int pcipcwd_notify_sys(struct notifier_block *this, unsigned long code, void *unused) | 624 | static int pcipcwd_notify_sys(struct notifier_block *this, unsigned long code, void *unused) |
| 630 | { | 625 | { |
| 631 | if (code==SYS_DOWN || code==SYS_HALT) { | 626 | if (code == SYS_DOWN || code == SYS_HALT) |
| 632 | /* Turn the WDT off */ | 627 | pcipcwd_stop(); /* Turn the WDT off */ |
| 633 | pcipcwd_stop(); | ||
| 634 | } | ||
| 635 | 628 | ||
| 636 | return NOTIFY_DONE; | 629 | return NOTIFY_DONE; |
| 637 | } | 630 | } |
| @@ -644,7 +637,7 @@ static const struct file_operations pcipcwd_fops = { | |||
| 644 | .owner = THIS_MODULE, | 637 | .owner = THIS_MODULE, |
| 645 | .llseek = no_llseek, | 638 | .llseek = no_llseek, |
| 646 | .write = pcipcwd_write, | 639 | .write = pcipcwd_write, |
| 647 | .ioctl = pcipcwd_ioctl, | 640 | .unlocked_ioctl = pcipcwd_ioctl, |
| 648 | .open = pcipcwd_open, | 641 | .open = pcipcwd_open, |
| 649 | .release = pcipcwd_release, | 642 | .release = pcipcwd_release, |
| 650 | }; | 643 | }; |
diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c index bf443d077a1e..c1685c942de6 100644 --- a/drivers/watchdog/pcwd_usb.c +++ b/drivers/watchdog/pcwd_usb.c | |||
| @@ -40,8 +40,7 @@ | |||
| 40 | #include <linux/slab.h> /* For kmalloc, ... */ | 40 | #include <linux/slab.h> /* For kmalloc, ... */ |
| 41 | #include <linux/mutex.h> /* For mutex locking */ | 41 | #include <linux/mutex.h> /* For mutex locking */ |
| 42 | #include <linux/hid.h> /* For HID_REQ_SET_REPORT & HID_DT_REPORT */ | 42 | #include <linux/hid.h> /* For HID_REQ_SET_REPORT & HID_DT_REPORT */ |
| 43 | 43 | #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ | |
| 44 | #include <asm/uaccess.h> /* For copy_to_user/put_user/... */ | ||
| 45 | 44 | ||
| 46 | 45 | ||
| 47 | #ifdef CONFIG_USB_DEBUG | 46 | #ifdef CONFIG_USB_DEBUG |
| @@ -88,7 +87,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" _ | |||
| 88 | #define USB_PCWD_PRODUCT_ID 0x1140 | 87 | #define USB_PCWD_PRODUCT_ID 0x1140 |
| 89 | 88 | ||
| 90 | /* table of devices that work with this driver */ | 89 | /* table of devices that work with this driver */ |
| 91 | static struct usb_device_id usb_pcwd_table [] = { | 90 | static struct usb_device_id usb_pcwd_table[] = { |
| 92 | { USB_DEVICE(USB_PCWD_VENDOR_ID, USB_PCWD_PRODUCT_ID) }, | 91 | { USB_DEVICE(USB_PCWD_VENDOR_ID, USB_PCWD_PRODUCT_ID) }, |
| 93 | { } /* Terminating entry */ | 92 | { } /* Terminating entry */ |
| 94 | }; | 93 | }; |
| @@ -110,7 +109,7 @@ MODULE_DEVICE_TABLE (usb, usb_pcwd_table); | |||
| 110 | #define CMD_DISABLE_WATCHDOG CMD_ENABLE_WATCHDOG | 109 | #define CMD_DISABLE_WATCHDOG CMD_ENABLE_WATCHDOG |
| 111 | 110 | ||
| 112 | /* Watchdog's Dip Switch heartbeat values */ | 111 | /* Watchdog's Dip Switch heartbeat values */ |
| 113 | static const int heartbeat_tbl [] = { | 112 | static const int heartbeat_tbl[] = { |
| 114 | 5, /* OFF-OFF-OFF = 5 Sec */ | 113 | 5, /* OFF-OFF-OFF = 5 Sec */ |
| 115 | 10, /* OFF-OFF-ON = 10 Sec */ | 114 | 10, /* OFF-OFF-ON = 10 Sec */ |
| 116 | 30, /* OFF-ON-OFF = 30 Sec */ | 115 | 30, /* OFF-ON-OFF = 30 Sec */ |
| @@ -130,15 +129,15 @@ static char expect_release; | |||
| 130 | 129 | ||
| 131 | /* Structure to hold all of our device specific stuff */ | 130 | /* Structure to hold all of our device specific stuff */ |
| 132 | struct usb_pcwd_private { | 131 | struct usb_pcwd_private { |
| 133 | struct usb_device * udev; /* save off the usb device pointer */ | 132 | struct usb_device *udev; /* save off the usb device pointer */ |
| 134 | struct usb_interface * interface; /* the interface for this device */ | 133 | struct usb_interface *interface; /* the interface for this device */ |
| 135 | 134 | ||
| 136 | unsigned int interface_number; /* the interface number used for cmd's */ | 135 | unsigned int interface_number; /* the interface number used for cmd's */ |
| 137 | 136 | ||
| 138 | unsigned char * intr_buffer; /* the buffer to intr data */ | 137 | unsigned char *intr_buffer; /* the buffer to intr data */ |
| 139 | dma_addr_t intr_dma; /* the dma address for the intr buffer */ | 138 | dma_addr_t intr_dma; /* the dma address for the intr buffer */ |
| 140 | size_t intr_size; /* the size of the intr buffer */ | 139 | size_t intr_size; /* the size of the intr buffer */ |
| 141 | struct urb * intr_urb; /* the urb used for the intr pipe */ | 140 | struct urb *intr_urb; /* the urb used for the intr pipe */ |
| 142 | 141 | ||
| 143 | unsigned char cmd_command; /* The command that is reported back */ | 142 | unsigned char cmd_command; /* The command that is reported back */ |
| 144 | unsigned char cmd_data_msb; /* The data MSB that is reported back */ | 143 | unsigned char cmd_data_msb; /* The data MSB that is reported back */ |
| @@ -154,8 +153,8 @@ static struct usb_pcwd_private *usb_pcwd_device; | |||
| 154 | static DEFINE_MUTEX(disconnect_mutex); | 153 | static DEFINE_MUTEX(disconnect_mutex); |
| 155 | 154 | ||
| 156 | /* local function prototypes */ | 155 | /* local function prototypes */ |
| 157 | static int usb_pcwd_probe (struct usb_interface *interface, const struct usb_device_id *id); | 156 | static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_device_id *id); |
| 158 | static void usb_pcwd_disconnect (struct usb_interface *interface); | 157 | static void usb_pcwd_disconnect(struct usb_interface *interface); |
| 159 | 158 | ||
| 160 | /* usb specific object needed to register this driver with the usb subsystem */ | 159 | /* usb specific object needed to register this driver with the usb subsystem */ |
| 161 | static struct usb_driver usb_pcwd_driver = { | 160 | static struct usb_driver usb_pcwd_driver = { |
| @@ -195,10 +194,10 @@ static void usb_pcwd_intr_done(struct urb *urb) | |||
| 195 | usb_pcwd->cmd_data_lsb = data[2]; | 194 | usb_pcwd->cmd_data_lsb = data[2]; |
| 196 | 195 | ||
| 197 | /* notify anyone waiting that the cmd has finished */ | 196 | /* notify anyone waiting that the cmd has finished */ |
| 198 | atomic_set (&usb_pcwd->cmd_received, 1); | 197 | atomic_set(&usb_pcwd->cmd_received, 1); |
| 199 | 198 | ||
| 200 | resubmit: | 199 | resubmit: |
| 201 | retval = usb_submit_urb (urb, GFP_ATOMIC); | 200 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
| 202 | if (retval) | 201 | if (retval) |
| 203 | printk(KERN_ERR PFX "can't resubmit intr, usb_submit_urb failed with result %d\n", | 202 | printk(KERN_ERR PFX "can't resubmit intr, usb_submit_urb failed with result %d\n", |
| 204 | retval); | 203 | retval); |
| @@ -224,7 +223,7 @@ static int usb_pcwd_send_command(struct usb_pcwd_private *usb_pcwd, unsigned cha | |||
| 224 | dbg("sending following data cmd=0x%02x msb=0x%02x lsb=0x%02x", | 223 | dbg("sending following data cmd=0x%02x msb=0x%02x lsb=0x%02x", |
| 225 | buf[0], buf[1], buf[2]); | 224 | buf[0], buf[1], buf[2]); |
| 226 | 225 | ||
| 227 | atomic_set (&usb_pcwd->cmd_received, 0); | 226 | atomic_set(&usb_pcwd->cmd_received, 0); |
| 228 | 227 | ||
| 229 | if (usb_control_msg(usb_pcwd->udev, usb_sndctrlpipe(usb_pcwd->udev, 0), | 228 | if (usb_control_msg(usb_pcwd->udev, usb_sndctrlpipe(usb_pcwd->udev, 0), |
| 230 | HID_REQ_SET_REPORT, HID_DT_REPORT, | 229 | HID_REQ_SET_REPORT, HID_DT_REPORT, |
| @@ -237,7 +236,7 @@ static int usb_pcwd_send_command(struct usb_pcwd_private *usb_pcwd, unsigned cha | |||
| 237 | got_response = 0; | 236 | got_response = 0; |
| 238 | for (count = 0; (count < USB_COMMAND_TIMEOUT) && (!got_response); count++) { | 237 | for (count = 0; (count < USB_COMMAND_TIMEOUT) && (!got_response); count++) { |
| 239 | mdelay(1); | 238 | mdelay(1); |
| 240 | if (atomic_read (&usb_pcwd->cmd_received)) | 239 | if (atomic_read(&usb_pcwd->cmd_received)) |
| 241 | got_response = 1; | 240 | got_response = 1; |
| 242 | } | 241 | } |
| 243 | 242 | ||
| @@ -356,7 +355,7 @@ static ssize_t usb_pcwd_write(struct file *file, const char __user *data, | |||
| 356 | /* scan to see whether or not we got the magic character */ | 355 | /* scan to see whether or not we got the magic character */ |
| 357 | for (i = 0; i != len; i++) { | 356 | for (i = 0; i != len; i++) { |
| 358 | char c; | 357 | char c; |
| 359 | if(get_user(c, data+i)) | 358 | if (get_user(c, data + i)) |
| 360 | return -EFAULT; | 359 | return -EFAULT; |
| 361 | if (c == 'V') | 360 | if (c == 'V') |
| 362 | expect_release = 42; | 361 | expect_release = 42; |
| @@ -369,8 +368,8 @@ static ssize_t usb_pcwd_write(struct file *file, const char __user *data, | |||
| 369 | return len; | 368 | return len; |
| 370 | } | 369 | } |
| 371 | 370 | ||
| 372 | static int usb_pcwd_ioctl(struct inode *inode, struct file *file, | 371 | static long usb_pcwd_ioctl(struct file *file, unsigned int cmd, |
| 373 | unsigned int cmd, unsigned long arg) | 372 | unsigned long arg) |
| 374 | { | 373 | { |
| 375 | void __user *argp = (void __user *)arg; | 374 | void __user *argp = (void __user *)arg; |
| 376 | int __user *p = argp; | 375 | int __user *p = argp; |
| @@ -383,77 +382,76 @@ static int usb_pcwd_ioctl(struct inode *inode, struct file *file, | |||
| 383 | }; | 382 | }; |
| 384 | 383 | ||
| 385 | switch (cmd) { | 384 | switch (cmd) { |
| 386 | case WDIOC_GETSUPPORT: | 385 | case WDIOC_GETSUPPORT: |
| 387 | return copy_to_user(argp, &ident, | 386 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; |
| 388 | sizeof (ident)) ? -EFAULT : 0; | ||
| 389 | 387 | ||
| 390 | case WDIOC_GETSTATUS: | 388 | case WDIOC_GETSTATUS: |
| 391 | case WDIOC_GETBOOTSTATUS: | 389 | case WDIOC_GETBOOTSTATUS: |
| 392 | return put_user(0, p); | 390 | return put_user(0, p); |
| 393 | 391 | ||
| 394 | case WDIOC_GETTEMP: | 392 | case WDIOC_GETTEMP: |
| 395 | { | 393 | { |
| 396 | int temperature; | 394 | int temperature; |
| 397 | 395 | ||
| 398 | if (usb_pcwd_get_temperature(usb_pcwd_device, &temperature)) | 396 | if (usb_pcwd_get_temperature(usb_pcwd_device, &temperature)) |
| 399 | return -EFAULT; | 397 | return -EFAULT; |
| 400 | 398 | ||
| 401 | return put_user(temperature, p); | 399 | return put_user(temperature, p); |
| 402 | } | 400 | } |
| 403 | 401 | ||
| 404 | case WDIOC_KEEPALIVE: | 402 | case WDIOC_SETOPTIONS: |
| 405 | usb_pcwd_keepalive(usb_pcwd_device); | 403 | { |
| 406 | return 0; | 404 | int new_options, retval = -EINVAL; |
| 407 | 405 | ||
| 408 | case WDIOC_SETOPTIONS: | 406 | if (get_user(new_options, p)) |
| 409 | { | 407 | return -EFAULT; |
| 410 | int new_options, retval = -EINVAL; | ||
| 411 | 408 | ||
| 412 | if (get_user (new_options, p)) | 409 | if (new_options & WDIOS_DISABLECARD) { |
| 413 | return -EFAULT; | 410 | usb_pcwd_stop(usb_pcwd_device); |
| 411 | retval = 0; | ||
| 412 | } | ||
| 414 | 413 | ||
| 415 | if (new_options & WDIOS_DISABLECARD) { | 414 | if (new_options & WDIOS_ENABLECARD) { |
| 416 | usb_pcwd_stop(usb_pcwd_device); | 415 | usb_pcwd_start(usb_pcwd_device); |
| 417 | retval = 0; | 416 | retval = 0; |
| 418 | } | 417 | } |
| 419 | 418 | ||
| 420 | if (new_options & WDIOS_ENABLECARD) { | 419 | return retval; |
| 421 | usb_pcwd_start(usb_pcwd_device); | 420 | } |
| 422 | retval = 0; | ||
| 423 | } | ||
| 424 | 421 | ||
| 425 | return retval; | 422 | case WDIOC_KEEPALIVE: |
| 426 | } | 423 | usb_pcwd_keepalive(usb_pcwd_device); |
| 424 | return 0; | ||
| 427 | 425 | ||
| 428 | case WDIOC_SETTIMEOUT: | 426 | case WDIOC_SETTIMEOUT: |
| 429 | { | 427 | { |
| 430 | int new_heartbeat; | 428 | int new_heartbeat; |
| 431 | 429 | ||
| 432 | if (get_user(new_heartbeat, p)) | 430 | if (get_user(new_heartbeat, p)) |
| 433 | return -EFAULT; | 431 | return -EFAULT; |
| 434 | 432 | ||
| 435 | if (usb_pcwd_set_heartbeat(usb_pcwd_device, new_heartbeat)) | 433 | if (usb_pcwd_set_heartbeat(usb_pcwd_device, new_heartbeat)) |
| 436 | return -EINVAL; | 434 | return -EINVAL; |
| 437 | 435 | ||
| 438 | usb_pcwd_keepalive(usb_pcwd_device); | 436 | usb_pcwd_keepalive(usb_pcwd_device); |
| 439 | /* Fall */ | 437 | /* Fall */ |
| 440 | } | 438 | } |
| 441 | 439 | ||
| 442 | case WDIOC_GETTIMEOUT: | 440 | case WDIOC_GETTIMEOUT: |
| 443 | return put_user(heartbeat, p); | 441 | return put_user(heartbeat, p); |
| 444 | 442 | ||
| 445 | case WDIOC_GETTIMELEFT: | 443 | case WDIOC_GETTIMELEFT: |
| 446 | { | 444 | { |
| 447 | int time_left; | 445 | int time_left; |
| 448 | 446 | ||
| 449 | if (usb_pcwd_get_timeleft(usb_pcwd_device, &time_left)) | 447 | if (usb_pcwd_get_timeleft(usb_pcwd_device, &time_left)) |
| 450 | return -EFAULT; | 448 | return -EFAULT; |
| 451 | 449 | ||
| 452 | return put_user(time_left, p); | 450 | return put_user(time_left, p); |
| 453 | } | 451 | } |
| 454 | 452 | ||
| 455 | default: | 453 | default: |
| 456 | return -ENOTTY; | 454 | return -ENOTTY; |
| 457 | } | 455 | } |
| 458 | } | 456 | } |
| 459 | 457 | ||
| @@ -519,10 +517,8 @@ static int usb_pcwd_temperature_release(struct inode *inode, struct file *file) | |||
| 519 | 517 | ||
| 520 | static int usb_pcwd_notify_sys(struct notifier_block *this, unsigned long code, void *unused) | 518 | static int usb_pcwd_notify_sys(struct notifier_block *this, unsigned long code, void *unused) |
| 521 | { | 519 | { |
| 522 | if (code==SYS_DOWN || code==SYS_HALT) { | 520 | if (code == SYS_DOWN || code == SYS_HALT) |
| 523 | /* Turn the WDT off */ | 521 | usb_pcwd_stop(usb_pcwd_device); /* Turn the WDT off */ |
| 524 | usb_pcwd_stop(usb_pcwd_device); | ||
| 525 | } | ||
| 526 | 522 | ||
| 527 | return NOTIFY_DONE; | 523 | return NOTIFY_DONE; |
| 528 | } | 524 | } |
| @@ -535,7 +531,7 @@ static const struct file_operations usb_pcwd_fops = { | |||
| 535 | .owner = THIS_MODULE, | 531 | .owner = THIS_MODULE, |
| 536 | .llseek = no_llseek, | 532 | .llseek = no_llseek, |
| 537 | .write = usb_pcwd_write, | 533 | .write = usb_pcwd_write, |
| 538 | .ioctl = usb_pcwd_ioctl, | 534 | .unlocked_ioctl = usb_pcwd_ioctl, |
| 539 | .open = usb_pcwd_open, | 535 | .open = usb_pcwd_open, |
| 540 | .release = usb_pcwd_release, | 536 | .release = usb_pcwd_release, |
| 541 | }; | 537 | }; |
| @@ -567,13 +563,13 @@ static struct notifier_block usb_pcwd_notifier = { | |||
| 567 | /** | 563 | /** |
| 568 | * usb_pcwd_delete | 564 | * usb_pcwd_delete |
| 569 | */ | 565 | */ |
| 570 | static inline void usb_pcwd_delete (struct usb_pcwd_private *usb_pcwd) | 566 | static inline void usb_pcwd_delete(struct usb_pcwd_private *usb_pcwd) |
| 571 | { | 567 | { |
| 572 | usb_free_urb(usb_pcwd->intr_urb); | 568 | usb_free_urb(usb_pcwd->intr_urb); |
| 573 | if (usb_pcwd->intr_buffer != NULL) | 569 | if (usb_pcwd->intr_buffer != NULL) |
| 574 | usb_buffer_free(usb_pcwd->udev, usb_pcwd->intr_size, | 570 | usb_buffer_free(usb_pcwd->udev, usb_pcwd->intr_size, |
| 575 | usb_pcwd->intr_buffer, usb_pcwd->intr_dma); | 571 | usb_pcwd->intr_buffer, usb_pcwd->intr_dma); |
| 576 | kfree (usb_pcwd); | 572 | kfree(usb_pcwd); |
| 577 | } | 573 | } |
| 578 | 574 | ||
| 579 | /** | 575 | /** |
| @@ -626,7 +622,7 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi | |||
| 626 | maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); | 622 | maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); |
| 627 | 623 | ||
| 628 | /* allocate memory for our device and initialize it */ | 624 | /* allocate memory for our device and initialize it */ |
| 629 | usb_pcwd = kzalloc (sizeof(struct usb_pcwd_private), GFP_KERNEL); | 625 | usb_pcwd = kzalloc(sizeof(struct usb_pcwd_private), GFP_KERNEL); |
| 630 | if (usb_pcwd == NULL) { | 626 | if (usb_pcwd == NULL) { |
| 631 | printk(KERN_ERR PFX "Out of memory\n"); | 627 | printk(KERN_ERR PFX "Out of memory\n"); |
| 632 | goto error; | 628 | goto error; |
| @@ -641,7 +637,8 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi | |||
| 641 | usb_pcwd->intr_size = (le16_to_cpu(endpoint->wMaxPacketSize) > 8 ? le16_to_cpu(endpoint->wMaxPacketSize) : 8); | 637 | usb_pcwd->intr_size = (le16_to_cpu(endpoint->wMaxPacketSize) > 8 ? le16_to_cpu(endpoint->wMaxPacketSize) : 8); |
| 642 | 638 | ||
| 643 | /* set up the memory buffer's */ | 639 | /* set up the memory buffer's */ |
| 644 | if (!(usb_pcwd->intr_buffer = usb_buffer_alloc(udev, usb_pcwd->intr_size, GFP_ATOMIC, &usb_pcwd->intr_dma))) { | 640 | usb_pcwd->intr_buffer = usb_buffer_alloc(udev, usb_pcwd->intr_size, GFP_ATOMIC, &usb_pcwd->intr_dma); |
| 641 | if (!usb_pcwd->intr_buffer) { | ||
| 645 | printk(KERN_ERR PFX "Out of memory\n"); | 642 | printk(KERN_ERR PFX "Out of memory\n"); |
| 646 | goto error; | 643 | goto error; |
| 647 | } | 644 | } |
| @@ -675,11 +672,10 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi | |||
| 675 | 672 | ||
| 676 | /* Get the Firmware Version */ | 673 | /* Get the Firmware Version */ |
| 677 | got_fw_rev = usb_pcwd_send_command(usb_pcwd, CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor); | 674 | got_fw_rev = usb_pcwd_send_command(usb_pcwd, CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor); |
| 678 | if (got_fw_rev) { | 675 | if (got_fw_rev) |
| 679 | sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor); | 676 | sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor); |
| 680 | } else { | 677 | else |
| 681 | sprintf(fw_ver_str, "<card no answer>"); | 678 | sprintf(fw_ver_str, "<card no answer>"); |
| 682 | } | ||
| 683 | 679 | ||
| 684 | printk(KERN_INFO PFX "Found card (Firmware: %s) with temp option\n", | 680 | printk(KERN_INFO PFX "Found card (Firmware: %s) with temp option\n", |
| 685 | fw_ver_str); | 681 | fw_ver_str); |
| @@ -725,7 +721,7 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi | |||
| 725 | } | 721 | } |
| 726 | 722 | ||
| 727 | /* we can register the device now, as it is ready */ | 723 | /* we can register the device now, as it is ready */ |
| 728 | usb_set_intfdata (interface, usb_pcwd); | 724 | usb_set_intfdata(interface, usb_pcwd); |
| 729 | 725 | ||
| 730 | printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n", | 726 | printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n", |
| 731 | heartbeat, nowayout); | 727 | heartbeat, nowayout); |
| @@ -759,8 +755,8 @@ static void usb_pcwd_disconnect(struct usb_interface *interface) | |||
| 759 | /* prevent races with open() */ | 755 | /* prevent races with open() */ |
| 760 | mutex_lock(&disconnect_mutex); | 756 | mutex_lock(&disconnect_mutex); |
| 761 | 757 | ||
| 762 | usb_pcwd = usb_get_intfdata (interface); | 758 | usb_pcwd = usb_get_intfdata(interface); |
| 763 | usb_set_intfdata (interface, NULL); | 759 | usb_set_intfdata(interface, NULL); |
| 764 | 760 | ||
| 765 | mutex_lock(&usb_pcwd->mtx); | 761 | mutex_lock(&usb_pcwd->mtx); |
| 766 | 762 | ||
| @@ -820,5 +816,5 @@ static void __exit usb_pcwd_exit(void) | |||
| 820 | } | 816 | } |
| 821 | 817 | ||
| 822 | 818 | ||
| 823 | module_init (usb_pcwd_init); | 819 | module_init(usb_pcwd_init); |
| 824 | module_exit (usb_pcwd_exit); | 820 | module_exit(usb_pcwd_exit); |
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c index f431a0427eaa..0ed84162437b 100644 --- a/drivers/watchdog/pnx4008_wdt.c +++ b/drivers/watchdog/pnx4008_wdt.c | |||
| @@ -28,10 +28,9 @@ | |||
| 28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
| 29 | #include <linux/clk.h> | 29 | #include <linux/clk.h> |
| 30 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
| 31 | 31 | #include <linux/uaccess.h> | |
| 32 | #include <linux/io.h> | ||
| 32 | #include <mach/hardware.h> | 33 | #include <mach/hardware.h> |
| 33 | #include <asm/uaccess.h> | ||
| 34 | #include <asm/io.h> | ||
| 35 | 34 | ||
| 36 | #define MODULE_NAME "PNX4008-WDT: " | 35 | #define MODULE_NAME "PNX4008-WDT: " |
| 37 | 36 | ||
| @@ -144,9 +143,8 @@ static int pnx4008_wdt_open(struct inode *inode, struct file *file) | |||
| 144 | return nonseekable_open(inode, file); | 143 | return nonseekable_open(inode, file); |
| 145 | } | 144 | } |
| 146 | 145 | ||
| 147 | static ssize_t | 146 | static ssize_t pnx4008_wdt_write(struct file *file, const char *data, |
| 148 | pnx4008_wdt_write(struct file *file, const char *data, size_t len, | 147 | size_t len, loff_t *ppos) |
| 149 | loff_t * ppos) | ||
| 150 | { | 148 | { |
| 151 | if (len) { | 149 | if (len) { |
| 152 | if (!nowayout) { | 150 | if (!nowayout) { |
| @@ -169,15 +167,14 @@ pnx4008_wdt_write(struct file *file, const char *data, size_t len, | |||
| 169 | return len; | 167 | return len; |
| 170 | } | 168 | } |
| 171 | 169 | ||
| 172 | static struct watchdog_info ident = { | 170 | static const struct watchdog_info ident = { |
| 173 | .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | | 171 | .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | |
| 174 | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | 172 | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, |
| 175 | .identity = "PNX4008 Watchdog", | 173 | .identity = "PNX4008 Watchdog", |
| 176 | }; | 174 | }; |
| 177 | 175 | ||
| 178 | static int | 176 | static long pnx4008_wdt_ioctl(struct inode *inode, struct file *file, |
| 179 | pnx4008_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 177 | unsigned int cmd, unsigned long arg) |
| 180 | unsigned long arg) | ||
| 181 | { | 178 | { |
| 182 | int ret = -ENOTTY; | 179 | int ret = -ENOTTY; |
| 183 | int time; | 180 | int time; |
| @@ -196,6 +193,11 @@ pnx4008_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
| 196 | ret = put_user(boot_status, (int *)arg); | 193 | ret = put_user(boot_status, (int *)arg); |
| 197 | break; | 194 | break; |
| 198 | 195 | ||
| 196 | case WDIOC_KEEPALIVE: | ||
| 197 | wdt_enable(); | ||
| 198 | ret = 0; | ||
| 199 | break; | ||
| 200 | |||
| 199 | case WDIOC_SETTIMEOUT: | 201 | case WDIOC_SETTIMEOUT: |
| 200 | ret = get_user(time, (int *)arg); | 202 | ret = get_user(time, (int *)arg); |
| 201 | if (ret) | 203 | if (ret) |
| @@ -213,11 +215,6 @@ pnx4008_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
| 213 | case WDIOC_GETTIMEOUT: | 215 | case WDIOC_GETTIMEOUT: |
| 214 | ret = put_user(heartbeat, (int *)arg); | 216 | ret = put_user(heartbeat, (int *)arg); |
| 215 | break; | 217 | break; |
| 216 | |||
| 217 | case WDIOC_KEEPALIVE: | ||
| 218 | wdt_enable(); | ||
| 219 | ret = 0; | ||
| 220 | break; | ||
| 221 | } | 218 | } |
| 222 | return ret; | 219 | return ret; |
| 223 | } | 220 | } |
| @@ -238,7 +235,7 @@ static const struct file_operations pnx4008_wdt_fops = { | |||
| 238 | .owner = THIS_MODULE, | 235 | .owner = THIS_MODULE, |
| 239 | .llseek = no_llseek, | 236 | .llseek = no_llseek, |
| 240 | .write = pnx4008_wdt_write, | 237 | .write = pnx4008_wdt_write, |
| 241 | .ioctl = pnx4008_wdt_ioctl, | 238 | .unlocked_ioctl = pnx4008_wdt_ioctl, |
| 242 | .open = pnx4008_wdt_open, | 239 | .open = pnx4008_wdt_open, |
| 243 | .release = pnx4008_wdt_release, | 240 | .release = pnx4008_wdt_release, |
| 244 | }; | 241 | }; |
diff --git a/drivers/watchdog/rm9k_wdt.c b/drivers/watchdog/rm9k_wdt.c index 5c921e471564..f1ae3729a19e 100644 --- a/drivers/watchdog/rm9k_wdt.c +++ b/drivers/watchdog/rm9k_wdt.c | |||
| @@ -29,10 +29,10 @@ | |||
| 29 | #include <linux/notifier.h> | 29 | #include <linux/notifier.h> |
| 30 | #include <linux/miscdevice.h> | 30 | #include <linux/miscdevice.h> |
| 31 | #include <linux/watchdog.h> | 31 | #include <linux/watchdog.h> |
| 32 | #include <asm/io.h> | 32 | #include <linux/io.h> |
| 33 | #include <linux/uaccess.h> | ||
| 33 | #include <asm/atomic.h> | 34 | #include <asm/atomic.h> |
| 34 | #include <asm/processor.h> | 35 | #include <asm/processor.h> |
| 35 | #include <asm/uaccess.h> | ||
| 36 | #include <asm/system.h> | 36 | #include <asm/system.h> |
| 37 | #include <asm/rm9k-ocd.h> | 37 | #include <asm/rm9k-ocd.h> |
| 38 | 38 | ||
| @@ -53,10 +53,12 @@ static void wdt_gpi_stop(void); | |||
| 53 | static void wdt_gpi_set_timeout(unsigned int); | 53 | static void wdt_gpi_set_timeout(unsigned int); |
| 54 | static int wdt_gpi_open(struct inode *, struct file *); | 54 | static int wdt_gpi_open(struct inode *, struct file *); |
| 55 | static int wdt_gpi_release(struct inode *, struct file *); | 55 | static int wdt_gpi_release(struct inode *, struct file *); |
| 56 | static ssize_t wdt_gpi_write(struct file *, const char __user *, size_t, loff_t *); | 56 | static ssize_t wdt_gpi_write(struct file *, const char __user *, size_t, |
| 57 | loff_t *); | ||
| 57 | static long wdt_gpi_ioctl(struct file *, unsigned int, unsigned long); | 58 | static long wdt_gpi_ioctl(struct file *, unsigned int, unsigned long); |
| 58 | static int wdt_gpi_notify(struct notifier_block *, unsigned long, void *); | 59 | static int wdt_gpi_notify(struct notifier_block *, unsigned long, void *); |
| 59 | static const struct resource *wdt_gpi_get_resource(struct platform_device *, const char *, unsigned int); | 60 | static const struct resource *wdt_gpi_get_resource(struct platform_device *, |
| 61 | const char *, unsigned int); | ||
| 60 | static int __init wdt_gpi_probe(struct device *); | 62 | static int __init wdt_gpi_probe(struct device *); |
| 61 | static int __exit wdt_gpi_remove(struct device *); | 63 | static int __exit wdt_gpi_remove(struct device *); |
| 62 | 64 | ||
| @@ -68,7 +70,7 @@ static int locked; | |||
| 68 | 70 | ||
| 69 | 71 | ||
| 70 | /* These are set from device resources */ | 72 | /* These are set from device resources */ |
| 71 | static void __iomem * wd_regs; | 73 | static void __iomem *wd_regs; |
| 72 | static unsigned int wd_irq, wd_ctr; | 74 | static unsigned int wd_irq, wd_ctr; |
| 73 | 75 | ||
| 74 | 76 | ||
| @@ -216,7 +218,8 @@ static int wdt_gpi_release(struct inode *inode, struct file *file) | |||
| 216 | if (expect_close) { | 218 | if (expect_close) { |
| 217 | wdt_gpi_stop(); | 219 | wdt_gpi_stop(); |
| 218 | free_irq(wd_irq, &miscdev); | 220 | free_irq(wd_irq, &miscdev); |
| 219 | printk(KERN_INFO "%s: watchdog stopped\n", wdt_gpi_name); | 221 | printk(KERN_INFO "%s: watchdog stopped\n", |
| 222 | wdt_gpi_name); | ||
| 220 | } else { | 223 | } else { |
| 221 | printk(KERN_CRIT "%s: unexpected close() -" | 224 | printk(KERN_CRIT "%s: unexpected close() -" |
| 222 | " watchdog left running\n", | 225 | " watchdog left running\n", |
| @@ -231,8 +234,8 @@ static int wdt_gpi_release(struct inode *inode, struct file *file) | |||
| 231 | return 0; | 234 | return 0; |
| 232 | } | 235 | } |
| 233 | 236 | ||
| 234 | static ssize_t | 237 | static ssize_t wdt_gpi_write(struct file *f, const char __user *d, size_t s, |
| 235 | wdt_gpi_write(struct file *f, const char __user *d, size_t s, loff_t *o) | 238 | loff_t *o) |
| 236 | { | 239 | { |
| 237 | char val; | 240 | char val; |
| 238 | 241 | ||
| @@ -241,8 +244,7 @@ wdt_gpi_write(struct file *f, const char __user *d, size_t s, loff_t *o) | |||
| 241 | return s ? 1 : 0; | 244 | return s ? 1 : 0; |
| 242 | } | 245 | } |
| 243 | 246 | ||
| 244 | static long | 247 | static long wdt_gpi_ioctl(struct file *f, unsigned int cmd, unsigned long arg) |
| 245 | wdt_gpi_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | ||
| 246 | { | 248 | { |
| 247 | long res = -ENOTTY; | 249 | long res = -ENOTTY; |
| 248 | const long size = _IOC_SIZE(cmd); | 250 | const long size = _IOC_SIZE(cmd); |
| @@ -271,7 +273,8 @@ wdt_gpi_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | |||
| 271 | case WDIOC_GETSUPPORT: | 273 | case WDIOC_GETSUPPORT: |
| 272 | wdinfo.options = nowayout ? | 274 | wdinfo.options = nowayout ? |
| 273 | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING : | 275 | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING : |
| 274 | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE; | 276 | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | |
| 277 | WDIOF_MAGICCLOSE; | ||
| 275 | res = __copy_to_user(argp, &wdinfo, size) ? -EFAULT : size; | 278 | res = __copy_to_user(argp, &wdinfo, size) ? -EFAULT : size; |
| 276 | break; | 279 | break; |
| 277 | 280 | ||
| @@ -322,8 +325,8 @@ wdt_gpi_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | |||
| 322 | 325 | ||
| 323 | 326 | ||
| 324 | /* Shutdown notifier */ | 327 | /* Shutdown notifier */ |
| 325 | static int | 328 | static int wdt_gpi_notify(struct notifier_block *this, unsigned long code, |
| 326 | wdt_gpi_notify(struct notifier_block *this, unsigned long code, void *unused) | 329 | void *unused) |
| 327 | { | 330 | { |
| 328 | if (code == SYS_DOWN || code == SYS_HALT) | 331 | if (code == SYS_DOWN || code == SYS_HALT) |
| 329 | wdt_gpi_stop(); | 332 | wdt_gpi_stop(); |
| @@ -333,9 +336,8 @@ wdt_gpi_notify(struct notifier_block *this, unsigned long code, void *unused) | |||
| 333 | 336 | ||
| 334 | 337 | ||
| 335 | /* Init & exit procedures */ | 338 | /* Init & exit procedures */ |
| 336 | static const struct resource * | 339 | static const struct resource *wdt_gpi_get_resource(struct platform_device *pdv, |
| 337 | wdt_gpi_get_resource(struct platform_device *pdv, const char *name, | 340 | const char *name, unsigned int type) |
| 338 | unsigned int type) | ||
| 339 | { | 341 | { |
| 340 | char buf[80]; | 342 | char buf[80]; |
| 341 | if (snprintf(buf, sizeof buf, "%s_0", name) >= sizeof buf) | 343 | if (snprintf(buf, sizeof buf, "%s_0", name) >= sizeof buf) |
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index f1fe800658f4..3da2b90d2fe6 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c | |||
| @@ -119,17 +119,6 @@ static void __s3c2410wdt_stop(void) | |||
| 119 | { | 119 | { |
| 120 | unsigned long wtcon; | 120 | unsigned long wtcon; |
| 121 | 121 | ||
| 122 | spin_lock(&wdt_lock); | ||
| 123 | wtcon = readl(wdt_base + S3C2410_WTCON); | ||
| 124 | wtcon &= ~(S3C2410_WTCON_ENABLE | S3C2410_WTCON_RSTEN); | ||
| 125 | writel(wtcon, wdt_base + S3C2410_WTCON); | ||
| 126 | spin_unlock(&wdt_lock); | ||
| 127 | } | ||
| 128 | |||
| 129 | static void __s3c2410wdt_stop(void) | ||
| 130 | { | ||
| 131 | unsigned long wtcon; | ||
| 132 | |||
| 133 | wtcon = readl(wdt_base + S3C2410_WTCON); | 122 | wtcon = readl(wdt_base + S3C2410_WTCON); |
| 134 | wtcon &= ~(S3C2410_WTCON_ENABLE | S3C2410_WTCON_RSTEN); | 123 | wtcon &= ~(S3C2410_WTCON_ENABLE | S3C2410_WTCON_RSTEN); |
| 135 | writel(wtcon, wdt_base + S3C2410_WTCON); | 124 | writel(wtcon, wdt_base + S3C2410_WTCON); |
| @@ -305,8 +294,6 @@ static long s3c2410wdt_ioctl(struct file *file, unsigned int cmd, | |||
| 305 | int new_margin; | 294 | int new_margin; |
| 306 | 295 | ||
| 307 | switch (cmd) { | 296 | switch (cmd) { |
| 308 | default: | ||
| 309 | return -ENOTTY; | ||
| 310 | case WDIOC_GETSUPPORT: | 297 | case WDIOC_GETSUPPORT: |
| 311 | return copy_to_user(argp, &s3c2410_wdt_ident, | 298 | return copy_to_user(argp, &s3c2410_wdt_ident, |
| 312 | sizeof(s3c2410_wdt_ident)) ? -EFAULT : 0; | 299 | sizeof(s3c2410_wdt_ident)) ? -EFAULT : 0; |
| @@ -325,6 +312,8 @@ static long s3c2410wdt_ioctl(struct file *file, unsigned int cmd, | |||
| 325 | return put_user(tmr_margin, p); | 312 | return put_user(tmr_margin, p); |
| 326 | case WDIOC_GETTIMEOUT: | 313 | case WDIOC_GETTIMEOUT: |
| 327 | return put_user(tmr_margin, p); | 314 | return put_user(tmr_margin, p); |
| 315 | default: | ||
| 316 | return -ENOTTY; | ||
| 328 | } | 317 | } |
| 329 | } | 318 | } |
| 330 | 319 | ||
diff --git a/drivers/watchdog/sa1100_wdt.c b/drivers/watchdog/sa1100_wdt.c index 97d9da758dcc..31a48437dc3d 100644 --- a/drivers/watchdog/sa1100_wdt.c +++ b/drivers/watchdog/sa1100_wdt.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/watchdog.h> | 26 | #include <linux/watchdog.h> |
| 27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
| 28 | #include <linux/bitops.h> | 28 | #include <linux/bitops.h> |
| 29 | #include <linux/uaccess.h> | ||
| 29 | 30 | ||
| 30 | #ifdef CONFIG_ARCH_PXA | 31 | #ifdef CONFIG_ARCH_PXA |
| 31 | #include <mach/pxa-regs.h> | 32 | #include <mach/pxa-regs.h> |
| @@ -33,7 +34,6 @@ | |||
| 33 | 34 | ||
| 34 | #include <mach/reset.h> | 35 | #include <mach/reset.h> |
| 35 | #include <mach/hardware.h> | 36 | #include <mach/hardware.h> |
| 36 | #include <asm/uaccess.h> | ||
| 37 | 37 | ||
| 38 | #define OSCR_FREQ CLOCK_TICK_RATE | 38 | #define OSCR_FREQ CLOCK_TICK_RATE |
| 39 | 39 | ||
| @@ -46,7 +46,7 @@ static int boot_status; | |||
| 46 | */ | 46 | */ |
| 47 | static int sa1100dog_open(struct inode *inode, struct file *file) | 47 | static int sa1100dog_open(struct inode *inode, struct file *file) |
| 48 | { | 48 | { |
| 49 | if (test_and_set_bit(1,&sa1100wdt_users)) | 49 | if (test_and_set_bit(1, &sa1100wdt_users)) |
| 50 | return -EBUSY; | 50 | return -EBUSY; |
| 51 | 51 | ||
| 52 | /* Activate SA1100 Watchdog timer */ | 52 | /* Activate SA1100 Watchdog timer */ |
| @@ -67,28 +67,27 @@ static int sa1100dog_open(struct inode *inode, struct file *file) | |||
| 67 | static int sa1100dog_release(struct inode *inode, struct file *file) | 67 | static int sa1100dog_release(struct inode *inode, struct file *file) |
| 68 | { | 68 | { |
| 69 | printk(KERN_CRIT "WATCHDOG: Device closed - timer will not stop\n"); | 69 | printk(KERN_CRIT "WATCHDOG: Device closed - timer will not stop\n"); |
| 70 | |||
| 71 | clear_bit(1, &sa1100wdt_users); | 70 | clear_bit(1, &sa1100wdt_users); |
| 72 | |||
| 73 | return 0; | 71 | return 0; |
| 74 | } | 72 | } |
| 75 | 73 | ||
| 76 | static ssize_t sa1100dog_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) | 74 | static ssize_t sa1100dog_write(struct file *file, const char __user *data, |
| 75 | size_t len, loff_t *ppos) | ||
| 77 | { | 76 | { |
| 78 | if (len) | 77 | if (len) |
| 79 | /* Refresh OSMR3 timer. */ | 78 | /* Refresh OSMR3 timer. */ |
| 80 | OSMR3 = OSCR + pre_margin; | 79 | OSMR3 = OSCR + pre_margin; |
| 81 | |||
| 82 | return len; | 80 | return len; |
| 83 | } | 81 | } |
| 84 | 82 | ||
| 85 | static struct watchdog_info ident = { | 83 | static const struct watchdog_info ident = { |
| 86 | .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | 84 | .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT |
| 85 | | WDIOF_KEEPALIVEPING, | ||
| 87 | .identity = "SA1100/PXA255 Watchdog", | 86 | .identity = "SA1100/PXA255 Watchdog", |
| 88 | }; | 87 | }; |
| 89 | 88 | ||
| 90 | static int sa1100dog_ioctl(struct inode *inode, struct file *file, | 89 | static long sa1100dog_ioctl(struct file *file, unsigned int cmd, |
| 91 | unsigned int cmd, unsigned long arg) | 90 | unsigned long arg) |
| 92 | { | 91 | { |
| 93 | int ret = -ENOTTY; | 92 | int ret = -ENOTTY; |
| 94 | int time; | 93 | int time; |
| @@ -109,6 +108,11 @@ static int sa1100dog_ioctl(struct inode *inode, struct file *file, | |||
| 109 | ret = put_user(boot_status, p); | 108 | ret = put_user(boot_status, p); |
| 110 | break; | 109 | break; |
| 111 | 110 | ||
| 111 | case WDIOC_KEEPALIVE: | ||
| 112 | OSMR3 = OSCR + pre_margin; | ||
| 113 | ret = 0; | ||
| 114 | break; | ||
| 115 | |||
| 112 | case WDIOC_SETTIMEOUT: | 116 | case WDIOC_SETTIMEOUT: |
| 113 | ret = get_user(time, p); | 117 | ret = get_user(time, p); |
| 114 | if (ret) | 118 | if (ret) |
| @@ -126,27 +130,20 @@ static int sa1100dog_ioctl(struct inode *inode, struct file *file, | |||
| 126 | case WDIOC_GETTIMEOUT: | 130 | case WDIOC_GETTIMEOUT: |
| 127 | ret = put_user(pre_margin / OSCR_FREQ, p); | 131 | ret = put_user(pre_margin / OSCR_FREQ, p); |
| 128 | break; | 132 | break; |
| 129 | |||
| 130 | case WDIOC_KEEPALIVE: | ||
| 131 | OSMR3 = OSCR + pre_margin; | ||
| 132 | ret = 0; | ||
| 133 | break; | ||
| 134 | } | 133 | } |
| 135 | return ret; | 134 | return ret; |
| 136 | } | 135 | } |
| 137 | 136 | ||
| 138 | static const struct file_operations sa1100dog_fops = | 137 | static const struct file_operations sa1100dog_fops = { |
| 139 | { | ||
| 140 | .owner = THIS_MODULE, | 138 | .owner = THIS_MODULE, |
| 141 | .llseek = no_llseek, | 139 | .llseek = no_llseek, |
| 142 | .write = sa1100dog_write, | 140 | .write = sa1100dog_write, |
| 143 | .ioctl = sa1100dog_ioctl, | 141 | .unlocked_ioctl = sa1100dog_ioctl, |
| 144 | .open = sa1100dog_open, | 142 | .open = sa1100dog_open, |
| 145 | .release = sa1100dog_release, | 143 | .release = sa1100dog_release, |
| 146 | }; | 144 | }; |
| 147 | 145 | ||
| 148 | static struct miscdevice sa1100dog_miscdev = | 146 | static struct miscdevice sa1100dog_miscdev = { |
| 149 | { | ||
| 150 | .minor = WATCHDOG_MINOR, | 147 | .minor = WATCHDOG_MINOR, |
| 151 | .name = "watchdog", | 148 | .name = "watchdog", |
| 152 | .fops = &sa1100dog_fops, | 149 | .fops = &sa1100dog_fops, |
| @@ -169,8 +166,9 @@ static int __init sa1100dog_init(void) | |||
| 169 | 166 | ||
| 170 | ret = misc_register(&sa1100dog_miscdev); | 167 | ret = misc_register(&sa1100dog_miscdev); |
| 171 | if (ret == 0) | 168 | if (ret == 0) |
| 172 | printk("SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n", | 169 | printk(KERN_INFO |
| 173 | margin); | 170 | "SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n", |
| 171 | margin); | ||
| 174 | return ret; | 172 | return ret; |
| 175 | } | 173 | } |
| 176 | 174 | ||
diff --git a/drivers/watchdog/sb_wdog.c b/drivers/watchdog/sb_wdog.c index b94431433695..27e526a07c9a 100644 --- a/drivers/watchdog/sb_wdog.c +++ b/drivers/watchdog/sb_wdog.c | |||
| @@ -57,6 +57,7 @@ | |||
| 57 | #include <asm/sibyte/sb1250_int.h> | 57 | #include <asm/sibyte/sb1250_int.h> |
| 58 | #include <asm/sibyte/sb1250_scd.h> | 58 | #include <asm/sibyte/sb1250_scd.h> |
| 59 | 59 | ||
| 60 | static DEFINE_SPINLOCK(sbwd_lock); | ||
| 60 | 61 | ||
| 61 | /* | 62 | /* |
| 62 | * set the initial count value of a timer | 63 | * set the initial count value of a timer |
| @@ -65,8 +66,10 @@ | |||
| 65 | */ | 66 | */ |
| 66 | void sbwdog_set(char __iomem *wdog, unsigned long t) | 67 | void sbwdog_set(char __iomem *wdog, unsigned long t) |
| 67 | { | 68 | { |
| 69 | spin_lock(&sbwd_lock); | ||
| 68 | __raw_writeb(0, wdog - 0x10); | 70 | __raw_writeb(0, wdog - 0x10); |
| 69 | __raw_writeq(t & 0x7fffffUL, wdog); | 71 | __raw_writeq(t & 0x7fffffUL, wdog); |
| 72 | spin_unlock(&sbwd_lock); | ||
| 70 | } | 73 | } |
| 71 | 74 | ||
| 72 | /* | 75 | /* |
| @@ -77,7 +80,9 @@ void sbwdog_set(char __iomem *wdog, unsigned long t) | |||
| 77 | */ | 80 | */ |
| 78 | void sbwdog_pet(char __iomem *wdog) | 81 | void sbwdog_pet(char __iomem *wdog) |
| 79 | { | 82 | { |
| 83 | spin_lock(&sbwd_lock); | ||
| 80 | __raw_writeb(__raw_readb(wdog) | 1, wdog); | 84 | __raw_writeb(__raw_readb(wdog) | 1, wdog); |
| 85 | spin_unlock(&sbwd_lock); | ||
| 81 | } | 86 | } |
| 82 | 87 | ||
| 83 | static unsigned long sbwdog_gate; /* keeps it to one thread only */ | 88 | static unsigned long sbwdog_gate; /* keeps it to one thread only */ |
| @@ -86,8 +91,9 @@ static char __iomem *user_dog = (char __iomem *)(IO_BASE + (A_SCD_WDOG_CFG_1)); | |||
| 86 | static unsigned long timeout = 0x7fffffUL; /* useconds: 8.3ish secs. */ | 91 | static unsigned long timeout = 0x7fffffUL; /* useconds: 8.3ish secs. */ |
| 87 | static int expect_close; | 92 | static int expect_close; |
| 88 | 93 | ||
| 89 | static struct watchdog_info ident = { | 94 | static const struct watchdog_info ident = { |
| 90 | .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | 95 | .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | |
| 96 | WDIOF_KEEPALIVEPING, | ||
| 91 | .identity = "SiByte Watchdog", | 97 | .identity = "SiByte Watchdog", |
| 92 | }; | 98 | }; |
| 93 | 99 | ||
| @@ -97,9 +103,8 @@ static struct watchdog_info ident = { | |||
| 97 | static int sbwdog_open(struct inode *inode, struct file *file) | 103 | static int sbwdog_open(struct inode *inode, struct file *file) |
| 98 | { | 104 | { |
| 99 | nonseekable_open(inode, file); | 105 | nonseekable_open(inode, file); |
| 100 | if (test_and_set_bit(0, &sbwdog_gate)) { | 106 | if (test_and_set_bit(0, &sbwdog_gate)) |
| 101 | return -EBUSY; | 107 | return -EBUSY; |
| 102 | } | ||
| 103 | __module_get(THIS_MODULE); | 108 | __module_get(THIS_MODULE); |
| 104 | 109 | ||
| 105 | /* | 110 | /* |
| @@ -120,8 +125,9 @@ static int sbwdog_release(struct inode *inode, struct file *file) | |||
| 120 | __raw_writeb(0, user_dog); | 125 | __raw_writeb(0, user_dog); |
| 121 | module_put(THIS_MODULE); | 126 | module_put(THIS_MODULE); |
| 122 | } else { | 127 | } else { |
| 123 | printk(KERN_CRIT "%s: Unexpected close, not stopping watchdog!\n", | 128 | printk(KERN_CRIT |
| 124 | ident.identity); | 129 | "%s: Unexpected close, not stopping watchdog!\n", |
| 130 | ident.identity); | ||
| 125 | sbwdog_pet(user_dog); | 131 | sbwdog_pet(user_dog); |
| 126 | } | 132 | } |
| 127 | clear_bit(0, &sbwdog_gate); | 133 | clear_bit(0, &sbwdog_gate); |
| @@ -147,12 +153,10 @@ static ssize_t sbwdog_write(struct file *file, const char __user *data, | |||
| 147 | for (i = 0; i != len; i++) { | 153 | for (i = 0; i != len; i++) { |
| 148 | char c; | 154 | char c; |
| 149 | 155 | ||
| 150 | if (get_user(c, data + i)) { | 156 | if (get_user(c, data + i)) |
| 151 | return -EFAULT; | 157 | return -EFAULT; |
| 152 | } | 158 | if (c == 'V') |
| 153 | if (c == 'V') { | ||
| 154 | expect_close = 42; | 159 | expect_close = 42; |
| 155 | } | ||
| 156 | } | 160 | } |
| 157 | sbwdog_pet(user_dog); | 161 | sbwdog_pet(user_dog); |
| 158 | } | 162 | } |
| @@ -160,8 +164,8 @@ static ssize_t sbwdog_write(struct file *file, const char __user *data, | |||
| 160 | return len; | 164 | return len; |
| 161 | } | 165 | } |
| 162 | 166 | ||
| 163 | static int sbwdog_ioctl(struct inode *inode, struct file *file, | 167 | static long sbwdog_ioctl(struct file *file, unsigned int cmd, |
| 164 | unsigned int cmd, unsigned long arg) | 168 | unsigned long arg) |
| 165 | { | 169 | { |
| 166 | int ret = -ENOTTY; | 170 | int ret = -ENOTTY; |
| 167 | unsigned long time; | 171 | unsigned long time; |
| @@ -178,11 +182,15 @@ static int sbwdog_ioctl(struct inode *inode, struct file *file, | |||
| 178 | ret = put_user(0, p); | 182 | ret = put_user(0, p); |
| 179 | break; | 183 | break; |
| 180 | 184 | ||
| 185 | case WDIOC_KEEPALIVE: | ||
| 186 | sbwdog_pet(user_dog); | ||
| 187 | ret = 0; | ||
| 188 | break; | ||
| 189 | |||
| 181 | case WDIOC_SETTIMEOUT: | 190 | case WDIOC_SETTIMEOUT: |
| 182 | ret = get_user(time, p); | 191 | ret = get_user(time, p); |
| 183 | if (ret) { | 192 | if (ret) |
| 184 | break; | 193 | break; |
| 185 | } | ||
| 186 | 194 | ||
| 187 | time *= 1000000; | 195 | time *= 1000000; |
| 188 | if (time > 0x7fffffUL) { | 196 | if (time > 0x7fffffUL) { |
| @@ -200,11 +208,6 @@ static int sbwdog_ioctl(struct inode *inode, struct file *file, | |||
| 200 | */ | 208 | */ |
| 201 | ret = put_user(__raw_readq(user_dog - 8) / 1000000, p); | 209 | ret = put_user(__raw_readq(user_dog - 8) / 1000000, p); |
| 202 | break; | 210 | break; |
| 203 | |||
| 204 | case WDIOC_KEEPALIVE: | ||
| 205 | sbwdog_pet(user_dog); | ||
| 206 | ret = 0; | ||
| 207 | break; | ||
| 208 | } | 211 | } |
| 209 | return ret; | 212 | return ret; |
| 210 | } | 213 | } |
| @@ -212,8 +215,8 @@ static int sbwdog_ioctl(struct inode *inode, struct file *file, | |||
| 212 | /* | 215 | /* |
| 213 | * Notifier for system down | 216 | * Notifier for system down |
| 214 | */ | 217 | */ |
| 215 | static int | 218 | static int sbwdog_notify_sys(struct notifier_block *this, unsigned long code, |
| 216 | sbwdog_notify_sys(struct notifier_block *this, unsigned long code, void *erf) | 219 | void *erf) |
| 217 | { | 220 | { |
| 218 | if (code == SYS_DOWN || code == SYS_HALT) { | 221 | if (code == SYS_DOWN || code == SYS_HALT) { |
| 219 | /* | 222 | /* |
| @@ -226,18 +229,16 @@ sbwdog_notify_sys(struct notifier_block *this, unsigned long code, void *erf) | |||
| 226 | return NOTIFY_DONE; | 229 | return NOTIFY_DONE; |
| 227 | } | 230 | } |
| 228 | 231 | ||
| 229 | static const struct file_operations sbwdog_fops = | 232 | static const struct file_operations sbwdog_fops = { |
| 230 | { | ||
| 231 | .owner = THIS_MODULE, | 233 | .owner = THIS_MODULE, |
| 232 | .llseek = no_llseek, | 234 | .llseek = no_llseek, |
| 233 | .write = sbwdog_write, | 235 | .write = sbwdog_write, |
| 234 | .ioctl = sbwdog_ioctl, | 236 | .unlocked_ioctl = sbwdog_ioctl, |
| 235 | .open = sbwdog_open, | 237 | .open = sbwdog_open, |
| 236 | .release = sbwdog_release, | 238 | .release = sbwdog_release, |
| 237 | }; | 239 | }; |
| 238 | 240 | ||
| 239 | static struct miscdevice sbwdog_miscdev = | 241 | static struct miscdevice sbwdog_miscdev = { |
| 240 | { | ||
| 241 | .minor = WATCHDOG_MINOR, | 242 | .minor = WATCHDOG_MINOR, |
| 242 | .name = "watchdog", | 243 | .name = "watchdog", |
| 243 | .fops = &sbwdog_fops, | 244 | .fops = &sbwdog_fops, |
| @@ -267,13 +268,12 @@ irqreturn_t sbwdog_interrupt(int irq, void *addr) | |||
| 267 | /* | 268 | /* |
| 268 | * if it's the second watchdog timer, it's for those users | 269 | * if it's the second watchdog timer, it's for those users |
| 269 | */ | 270 | */ |
| 270 | if (wd_cfg_reg == user_dog) { | 271 | if (wd_cfg_reg == user_dog) |
| 271 | printk(KERN_CRIT | 272 | printk(KERN_CRIT |
| 272 | "%s in danger of initiating system reset in %ld.%01ld seconds\n", | 273 | "%s in danger of initiating system reset in %ld.%01ld seconds\n", |
| 273 | ident.identity, wd_init / 1000000, (wd_init / 100000) % 10); | 274 | ident.identity, wd_init / 1000000, (wd_init / 100000) % 10); |
| 274 | } else { | 275 | else |
| 275 | cfg |= 1; | 276 | cfg |= 1; |
| 276 | } | ||
| 277 | 277 | ||
| 278 | __raw_writeb(cfg, wd_cfg_reg); | 278 | __raw_writeb(cfg, wd_cfg_reg); |
| 279 | 279 | ||
| @@ -289,28 +289,31 @@ static int __init sbwdog_init(void) | |||
| 289 | */ | 289 | */ |
| 290 | ret = register_reboot_notifier(&sbwdog_notifier); | 290 | ret = register_reboot_notifier(&sbwdog_notifier); |
| 291 | if (ret) { | 291 | if (ret) { |
| 292 | printk (KERN_ERR "%s: cannot register reboot notifier (err=%d)\n", | 292 | printk(KERN_ERR |
| 293 | ident.identity, ret); | 293 | "%s: cannot register reboot notifier (err=%d)\n", |
| 294 | ident.identity, ret); | ||
| 294 | return ret; | 295 | return ret; |
| 295 | } | 296 | } |
| 296 | 297 | ||
| 297 | /* | 298 | /* |
| 298 | * get the resources | 299 | * get the resources |
| 299 | */ | 300 | */ |
| 300 | ret = misc_register(&sbwdog_miscdev); | ||
| 301 | if (ret == 0) { | ||
| 302 | printk(KERN_INFO "%s: timeout is %ld.%ld secs\n", ident.identity, | ||
| 303 | timeout / 1000000, (timeout / 100000) % 10); | ||
| 304 | } | ||
| 305 | 301 | ||
| 306 | ret = request_irq(1, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED, | 302 | ret = request_irq(1, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED, |
| 307 | ident.identity, (void *)user_dog); | 303 | ident.identity, (void *)user_dog); |
| 308 | if (ret) { | 304 | if (ret) { |
| 309 | printk(KERN_ERR "%s: failed to request irq 1 - %d\n", ident.identity, | 305 | printk(KERN_ERR "%s: failed to request irq 1 - %d\n", |
| 310 | ret); | 306 | ident.identity, ret); |
| 311 | misc_deregister(&sbwdog_miscdev); | 307 | return ret; |
| 312 | } | 308 | } |
| 313 | 309 | ||
| 310 | ret = misc_register(&sbwdog_miscdev); | ||
| 311 | if (ret == 0) { | ||
| 312 | printk(KERN_INFO "%s: timeout is %ld.%ld secs\n", | ||
| 313 | ident.identity, | ||
| 314 | timeout / 1000000, (timeout / 100000) % 10); | ||
| 315 | } else | ||
| 316 | free_irq(1, (void *)user_dog); | ||
| 314 | return ret; | 317 | return ret; |
| 315 | } | 318 | } |
| 316 | 319 | ||
| @@ -327,7 +330,7 @@ MODULE_DESCRIPTION("SiByte Watchdog"); | |||
| 327 | 330 | ||
| 328 | module_param(timeout, ulong, 0); | 331 | module_param(timeout, ulong, 0); |
| 329 | MODULE_PARM_DESC(timeout, | 332 | MODULE_PARM_DESC(timeout, |
| 330 | "Watchdog timeout in microseconds (max/default 8388607 or 8.3ish secs)"); | 333 | "Watchdog timeout in microseconds (max/default 8388607 or 8.3ish secs)"); |
| 331 | 334 | ||
| 332 | MODULE_LICENSE("GPL"); | 335 | MODULE_LICENSE("GPL"); |
| 333 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | 336 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); |
| @@ -336,16 +339,15 @@ MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | |||
| 336 | * example code that can be put in a platform code area to utilize the | 339 | * example code that can be put in a platform code area to utilize the |
| 337 | * first watchdog timer for the kernels own purpose. | 340 | * first watchdog timer for the kernels own purpose. |
| 338 | 341 | ||
| 339 | void | 342 | void platform_wd_setup(void) |
| 340 | platform_wd_setup(void) | ||
| 341 | { | 343 | { |
| 342 | int ret; | 344 | int ret; |
| 343 | 345 | ||
| 344 | ret = request_irq(0, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED, | 346 | ret = request_irq(1, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED, |
| 345 | "Kernel Watchdog", IOADDR(A_SCD_WDOG_CFG_0)); | 347 | "Kernel Watchdog", IOADDR(A_SCD_WDOG_CFG_0)); |
| 346 | if (ret) { | 348 | if (ret) { |
| 347 | printk(KERN_CRIT "Watchdog IRQ zero(0) failed to be requested - %d\n", | 349 | printk(KERN_CRIT |
| 348 | ret); | 350 | "Watchdog IRQ zero(0) failed to be requested - %d\n", ret); |
| 349 | } | 351 | } |
| 350 | } | 352 | } |
| 351 | 353 | ||
diff --git a/drivers/watchdog/sbc60xxwdt.c b/drivers/watchdog/sbc60xxwdt.c index ef76f01625e7..3266daaaecf8 100644 --- a/drivers/watchdog/sbc60xxwdt.c +++ b/drivers/watchdog/sbc60xxwdt.c | |||
| @@ -16,19 +16,23 @@ | |||
| 16 | * | 16 | * |
| 17 | * 12/4 - 2000 [Initial revision] | 17 | * 12/4 - 2000 [Initial revision] |
| 18 | * 25/4 - 2000 Added /dev/watchdog support | 18 | * 25/4 - 2000 Added /dev/watchdog support |
| 19 | * 09/5 - 2001 [smj@oro.net] fixed fop_write to "return 1" on success | 19 | * 09/5 - 2001 [smj@oro.net] fixed fop_write to "return 1" |
| 20 | * on success | ||
| 20 | * 12/4 - 2002 [rob@osinvestor.com] eliminate fop_read | 21 | * 12/4 - 2002 [rob@osinvestor.com] eliminate fop_read |
| 21 | * fix possible wdt_is_open race | 22 | * fix possible wdt_is_open race |
| 22 | * add CONFIG_WATCHDOG_NOWAYOUT support | 23 | * add CONFIG_WATCHDOG_NOWAYOUT support |
| 23 | * remove lock_kernel/unlock_kernel pairs | 24 | * remove lock_kernel/unlock_kernel pairs |
| 24 | * added KERN_* to printk's | 25 | * added KERN_* to printk's |
| 25 | * got rid of extraneous comments | 26 | * got rid of extraneous comments |
| 26 | * changed watchdog_info to correctly reflect what the driver offers | 27 | * changed watchdog_info to correctly reflect what |
| 27 | * added WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS, WDIOC_SETTIMEOUT, | 28 | * the driver offers |
| 28 | * WDIOC_GETTIMEOUT, and WDIOC_SETOPTIONS ioctls | 29 | * added WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS, |
| 30 | * WDIOC_SETTIMEOUT, WDIOC_GETTIMEOUT, and | ||
| 31 | * WDIOC_SETOPTIONS ioctls | ||
| 29 | * 09/8 - 2003 [wim@iguana.be] cleanup of trailing spaces | 32 | * 09/8 - 2003 [wim@iguana.be] cleanup of trailing spaces |
| 30 | * use module_param | 33 | * use module_param |
| 31 | * made timeout (the emulated heartbeat) a module_param | 34 | * made timeout (the emulated heartbeat) a |
| 35 | * module_param | ||
| 32 | * made the keepalive ping an internal subroutine | 36 | * made the keepalive ping an internal subroutine |
| 33 | * made wdt_stop and wdt_start module params | 37 | * made wdt_stop and wdt_start module params |
| 34 | * added extra printk's for startup problems | 38 | * added extra printk's for startup problems |
| @@ -56,9 +60,9 @@ | |||
| 56 | #include <linux/notifier.h> | 60 | #include <linux/notifier.h> |
| 57 | #include <linux/reboot.h> | 61 | #include <linux/reboot.h> |
| 58 | #include <linux/init.h> | 62 | #include <linux/init.h> |
| 63 | #include <linux/io.h> | ||
| 64 | #include <linux/uaccess.h> | ||
| 59 | 65 | ||
| 60 | #include <asm/io.h> | ||
| 61 | #include <asm/uaccess.h> | ||
| 62 | #include <asm/system.h> | 66 | #include <asm/system.h> |
| 63 | 67 | ||
| 64 | #define OUR_NAME "sbc60xxwdt" | 68 | #define OUR_NAME "sbc60xxwdt" |
| @@ -94,13 +98,18 @@ MODULE_PARM_DESC(wdt_start, "SBC60xx WDT 'start' io port (default 0x443)"); | |||
| 94 | */ | 98 | */ |
| 95 | 99 | ||
| 96 | #define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ | 100 | #define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ |
| 97 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ | 101 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds, multiplied by HZ to |
| 102 | get seconds to wait for a ping */ | ||
| 98 | module_param(timeout, int, 0); | 103 | module_param(timeout, int, 0); |
| 99 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | 104 | MODULE_PARM_DESC(timeout, |
| 105 | "Watchdog timeout in seconds. (1<=timeout<=3600, default=" | ||
| 106 | __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | ||
| 100 | 107 | ||
| 101 | static int nowayout = WATCHDOG_NOWAYOUT; | 108 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 102 | module_param(nowayout, int, 0); | 109 | module_param(nowayout, int, 0); |
| 103 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 110 | MODULE_PARM_DESC(nowayout, |
| 111 | "Watchdog cannot be stopped once started (default=" | ||
| 112 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 104 | 113 | ||
| 105 | static void wdt_timer_ping(unsigned long); | 114 | static void wdt_timer_ping(unsigned long); |
| 106 | static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0); | 115 | static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0); |
| @@ -117,15 +126,14 @@ static void wdt_timer_ping(unsigned long data) | |||
| 117 | /* If we got a heartbeat pulse within the WDT_US_INTERVAL | 126 | /* If we got a heartbeat pulse within the WDT_US_INTERVAL |
| 118 | * we agree to ping the WDT | 127 | * we agree to ping the WDT |
| 119 | */ | 128 | */ |
| 120 | if(time_before(jiffies, next_heartbeat)) | 129 | if (time_before(jiffies, next_heartbeat)) { |
| 121 | { | ||
| 122 | /* Ping the WDT by reading from wdt_start */ | 130 | /* Ping the WDT by reading from wdt_start */ |
| 123 | inb_p(wdt_start); | 131 | inb_p(wdt_start); |
| 124 | /* Re-set the timer interval */ | 132 | /* Re-set the timer interval */ |
| 125 | mod_timer(&timer, jiffies + WDT_INTERVAL); | 133 | mod_timer(&timer, jiffies + WDT_INTERVAL); |
| 126 | } else { | 134 | } else |
| 127 | printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); | 135 | printk(KERN_WARNING PFX |
| 128 | } | 136 | "Heartbeat lost! Will not ping the watchdog\n"); |
| 129 | } | 137 | } |
| 130 | 138 | ||
| 131 | /* | 139 | /* |
| @@ -159,40 +167,40 @@ static void wdt_keepalive(void) | |||
| 159 | * /dev/watchdog handling | 167 | * /dev/watchdog handling |
| 160 | */ | 168 | */ |
| 161 | 169 | ||
| 162 | static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos) | 170 | static ssize_t fop_write(struct file *file, const char __user *buf, |
| 171 | size_t count, loff_t *ppos) | ||
| 163 | { | 172 | { |
| 164 | /* See if we got the magic character 'V' and reload the timer */ | 173 | /* See if we got the magic character 'V' and reload the timer */ |
| 165 | if(count) | 174 | if (count) { |
| 166 | { | 175 | if (!nowayout) { |
| 167 | if (!nowayout) | ||
| 168 | { | ||
| 169 | size_t ofs; | 176 | size_t ofs; |
| 170 | 177 | ||
| 171 | /* note: just in case someone wrote the magic character | 178 | /* note: just in case someone wrote the |
| 172 | * five months ago... */ | 179 | magic character five months ago... */ |
| 173 | wdt_expect_close = 0; | 180 | wdt_expect_close = 0; |
| 174 | 181 | ||
| 175 | /* scan to see whether or not we got the magic character */ | 182 | /* scan to see whether or not we got the |
| 176 | for(ofs = 0; ofs != count; ofs++) | 183 | magic character */ |
| 177 | { | 184 | for (ofs = 0; ofs != count; ofs++) { |
| 178 | char c; | 185 | char c; |
| 179 | if(get_user(c, buf+ofs)) | 186 | if (get_user(c, buf + ofs)) |
| 180 | return -EFAULT; | 187 | return -EFAULT; |
| 181 | if(c == 'V') | 188 | if (c == 'V') |
| 182 | wdt_expect_close = 42; | 189 | wdt_expect_close = 42; |
| 183 | } | 190 | } |
| 184 | } | 191 | } |
| 185 | 192 | ||
| 186 | /* Well, anyhow someone wrote to us, we should return that favour */ | 193 | /* Well, anyhow someone wrote to us, we should |
| 194 | return that favour */ | ||
| 187 | wdt_keepalive(); | 195 | wdt_keepalive(); |
| 188 | } | 196 | } |
| 189 | return count; | 197 | return count; |
| 190 | } | 198 | } |
| 191 | 199 | ||
| 192 | static int fop_open(struct inode * inode, struct file * file) | 200 | static int fop_open(struct inode *inode, struct file *file) |
| 193 | { | 201 | { |
| 194 | /* Just in case we're already talking to someone... */ | 202 | /* Just in case we're already talking to someone... */ |
| 195 | if(test_and_set_bit(0, &wdt_is_open)) | 203 | if (test_and_set_bit(0, &wdt_is_open)) |
| 196 | return -EBUSY; | 204 | return -EBUSY; |
| 197 | 205 | ||
| 198 | if (nowayout) | 206 | if (nowayout) |
| @@ -203,78 +211,72 @@ static int fop_open(struct inode * inode, struct file * file) | |||
| 203 | return nonseekable_open(inode, file); | 211 | return nonseekable_open(inode, file); |
| 204 | } | 212 | } |
| 205 | 213 | ||
| 206 | static int fop_close(struct inode * inode, struct file * file) | 214 | static int fop_close(struct inode *inode, struct file *file) |
| 207 | { | 215 | { |
| 208 | if(wdt_expect_close == 42) | 216 | if (wdt_expect_close == 42) |
| 209 | wdt_turnoff(); | 217 | wdt_turnoff(); |
| 210 | else { | 218 | else { |
| 211 | del_timer(&timer); | 219 | del_timer(&timer); |
| 212 | printk(KERN_CRIT PFX "device file closed unexpectedly. Will not stop the WDT!\n"); | 220 | printk(KERN_CRIT PFX |
| 221 | "device file closed unexpectedly. Will not stop the WDT!\n"); | ||
| 213 | } | 222 | } |
| 214 | clear_bit(0, &wdt_is_open); | 223 | clear_bit(0, &wdt_is_open); |
| 215 | wdt_expect_close = 0; | 224 | wdt_expect_close = 0; |
| 216 | return 0; | 225 | return 0; |
| 217 | } | 226 | } |
| 218 | 227 | ||
| 219 | static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 228 | static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 220 | unsigned long arg) | ||
| 221 | { | 229 | { |
| 222 | void __user *argp = (void __user *)arg; | 230 | void __user *argp = (void __user *)arg; |
| 223 | int __user *p = argp; | 231 | int __user *p = argp; |
| 224 | static struct watchdog_info ident= | 232 | static const struct watchdog_info ident = { |
| 225 | { | 233 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | |
| 226 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, | 234 | WDIOF_MAGICCLOSE, |
| 227 | .firmware_version = 1, | 235 | .firmware_version = 1, |
| 228 | .identity = "SBC60xx", | 236 | .identity = "SBC60xx", |
| 229 | }; | 237 | }; |
| 230 | 238 | ||
| 231 | switch(cmd) | 239 | switch (cmd) { |
| 240 | case WDIOC_GETSUPPORT: | ||
| 241 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; | ||
| 242 | case WDIOC_GETSTATUS: | ||
| 243 | case WDIOC_GETBOOTSTATUS: | ||
| 244 | return put_user(0, p); | ||
| 245 | case WDIOC_SETOPTIONS: | ||
| 232 | { | 246 | { |
| 233 | default: | 247 | int new_options, retval = -EINVAL; |
| 234 | return -ENOTTY; | 248 | if (get_user(new_options, p)) |
| 235 | case WDIOC_GETSUPPORT: | 249 | return -EFAULT; |
| 236 | return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; | 250 | if (new_options & WDIOS_DISABLECARD) { |
| 237 | case WDIOC_GETSTATUS: | 251 | wdt_turnoff(); |
| 238 | case WDIOC_GETBOOTSTATUS: | 252 | retval = 0; |
| 239 | return put_user(0, p); | ||
| 240 | case WDIOC_KEEPALIVE: | ||
| 241 | wdt_keepalive(); | ||
| 242 | return 0; | ||
| 243 | case WDIOC_SETOPTIONS: | ||
| 244 | { | ||
| 245 | int new_options, retval = -EINVAL; | ||
| 246 | |||
| 247 | if(get_user(new_options, p)) | ||
| 248 | return -EFAULT; | ||
| 249 | |||
| 250 | if(new_options & WDIOS_DISABLECARD) { | ||
| 251 | wdt_turnoff(); | ||
| 252 | retval = 0; | ||
| 253 | } | ||
| 254 | |||
| 255 | if(new_options & WDIOS_ENABLECARD) { | ||
| 256 | wdt_startup(); | ||
| 257 | retval = 0; | ||
| 258 | } | ||
| 259 | |||
| 260 | return retval; | ||
| 261 | } | 253 | } |
| 262 | case WDIOC_SETTIMEOUT: | 254 | if (new_options & WDIOS_ENABLECARD) { |
| 263 | { | 255 | wdt_startup(); |
| 264 | int new_timeout; | 256 | retval = 0; |
| 265 | |||
| 266 | if(get_user(new_timeout, p)) | ||
| 267 | return -EFAULT; | ||
| 268 | |||
| 269 | if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */ | ||
| 270 | return -EINVAL; | ||
| 271 | |||
| 272 | timeout = new_timeout; | ||
| 273 | wdt_keepalive(); | ||
| 274 | /* Fall through */ | ||
| 275 | } | 257 | } |
| 276 | case WDIOC_GETTIMEOUT: | 258 | return retval; |
| 277 | return put_user(timeout, p); | 259 | } |
| 260 | case WDIOC_KEEPALIVE: | ||
| 261 | wdt_keepalive(); | ||
| 262 | return 0; | ||
| 263 | case WDIOC_SETTIMEOUT: | ||
| 264 | { | ||
| 265 | int new_timeout; | ||
| 266 | if (get_user(new_timeout, p)) | ||
| 267 | return -EFAULT; | ||
| 268 | /* arbitrary upper limit */ | ||
| 269 | if (new_timeout < 1 || new_timeout > 3600) | ||
| 270 | return -EINVAL; | ||
| 271 | |||
| 272 | timeout = new_timeout; | ||
| 273 | wdt_keepalive(); | ||
| 274 | /* Fall through */ | ||
| 275 | } | ||
| 276 | case WDIOC_GETTIMEOUT: | ||
| 277 | return put_user(timeout, p); | ||
| 278 | default: | ||
| 279 | return -ENOTTY; | ||
| 278 | } | 280 | } |
| 279 | } | 281 | } |
| 280 | 282 | ||
| @@ -284,7 +286,7 @@ static const struct file_operations wdt_fops = { | |||
| 284 | .write = fop_write, | 286 | .write = fop_write, |
| 285 | .open = fop_open, | 287 | .open = fop_open, |
| 286 | .release = fop_close, | 288 | .release = fop_close, |
| 287 | .ioctl = fop_ioctl, | 289 | .unlocked_ioctl = fop_ioctl, |
| 288 | }; | 290 | }; |
| 289 | 291 | ||
| 290 | static struct miscdevice wdt_miscdev = { | 292 | static struct miscdevice wdt_miscdev = { |
| @@ -300,7 +302,7 @@ static struct miscdevice wdt_miscdev = { | |||
| 300 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, | 302 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, |
| 301 | void *unused) | 303 | void *unused) |
| 302 | { | 304 | { |
| 303 | if(code==SYS_DOWN || code==SYS_HALT) | 305 | if (code == SYS_DOWN || code == SYS_HALT) |
| 304 | wdt_turnoff(); | 306 | wdt_turnoff(); |
| 305 | return NOTIFY_DONE; | 307 | return NOTIFY_DONE; |
| 306 | } | 308 | } |
| @@ -310,8 +312,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, | |||
| 310 | * turn the timebomb registers off. | 312 | * turn the timebomb registers off. |
| 311 | */ | 313 | */ |
| 312 | 314 | ||
| 313 | static struct notifier_block wdt_notifier= | 315 | static struct notifier_block wdt_notifier = { |
| 314 | { | ||
| 315 | .notifier_call = wdt_notify_sys, | 316 | .notifier_call = wdt_notify_sys, |
| 316 | }; | 317 | }; |
| 317 | 318 | ||
| @@ -324,23 +325,22 @@ static void __exit sbc60xxwdt_unload(void) | |||
| 324 | 325 | ||
| 325 | unregister_reboot_notifier(&wdt_notifier); | 326 | unregister_reboot_notifier(&wdt_notifier); |
| 326 | if ((wdt_stop != 0x45) && (wdt_stop != wdt_start)) | 327 | if ((wdt_stop != 0x45) && (wdt_stop != wdt_start)) |
| 327 | release_region(wdt_stop,1); | 328 | release_region(wdt_stop, 1); |
| 328 | release_region(wdt_start,1); | 329 | release_region(wdt_start, 1); |
| 329 | } | 330 | } |
| 330 | 331 | ||
| 331 | static int __init sbc60xxwdt_init(void) | 332 | static int __init sbc60xxwdt_init(void) |
| 332 | { | 333 | { |
| 333 | int rc = -EBUSY; | 334 | int rc = -EBUSY; |
| 334 | 335 | ||
| 335 | if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */ | 336 | if (timeout < 1 || timeout > 3600) { /* arbitrary upper limit */ |
| 336 | { | ||
| 337 | timeout = WATCHDOG_TIMEOUT; | 337 | timeout = WATCHDOG_TIMEOUT; |
| 338 | printk(KERN_INFO PFX "timeout value must be 1<=x<=3600, using %d\n", | 338 | printk(KERN_INFO PFX |
| 339 | timeout); | 339 | "timeout value must be 1 <= x <= 3600, using %d\n", |
| 340 | } | 340 | timeout); |
| 341 | } | ||
| 341 | 342 | ||
| 342 | if (!request_region(wdt_start, 1, "SBC 60XX WDT")) | 343 | if (!request_region(wdt_start, 1, "SBC 60XX WDT")) { |
| 343 | { | ||
| 344 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", | 344 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", |
| 345 | wdt_start); | 345 | wdt_start); |
| 346 | rc = -EIO; | 346 | rc = -EIO; |
| @@ -348,33 +348,30 @@ static int __init sbc60xxwdt_init(void) | |||
| 348 | } | 348 | } |
| 349 | 349 | ||
| 350 | /* We cannot reserve 0x45 - the kernel already has! */ | 350 | /* We cannot reserve 0x45 - the kernel already has! */ |
| 351 | if ((wdt_stop != 0x45) && (wdt_stop != wdt_start)) | 351 | if (wdt_stop != 0x45 && wdt_stop != wdt_start) { |
| 352 | { | 352 | if (!request_region(wdt_stop, 1, "SBC 60XX WDT")) { |
| 353 | if (!request_region(wdt_stop, 1, "SBC 60XX WDT")) | 353 | printk(KERN_ERR PFX |
| 354 | { | 354 | "I/O address 0x%04x already in use\n", |
| 355 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", | 355 | wdt_stop); |
| 356 | wdt_stop); | ||
| 357 | rc = -EIO; | 356 | rc = -EIO; |
| 358 | goto err_out_region1; | 357 | goto err_out_region1; |
| 359 | } | 358 | } |
| 360 | } | 359 | } |
| 361 | 360 | ||
| 362 | rc = register_reboot_notifier(&wdt_notifier); | 361 | rc = register_reboot_notifier(&wdt_notifier); |
| 363 | if (rc) | 362 | if (rc) { |
| 364 | { | 363 | printk(KERN_ERR PFX |
| 365 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 364 | "cannot register reboot notifier (err=%d)\n", rc); |
| 366 | rc); | ||
| 367 | goto err_out_region2; | 365 | goto err_out_region2; |
| 368 | } | 366 | } |
| 369 | 367 | ||
| 370 | rc = misc_register(&wdt_miscdev); | 368 | rc = misc_register(&wdt_miscdev); |
| 371 | if (rc) | 369 | if (rc) { |
| 372 | { | 370 | printk(KERN_ERR PFX |
| 373 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 371 | "cannot register miscdev on minor=%d (err=%d)\n", |
| 374 | wdt_miscdev.minor, rc); | 372 | wdt_miscdev.minor, rc); |
| 375 | goto err_out_reboot; | 373 | goto err_out_reboot; |
| 376 | } | 374 | } |
| 377 | |||
| 378 | printk(KERN_INFO PFX "WDT driver for 60XX single board computer initialised. timeout=%d sec (nowayout=%d)\n", | 375 | printk(KERN_INFO PFX "WDT driver for 60XX single board computer initialised. timeout=%d sec (nowayout=%d)\n", |
| 379 | timeout, nowayout); | 376 | timeout, nowayout); |
| 380 | 377 | ||
| @@ -383,10 +380,10 @@ static int __init sbc60xxwdt_init(void) | |||
| 383 | err_out_reboot: | 380 | err_out_reboot: |
| 384 | unregister_reboot_notifier(&wdt_notifier); | 381 | unregister_reboot_notifier(&wdt_notifier); |
| 385 | err_out_region2: | 382 | err_out_region2: |
| 386 | if ((wdt_stop != 0x45) && (wdt_stop != wdt_start)) | 383 | if (wdt_stop != 0x45 && wdt_stop != wdt_start) |
| 387 | release_region(wdt_stop,1); | 384 | release_region(wdt_stop, 1); |
| 388 | err_out_region1: | 385 | err_out_region1: |
| 389 | release_region(wdt_start,1); | 386 | release_region(wdt_start, 1); |
| 390 | err_out: | 387 | err_out: |
| 391 | return rc; | 388 | return rc; |
| 392 | } | 389 | } |
diff --git a/drivers/watchdog/sbc7240_wdt.c b/drivers/watchdog/sbc7240_wdt.c index 4c8cefbd8627..67ddeb1c830a 100644 --- a/drivers/watchdog/sbc7240_wdt.c +++ b/drivers/watchdog/sbc7240_wdt.c | |||
| @@ -27,10 +27,10 @@ | |||
| 27 | #include <linux/reboot.h> | 27 | #include <linux/reboot.h> |
| 28 | #include <linux/types.h> | 28 | #include <linux/types.h> |
| 29 | #include <linux/watchdog.h> | 29 | #include <linux/watchdog.h> |
| 30 | #include <linux/io.h> | ||
| 31 | #include <linux/uaccess.h> | ||
| 30 | #include <asm/atomic.h> | 32 | #include <asm/atomic.h> |
| 31 | #include <asm/io.h> | ||
| 32 | #include <asm/system.h> | 33 | #include <asm/system.h> |
| 33 | #include <asm/uaccess.h> | ||
| 34 | 34 | ||
| 35 | #define SBC7240_PREFIX "sbc7240_wdt: " | 35 | #define SBC7240_PREFIX "sbc7240_wdt: " |
| 36 | 36 | ||
| @@ -159,7 +159,7 @@ static int fop_close(struct inode *inode, struct file *file) | |||
| 159 | return 0; | 159 | return 0; |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | static struct watchdog_info ident = { | 162 | static const struct watchdog_info ident = { |
| 163 | .options = WDIOF_KEEPALIVEPING| | 163 | .options = WDIOF_KEEPALIVEPING| |
| 164 | WDIOF_SETTIMEOUT| | 164 | WDIOF_SETTIMEOUT| |
| 165 | WDIOF_MAGICCLOSE, | 165 | WDIOF_MAGICCLOSE, |
| @@ -168,50 +168,50 @@ static struct watchdog_info ident = { | |||
| 168 | }; | 168 | }; |
| 169 | 169 | ||
| 170 | 170 | ||
| 171 | static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 171 | static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 172 | unsigned long arg) | ||
| 173 | { | 172 | { |
| 174 | switch (cmd) { | 173 | switch (cmd) { |
| 175 | case WDIOC_GETSUPPORT: | 174 | case WDIOC_GETSUPPORT: |
| 176 | return copy_to_user | 175 | return copy_to_user((void __user *)arg, &ident, sizeof(ident)) |
| 177 | ((void __user *)arg, &ident, sizeof(ident)) | 176 | ? -EFAULT : 0; |
| 178 | ? -EFAULT : 0; | ||
| 179 | case WDIOC_GETSTATUS: | 177 | case WDIOC_GETSTATUS: |
| 180 | case WDIOC_GETBOOTSTATUS: | 178 | case WDIOC_GETBOOTSTATUS: |
| 181 | return put_user(0, (int __user *)arg); | 179 | return put_user(0, (int __user *)arg); |
| 182 | case WDIOC_KEEPALIVE: | 180 | case WDIOC_SETOPTIONS: |
| 183 | wdt_keepalive(); | 181 | { |
| 184 | return 0; | 182 | int options; |
| 185 | case WDIOC_SETOPTIONS:{ | 183 | int retval = -EINVAL; |
| 186 | int options; | ||
| 187 | int retval = -EINVAL; | ||
| 188 | 184 | ||
| 189 | if (get_user(options, (int __user *)arg)) | 185 | if (get_user(options, (int __user *)arg)) |
| 190 | return -EFAULT; | 186 | return -EFAULT; |
| 191 | 187 | ||
| 192 | if (options & WDIOS_DISABLECARD) { | 188 | if (options & WDIOS_DISABLECARD) { |
| 193 | wdt_disable(); | 189 | wdt_disable(); |
| 194 | retval = 0; | 190 | retval = 0; |
| 195 | } | 191 | } |
| 196 | |||
| 197 | if (options & WDIOS_ENABLECARD) { | ||
| 198 | wdt_enable(); | ||
| 199 | retval = 0; | ||
| 200 | } | ||
| 201 | 192 | ||
| 202 | return retval; | 193 | if (options & WDIOS_ENABLECARD) { |
| 194 | wdt_enable(); | ||
| 195 | retval = 0; | ||
| 203 | } | 196 | } |
| 204 | case WDIOC_SETTIMEOUT:{ | ||
| 205 | int new_timeout; | ||
| 206 | 197 | ||
| 207 | if (get_user(new_timeout, (int __user *)arg)) | 198 | return retval; |
| 208 | return -EFAULT; | 199 | } |
| 200 | case WDIOC_KEEPALIVE: | ||
| 201 | wdt_keepalive(); | ||
| 202 | return 0; | ||
| 203 | case WDIOC_SETTIMEOUT: | ||
| 204 | { | ||
| 205 | int new_timeout; | ||
| 209 | 206 | ||
| 210 | if (wdt_set_timeout(new_timeout)) | 207 | if (get_user(new_timeout, (int __user *)arg)) |
| 211 | return -EINVAL; | 208 | return -EFAULT; |
| 212 | 209 | ||
| 213 | /* Fall through */ | 210 | if (wdt_set_timeout(new_timeout)) |
| 214 | } | 211 | return -EINVAL; |
| 212 | |||
| 213 | /* Fall through */ | ||
| 214 | } | ||
| 215 | case WDIOC_GETTIMEOUT: | 215 | case WDIOC_GETTIMEOUT: |
| 216 | return put_user(timeout, (int __user *)arg); | 216 | return put_user(timeout, (int __user *)arg); |
| 217 | default: | 217 | default: |
| @@ -225,7 +225,7 @@ static const struct file_operations wdt_fops = { | |||
| 225 | .write = fop_write, | 225 | .write = fop_write, |
| 226 | .open = fop_open, | 226 | .open = fop_open, |
| 227 | .release = fop_close, | 227 | .release = fop_close, |
| 228 | .ioctl = fop_ioctl, | 228 | .unlocked_ioctl = fop_ioctl, |
| 229 | }; | 229 | }; |
| 230 | 230 | ||
| 231 | static struct miscdevice wdt_miscdev = { | 231 | static struct miscdevice wdt_miscdev = { |
diff --git a/drivers/watchdog/sbc8360.c b/drivers/watchdog/sbc8360.c index 2ee2677f3648..fd83dd052d8c 100644 --- a/drivers/watchdog/sbc8360.c +++ b/drivers/watchdog/sbc8360.c | |||
| @@ -48,13 +48,12 @@ | |||
| 48 | #include <linux/init.h> | 48 | #include <linux/init.h> |
| 49 | #include <linux/spinlock.h> | 49 | #include <linux/spinlock.h> |
| 50 | #include <linux/moduleparam.h> | 50 | #include <linux/moduleparam.h> |
| 51 | #include <linux/io.h> | ||
| 52 | #include <linux/uaccess.h> | ||
| 51 | 53 | ||
| 52 | #include <asm/io.h> | ||
| 53 | #include <asm/uaccess.h> | ||
| 54 | #include <asm/system.h> | 54 | #include <asm/system.h> |
| 55 | 55 | ||
| 56 | static unsigned long sbc8360_is_open; | 56 | static unsigned long sbc8360_is_open; |
| 57 | static DEFINE_SPINLOCK(sbc8360_lock); | ||
| 58 | static char expect_close; | 57 | static char expect_close; |
| 59 | 58 | ||
| 60 | #define PFX "sbc8360: " | 59 | #define PFX "sbc8360: " |
| @@ -204,7 +203,8 @@ module_param(timeout, int, 0); | |||
| 204 | MODULE_PARM_DESC(timeout, "Index into timeout table (0-63) (default=27 (60s))"); | 203 | MODULE_PARM_DESC(timeout, "Index into timeout table (0-63) (default=27 (60s))"); |
| 205 | module_param(nowayout, int, 0); | 204 | module_param(nowayout, int, 0); |
| 206 | MODULE_PARM_DESC(nowayout, | 205 | MODULE_PARM_DESC(nowayout, |
| 207 | "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 206 | "Watchdog cannot be stopped once started (default=" |
| 207 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 208 | 208 | ||
| 209 | /* | 209 | /* |
| 210 | * Kernel methods. | 210 | * Kernel methods. |
| @@ -231,9 +231,16 @@ static void sbc8360_ping(void) | |||
| 231 | outb(wd_margin, SBC8360_BASETIME); | 231 | outb(wd_margin, SBC8360_BASETIME); |
| 232 | } | 232 | } |
| 233 | 233 | ||
| 234 | /* stop watchdog */ | ||
| 235 | static void sbc8360_stop(void) | ||
| 236 | { | ||
| 237 | /* De-activate the watchdog */ | ||
| 238 | outb(0, SBC8360_ENABLE); | ||
| 239 | } | ||
| 240 | |||
| 234 | /* Userspace pings kernel driver, or requests clean close */ | 241 | /* Userspace pings kernel driver, or requests clean close */ |
| 235 | static ssize_t sbc8360_write(struct file *file, const char __user * buf, | 242 | static ssize_t sbc8360_write(struct file *file, const char __user *buf, |
| 236 | size_t count, loff_t * ppos) | 243 | size_t count, loff_t *ppos) |
| 237 | { | 244 | { |
| 238 | if (count) { | 245 | if (count) { |
| 239 | if (!nowayout) { | 246 | if (!nowayout) { |
| @@ -257,16 +264,12 @@ static ssize_t sbc8360_write(struct file *file, const char __user * buf, | |||
| 257 | 264 | ||
| 258 | static int sbc8360_open(struct inode *inode, struct file *file) | 265 | static int sbc8360_open(struct inode *inode, struct file *file) |
| 259 | { | 266 | { |
| 260 | spin_lock(&sbc8360_lock); | 267 | if (test_and_set_bit(0, &sbc8360_is_open)) |
| 261 | if (test_and_set_bit(0, &sbc8360_is_open)) { | ||
| 262 | spin_unlock(&sbc8360_lock); | ||
| 263 | return -EBUSY; | 268 | return -EBUSY; |
| 264 | } | ||
| 265 | if (nowayout) | 269 | if (nowayout) |
| 266 | __module_get(THIS_MODULE); | 270 | __module_get(THIS_MODULE); |
| 267 | 271 | ||
| 268 | /* Activate and ping once to start the countdown */ | 272 | /* Activate and ping once to start the countdown */ |
| 269 | spin_unlock(&sbc8360_lock); | ||
| 270 | sbc8360_activate(); | 273 | sbc8360_activate(); |
| 271 | sbc8360_ping(); | 274 | sbc8360_ping(); |
| 272 | return nonseekable_open(inode, file); | 275 | return nonseekable_open(inode, file); |
| @@ -274,16 +277,14 @@ static int sbc8360_open(struct inode *inode, struct file *file) | |||
| 274 | 277 | ||
| 275 | static int sbc8360_close(struct inode *inode, struct file *file) | 278 | static int sbc8360_close(struct inode *inode, struct file *file) |
| 276 | { | 279 | { |
| 277 | spin_lock(&sbc8360_lock); | ||
| 278 | if (expect_close == 42) | 280 | if (expect_close == 42) |
| 279 | outb(0, SBC8360_ENABLE); | 281 | sbc8360_stop(); |
| 280 | else | 282 | else |
| 281 | printk(KERN_CRIT PFX | 283 | printk(KERN_CRIT PFX |
| 282 | "SBC8360 device closed unexpectedly. SBC8360 will not stop!\n"); | 284 | "SBC8360 device closed unexpectedly. SBC8360 will not stop!\n"); |
| 283 | 285 | ||
| 284 | clear_bit(0, &sbc8360_is_open); | 286 | clear_bit(0, &sbc8360_is_open); |
| 285 | expect_close = 0; | 287 | expect_close = 0; |
| 286 | spin_unlock(&sbc8360_lock); | ||
| 287 | return 0; | 288 | return 0; |
| 288 | } | 289 | } |
| 289 | 290 | ||
| @@ -294,10 +295,9 @@ static int sbc8360_close(struct inode *inode, struct file *file) | |||
| 294 | static int sbc8360_notify_sys(struct notifier_block *this, unsigned long code, | 295 | static int sbc8360_notify_sys(struct notifier_block *this, unsigned long code, |
| 295 | void *unused) | 296 | void *unused) |
| 296 | { | 297 | { |
| 297 | if (code == SYS_DOWN || code == SYS_HALT) { | 298 | if (code == SYS_DOWN || code == SYS_HALT) |
| 298 | /* Disable the SBC8360 Watchdog */ | 299 | sbc8360_stop(); /* Disable the SBC8360 Watchdog */ |
| 299 | outb(0, SBC8360_ENABLE); | 300 | |
| 300 | } | ||
| 301 | return NOTIFY_DONE; | 301 | return NOTIFY_DONE; |
| 302 | } | 302 | } |
| 303 | 303 | ||
| @@ -382,13 +382,13 @@ static int __init sbc8360_init(void) | |||
| 382 | 382 | ||
| 383 | return 0; | 383 | return 0; |
| 384 | 384 | ||
| 385 | out_nomisc: | 385 | out_nomisc: |
| 386 | unregister_reboot_notifier(&sbc8360_notifier); | 386 | unregister_reboot_notifier(&sbc8360_notifier); |
| 387 | out_noreboot: | 387 | out_noreboot: |
| 388 | release_region(SBC8360_BASETIME, 1); | 388 | release_region(SBC8360_BASETIME, 1); |
| 389 | out_nobasetimereg: | 389 | out_nobasetimereg: |
| 390 | release_region(SBC8360_ENABLE, 1); | 390 | release_region(SBC8360_ENABLE, 1); |
| 391 | out: | 391 | out: |
| 392 | return res; | 392 | return res; |
| 393 | } | 393 | } |
| 394 | 394 | ||
diff --git a/drivers/watchdog/sbc_epx_c3.c b/drivers/watchdog/sbc_epx_c3.c index 82cbd8809a69..e5e470ca7759 100644 --- a/drivers/watchdog/sbc_epx_c3.c +++ b/drivers/watchdog/sbc_epx_c3.c | |||
| @@ -25,8 +25,8 @@ | |||
| 25 | #include <linux/reboot.h> | 25 | #include <linux/reboot.h> |
| 26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
| 27 | #include <linux/ioport.h> | 27 | #include <linux/ioport.h> |
| 28 | #include <asm/uaccess.h> | 28 | #include <linux/uaccess.h> |
| 29 | #include <asm/io.h> | 29 | #include <linux/io.h> |
| 30 | 30 | ||
| 31 | #define PFX "epx_c3: " | 31 | #define PFX "epx_c3: " |
| 32 | static int epx_c3_alive; | 32 | static int epx_c3_alive; |
| @@ -100,12 +100,12 @@ static ssize_t epx_c3_write(struct file *file, const char __user *data, | |||
| 100 | return len; | 100 | return len; |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | static int epx_c3_ioctl(struct inode *inode, struct file *file, | 103 | static long epx_c3_ioctl(struct file *file, unsigned int cmd, |
| 104 | unsigned int cmd, unsigned long arg) | 104 | unsigned long arg) |
| 105 | { | 105 | { |
| 106 | int options, retval = -EINVAL; | 106 | int options, retval = -EINVAL; |
| 107 | int __user *argp = (void __user *)arg; | 107 | int __user *argp = (void __user *)arg; |
| 108 | static struct watchdog_info ident = { | 108 | static const struct watchdog_info ident = { |
| 109 | .options = WDIOF_KEEPALIVEPING | | 109 | .options = WDIOF_KEEPALIVEPING | |
| 110 | WDIOF_MAGICCLOSE, | 110 | WDIOF_MAGICCLOSE, |
| 111 | .firmware_version = 0, | 111 | .firmware_version = 0, |
| @@ -120,11 +120,6 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file, | |||
| 120 | case WDIOC_GETSTATUS: | 120 | case WDIOC_GETSTATUS: |
| 121 | case WDIOC_GETBOOTSTATUS: | 121 | case WDIOC_GETBOOTSTATUS: |
| 122 | return put_user(0, argp); | 122 | return put_user(0, argp); |
| 123 | case WDIOC_KEEPALIVE: | ||
| 124 | epx_c3_pet(); | ||
| 125 | return 0; | ||
| 126 | case WDIOC_GETTIMEOUT: | ||
| 127 | return put_user(WATCHDOG_TIMEOUT, argp); | ||
| 128 | case WDIOC_SETOPTIONS: | 123 | case WDIOC_SETOPTIONS: |
| 129 | if (get_user(options, argp)) | 124 | if (get_user(options, argp)) |
| 130 | return -EFAULT; | 125 | return -EFAULT; |
| @@ -140,6 +135,11 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file, | |||
| 140 | } | 135 | } |
| 141 | 136 | ||
| 142 | return retval; | 137 | return retval; |
| 138 | case WDIOC_KEEPALIVE: | ||
| 139 | epx_c3_pet(); | ||
| 140 | return 0; | ||
| 141 | case WDIOC_GETTIMEOUT: | ||
| 142 | return put_user(WATCHDOG_TIMEOUT, argp); | ||
| 143 | default: | 143 | default: |
| 144 | return -ENOTTY; | 144 | return -ENOTTY; |
| 145 | } | 145 | } |
| @@ -158,7 +158,7 @@ static const struct file_operations epx_c3_fops = { | |||
| 158 | .owner = THIS_MODULE, | 158 | .owner = THIS_MODULE, |
| 159 | .llseek = no_llseek, | 159 | .llseek = no_llseek, |
| 160 | .write = epx_c3_write, | 160 | .write = epx_c3_write, |
| 161 | .ioctl = epx_c3_ioctl, | 161 | .unlocked_ioctl = epx_c3_ioctl, |
| 162 | .open = epx_c3_open, | 162 | .open = epx_c3_open, |
| 163 | .release = epx_c3_release, | 163 | .release = epx_c3_release, |
| 164 | }; | 164 | }; |
diff --git a/drivers/watchdog/sc1200wdt.c b/drivers/watchdog/sc1200wdt.c index 621ebad56d86..23da3ccd832a 100644 --- a/drivers/watchdog/sc1200wdt.c +++ b/drivers/watchdog/sc1200wdt.c | |||
| @@ -196,7 +196,6 @@ static long sc1200wdt_ioctl(struct file *file, unsigned int cmd, | |||
| 196 | }; | 196 | }; |
| 197 | 197 | ||
| 198 | switch (cmd) { | 198 | switch (cmd) { |
| 199 | |||
| 200 | case WDIOC_GETSUPPORT: | 199 | case WDIOC_GETSUPPORT: |
| 201 | if (copy_to_user(argp, &ident, sizeof ident)) | 200 | if (copy_to_user(argp, &ident, sizeof ident)) |
| 202 | return -EFAULT; | 201 | return -EFAULT; |
| @@ -208,24 +207,6 @@ static long sc1200wdt_ioctl(struct file *file, unsigned int cmd, | |||
| 208 | case WDIOC_GETBOOTSTATUS: | 207 | case WDIOC_GETBOOTSTATUS: |
| 209 | return put_user(0, p); | 208 | return put_user(0, p); |
| 210 | 209 | ||
| 211 | case WDIOC_KEEPALIVE: | ||
| 212 | sc1200wdt_write_data(WDTO, timeout); | ||
| 213 | return 0; | ||
| 214 | |||
| 215 | case WDIOC_SETTIMEOUT: | ||
| 216 | if (get_user(new_timeout, p)) | ||
| 217 | return -EFAULT; | ||
| 218 | /* the API states this is given in secs */ | ||
| 219 | new_timeout /= 60; | ||
| 220 | if (new_timeout < 0 || new_timeout > MAX_TIMEOUT) | ||
| 221 | return -EINVAL; | ||
| 222 | timeout = new_timeout; | ||
| 223 | sc1200wdt_write_data(WDTO, timeout); | ||
| 224 | /* fall through and return the new timeout */ | ||
| 225 | |||
| 226 | case WDIOC_GETTIMEOUT: | ||
| 227 | return put_user(timeout * 60, p); | ||
| 228 | |||
| 229 | case WDIOC_SETOPTIONS: | 210 | case WDIOC_SETOPTIONS: |
| 230 | { | 211 | { |
| 231 | int options, retval = -EINVAL; | 212 | int options, retval = -EINVAL; |
| @@ -245,6 +226,24 @@ static long sc1200wdt_ioctl(struct file *file, unsigned int cmd, | |||
| 245 | 226 | ||
| 246 | return retval; | 227 | return retval; |
| 247 | } | 228 | } |
| 229 | case WDIOC_KEEPALIVE: | ||
| 230 | sc1200wdt_write_data(WDTO, timeout); | ||
| 231 | return 0; | ||
| 232 | |||
| 233 | case WDIOC_SETTIMEOUT: | ||
| 234 | if (get_user(new_timeout, p)) | ||
| 235 | return -EFAULT; | ||
| 236 | /* the API states this is given in secs */ | ||
| 237 | new_timeout /= 60; | ||
| 238 | if (new_timeout < 0 || new_timeout > MAX_TIMEOUT) | ||
| 239 | return -EINVAL; | ||
| 240 | timeout = new_timeout; | ||
| 241 | sc1200wdt_write_data(WDTO, timeout); | ||
| 242 | /* fall through and return the new timeout */ | ||
| 243 | |||
| 244 | case WDIOC_GETTIMEOUT: | ||
| 245 | return put_user(timeout * 60, p); | ||
| 246 | |||
| 248 | default: | 247 | default: |
| 249 | return -ENOTTY; | 248 | return -ENOTTY; |
| 250 | } | 249 | } |
| @@ -280,7 +279,7 @@ static ssize_t sc1200wdt_write(struct file *file, const char __user *data, | |||
| 280 | for (i = 0; i != len; i++) { | 279 | for (i = 0; i != len; i++) { |
| 281 | char c; | 280 | char c; |
| 282 | 281 | ||
| 283 | if (get_user(c, data+i)) | 282 | if (get_user(c, data + i)) |
| 284 | return -EFAULT; | 283 | return -EFAULT; |
| 285 | if (c == 'V') | 284 | if (c == 'V') |
| 286 | expect_close = 42; | 285 | expect_close = 42; |
diff --git a/drivers/watchdog/sc520_wdt.c b/drivers/watchdog/sc520_wdt.c index 2847324a2be2..a2b6c1067ec5 100644 --- a/drivers/watchdog/sc520_wdt.c +++ b/drivers/watchdog/sc520_wdt.c | |||
| @@ -64,9 +64,9 @@ | |||
| 64 | #include <linux/reboot.h> | 64 | #include <linux/reboot.h> |
| 65 | #include <linux/init.h> | 65 | #include <linux/init.h> |
| 66 | #include <linux/jiffies.h> | 66 | #include <linux/jiffies.h> |
| 67 | #include <linux/io.h> | ||
| 68 | #include <linux/uaccess.h> | ||
| 67 | 69 | ||
| 68 | #include <asm/io.h> | ||
| 69 | #include <asm/uaccess.h> | ||
| 70 | #include <asm/system.h> | 70 | #include <asm/system.h> |
| 71 | 71 | ||
| 72 | #define OUR_NAME "sc520_wdt" | 72 | #define OUR_NAME "sc520_wdt" |
| @@ -91,13 +91,18 @@ | |||
| 91 | */ | 91 | */ |
| 92 | 92 | ||
| 93 | #define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ | 93 | #define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ |
| 94 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ | 94 | /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ |
| 95 | static int timeout = WATCHDOG_TIMEOUT; | ||
| 95 | module_param(timeout, int, 0); | 96 | module_param(timeout, int, 0); |
| 96 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | 97 | MODULE_PARM_DESC(timeout, |
| 98 | "Watchdog timeout in seconds. (1 <= timeout <= 3600, default=" | ||
| 99 | __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | ||
| 97 | 100 | ||
| 98 | static int nowayout = WATCHDOG_NOWAYOUT; | 101 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 99 | module_param(nowayout, int, 0); | 102 | module_param(nowayout, int, 0); |
| 100 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 103 | MODULE_PARM_DESC(nowayout, |
| 104 | "Watchdog cannot be stopped once started (default=" | ||
| 105 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 101 | 106 | ||
| 102 | /* | 107 | /* |
| 103 | * AMD Elan SC520 - Watchdog Timer Registers | 108 | * AMD Elan SC520 - Watchdog Timer Registers |
| @@ -136,8 +141,7 @@ static void wdt_timer_ping(unsigned long data) | |||
| 136 | /* If we got a heartbeat pulse within the WDT_US_INTERVAL | 141 | /* If we got a heartbeat pulse within the WDT_US_INTERVAL |
| 137 | * we agree to ping the WDT | 142 | * we agree to ping the WDT |
| 138 | */ | 143 | */ |
| 139 | if(time_before(jiffies, next_heartbeat)) | 144 | if (time_before(jiffies, next_heartbeat)) { |
| 140 | { | ||
| 141 | /* Ping the WDT */ | 145 | /* Ping the WDT */ |
| 142 | spin_lock(&wdt_spinlock); | 146 | spin_lock(&wdt_spinlock); |
| 143 | writew(0xAAAA, wdtmrctl); | 147 | writew(0xAAAA, wdtmrctl); |
| @@ -146,9 +150,9 @@ static void wdt_timer_ping(unsigned long data) | |||
| 146 | 150 | ||
| 147 | /* Re-set the timer interval */ | 151 | /* Re-set the timer interval */ |
| 148 | mod_timer(&timer, jiffies + WDT_INTERVAL); | 152 | mod_timer(&timer, jiffies + WDT_INTERVAL); |
| 149 | } else { | 153 | } else |
| 150 | printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); | 154 | printk(KERN_WARNING PFX |
| 151 | } | 155 | "Heartbeat lost! Will not ping the watchdog\n"); |
| 152 | } | 156 | } |
| 153 | 157 | ||
| 154 | /* | 158 | /* |
| @@ -162,7 +166,7 @@ static void wdt_config(int writeval) | |||
| 162 | 166 | ||
| 163 | /* buy some time (ping) */ | 167 | /* buy some time (ping) */ |
| 164 | spin_lock_irqsave(&wdt_spinlock, flags); | 168 | spin_lock_irqsave(&wdt_spinlock, flags); |
| 165 | dummy=readw(wdtmrctl); /* ensure write synchronization */ | 169 | dummy = readw(wdtmrctl); /* ensure write synchronization */ |
| 166 | writew(0xAAAA, wdtmrctl); | 170 | writew(0xAAAA, wdtmrctl); |
| 167 | writew(0x5555, wdtmrctl); | 171 | writew(0x5555, wdtmrctl); |
| 168 | /* unlock WDT = make WDT configuration register writable one time */ | 172 | /* unlock WDT = make WDT configuration register writable one time */ |
| @@ -219,10 +223,11 @@ static int wdt_set_heartbeat(int t) | |||
| 219 | * /dev/watchdog handling | 223 | * /dev/watchdog handling |
| 220 | */ | 224 | */ |
| 221 | 225 | ||
| 222 | static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos) | 226 | static ssize_t fop_write(struct file *file, const char __user *buf, |
| 227 | size_t count, loff_t *ppos) | ||
| 223 | { | 228 | { |
| 224 | /* See if we got the magic character 'V' and reload the timer */ | 229 | /* See if we got the magic character 'V' and reload the timer */ |
| 225 | if(count) { | 230 | if (count) { |
| 226 | if (!nowayout) { | 231 | if (!nowayout) { |
| 227 | size_t ofs; | 232 | size_t ofs; |
| 228 | 233 | ||
| @@ -231,25 +236,26 @@ static ssize_t fop_write(struct file * file, const char __user * buf, size_t cou | |||
| 231 | wdt_expect_close = 0; | 236 | wdt_expect_close = 0; |
| 232 | 237 | ||
| 233 | /* now scan */ | 238 | /* now scan */ |
| 234 | for(ofs = 0; ofs != count; ofs++) { | 239 | for (ofs = 0; ofs != count; ofs++) { |
| 235 | char c; | 240 | char c; |
| 236 | if (get_user(c, buf + ofs)) | 241 | if (get_user(c, buf + ofs)) |
| 237 | return -EFAULT; | 242 | return -EFAULT; |
| 238 | if(c == 'V') | 243 | if (c == 'V') |
| 239 | wdt_expect_close = 42; | 244 | wdt_expect_close = 42; |
| 240 | } | 245 | } |
| 241 | } | 246 | } |
| 242 | 247 | ||
| 243 | /* Well, anyhow someone wrote to us, we should return that favour */ | 248 | /* Well, anyhow someone wrote to us, we should |
| 249 | return that favour */ | ||
| 244 | wdt_keepalive(); | 250 | wdt_keepalive(); |
| 245 | } | 251 | } |
| 246 | return count; | 252 | return count; |
| 247 | } | 253 | } |
| 248 | 254 | ||
| 249 | static int fop_open(struct inode * inode, struct file * file) | 255 | static int fop_open(struct inode *inode, struct file *file) |
| 250 | { | 256 | { |
| 251 | /* Just in case we're already talking to someone... */ | 257 | /* Just in case we're already talking to someone... */ |
| 252 | if(test_and_set_bit(0, &wdt_is_open)) | 258 | if (test_and_set_bit(0, &wdt_is_open)) |
| 253 | return -EBUSY; | 259 | return -EBUSY; |
| 254 | if (nowayout) | 260 | if (nowayout) |
| 255 | __module_get(THIS_MODULE); | 261 | __module_get(THIS_MODULE); |
| @@ -259,12 +265,13 @@ static int fop_open(struct inode * inode, struct file * file) | |||
| 259 | return nonseekable_open(inode, file); | 265 | return nonseekable_open(inode, file); |
| 260 | } | 266 | } |
| 261 | 267 | ||
| 262 | static int fop_close(struct inode * inode, struct file * file) | 268 | static int fop_close(struct inode *inode, struct file *file) |
| 263 | { | 269 | { |
| 264 | if(wdt_expect_close == 42) { | 270 | if (wdt_expect_close == 42) |
| 265 | wdt_turnoff(); | 271 | wdt_turnoff(); |
| 266 | } else { | 272 | else { |
| 267 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 273 | printk(KERN_CRIT PFX |
| 274 | "Unexpected close, not stopping watchdog!\n"); | ||
| 268 | wdt_keepalive(); | 275 | wdt_keepalive(); |
| 269 | } | 276 | } |
| 270 | clear_bit(0, &wdt_is_open); | 277 | clear_bit(0, &wdt_is_open); |
| @@ -272,63 +279,62 @@ static int fop_close(struct inode * inode, struct file * file) | |||
| 272 | return 0; | 279 | return 0; |
| 273 | } | 280 | } |
| 274 | 281 | ||
| 275 | static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 282 | static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 276 | unsigned long arg) | ||
| 277 | { | 283 | { |
| 278 | void __user *argp = (void __user *)arg; | 284 | void __user *argp = (void __user *)arg; |
| 279 | int __user *p = argp; | 285 | int __user *p = argp; |
| 280 | static struct watchdog_info ident = { | 286 | static const struct watchdog_info ident = { |
| 281 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, | 287 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
| 288 | | WDIOF_MAGICCLOSE, | ||
| 282 | .firmware_version = 1, | 289 | .firmware_version = 1, |
| 283 | .identity = "SC520", | 290 | .identity = "SC520", |
| 284 | }; | 291 | }; |
| 285 | 292 | ||
| 286 | switch(cmd) | 293 | switch (cmd) { |
| 294 | case WDIOC_GETSUPPORT: | ||
| 295 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; | ||
| 296 | case WDIOC_GETSTATUS: | ||
| 297 | case WDIOC_GETBOOTSTATUS: | ||
| 298 | return put_user(0, p); | ||
| 299 | case WDIOC_SETOPTIONS: | ||
| 287 | { | 300 | { |
| 288 | default: | 301 | int new_options, retval = -EINVAL; |
| 289 | return -ENOTTY; | ||
| 290 | case WDIOC_GETSUPPORT: | ||
| 291 | return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; | ||
| 292 | case WDIOC_GETSTATUS: | ||
| 293 | case WDIOC_GETBOOTSTATUS: | ||
| 294 | return put_user(0, p); | ||
| 295 | case WDIOC_KEEPALIVE: | ||
| 296 | wdt_keepalive(); | ||
| 297 | return 0; | ||
| 298 | case WDIOC_SETOPTIONS: | ||
| 299 | { | ||
| 300 | int new_options, retval = -EINVAL; | ||
| 301 | |||
| 302 | if(get_user(new_options, p)) | ||
| 303 | return -EFAULT; | ||
| 304 | |||
| 305 | if(new_options & WDIOS_DISABLECARD) { | ||
| 306 | wdt_turnoff(); | ||
| 307 | retval = 0; | ||
| 308 | } | ||
| 309 | 302 | ||
| 310 | if(new_options & WDIOS_ENABLECARD) { | 303 | if (get_user(new_options, p)) |
| 311 | wdt_startup(); | 304 | return -EFAULT; |
| 312 | retval = 0; | ||
| 313 | } | ||
| 314 | 305 | ||
| 315 | return retval; | 306 | if (new_options & WDIOS_DISABLECARD) { |
| 307 | wdt_turnoff(); | ||
| 308 | retval = 0; | ||
| 316 | } | 309 | } |
| 317 | case WDIOC_SETTIMEOUT: | ||
| 318 | { | ||
| 319 | int new_timeout; | ||
| 320 | 310 | ||
| 321 | if(get_user(new_timeout, p)) | 311 | if (new_options & WDIOS_ENABLECARD) { |
| 322 | return -EFAULT; | 312 | wdt_startup(); |
| 313 | retval = 0; | ||
| 314 | } | ||
| 323 | 315 | ||
| 324 | if(wdt_set_heartbeat(new_timeout)) | 316 | return retval; |
| 325 | return -EINVAL; | 317 | } |
| 318 | case WDIOC_KEEPALIVE: | ||
| 319 | wdt_keepalive(); | ||
| 320 | return 0; | ||
| 321 | case WDIOC_SETTIMEOUT: | ||
| 322 | { | ||
| 323 | int new_timeout; | ||
| 326 | 324 | ||
| 327 | wdt_keepalive(); | 325 | if (get_user(new_timeout, p)) |
| 328 | /* Fall through */ | 326 | return -EFAULT; |
| 329 | } | 327 | |
| 330 | case WDIOC_GETTIMEOUT: | 328 | if (wdt_set_heartbeat(new_timeout)) |
| 331 | return put_user(timeout, p); | 329 | return -EINVAL; |
| 330 | |||
| 331 | wdt_keepalive(); | ||
| 332 | /* Fall through */ | ||
| 333 | } | ||
| 334 | case WDIOC_GETTIMEOUT: | ||
| 335 | return put_user(timeout, p); | ||
| 336 | default: | ||
| 337 | return -ENOTTY; | ||
| 332 | } | 338 | } |
| 333 | } | 339 | } |
| 334 | 340 | ||
| @@ -338,7 +344,7 @@ static const struct file_operations wdt_fops = { | |||
| 338 | .write = fop_write, | 344 | .write = fop_write, |
| 339 | .open = fop_open, | 345 | .open = fop_open, |
| 340 | .release = fop_close, | 346 | .release = fop_close, |
| 341 | .ioctl = fop_ioctl, | 347 | .unlocked_ioctl = fop_ioctl, |
| 342 | }; | 348 | }; |
| 343 | 349 | ||
| 344 | static struct miscdevice wdt_miscdev = { | 350 | static struct miscdevice wdt_miscdev = { |
| @@ -354,7 +360,7 @@ static struct miscdevice wdt_miscdev = { | |||
| 354 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, | 360 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, |
| 355 | void *unused) | 361 | void *unused) |
| 356 | { | 362 | { |
| 357 | if(code==SYS_DOWN || code==SYS_HALT) | 363 | if (code == SYS_DOWN || code == SYS_HALT) |
| 358 | wdt_turnoff(); | 364 | wdt_turnoff(); |
| 359 | return NOTIFY_DONE; | 365 | return NOTIFY_DONE; |
| 360 | } | 366 | } |
| @@ -383,11 +389,13 @@ static int __init sc520_wdt_init(void) | |||
| 383 | { | 389 | { |
| 384 | int rc = -EBUSY; | 390 | int rc = -EBUSY; |
| 385 | 391 | ||
| 386 | /* Check that the timeout value is within it's range ; if not reset to the default */ | 392 | /* Check that the timeout value is within it's range ; |
| 393 | if not reset to the default */ | ||
| 387 | if (wdt_set_heartbeat(timeout)) { | 394 | if (wdt_set_heartbeat(timeout)) { |
| 388 | wdt_set_heartbeat(WATCHDOG_TIMEOUT); | 395 | wdt_set_heartbeat(WATCHDOG_TIMEOUT); |
| 389 | printk(KERN_INFO PFX "timeout value must be 1<=timeout<=3600, using %d\n", | 396 | printk(KERN_INFO PFX |
| 390 | WATCHDOG_TIMEOUT); | 397 | "timeout value must be 1 <= timeout <= 3600, using %d\n", |
| 398 | WATCHDOG_TIMEOUT); | ||
| 391 | } | 399 | } |
| 392 | 400 | ||
| 393 | wdtmrctl = ioremap((unsigned long)(MMCR_BASE + OFFS_WDTMRCTL), 2); | 401 | wdtmrctl = ioremap((unsigned long)(MMCR_BASE + OFFS_WDTMRCTL), 2); |
| @@ -399,20 +407,22 @@ static int __init sc520_wdt_init(void) | |||
| 399 | 407 | ||
| 400 | rc = register_reboot_notifier(&wdt_notifier); | 408 | rc = register_reboot_notifier(&wdt_notifier); |
| 401 | if (rc) { | 409 | if (rc) { |
| 402 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 410 | printk(KERN_ERR PFX |
| 403 | rc); | 411 | "cannot register reboot notifier (err=%d)\n", rc); |
| 404 | goto err_out_ioremap; | 412 | goto err_out_ioremap; |
| 405 | } | 413 | } |
| 406 | 414 | ||
| 407 | rc = misc_register(&wdt_miscdev); | 415 | rc = misc_register(&wdt_miscdev); |
| 408 | if (rc) { | 416 | if (rc) { |
| 409 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 417 | printk(KERN_ERR PFX |
| 410 | WATCHDOG_MINOR, rc); | 418 | "cannot register miscdev on minor=%d (err=%d)\n", |
| 419 | WATCHDOG_MINOR, rc); | ||
| 411 | goto err_out_notifier; | 420 | goto err_out_notifier; |
| 412 | } | 421 | } |
| 413 | 422 | ||
| 414 | printk(KERN_INFO PFX "WDT driver for SC520 initialised. timeout=%d sec (nowayout=%d)\n", | 423 | printk(KERN_INFO PFX |
| 415 | timeout,nowayout); | 424 | "WDT driver for SC520 initialised. timeout=%d sec (nowayout=%d)\n", |
| 425 | timeout, nowayout); | ||
| 416 | 426 | ||
| 417 | return 0; | 427 | return 0; |
| 418 | 428 | ||
diff --git a/drivers/watchdog/scx200_wdt.c b/drivers/watchdog/scx200_wdt.c index d55882bca319..9e19a10a5bb9 100644 --- a/drivers/watchdog/scx200_wdt.c +++ b/drivers/watchdog/scx200_wdt.c | |||
| @@ -27,9 +27,8 @@ | |||
| 27 | #include <linux/fs.h> | 27 | #include <linux/fs.h> |
| 28 | #include <linux/ioport.h> | 28 | #include <linux/ioport.h> |
| 29 | #include <linux/scx200.h> | 29 | #include <linux/scx200.h> |
| 30 | 30 | #include <linux/uaccess.h> | |
| 31 | #include <asm/uaccess.h> | 31 | #include <linux/io.h> |
| 32 | #include <asm/io.h> | ||
| 33 | 32 | ||
| 34 | #define NAME "scx200_wdt" | 33 | #define NAME "scx200_wdt" |
| 35 | 34 | ||
| @@ -47,8 +46,9 @@ module_param(nowayout, int, 0); | |||
| 47 | MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); | 46 | MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); |
| 48 | 47 | ||
| 49 | static u16 wdto_restart; | 48 | static u16 wdto_restart; |
| 50 | static struct semaphore open_semaphore; | ||
| 51 | static char expect_close; | 49 | static char expect_close; |
| 50 | static unsigned long open_lock; | ||
| 51 | static DEFINE_SPINLOCK(scx_lock); | ||
| 52 | 52 | ||
| 53 | /* Bits of the WDCNFG register */ | 53 | /* Bits of the WDCNFG register */ |
| 54 | #define W_ENABLE 0x00fa /* Enable watchdog */ | 54 | #define W_ENABLE 0x00fa /* Enable watchdog */ |
| @@ -59,7 +59,9 @@ static char expect_close; | |||
| 59 | 59 | ||
| 60 | static void scx200_wdt_ping(void) | 60 | static void scx200_wdt_ping(void) |
| 61 | { | 61 | { |
| 62 | spin_lock(&scx_lock); | ||
| 62 | outw(wdto_restart, scx200_cb_base + SCx200_WDT_WDTO); | 63 | outw(wdto_restart, scx200_cb_base + SCx200_WDT_WDTO); |
| 64 | spin_unlock(&scx_lock); | ||
| 63 | } | 65 | } |
| 64 | 66 | ||
| 65 | static void scx200_wdt_update_margin(void) | 67 | static void scx200_wdt_update_margin(void) |
| @@ -73,9 +75,11 @@ static void scx200_wdt_enable(void) | |||
| 73 | printk(KERN_DEBUG NAME ": enabling watchdog timer, wdto_restart = %d\n", | 75 | printk(KERN_DEBUG NAME ": enabling watchdog timer, wdto_restart = %d\n", |
| 74 | wdto_restart); | 76 | wdto_restart); |
| 75 | 77 | ||
| 78 | spin_lock(&scx_lock); | ||
| 76 | outw(0, scx200_cb_base + SCx200_WDT_WDTO); | 79 | outw(0, scx200_cb_base + SCx200_WDT_WDTO); |
| 77 | outb(SCx200_WDT_WDSTS_WDOVF, scx200_cb_base + SCx200_WDT_WDSTS); | 80 | outb(SCx200_WDT_WDSTS_WDOVF, scx200_cb_base + SCx200_WDT_WDSTS); |
| 78 | outw(W_ENABLE, scx200_cb_base + SCx200_WDT_WDCNFG); | 81 | outw(W_ENABLE, scx200_cb_base + SCx200_WDT_WDCNFG); |
| 82 | spin_unlock(&scx_lock); | ||
| 79 | 83 | ||
| 80 | scx200_wdt_ping(); | 84 | scx200_wdt_ping(); |
| 81 | } | 85 | } |
| @@ -84,15 +88,17 @@ static void scx200_wdt_disable(void) | |||
| 84 | { | 88 | { |
| 85 | printk(KERN_DEBUG NAME ": disabling watchdog timer\n"); | 89 | printk(KERN_DEBUG NAME ": disabling watchdog timer\n"); |
| 86 | 90 | ||
| 91 | spin_lock(&scx_lock); | ||
| 87 | outw(0, scx200_cb_base + SCx200_WDT_WDTO); | 92 | outw(0, scx200_cb_base + SCx200_WDT_WDTO); |
| 88 | outb(SCx200_WDT_WDSTS_WDOVF, scx200_cb_base + SCx200_WDT_WDSTS); | 93 | outb(SCx200_WDT_WDSTS_WDOVF, scx200_cb_base + SCx200_WDT_WDSTS); |
| 89 | outw(W_DISABLE, scx200_cb_base + SCx200_WDT_WDCNFG); | 94 | outw(W_DISABLE, scx200_cb_base + SCx200_WDT_WDCNFG); |
| 95 | spin_unlock(&scx_lock); | ||
| 90 | } | 96 | } |
| 91 | 97 | ||
| 92 | static int scx200_wdt_open(struct inode *inode, struct file *file) | 98 | static int scx200_wdt_open(struct inode *inode, struct file *file) |
| 93 | { | 99 | { |
| 94 | /* only allow one at a time */ | 100 | /* only allow one at a time */ |
| 95 | if (down_trylock(&open_semaphore)) | 101 | if (test_and_set_bit(0, &open_lock)) |
| 96 | return -EBUSY; | 102 | return -EBUSY; |
| 97 | scx200_wdt_enable(); | 103 | scx200_wdt_enable(); |
| 98 | 104 | ||
| @@ -101,13 +107,12 @@ static int scx200_wdt_open(struct inode *inode, struct file *file) | |||
| 101 | 107 | ||
| 102 | static int scx200_wdt_release(struct inode *inode, struct file *file) | 108 | static int scx200_wdt_release(struct inode *inode, struct file *file) |
| 103 | { | 109 | { |
| 104 | if (expect_close != 42) { | 110 | if (expect_close != 42) |
| 105 | printk(KERN_WARNING NAME ": watchdog device closed unexpectedly, will not disable the watchdog timer\n"); | 111 | printk(KERN_WARNING NAME ": watchdog device closed unexpectedly, will not disable the watchdog timer\n"); |
| 106 | } else if (!nowayout) { | 112 | else if (!nowayout) |
| 107 | scx200_wdt_disable(); | 113 | scx200_wdt_disable(); |
| 108 | } | ||
| 109 | expect_close = 0; | 114 | expect_close = 0; |
| 110 | up(&open_semaphore); | 115 | clear_bit(0, &open_lock); |
| 111 | 116 | ||
| 112 | return 0; | 117 | return 0; |
| 113 | } | 118 | } |
| @@ -122,8 +127,7 @@ static int scx200_wdt_notify_sys(struct notifier_block *this, | |||
| 122 | return NOTIFY_DONE; | 127 | return NOTIFY_DONE; |
| 123 | } | 128 | } |
| 124 | 129 | ||
| 125 | static struct notifier_block scx200_wdt_notifier = | 130 | static struct notifier_block scx200_wdt_notifier = { |
| 126 | { | ||
| 127 | .notifier_call = scx200_wdt_notify_sys, | 131 | .notifier_call = scx200_wdt_notify_sys, |
| 128 | }; | 132 | }; |
| 129 | 133 | ||
| @@ -131,8 +135,7 @@ static ssize_t scx200_wdt_write(struct file *file, const char __user *data, | |||
| 131 | size_t len, loff_t *ppos) | 135 | size_t len, loff_t *ppos) |
| 132 | { | 136 | { |
| 133 | /* check for a magic close character */ | 137 | /* check for a magic close character */ |
| 134 | if (len) | 138 | if (len) { |
| 135 | { | ||
| 136 | size_t i; | 139 | size_t i; |
| 137 | 140 | ||
| 138 | scx200_wdt_ping(); | 141 | scx200_wdt_ping(); |
| @@ -140,7 +143,7 @@ static ssize_t scx200_wdt_write(struct file *file, const char __user *data, | |||
| 140 | expect_close = 0; | 143 | expect_close = 0; |
| 141 | for (i = 0; i < len; ++i) { | 144 | for (i = 0; i < len; ++i) { |
| 142 | char c; | 145 | char c; |
| 143 | if (get_user(c, data+i)) | 146 | if (get_user(c, data + i)) |
| 144 | return -EFAULT; | 147 | return -EFAULT; |
| 145 | if (c == 'V') | 148 | if (c == 'V') |
| 146 | expect_close = 42; | 149 | expect_close = 42; |
| @@ -152,23 +155,21 @@ static ssize_t scx200_wdt_write(struct file *file, const char __user *data, | |||
| 152 | return 0; | 155 | return 0; |
| 153 | } | 156 | } |
| 154 | 157 | ||
| 155 | static int scx200_wdt_ioctl(struct inode *inode, struct file *file, | 158 | static long scx200_wdt_ioctl(struct file *file, unsigned int cmd, |
| 156 | unsigned int cmd, unsigned long arg) | 159 | unsigned long arg) |
| 157 | { | 160 | { |
| 158 | void __user *argp = (void __user *)arg; | 161 | void __user *argp = (void __user *)arg; |
| 159 | int __user *p = argp; | 162 | int __user *p = argp; |
| 160 | static struct watchdog_info ident = { | 163 | static const struct watchdog_info ident = { |
| 161 | .identity = "NatSemi SCx200 Watchdog", | 164 | .identity = "NatSemi SCx200 Watchdog", |
| 162 | .firmware_version = 1, | 165 | .firmware_version = 1, |
| 163 | .options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING), | 166 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, |
| 164 | }; | 167 | }; |
| 165 | int new_margin; | 168 | int new_margin; |
| 166 | 169 | ||
| 167 | switch (cmd) { | 170 | switch (cmd) { |
| 168 | default: | ||
| 169 | return -ENOTTY; | ||
| 170 | case WDIOC_GETSUPPORT: | 171 | case WDIOC_GETSUPPORT: |
| 171 | if(copy_to_user(argp, &ident, sizeof(ident))) | 172 | if (copy_to_user(argp, &ident, sizeof(ident))) |
| 172 | return -EFAULT; | 173 | return -EFAULT; |
| 173 | return 0; | 174 | return 0; |
| 174 | case WDIOC_GETSTATUS: | 175 | case WDIOC_GETSTATUS: |
| @@ -191,22 +192,24 @@ static int scx200_wdt_ioctl(struct inode *inode, struct file *file, | |||
| 191 | if (put_user(margin, p)) | 192 | if (put_user(margin, p)) |
| 192 | return -EFAULT; | 193 | return -EFAULT; |
| 193 | return 0; | 194 | return 0; |
| 195 | default: | ||
| 196 | return -ENOTTY; | ||
| 194 | } | 197 | } |
| 195 | } | 198 | } |
| 196 | 199 | ||
| 197 | static const struct file_operations scx200_wdt_fops = { | 200 | static const struct file_operations scx200_wdt_fops = { |
| 198 | .owner = THIS_MODULE, | 201 | .owner = THIS_MODULE, |
| 199 | .llseek = no_llseek, | 202 | .llseek = no_llseek, |
| 200 | .write = scx200_wdt_write, | 203 | .write = scx200_wdt_write, |
| 201 | .ioctl = scx200_wdt_ioctl, | 204 | .unlocked_ioctl = scx200_wdt_ioctl, |
| 202 | .open = scx200_wdt_open, | 205 | .open = scx200_wdt_open, |
| 203 | .release = scx200_wdt_release, | 206 | .release = scx200_wdt_release, |
| 204 | }; | 207 | }; |
| 205 | 208 | ||
| 206 | static struct miscdevice scx200_wdt_miscdev = { | 209 | static struct miscdevice scx200_wdt_miscdev = { |
| 207 | .minor = WATCHDOG_MINOR, | 210 | .minor = WATCHDOG_MINOR, |
| 208 | .name = "watchdog", | 211 | .name = "watchdog", |
| 209 | .fops = &scx200_wdt_fops, | 212 | .fops = &scx200_wdt_fops, |
| 210 | }; | 213 | }; |
| 211 | 214 | ||
| 212 | static int __init scx200_wdt_init(void) | 215 | static int __init scx200_wdt_init(void) |
| @@ -229,8 +232,6 @@ static int __init scx200_wdt_init(void) | |||
| 229 | scx200_wdt_update_margin(); | 232 | scx200_wdt_update_margin(); |
| 230 | scx200_wdt_disable(); | 233 | scx200_wdt_disable(); |
| 231 | 234 | ||
| 232 | sema_init(&open_semaphore, 1); | ||
| 233 | |||
| 234 | r = register_reboot_notifier(&scx200_wdt_notifier); | 235 | r = register_reboot_notifier(&scx200_wdt_notifier); |
| 235 | if (r) { | 236 | if (r) { |
| 236 | printk(KERN_ERR NAME ": unable to register reboot notifier"); | 237 | printk(KERN_ERR NAME ": unable to register reboot notifier"); |
| @@ -263,7 +264,7 @@ module_exit(scx200_wdt_cleanup); | |||
| 263 | 264 | ||
| 264 | /* | 265 | /* |
| 265 | Local variables: | 266 | Local variables: |
| 266 | compile-command: "make -k -C ../.. SUBDIRS=drivers/char modules" | 267 | compile-command: "make -k -C ../.. SUBDIRS=drivers/char modules" |
| 267 | c-basic-offset: 8 | 268 | c-basic-offset: 8 |
| 268 | End: | 269 | End: |
| 269 | */ | 270 | */ |
diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index 1277f7e9cc54..824125adf90a 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c | |||
| @@ -28,9 +28,9 @@ | |||
| 28 | #include <linux/ioport.h> | 28 | #include <linux/ioport.h> |
| 29 | #include <linux/fs.h> | 29 | #include <linux/fs.h> |
| 30 | #include <linux/mm.h> | 30 | #include <linux/mm.h> |
| 31 | #include <asm/io.h> | 31 | #include <linux/io.h> |
| 32 | #include <asm/uaccess.h> | 32 | #include <linux/uaccess.h> |
| 33 | #include <asm/watchdog.h> | 33 | #include <linux/watchdog.h> |
| 34 | 34 | ||
| 35 | #define PFX "shwdt: " | 35 | #define PFX "shwdt: " |
| 36 | 36 | ||
| @@ -72,6 +72,7 @@ static struct watchdog_info sh_wdt_info; | |||
| 72 | static char shwdt_expect_close; | 72 | static char shwdt_expect_close; |
| 73 | static DEFINE_TIMER(timer, sh_wdt_ping, 0, 0); | 73 | static DEFINE_TIMER(timer, sh_wdt_ping, 0, 0); |
| 74 | static unsigned long next_heartbeat; | 74 | static unsigned long next_heartbeat; |
| 75 | static DEFINE_SPINLOCK(shwdt_lock); | ||
| 75 | 76 | ||
| 76 | #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ | 77 | #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ |
| 77 | static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ | 78 | static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ |
| @@ -86,6 +87,9 @@ static int nowayout = WATCHDOG_NOWAYOUT; | |||
| 86 | static void sh_wdt_start(void) | 87 | static void sh_wdt_start(void) |
| 87 | { | 88 | { |
| 88 | __u8 csr; | 89 | __u8 csr; |
| 90 | unsigned long flags; | ||
| 91 | |||
| 92 | spin_lock_irqsave(&wdt_lock, flags); | ||
| 89 | 93 | ||
| 90 | next_heartbeat = jiffies + (heartbeat * HZ); | 94 | next_heartbeat = jiffies + (heartbeat * HZ); |
| 91 | mod_timer(&timer, next_ping_period(clock_division_ratio)); | 95 | mod_timer(&timer, next_ping_period(clock_division_ratio)); |
| @@ -123,6 +127,7 @@ static void sh_wdt_start(void) | |||
| 123 | csr &= ~RSTCSR_RSTS; | 127 | csr &= ~RSTCSR_RSTS; |
| 124 | sh_wdt_write_rstcsr(csr); | 128 | sh_wdt_write_rstcsr(csr); |
| 125 | #endif | 129 | #endif |
| 130 | spin_unlock_irqrestore(&wdt_lock, flags); | ||
| 126 | } | 131 | } |
| 127 | 132 | ||
| 128 | /** | 133 | /** |
| @@ -132,12 +137,16 @@ static void sh_wdt_start(void) | |||
| 132 | static void sh_wdt_stop(void) | 137 | static void sh_wdt_stop(void) |
| 133 | { | 138 | { |
| 134 | __u8 csr; | 139 | __u8 csr; |
| 140 | unsigned long flags; | ||
| 141 | |||
| 142 | spin_lock_irqsave(&wdt_lock, flags); | ||
| 135 | 143 | ||
| 136 | del_timer(&timer); | 144 | del_timer(&timer); |
| 137 | 145 | ||
| 138 | csr = sh_wdt_read_csr(); | 146 | csr = sh_wdt_read_csr(); |
| 139 | csr &= ~WTCSR_TME; | 147 | csr &= ~WTCSR_TME; |
| 140 | sh_wdt_write_csr(csr); | 148 | sh_wdt_write_csr(csr); |
| 149 | spin_unlock_irqrestore(&wdt_lock, flags); | ||
| 141 | } | 150 | } |
| 142 | 151 | ||
| 143 | /** | 152 | /** |
| @@ -146,7 +155,11 @@ static void sh_wdt_stop(void) | |||
| 146 | */ | 155 | */ |
| 147 | static inline void sh_wdt_keepalive(void) | 156 | static inline void sh_wdt_keepalive(void) |
| 148 | { | 157 | { |
| 158 | unsigned long flags; | ||
| 159 | |||
| 160 | spin_lock_irqsave(&wdt_lock, flags); | ||
| 149 | next_heartbeat = jiffies + (heartbeat * HZ); | 161 | next_heartbeat = jiffies + (heartbeat * HZ); |
| 162 | spin_unlock_irqrestore(&wdt_lock, flags); | ||
| 150 | } | 163 | } |
| 151 | 164 | ||
| 152 | /** | 165 | /** |
| @@ -155,10 +168,14 @@ static inline void sh_wdt_keepalive(void) | |||
| 155 | */ | 168 | */ |
| 156 | static int sh_wdt_set_heartbeat(int t) | 169 | static int sh_wdt_set_heartbeat(int t) |
| 157 | { | 170 | { |
| 158 | if (unlikely((t < 1) || (t > 3600))) /* arbitrary upper limit */ | 171 | unsigned long flags; |
| 172 | |||
| 173 | if (unlikely(t < 1 || t > 3600)) /* arbitrary upper limit */ | ||
| 159 | return -EINVAL; | 174 | return -EINVAL; |
| 160 | 175 | ||
| 176 | spin_lock_irqsave(&wdt_lock, flags); | ||
| 161 | heartbeat = t; | 177 | heartbeat = t; |
| 178 | spin_unlock_irqrestore(&wdt_lock, flags); | ||
| 162 | return 0; | 179 | return 0; |
| 163 | } | 180 | } |
| 164 | 181 | ||
| @@ -170,6 +187,9 @@ static int sh_wdt_set_heartbeat(int t) | |||
| 170 | */ | 187 | */ |
| 171 | static void sh_wdt_ping(unsigned long data) | 188 | static void sh_wdt_ping(unsigned long data) |
| 172 | { | 189 | { |
| 190 | unsigned long flags; | ||
| 191 | |||
| 192 | spin_lock_irqsave(&wdt_lock, flags); | ||
| 173 | if (time_before(jiffies, next_heartbeat)) { | 193 | if (time_before(jiffies, next_heartbeat)) { |
| 174 | __u8 csr; | 194 | __u8 csr; |
| 175 | 195 | ||
| @@ -183,6 +203,7 @@ static void sh_wdt_ping(unsigned long data) | |||
| 183 | } else | 203 | } else |
| 184 | printk(KERN_WARNING PFX "Heartbeat lost! Will not ping " | 204 | printk(KERN_WARNING PFX "Heartbeat lost! Will not ping " |
| 185 | "the watchdog\n"); | 205 | "the watchdog\n"); |
| 206 | spin_unlock_irqrestore(&wdt_lock, flags); | ||
| 186 | } | 207 | } |
| 187 | 208 | ||
| 188 | /** | 209 | /** |
| @@ -310,7 +331,6 @@ static int sh_wdt_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 310 | 331 | ||
| 311 | /** | 332 | /** |
| 312 | * sh_wdt_ioctl - Query Device | 333 | * sh_wdt_ioctl - Query Device |
| 313 | * @inode: inode of device | ||
| 314 | * @file: file handle of device | 334 | * @file: file handle of device |
| 315 | * @cmd: watchdog command | 335 | * @cmd: watchdog command |
| 316 | * @arg: argument | 336 | * @arg: argument |
| @@ -318,53 +338,51 @@ static int sh_wdt_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 318 | * Query basic information from the device or ping it, as outlined by the | 338 | * Query basic information from the device or ping it, as outlined by the |
| 319 | * watchdog API. | 339 | * watchdog API. |
| 320 | */ | 340 | */ |
| 321 | static int sh_wdt_ioctl(struct inode *inode, struct file *file, | 341 | static long sh_wdt_ioctl(struct file *file, unsigned int cmd, |
| 322 | unsigned int cmd, unsigned long arg) | 342 | unsigned long arg) |
| 323 | { | 343 | { |
| 324 | int new_heartbeat; | 344 | int new_heartbeat; |
| 325 | int options, retval = -EINVAL; | 345 | int options, retval = -EINVAL; |
| 326 | 346 | ||
| 327 | switch (cmd) { | 347 | switch (cmd) { |
| 328 | case WDIOC_GETSUPPORT: | 348 | case WDIOC_GETSUPPORT: |
| 329 | return copy_to_user((struct watchdog_info *)arg, | 349 | return copy_to_user((struct watchdog_info *)arg, |
| 330 | &sh_wdt_info, | 350 | &sh_wdt_info, sizeof(sh_wdt_info)) ? -EFAULT : 0; |
| 331 | sizeof(sh_wdt_info)) ? -EFAULT : 0; | 351 | case WDIOC_GETSTATUS: |
| 332 | case WDIOC_GETSTATUS: | 352 | case WDIOC_GETBOOTSTATUS: |
| 333 | case WDIOC_GETBOOTSTATUS: | 353 | return put_user(0, (int *)arg); |
| 334 | return put_user(0, (int *)arg); | 354 | case WDIOC_SETOPTIONS: |
| 335 | case WDIOC_KEEPALIVE: | 355 | if (get_user(options, (int *)arg)) |
| 336 | sh_wdt_keepalive(); | 356 | return -EFAULT; |
| 337 | return 0; | 357 | |
| 338 | case WDIOC_SETTIMEOUT: | 358 | if (options & WDIOS_DISABLECARD) { |
| 339 | if (get_user(new_heartbeat, (int *)arg)) | 359 | sh_wdt_stop(); |
| 340 | return -EFAULT; | 360 | retval = 0; |
| 341 | 361 | } | |
| 342 | if (sh_wdt_set_heartbeat(new_heartbeat)) | ||
| 343 | return -EINVAL; | ||
| 344 | |||
| 345 | sh_wdt_keepalive(); | ||
| 346 | /* Fall */ | ||
| 347 | case WDIOC_GETTIMEOUT: | ||
| 348 | return put_user(heartbeat, (int *)arg); | ||
| 349 | case WDIOC_SETOPTIONS: | ||
| 350 | if (get_user(options, (int *)arg)) | ||
| 351 | return -EFAULT; | ||
| 352 | |||
| 353 | if (options & WDIOS_DISABLECARD) { | ||
| 354 | sh_wdt_stop(); | ||
| 355 | retval = 0; | ||
| 356 | } | ||
| 357 | 362 | ||
| 358 | if (options & WDIOS_ENABLECARD) { | 363 | if (options & WDIOS_ENABLECARD) { |
| 359 | sh_wdt_start(); | 364 | sh_wdt_start(); |
| 360 | retval = 0; | 365 | retval = 0; |
| 361 | } | 366 | } |
| 362 | 367 | ||
| 363 | return retval; | 368 | return retval; |
| 364 | default: | 369 | case WDIOC_KEEPALIVE: |
| 365 | return -ENOTTY; | 370 | sh_wdt_keepalive(); |
| 366 | } | 371 | return 0; |
| 372 | case WDIOC_SETTIMEOUT: | ||
| 373 | if (get_user(new_heartbeat, (int *)arg)) | ||
| 374 | return -EFAULT; | ||
| 375 | |||
| 376 | if (sh_wdt_set_heartbeat(new_heartbeat)) | ||
| 377 | return -EINVAL; | ||
| 367 | 378 | ||
| 379 | sh_wdt_keepalive(); | ||
| 380 | /* Fall */ | ||
| 381 | case WDIOC_GETTIMEOUT: | ||
| 382 | return put_user(heartbeat, (int *)arg); | ||
| 383 | default: | ||
| 384 | return -ENOTTY; | ||
| 385 | } | ||
| 368 | return 0; | 386 | return 0; |
| 369 | } | 387 | } |
| 370 | 388 | ||
| @@ -390,13 +408,13 @@ static const struct file_operations sh_wdt_fops = { | |||
| 390 | .owner = THIS_MODULE, | 408 | .owner = THIS_MODULE, |
| 391 | .llseek = no_llseek, | 409 | .llseek = no_llseek, |
| 392 | .write = sh_wdt_write, | 410 | .write = sh_wdt_write, |
| 393 | .ioctl = sh_wdt_ioctl, | 411 | .unlocked_ioctl = sh_wdt_ioctl, |
| 394 | .open = sh_wdt_open, | 412 | .open = sh_wdt_open, |
| 395 | .release = sh_wdt_close, | 413 | .release = sh_wdt_close, |
| 396 | .mmap = sh_wdt_mmap, | 414 | .mmap = sh_wdt_mmap, |
| 397 | }; | 415 | }; |
| 398 | 416 | ||
| 399 | static struct watchdog_info sh_wdt_info = { | 417 | static const struct watchdog_info sh_wdt_info = { |
| 400 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | | 418 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | |
| 401 | WDIOF_MAGICCLOSE, | 419 | WDIOF_MAGICCLOSE, |
| 402 | .firmware_version = 1, | 420 | .firmware_version = 1, |
| @@ -422,30 +440,33 @@ static int __init sh_wdt_init(void) | |||
| 422 | { | 440 | { |
| 423 | int rc; | 441 | int rc; |
| 424 | 442 | ||
| 425 | if ((clock_division_ratio < 0x5) || (clock_division_ratio > 0x7)) { | 443 | if (clock_division_ratio < 0x5 || clock_division_ratio > 0x7) { |
| 426 | clock_division_ratio = WTCSR_CKS_4096; | 444 | clock_division_ratio = WTCSR_CKS_4096; |
| 427 | printk(KERN_INFO PFX "clock_division_ratio value must " | 445 | printk(KERN_INFO PFX |
| 428 | "be 0x5<=x<=0x7, using %d\n", clock_division_ratio); | 446 | "clock_division_ratio value must be 0x5<=x<=0x7, using %d\n", |
| 447 | clock_division_ratio); | ||
| 429 | } | 448 | } |
| 430 | 449 | ||
| 431 | rc = sh_wdt_set_heartbeat(heartbeat); | 450 | rc = sh_wdt_set_heartbeat(heartbeat); |
| 432 | if (unlikely(rc)) { | 451 | if (unlikely(rc)) { |
| 433 | heartbeat = WATCHDOG_HEARTBEAT; | 452 | heartbeat = WATCHDOG_HEARTBEAT; |
| 434 | printk(KERN_INFO PFX "heartbeat value must " | 453 | printk(KERN_INFO PFX |
| 435 | "be 1<=x<=3600, using %d\n", heartbeat); | 454 | "heartbeat value must be 1<=x<=3600, using %d\n", |
| 455 | heartbeat); | ||
| 436 | } | 456 | } |
| 437 | 457 | ||
| 438 | rc = register_reboot_notifier(&sh_wdt_notifier); | 458 | rc = register_reboot_notifier(&sh_wdt_notifier); |
| 439 | if (unlikely(rc)) { | 459 | if (unlikely(rc)) { |
| 440 | printk(KERN_ERR PFX "Can't register reboot notifier (err=%d)\n", | 460 | printk(KERN_ERR PFX |
| 441 | rc); | 461 | "Can't register reboot notifier (err=%d)\n", rc); |
| 442 | return rc; | 462 | return rc; |
| 443 | } | 463 | } |
| 444 | 464 | ||
| 445 | rc = misc_register(&sh_wdt_miscdev); | 465 | rc = misc_register(&sh_wdt_miscdev); |
| 446 | if (unlikely(rc)) { | 466 | if (unlikely(rc)) { |
| 447 | printk(KERN_ERR PFX "Can't register miscdev on " | 467 | printk(KERN_ERR PFX |
| 448 | "minor=%d (err=%d)\n", sh_wdt_miscdev.minor, rc); | 468 | "Can't register miscdev on minor=%d (err=%d)\n", |
| 469 | sh_wdt_miscdev.minor, rc); | ||
| 449 | unregister_reboot_notifier(&sh_wdt_notifier); | 470 | unregister_reboot_notifier(&sh_wdt_notifier); |
| 450 | return rc; | 471 | return rc; |
| 451 | } | 472 | } |
| @@ -476,10 +497,14 @@ module_param(clock_division_ratio, int, 0); | |||
| 476 | MODULE_PARM_DESC(clock_division_ratio, "Clock division ratio. Valid ranges are from 0x5 (1.31ms) to 0x7 (5.25ms). (default=" __MODULE_STRING(clock_division_ratio) ")"); | 497 | MODULE_PARM_DESC(clock_division_ratio, "Clock division ratio. Valid ranges are from 0x5 (1.31ms) to 0x7 (5.25ms). (default=" __MODULE_STRING(clock_division_ratio) ")"); |
| 477 | 498 | ||
| 478 | module_param(heartbeat, int, 0); | 499 | module_param(heartbeat, int, 0); |
| 479 | MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (1<=heartbeat<=3600, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); | 500 | MODULE_PARM_DESC(heartbeat, |
| 501 | "Watchdog heartbeat in seconds. (1 <= heartbeat <= 3600, default=" | ||
| 502 | __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); | ||
| 480 | 503 | ||
| 481 | module_param(nowayout, int, 0); | 504 | module_param(nowayout, int, 0); |
| 482 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 505 | MODULE_PARM_DESC(nowayout, |
| 506 | "Watchdog cannot be stopped once started (default=" | ||
| 507 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 483 | 508 | ||
| 484 | module_init(sh_wdt_init); | 509 | module_init(sh_wdt_init); |
| 485 | module_exit(sh_wdt_exit); | 510 | module_exit(sh_wdt_exit); |
diff --git a/drivers/watchdog/smsc37b787_wdt.c b/drivers/watchdog/smsc37b787_wdt.c index 5d2b5ba61414..988ff1d5b4be 100644 --- a/drivers/watchdog/smsc37b787_wdt.c +++ b/drivers/watchdog/smsc37b787_wdt.c | |||
| @@ -18,7 +18,7 @@ | |||
| 18 | * History: | 18 | * History: |
| 19 | * 2003 - Created version 1.0 for Linux 2.4.x. | 19 | * 2003 - Created version 1.0 for Linux 2.4.x. |
| 20 | * 2006 - Ported to Linux 2.6, added nowayout and MAGICCLOSE | 20 | * 2006 - Ported to Linux 2.6, added nowayout and MAGICCLOSE |
| 21 | * features. Released version 1.1 | 21 | * features. Released version 1.1 |
| 22 | * | 22 | * |
| 23 | * Theory of operation: | 23 | * Theory of operation: |
| 24 | * | 24 | * |
| @@ -55,9 +55,9 @@ | |||
| 55 | #include <linux/reboot.h> | 55 | #include <linux/reboot.h> |
| 56 | #include <linux/init.h> | 56 | #include <linux/init.h> |
| 57 | #include <linux/spinlock.h> | 57 | #include <linux/spinlock.h> |
| 58 | #include <linux/io.h> | ||
| 59 | #include <linux/uaccess.h> | ||
| 58 | 60 | ||
| 59 | #include <asm/io.h> | ||
| 60 | #include <asm/uaccess.h> | ||
| 61 | #include <asm/system.h> | 61 | #include <asm/system.h> |
| 62 | 62 | ||
| 63 | /* enable support for minutes as units? */ | 63 | /* enable support for minutes as units? */ |
| @@ -71,15 +71,15 @@ | |||
| 71 | #define UNIT_MINUTE 1 | 71 | #define UNIT_MINUTE 1 |
| 72 | 72 | ||
| 73 | #define MODNAME "smsc37b787_wdt: " | 73 | #define MODNAME "smsc37b787_wdt: " |
| 74 | #define VERSION "1.1" | 74 | #define VERSION "1.1" |
| 75 | 75 | ||
| 76 | #define IOPORT 0x3F0 | 76 | #define IOPORT 0x3F0 |
| 77 | #define IOPORT_SIZE 2 | 77 | #define IOPORT_SIZE 2 |
| 78 | #define IODEV_NO 8 | 78 | #define IODEV_NO 8 |
| 79 | 79 | ||
| 80 | static int unit = UNIT_SECOND; /* timer's unit */ | 80 | static int unit = UNIT_SECOND; /* timer's unit */ |
| 81 | static int timeout = 60; /* timeout value: default is 60 "units" */ | 81 | static int timeout = 60; /* timeout value: default is 60 "units" */ |
| 82 | static unsigned long timer_enabled = 0; /* is the timer enabled? */ | 82 | static unsigned long timer_enabled; /* is the timer enabled? */ |
| 83 | 83 | ||
| 84 | static char expect_close; /* is the close expected? */ | 84 | static char expect_close; /* is the close expected? */ |
| 85 | 85 | ||
| @@ -93,114 +93,121 @@ static int nowayout = WATCHDOG_NOWAYOUT; | |||
| 93 | 93 | ||
| 94 | static inline void open_io_config(void) | 94 | static inline void open_io_config(void) |
| 95 | { | 95 | { |
| 96 | outb(0x55, IOPORT); | 96 | outb(0x55, IOPORT); |
| 97 | mdelay(1); | 97 | mdelay(1); |
| 98 | outb(0x55, IOPORT); | 98 | outb(0x55, IOPORT); |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | /* lock the IO chip */ | 101 | /* lock the IO chip */ |
| 102 | static inline void close_io_config(void) | 102 | static inline void close_io_config(void) |
| 103 | { | 103 | { |
| 104 | outb(0xAA, IOPORT); | 104 | outb(0xAA, IOPORT); |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | /* select the IO device */ | 107 | /* select the IO device */ |
| 108 | static inline void select_io_device(unsigned char devno) | 108 | static inline void select_io_device(unsigned char devno) |
| 109 | { | 109 | { |
| 110 | outb(0x07, IOPORT); | 110 | outb(0x07, IOPORT); |
| 111 | outb(devno, IOPORT+1); | 111 | outb(devno, IOPORT+1); |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | /* write to the control register */ | 114 | /* write to the control register */ |
| 115 | static inline void write_io_cr(unsigned char reg, unsigned char data) | 115 | static inline void write_io_cr(unsigned char reg, unsigned char data) |
| 116 | { | 116 | { |
| 117 | outb(reg, IOPORT); | 117 | outb(reg, IOPORT); |
| 118 | outb(data, IOPORT+1); | 118 | outb(data, IOPORT+1); |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | /* read from the control register */ | 121 | /* read from the control register */ |
| 122 | static inline char read_io_cr(unsigned char reg) | 122 | static inline char read_io_cr(unsigned char reg) |
| 123 | { | 123 | { |
| 124 | outb(reg, IOPORT); | 124 | outb(reg, IOPORT); |
| 125 | return inb(IOPORT+1); | 125 | return inb(IOPORT+1); |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | /* -- Medium level functions ------------------------------------*/ | 128 | /* -- Medium level functions ------------------------------------*/ |
| 129 | 129 | ||
| 130 | static inline void gpio_bit12(unsigned char reg) | 130 | static inline void gpio_bit12(unsigned char reg) |
| 131 | { | 131 | { |
| 132 | // -- General Purpose I/O Bit 1.2 -- | 132 | /* -- General Purpose I/O Bit 1.2 -- |
| 133 | // Bit 0, In/Out: 0 = Output, 1 = Input | 133 | * Bit 0, In/Out: 0 = Output, 1 = Input |
| 134 | // Bit 1, Polarity: 0 = No Invert, 1 = Invert | 134 | * Bit 1, Polarity: 0 = No Invert, 1 = Invert |
| 135 | // Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable | 135 | * Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable |
| 136 | // Bit 3/4, Function select: 00 = GPI/O, 01 = WDT, 10 = P17, | 136 | * Bit 3/4, Function select: 00 = GPI/O, 01 = WDT, 10 = P17, |
| 137 | // 11 = Either Edge Triggered Intr. 2 | 137 | * 11 = Either Edge Triggered Intr. 2 |
| 138 | // Bit 5/6 (Reserved) | 138 | * Bit 5/6 (Reserved) |
| 139 | // Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain | 139 | * Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain |
| 140 | write_io_cr(0xE2, reg); | 140 | */ |
| 141 | write_io_cr(0xE2, reg); | ||
| 141 | } | 142 | } |
| 142 | 143 | ||
| 143 | static inline void gpio_bit13(unsigned char reg) | 144 | static inline void gpio_bit13(unsigned char reg) |
| 144 | { | 145 | { |
| 145 | // -- General Purpose I/O Bit 1.3 -- | 146 | /* -- General Purpose I/O Bit 1.3 -- |
| 146 | // Bit 0, In/Out: 0 = Output, 1 = Input | 147 | * Bit 0, In/Out: 0 = Output, 1 = Input |
| 147 | // Bit 1, Polarity: 0 = No Invert, 1 = Invert | 148 | * Bit 1, Polarity: 0 = No Invert, 1 = Invert |
| 148 | // Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable | 149 | * Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable |
| 149 | // Bit 3, Function select: 0 = GPI/O, 1 = LED | 150 | * Bit 3, Function select: 0 = GPI/O, 1 = LED |
| 150 | // Bit 4-6 (Reserved) | 151 | * Bit 4-6 (Reserved) |
| 151 | // Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain | 152 | * Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain |
| 152 | write_io_cr(0xE3, reg); | 153 | */ |
| 154 | write_io_cr(0xE3, reg); | ||
| 153 | } | 155 | } |
| 154 | 156 | ||
| 155 | static inline void wdt_timer_units(unsigned char new_units) | 157 | static inline void wdt_timer_units(unsigned char new_units) |
| 156 | { | 158 | { |
| 157 | // -- Watchdog timer units -- | 159 | /* -- Watchdog timer units -- |
| 158 | // Bit 0-6 (Reserved) | 160 | * Bit 0-6 (Reserved) |
| 159 | // Bit 7, WDT Time-out Value Units Select | 161 | * Bit 7, WDT Time-out Value Units Select |
| 160 | // (0 = Minutes, 1 = Seconds) | 162 | * (0 = Minutes, 1 = Seconds) |
| 161 | write_io_cr(0xF1, new_units); | 163 | */ |
| 164 | write_io_cr(0xF1, new_units); | ||
| 162 | } | 165 | } |
| 163 | 166 | ||
| 164 | static inline void wdt_timeout_value(unsigned char new_timeout) | 167 | static inline void wdt_timeout_value(unsigned char new_timeout) |
| 165 | { | 168 | { |
| 166 | // -- Watchdog Timer Time-out Value -- | 169 | /* -- Watchdog Timer Time-out Value -- |
| 167 | // Bit 0-7 Binary coded units (0=Disabled, 1..255) | 170 | * Bit 0-7 Binary coded units (0=Disabled, 1..255) |
| 168 | write_io_cr(0xF2, new_timeout); | 171 | */ |
| 172 | write_io_cr(0xF2, new_timeout); | ||
| 169 | } | 173 | } |
| 170 | 174 | ||
| 171 | static inline void wdt_timer_conf(unsigned char conf) | 175 | static inline void wdt_timer_conf(unsigned char conf) |
| 172 | { | 176 | { |
| 173 | // -- Watchdog timer configuration -- | 177 | /* -- Watchdog timer configuration -- |
| 174 | // Bit 0 Joystick enable: 0* = No Reset, 1 = Reset WDT upon Gameport I/O | 178 | * Bit 0 Joystick enable: 0* = No Reset, 1 = Reset WDT upon |
| 175 | // Bit 1 Keyboard enable: 0* = No Reset, 1 = Reset WDT upon KBD Intr. | 179 | * Gameport I/O |
| 176 | // Bit 2 Mouse enable: 0* = No Reset, 1 = Reset WDT upon Mouse Intr. | 180 | * Bit 1 Keyboard enable: 0* = No Reset, 1 = Reset WDT upon KBD Intr. |
| 177 | // Bit 3 Reset the timer | 181 | * Bit 2 Mouse enable: 0* = No Reset, 1 = Reset WDT upon Mouse Intr |
| 178 | // (Wrong in SMsC documentation? Given as: PowerLED Timout Enabled) | 182 | * Bit 3 Reset the timer |
| 179 | // Bit 4-7 WDT Interrupt Mapping: (0000* = Disabled, | 183 | * (Wrong in SMsC documentation? Given as: PowerLED Timout |
| 180 | // 0001=IRQ1, 0010=(Invalid), 0011=IRQ3 to 1111=IRQ15) | 184 | * Enabled) |
| 181 | write_io_cr(0xF3, conf); | 185 | * Bit 4-7 WDT Interrupt Mapping: (0000* = Disabled, |
| 186 | * 0001=IRQ1, 0010=(Invalid), 0011=IRQ3 to 1111=IRQ15) | ||
| 187 | */ | ||
| 188 | write_io_cr(0xF3, conf); | ||
| 182 | } | 189 | } |
| 183 | 190 | ||
| 184 | static inline void wdt_timer_ctrl(unsigned char reg) | 191 | static inline void wdt_timer_ctrl(unsigned char reg) |
| 185 | { | 192 | { |
| 186 | // -- Watchdog timer control -- | 193 | /* -- Watchdog timer control -- |
| 187 | // Bit 0 Status Bit: 0 = Timer counting, 1 = Timeout occured | 194 | * Bit 0 Status Bit: 0 = Timer counting, 1 = Timeout occured |
| 188 | // Bit 1 Power LED Toggle: 0 = Disable Toggle, 1 = Toggle at 1 Hz | 195 | * Bit 1 Power LED Toggle: 0 = Disable Toggle, 1 = Toggle at 1 Hz |
| 189 | // Bit 2 Force Timeout: 1 = Forces WD timeout event (self-cleaning) | 196 | * Bit 2 Force Timeout: 1 = Forces WD timeout event (self-cleaning) |
| 190 | // Bit 3 P20 Force Timeout enabled: | 197 | * Bit 3 P20 Force Timeout enabled: |
| 191 | // 0 = P20 activity does not generate the WD timeout event | 198 | * 0 = P20 activity does not generate the WD timeout event |
| 192 | // 1 = P20 Allows rising edge of P20, from the keyboard | 199 | * 1 = P20 Allows rising edge of P20, from the keyboard |
| 193 | // controller, to force the WD timeout event. | 200 | * controller, to force the WD timeout event. |
| 194 | // Bit 4 (Reserved) | 201 | * Bit 4 (Reserved) |
| 195 | // -- Soft power management -- | 202 | * -- Soft power management -- |
| 196 | // Bit 5 Stop Counter: 1 = Stop software power down counter | 203 | * Bit 5 Stop Counter: 1 = Stop software power down counter |
| 197 | // set via register 0xB8, (self-cleaning) | 204 | * set via register 0xB8, (self-cleaning) |
| 198 | // (Upon read: 0 = Counter running, 1 = Counter stopped) | 205 | * (Upon read: 0 = Counter running, 1 = Counter stopped) |
| 199 | // Bit 6 Restart Counter: 1 = Restart software power down counter | 206 | * Bit 6 Restart Counter: 1 = Restart software power down counter |
| 200 | // set via register 0xB8, (self-cleaning) | 207 | * set via register 0xB8, (self-cleaning) |
| 201 | // Bit 7 SPOFF: 1 = Force software power down (self-cleaning) | 208 | * Bit 7 SPOFF: 1 = Force software power down (self-cleaning) |
| 202 | 209 | */ | |
| 203 | write_io_cr(0xF4, reg); | 210 | write_io_cr(0xF4, reg); |
| 204 | } | 211 | } |
| 205 | 212 | ||
| 206 | /* -- Higher level functions ------------------------------------*/ | 213 | /* -- Higher level functions ------------------------------------*/ |
| @@ -209,33 +216,34 @@ static inline void wdt_timer_ctrl(unsigned char reg) | |||
| 209 | 216 | ||
| 210 | static void wb_smsc_wdt_initialize(void) | 217 | static void wb_smsc_wdt_initialize(void) |
| 211 | { | 218 | { |
| 212 | unsigned char old; | 219 | unsigned char old; |
| 213 | 220 | ||
| 214 | spin_lock(&io_lock); | 221 | spin_lock(&io_lock); |
| 215 | open_io_config(); | 222 | open_io_config(); |
| 216 | select_io_device(IODEV_NO); | 223 | select_io_device(IODEV_NO); |
| 217 | 224 | ||
| 218 | // enable the watchdog | 225 | /* enable the watchdog */ |
| 219 | gpio_bit13(0x08); // Select pin 80 = LED not GPIO | 226 | gpio_bit13(0x08); /* Select pin 80 = LED not GPIO */ |
| 220 | gpio_bit12(0x0A); // Set pin 79 = WDT not GPIO/Output/Polarity=Invert | 227 | gpio_bit12(0x0A); /* Set pin 79 = WDT not |
| 228 | GPIO/Output/Polarity=Invert */ | ||
| 229 | /* disable the timeout */ | ||
| 230 | wdt_timeout_value(0); | ||
| 221 | 231 | ||
| 222 | // disable the timeout | 232 | /* reset control register */ |
| 223 | wdt_timeout_value(0); | 233 | wdt_timer_ctrl(0x00); |
| 224 | 234 | ||
| 225 | // reset control register | 235 | /* reset configuration register */ |
| 226 | wdt_timer_ctrl(0x00); | ||
| 227 | |||
| 228 | // reset configuration register | ||
| 229 | wdt_timer_conf(0x00); | 236 | wdt_timer_conf(0x00); |
| 230 | 237 | ||
| 231 | // read old (timer units) register | 238 | /* read old (timer units) register */ |
| 232 | old = read_io_cr(0xF1) & 0x7F; | 239 | old = read_io_cr(0xF1) & 0x7F; |
| 233 | if (unit == UNIT_SECOND) old |= 0x80; // set to seconds | 240 | if (unit == UNIT_SECOND) |
| 241 | old |= 0x80; /* set to seconds */ | ||
| 234 | 242 | ||
| 235 | // set the watchdog timer units | 243 | /* set the watchdog timer units */ |
| 236 | wdt_timer_units(old); | 244 | wdt_timer_units(old); |
| 237 | 245 | ||
| 238 | close_io_config(); | 246 | close_io_config(); |
| 239 | spin_unlock(&io_lock); | 247 | spin_unlock(&io_lock); |
| 240 | } | 248 | } |
| 241 | 249 | ||
| @@ -244,23 +252,23 @@ static void wb_smsc_wdt_initialize(void) | |||
| 244 | static void wb_smsc_wdt_shutdown(void) | 252 | static void wb_smsc_wdt_shutdown(void) |
| 245 | { | 253 | { |
| 246 | spin_lock(&io_lock); | 254 | spin_lock(&io_lock); |
| 247 | open_io_config(); | 255 | open_io_config(); |
| 248 | select_io_device(IODEV_NO); | 256 | select_io_device(IODEV_NO); |
| 249 | 257 | ||
| 250 | // disable the watchdog | 258 | /* disable the watchdog */ |
| 251 | gpio_bit13(0x09); | 259 | gpio_bit13(0x09); |
| 252 | gpio_bit12(0x09); | 260 | gpio_bit12(0x09); |
| 253 | 261 | ||
| 254 | // reset watchdog config register | 262 | /* reset watchdog config register */ |
| 255 | wdt_timer_conf(0x00); | 263 | wdt_timer_conf(0x00); |
| 256 | 264 | ||
| 257 | // reset watchdog control register | 265 | /* reset watchdog control register */ |
| 258 | wdt_timer_ctrl(0x00); | 266 | wdt_timer_ctrl(0x00); |
| 259 | 267 | ||
| 260 | // disable timeout | 268 | /* disable timeout */ |
| 261 | wdt_timeout_value(0x00); | 269 | wdt_timeout_value(0x00); |
| 262 | 270 | ||
| 263 | close_io_config(); | 271 | close_io_config(); |
| 264 | spin_unlock(&io_lock); | 272 | spin_unlock(&io_lock); |
| 265 | } | 273 | } |
| 266 | 274 | ||
| @@ -269,16 +277,16 @@ static void wb_smsc_wdt_shutdown(void) | |||
| 269 | static void wb_smsc_wdt_set_timeout(unsigned char new_timeout) | 277 | static void wb_smsc_wdt_set_timeout(unsigned char new_timeout) |
| 270 | { | 278 | { |
| 271 | spin_lock(&io_lock); | 279 | spin_lock(&io_lock); |
| 272 | open_io_config(); | 280 | open_io_config(); |
| 273 | select_io_device(IODEV_NO); | 281 | select_io_device(IODEV_NO); |
| 274 | 282 | ||
| 275 | // set Power LED to blink, if we enable the timeout | 283 | /* set Power LED to blink, if we enable the timeout */ |
| 276 | wdt_timer_ctrl((new_timeout == 0) ? 0x00 : 0x02); | 284 | wdt_timer_ctrl((new_timeout == 0) ? 0x00 : 0x02); |
| 277 | 285 | ||
| 278 | // set timeout value | 286 | /* set timeout value */ |
| 279 | wdt_timeout_value(new_timeout); | 287 | wdt_timeout_value(new_timeout); |
| 280 | 288 | ||
| 281 | close_io_config(); | 289 | close_io_config(); |
| 282 | spin_unlock(&io_lock); | 290 | spin_unlock(&io_lock); |
| 283 | } | 291 | } |
| 284 | 292 | ||
| @@ -286,32 +294,32 @@ static void wb_smsc_wdt_set_timeout(unsigned char new_timeout) | |||
| 286 | 294 | ||
| 287 | static unsigned char wb_smsc_wdt_get_timeout(void) | 295 | static unsigned char wb_smsc_wdt_get_timeout(void) |
| 288 | { | 296 | { |
| 289 | unsigned char set_timeout; | 297 | unsigned char set_timeout; |
| 290 | 298 | ||
| 291 | spin_lock(&io_lock); | 299 | spin_lock(&io_lock); |
| 292 | open_io_config(); | 300 | open_io_config(); |
| 293 | select_io_device(IODEV_NO); | 301 | select_io_device(IODEV_NO); |
| 294 | set_timeout = read_io_cr(0xF2); | 302 | set_timeout = read_io_cr(0xF2); |
| 295 | close_io_config(); | 303 | close_io_config(); |
| 296 | spin_unlock(&io_lock); | 304 | spin_unlock(&io_lock); |
| 297 | 305 | ||
| 298 | return set_timeout; | 306 | return set_timeout; |
| 299 | } | 307 | } |
| 300 | 308 | ||
| 301 | /* disable watchdog */ | 309 | /* disable watchdog */ |
| 302 | 310 | ||
| 303 | static void wb_smsc_wdt_disable(void) | 311 | static void wb_smsc_wdt_disable(void) |
| 304 | { | 312 | { |
| 305 | // set the timeout to 0 to disable the watchdog | 313 | /* set the timeout to 0 to disable the watchdog */ |
| 306 | wb_smsc_wdt_set_timeout(0); | 314 | wb_smsc_wdt_set_timeout(0); |
| 307 | } | 315 | } |
| 308 | 316 | ||
| 309 | /* enable watchdog by setting the current timeout */ | 317 | /* enable watchdog by setting the current timeout */ |
| 310 | 318 | ||
| 311 | static void wb_smsc_wdt_enable(void) | 319 | static void wb_smsc_wdt_enable(void) |
| 312 | { | 320 | { |
| 313 | // set the current timeout... | 321 | /* set the current timeout... */ |
| 314 | wb_smsc_wdt_set_timeout(timeout); | 322 | wb_smsc_wdt_set_timeout(timeout); |
| 315 | } | 323 | } |
| 316 | 324 | ||
| 317 | /* reset the timer */ | 325 | /* reset the timer */ |
| @@ -319,14 +327,14 @@ static void wb_smsc_wdt_enable(void) | |||
| 319 | static void wb_smsc_wdt_reset_timer(void) | 327 | static void wb_smsc_wdt_reset_timer(void) |
| 320 | { | 328 | { |
| 321 | spin_lock(&io_lock); | 329 | spin_lock(&io_lock); |
| 322 | open_io_config(); | 330 | open_io_config(); |
| 323 | select_io_device(IODEV_NO); | 331 | select_io_device(IODEV_NO); |
| 324 | 332 | ||
| 325 | // reset the timer | 333 | /* reset the timer */ |
| 326 | wdt_timeout_value(timeout); | 334 | wdt_timeout_value(timeout); |
| 327 | wdt_timer_conf(0x08); | 335 | wdt_timer_conf(0x08); |
| 328 | 336 | ||
| 329 | close_io_config(); | 337 | close_io_config(); |
| 330 | spin_unlock(&io_lock); | 338 | spin_unlock(&io_lock); |
| 331 | } | 339 | } |
| 332 | 340 | ||
| @@ -355,7 +363,9 @@ static int wb_smsc_wdt_open(struct inode *inode, struct file *file) | |||
| 355 | /* Reload and activate timer */ | 363 | /* Reload and activate timer */ |
| 356 | wb_smsc_wdt_enable(); | 364 | wb_smsc_wdt_enable(); |
| 357 | 365 | ||
| 358 | printk(KERN_INFO MODNAME "Watchdog enabled. Timeout set to %d %s.\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)"); | 366 | printk(KERN_INFO MODNAME |
| 367 | "Watchdog enabled. Timeout set to %d %s.\n", | ||
| 368 | timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)"); | ||
| 359 | 369 | ||
| 360 | return nonseekable_open(inode, file); | 370 | return nonseekable_open(inode, file); |
| 361 | } | 371 | } |
| @@ -367,10 +377,12 @@ static int wb_smsc_wdt_release(struct inode *inode, struct file *file) | |||
| 367 | /* Shut off the timer. */ | 377 | /* Shut off the timer. */ |
| 368 | 378 | ||
| 369 | if (expect_close == 42) { | 379 | if (expect_close == 42) { |
| 370 | wb_smsc_wdt_disable(); | 380 | wb_smsc_wdt_disable(); |
| 371 | printk(KERN_INFO MODNAME "Watchdog disabled, sleeping again...\n"); | 381 | printk(KERN_INFO MODNAME |
| 382 | "Watchdog disabled, sleeping again...\n"); | ||
| 372 | } else { | 383 | } else { |
| 373 | printk(KERN_CRIT MODNAME "Unexpected close, not stopping watchdog!\n"); | 384 | printk(KERN_CRIT MODNAME |
| 385 | "Unexpected close, not stopping watchdog!\n"); | ||
| 374 | wb_smsc_wdt_reset_timer(); | 386 | wb_smsc_wdt_reset_timer(); |
| 375 | } | 387 | } |
| 376 | 388 | ||
| @@ -392,10 +404,11 @@ static ssize_t wb_smsc_wdt_write(struct file *file, const char __user *data, | |||
| 392 | /* reset expect flag */ | 404 | /* reset expect flag */ |
| 393 | expect_close = 0; | 405 | expect_close = 0; |
| 394 | 406 | ||
| 395 | /* scan to see whether or not we got the magic character */ | 407 | /* scan to see whether or not we got the |
| 408 | magic character */ | ||
| 396 | for (i = 0; i != len; i++) { | 409 | for (i = 0; i != len; i++) { |
| 397 | char c; | 410 | char c; |
| 398 | if (get_user(c, data+i)) | 411 | if (get_user(c, data + i)) |
| 399 | return -EFAULT; | 412 | return -EFAULT; |
| 400 | if (c == 'V') | 413 | if (c == 'V') |
| 401 | expect_close = 42; | 414 | expect_close = 42; |
| @@ -410,8 +423,8 @@ static ssize_t wb_smsc_wdt_write(struct file *file, const char __user *data, | |||
| 410 | 423 | ||
| 411 | /* ioctl => control interface */ | 424 | /* ioctl => control interface */ |
| 412 | 425 | ||
| 413 | static int wb_smsc_wdt_ioctl(struct inode *inode, struct file *file, | 426 | static long wb_smsc_wdt_ioctl(struct file *file, |
| 414 | unsigned int cmd, unsigned long arg) | 427 | unsigned int cmd, unsigned long arg) |
| 415 | { | 428 | { |
| 416 | int new_timeout; | 429 | int new_timeout; |
| 417 | 430 | ||
| @@ -420,89 +433,73 @@ static int wb_smsc_wdt_ioctl(struct inode *inode, struct file *file, | |||
| 420 | int __user *i; | 433 | int __user *i; |
| 421 | } uarg; | 434 | } uarg; |
| 422 | 435 | ||
| 423 | static struct watchdog_info ident = { | 436 | static const struct watchdog_info ident = { |
| 424 | .options = WDIOF_KEEPALIVEPING | | 437 | .options = WDIOF_KEEPALIVEPING | |
| 425 | WDIOF_SETTIMEOUT | | 438 | WDIOF_SETTIMEOUT | |
| 426 | WDIOF_MAGICCLOSE, | 439 | WDIOF_MAGICCLOSE, |
| 427 | .firmware_version = 0, | 440 | .firmware_version = 0, |
| 428 | .identity = "SMsC 37B787 Watchdog" | 441 | .identity = "SMsC 37B787 Watchdog", |
| 429 | }; | 442 | }; |
| 430 | 443 | ||
| 431 | uarg.i = (int __user *)arg; | 444 | uarg.i = (int __user *)arg; |
| 432 | 445 | ||
| 433 | switch (cmd) { | 446 | switch (cmd) { |
| 434 | default: | 447 | case WDIOC_GETSUPPORT: |
| 435 | return -ENOTTY; | 448 | return copy_to_user(uarg.ident, &ident, sizeof(ident)) |
| 436 | 449 | ? -EFAULT : 0; | |
| 437 | case WDIOC_GETSUPPORT: | 450 | case WDIOC_GETSTATUS: |
| 438 | return copy_to_user(uarg.ident, &ident, | 451 | return put_user(wb_smsc_wdt_status(), uarg.i); |
| 439 | sizeof(ident)) ? -EFAULT : 0; | 452 | case WDIOC_GETBOOTSTATUS: |
| 440 | 453 | return put_user(0, uarg.i); | |
| 441 | case WDIOC_GETSTATUS: | 454 | case WDIOC_SETOPTIONS: |
| 442 | return put_user(wb_smsc_wdt_status(), uarg.i); | 455 | { |
| 443 | 456 | int options, retval = -EINVAL; | |
| 444 | case WDIOC_GETBOOTSTATUS: | ||
| 445 | return put_user(0, uarg.i); | ||
| 446 | |||
| 447 | case WDIOC_KEEPALIVE: | ||
| 448 | wb_smsc_wdt_reset_timer(); | ||
| 449 | return 0; | ||
| 450 | |||
| 451 | case WDIOC_SETTIMEOUT: | ||
| 452 | if (get_user(new_timeout, uarg.i)) | ||
| 453 | return -EFAULT; | ||
| 454 | |||
| 455 | // the API states this is given in secs | ||
| 456 | if (unit == UNIT_MINUTE) | ||
| 457 | new_timeout /= 60; | ||
| 458 | |||
| 459 | if (new_timeout < 0 || new_timeout > MAX_TIMEOUT) | ||
| 460 | return -EINVAL; | ||
| 461 | |||
| 462 | timeout = new_timeout; | ||
| 463 | wb_smsc_wdt_set_timeout(timeout); | ||
| 464 | |||
| 465 | // fall through and return the new timeout... | ||
| 466 | |||
| 467 | case WDIOC_GETTIMEOUT: | ||
| 468 | |||
| 469 | new_timeout = timeout; | ||
| 470 | |||
| 471 | if (unit == UNIT_MINUTE) | ||
| 472 | new_timeout *= 60; | ||
| 473 | |||
| 474 | return put_user(new_timeout, uarg.i); | ||
| 475 | |||
| 476 | case WDIOC_SETOPTIONS: | ||
| 477 | { | ||
| 478 | int options, retval = -EINVAL; | ||
| 479 | |||
| 480 | if (get_user(options, uarg.i)) | ||
| 481 | return -EFAULT; | ||
| 482 | |||
| 483 | if (options & WDIOS_DISABLECARD) { | ||
| 484 | wb_smsc_wdt_disable(); | ||
| 485 | retval = 0; | ||
| 486 | } | ||
| 487 | 457 | ||
| 488 | if (options & WDIOS_ENABLECARD) { | 458 | if (get_user(options, uarg.i)) |
| 489 | wb_smsc_wdt_enable(); | 459 | return -EFAULT; |
| 490 | retval = 0; | ||
| 491 | } | ||
| 492 | 460 | ||
| 493 | return retval; | 461 | if (options & WDIOS_DISABLECARD) { |
| 462 | wb_smsc_wdt_disable(); | ||
| 463 | retval = 0; | ||
| 464 | } | ||
| 465 | if (options & WDIOS_ENABLECARD) { | ||
| 466 | wb_smsc_wdt_enable(); | ||
| 467 | retval = 0; | ||
| 494 | } | 468 | } |
| 469 | return retval; | ||
| 470 | } | ||
| 471 | case WDIOC_KEEPALIVE: | ||
| 472 | wb_smsc_wdt_reset_timer(); | ||
| 473 | return 0; | ||
| 474 | case WDIOC_SETTIMEOUT: | ||
| 475 | if (get_user(new_timeout, uarg.i)) | ||
| 476 | return -EFAULT; | ||
| 477 | /* the API states this is given in secs */ | ||
| 478 | if (unit == UNIT_MINUTE) | ||
| 479 | new_timeout /= 60; | ||
| 480 | if (new_timeout < 0 || new_timeout > MAX_TIMEOUT) | ||
| 481 | return -EINVAL; | ||
| 482 | timeout = new_timeout; | ||
| 483 | wb_smsc_wdt_set_timeout(timeout); | ||
| 484 | /* fall through and return the new timeout... */ | ||
| 485 | case WDIOC_GETTIMEOUT: | ||
| 486 | new_timeout = timeout; | ||
| 487 | if (unit == UNIT_MINUTE) | ||
| 488 | new_timeout *= 60; | ||
| 489 | return put_user(new_timeout, uarg.i); | ||
| 490 | default: | ||
| 491 | return -ENOTTY; | ||
| 495 | } | 492 | } |
| 496 | } | 493 | } |
| 497 | 494 | ||
| 498 | /* -- Notifier funtions -----------------------------------------*/ | 495 | /* -- Notifier funtions -----------------------------------------*/ |
| 499 | 496 | ||
| 500 | static int wb_smsc_wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) | 497 | static int wb_smsc_wdt_notify_sys(struct notifier_block *this, |
| 498 | unsigned long code, void *unused) | ||
| 501 | { | 499 | { |
| 502 | if (code == SYS_DOWN || code == SYS_HALT) | 500 | if (code == SYS_DOWN || code == SYS_HALT) { |
| 503 | { | 501 | /* set timeout to 0, to avoid possible race-condition */ |
| 504 | // set timeout to 0, to avoid possible race-condition | 502 | timeout = 0; |
| 505 | timeout = 0; | ||
| 506 | wb_smsc_wdt_disable(); | 503 | wb_smsc_wdt_disable(); |
| 507 | } | 504 | } |
| 508 | return NOTIFY_DONE; | 505 | return NOTIFY_DONE; |
| @@ -510,23 +507,20 @@ static int wb_smsc_wdt_notify_sys(struct notifier_block *this, unsigned long cod | |||
| 510 | 507 | ||
| 511 | /* -- Module's structures ---------------------------------------*/ | 508 | /* -- Module's structures ---------------------------------------*/ |
| 512 | 509 | ||
| 513 | static const struct file_operations wb_smsc_wdt_fops = | 510 | static const struct file_operations wb_smsc_wdt_fops = { |
| 514 | { | 511 | .owner = THIS_MODULE, |
| 515 | .owner = THIS_MODULE, | ||
| 516 | .llseek = no_llseek, | 512 | .llseek = no_llseek, |
| 517 | .write = wb_smsc_wdt_write, | 513 | .write = wb_smsc_wdt_write, |
| 518 | .ioctl = wb_smsc_wdt_ioctl, | 514 | .unlocked_ioctl = wb_smsc_wdt_ioctl, |
| 519 | .open = wb_smsc_wdt_open, | 515 | .open = wb_smsc_wdt_open, |
| 520 | .release = wb_smsc_wdt_release, | 516 | .release = wb_smsc_wdt_release, |
| 521 | }; | 517 | }; |
| 522 | 518 | ||
| 523 | static struct notifier_block wb_smsc_wdt_notifier = | 519 | static struct notifier_block wb_smsc_wdt_notifier = { |
| 524 | { | ||
| 525 | .notifier_call = wb_smsc_wdt_notify_sys, | 520 | .notifier_call = wb_smsc_wdt_notify_sys, |
| 526 | }; | 521 | }; |
| 527 | 522 | ||
| 528 | static struct miscdevice wb_smsc_wdt_miscdev = | 523 | static struct miscdevice wb_smsc_wdt_miscdev = { |
| 529 | { | ||
| 530 | .minor = WATCHDOG_MINOR, | 524 | .minor = WATCHDOG_MINOR, |
| 531 | .name = "watchdog", | 525 | .name = "watchdog", |
| 532 | .fops = &wb_smsc_wdt_fops, | 526 | .fops = &wb_smsc_wdt_fops, |
| @@ -540,39 +534,44 @@ static int __init wb_smsc_wdt_init(void) | |||
| 540 | { | 534 | { |
| 541 | int ret; | 535 | int ret; |
| 542 | 536 | ||
| 543 | printk("SMsC 37B787 watchdog component driver " VERSION " initialising...\n"); | 537 | printk(KERN_INFO "SMsC 37B787 watchdog component driver " |
| 538 | VERSION " initialising...\n"); | ||
| 544 | 539 | ||
| 545 | if (!request_region(IOPORT, IOPORT_SIZE, "SMsC 37B787 watchdog")) { | 540 | if (!request_region(IOPORT, IOPORT_SIZE, "SMsC 37B787 watchdog")) { |
| 546 | printk(KERN_ERR MODNAME "Unable to register IO port %#x\n", IOPORT); | 541 | printk(KERN_ERR MODNAME "Unable to register IO port %#x\n", |
| 542 | IOPORT); | ||
| 547 | ret = -EBUSY; | 543 | ret = -EBUSY; |
| 548 | goto out_pnp; | 544 | goto out_pnp; |
| 549 | } | 545 | } |
| 550 | 546 | ||
| 551 | // set new maximum, if it's too big | 547 | /* set new maximum, if it's too big */ |
| 552 | if (timeout > MAX_TIMEOUT) | 548 | if (timeout > MAX_TIMEOUT) |
| 553 | timeout = MAX_TIMEOUT; | 549 | timeout = MAX_TIMEOUT; |
| 554 | 550 | ||
| 555 | // init the watchdog timer | 551 | /* init the watchdog timer */ |
| 556 | wb_smsc_wdt_initialize(); | 552 | wb_smsc_wdt_initialize(); |
| 557 | 553 | ||
| 558 | ret = register_reboot_notifier(&wb_smsc_wdt_notifier); | 554 | ret = register_reboot_notifier(&wb_smsc_wdt_notifier); |
| 559 | if (ret) { | 555 | if (ret) { |
| 560 | printk(KERN_ERR MODNAME "Unable to register reboot notifier err = %d\n", ret); | 556 | printk(KERN_ERR MODNAME |
| 557 | "Unable to register reboot notifier err = %d\n", ret); | ||
| 561 | goto out_io; | 558 | goto out_io; |
| 562 | } | 559 | } |
| 563 | 560 | ||
| 564 | ret = misc_register(&wb_smsc_wdt_miscdev); | 561 | ret = misc_register(&wb_smsc_wdt_miscdev); |
| 565 | if (ret) { | 562 | if (ret) { |
| 566 | printk(KERN_ERR MODNAME "Unable to register miscdev on minor %d\n", WATCHDOG_MINOR); | 563 | printk(KERN_ERR MODNAME |
| 564 | "Unable to register miscdev on minor %d\n", | ||
| 565 | WATCHDOG_MINOR); | ||
| 567 | goto out_rbt; | 566 | goto out_rbt; |
| 568 | } | 567 | } |
| 569 | 568 | ||
| 570 | // output info | 569 | /* output info */ |
| 571 | printk(KERN_INFO MODNAME "Timeout set to %d %s.\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)"); | 570 | printk(KERN_INFO MODNAME "Timeout set to %d %s.\n", |
| 572 | printk(KERN_INFO MODNAME "Watchdog initialized and sleeping (nowayout=%d)...\n", nowayout); | 571 | timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)"); |
| 573 | 572 | printk(KERN_INFO MODNAME | |
| 574 | // ret = 0 | 573 | "Watchdog initialized and sleeping (nowayout=%d)...\n", |
| 575 | 574 | nowayout); | |
| 576 | out_clean: | 575 | out_clean: |
| 577 | return ret; | 576 | return ret; |
| 578 | 577 | ||
| @@ -591,8 +590,7 @@ out_pnp: | |||
| 591 | static void __exit wb_smsc_wdt_exit(void) | 590 | static void __exit wb_smsc_wdt_exit(void) |
| 592 | { | 591 | { |
| 593 | /* Stop the timer before we leave */ | 592 | /* Stop the timer before we leave */ |
| 594 | if (!nowayout) | 593 | if (!nowayout) { |
| 595 | { | ||
| 596 | wb_smsc_wdt_shutdown(); | 594 | wb_smsc_wdt_shutdown(); |
| 597 | printk(KERN_INFO MODNAME "Watchdog disabled.\n"); | 595 | printk(KERN_INFO MODNAME "Watchdog disabled.\n"); |
| 598 | } | 596 | } |
| @@ -601,25 +599,29 @@ static void __exit wb_smsc_wdt_exit(void) | |||
| 601 | unregister_reboot_notifier(&wb_smsc_wdt_notifier); | 599 | unregister_reboot_notifier(&wb_smsc_wdt_notifier); |
| 602 | release_region(IOPORT, IOPORT_SIZE); | 600 | release_region(IOPORT, IOPORT_SIZE); |
| 603 | 601 | ||
| 604 | printk("SMsC 37B787 watchdog component driver removed.\n"); | 602 | printk(KERN_INFO "SMsC 37B787 watchdog component driver removed.\n"); |
| 605 | } | 603 | } |
| 606 | 604 | ||
| 607 | module_init(wb_smsc_wdt_init); | 605 | module_init(wb_smsc_wdt_init); |
| 608 | module_exit(wb_smsc_wdt_exit); | 606 | module_exit(wb_smsc_wdt_exit); |
| 609 | 607 | ||
| 610 | MODULE_AUTHOR("Sven Anders <anders@anduras.de>"); | 608 | MODULE_AUTHOR("Sven Anders <anders@anduras.de>"); |
| 611 | MODULE_DESCRIPTION("Driver for SMsC 37B787 watchdog component (Version " VERSION ")"); | 609 | MODULE_DESCRIPTION("Driver for SMsC 37B787 watchdog component (Version " |
| 610 | VERSION ")"); | ||
| 612 | MODULE_LICENSE("GPL"); | 611 | MODULE_LICENSE("GPL"); |
| 613 | 612 | ||
| 614 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | 613 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); |
| 615 | 614 | ||
| 616 | #ifdef SMSC_SUPPORT_MINUTES | 615 | #ifdef SMSC_SUPPORT_MINUTES |
| 617 | module_param(unit, int, 0); | 616 | module_param(unit, int, 0); |
| 618 | MODULE_PARM_DESC(unit, "set unit to use, 0=seconds or 1=minutes, default is 0"); | 617 | MODULE_PARM_DESC(unit, |
| 618 | "set unit to use, 0=seconds or 1=minutes, default is 0"); | ||
| 619 | #endif | 619 | #endif |
| 620 | 620 | ||
| 621 | module_param(timeout, int, 0); | 621 | module_param(timeout, int, 0); |
| 622 | MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60"); | 622 | MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60"); |
| 623 | 623 | ||
| 624 | module_param(nowayout, int, 0); | 624 | module_param(nowayout, int, 0); |
| 625 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 625 | MODULE_PARM_DESC(nowayout, |
| 626 | "Watchdog cannot be stopped once started (default=" | ||
| 627 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
diff --git a/drivers/watchdog/softdog.c b/drivers/watchdog/softdog.c index 9c3694909243..c650464c5c63 100644 --- a/drivers/watchdog/softdog.c +++ b/drivers/watchdog/softdog.c | |||
| @@ -47,19 +47,22 @@ | |||
| 47 | #include <linux/reboot.h> | 47 | #include <linux/reboot.h> |
| 48 | #include <linux/init.h> | 48 | #include <linux/init.h> |
| 49 | #include <linux/jiffies.h> | 49 | #include <linux/jiffies.h> |
| 50 | 50 | #include <linux/uaccess.h> | |
| 51 | #include <asm/uaccess.h> | ||
| 52 | 51 | ||
| 53 | #define PFX "SoftDog: " | 52 | #define PFX "SoftDog: " |
| 54 | 53 | ||
| 55 | #define TIMER_MARGIN 60 /* Default is 60 seconds */ | 54 | #define TIMER_MARGIN 60 /* Default is 60 seconds */ |
| 56 | static int soft_margin = TIMER_MARGIN; /* in seconds */ | 55 | static int soft_margin = TIMER_MARGIN; /* in seconds */ |
| 57 | module_param(soft_margin, int, 0); | 56 | module_param(soft_margin, int, 0); |
| 58 | MODULE_PARM_DESC(soft_margin, "Watchdog soft_margin in seconds. (0<soft_margin<65536, default=" __MODULE_STRING(TIMER_MARGIN) ")"); | 57 | MODULE_PARM_DESC(soft_margin, |
| 58 | "Watchdog soft_margin in seconds. (0 < soft_margin < 65536, default=" | ||
| 59 | __MODULE_STRING(TIMER_MARGIN) ")"); | ||
| 59 | 60 | ||
| 60 | static int nowayout = WATCHDOG_NOWAYOUT; | 61 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 61 | module_param(nowayout, int, 0); | 62 | module_param(nowayout, int, 0); |
| 62 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 63 | MODULE_PARM_DESC(nowayout, |
| 64 | "Watchdog cannot be stopped once started (default=" | ||
| 65 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 63 | 66 | ||
| 64 | #ifdef ONLY_TESTING | 67 | #ifdef ONLY_TESTING |
| 65 | static int soft_noboot = 1; | 68 | static int soft_noboot = 1; |
| @@ -93,8 +96,7 @@ static void watchdog_fire(unsigned long data) | |||
| 93 | 96 | ||
| 94 | if (soft_noboot) | 97 | if (soft_noboot) |
| 95 | printk(KERN_CRIT PFX "Triggered - Reboot ignored.\n"); | 98 | printk(KERN_CRIT PFX "Triggered - Reboot ignored.\n"); |
| 96 | else | 99 | else { |
| 97 | { | ||
| 98 | printk(KERN_CRIT PFX "Initiating system reboot.\n"); | 100 | printk(KERN_CRIT PFX "Initiating system reboot.\n"); |
| 99 | emergency_restart(); | 101 | emergency_restart(); |
| 100 | printk(KERN_CRIT PFX "Reboot didn't ?????\n"); | 102 | printk(KERN_CRIT PFX "Reboot didn't ?????\n"); |
| @@ -153,7 +155,8 @@ static int softdog_release(struct inode *inode, struct file *file) | |||
| 153 | softdog_stop(); | 155 | softdog_stop(); |
| 154 | module_put(THIS_MODULE); | 156 | module_put(THIS_MODULE); |
| 155 | } else { | 157 | } else { |
| 156 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 158 | printk(KERN_CRIT PFX |
| 159 | "Unexpected close, not stopping watchdog!\n"); | ||
| 157 | set_bit(0, &orphan_timer); | 160 | set_bit(0, &orphan_timer); |
| 158 | softdog_keepalive(); | 161 | softdog_keepalive(); |
| 159 | } | 162 | } |
| @@ -162,12 +165,13 @@ static int softdog_release(struct inode *inode, struct file *file) | |||
| 162 | return 0; | 165 | return 0; |
| 163 | } | 166 | } |
| 164 | 167 | ||
| 165 | static ssize_t softdog_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) | 168 | static ssize_t softdog_write(struct file *file, const char __user *data, |
| 169 | size_t len, loff_t *ppos) | ||
| 166 | { | 170 | { |
| 167 | /* | 171 | /* |
| 168 | * Refresh the timer. | 172 | * Refresh the timer. |
| 169 | */ | 173 | */ |
| 170 | if(len) { | 174 | if (len) { |
| 171 | if (!nowayout) { | 175 | if (!nowayout) { |
| 172 | size_t i; | 176 | size_t i; |
| 173 | 177 | ||
| @@ -188,13 +192,13 @@ static ssize_t softdog_write(struct file *file, const char __user *data, size_t | |||
| 188 | return len; | 192 | return len; |
| 189 | } | 193 | } |
| 190 | 194 | ||
| 191 | static int softdog_ioctl(struct inode *inode, struct file *file, | 195 | static long softdog_ioctl(struct file *file, unsigned int cmd, |
| 192 | unsigned int cmd, unsigned long arg) | 196 | unsigned long arg) |
| 193 | { | 197 | { |
| 194 | void __user *argp = (void __user *)arg; | 198 | void __user *argp = (void __user *)arg; |
| 195 | int __user *p = argp; | 199 | int __user *p = argp; |
| 196 | int new_margin; | 200 | int new_margin; |
| 197 | static struct watchdog_info ident = { | 201 | static const struct watchdog_info ident = { |
| 198 | .options = WDIOF_SETTIMEOUT | | 202 | .options = WDIOF_SETTIMEOUT | |
| 199 | WDIOF_KEEPALIVEPING | | 203 | WDIOF_KEEPALIVEPING | |
| 200 | WDIOF_MAGICCLOSE, | 204 | WDIOF_MAGICCLOSE, |
| @@ -202,26 +206,25 @@ static int softdog_ioctl(struct inode *inode, struct file *file, | |||
| 202 | .identity = "Software Watchdog", | 206 | .identity = "Software Watchdog", |
| 203 | }; | 207 | }; |
| 204 | switch (cmd) { | 208 | switch (cmd) { |
| 205 | default: | 209 | case WDIOC_GETSUPPORT: |
| 206 | return -ENOTTY; | 210 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; |
| 207 | case WDIOC_GETSUPPORT: | 211 | case WDIOC_GETSTATUS: |
| 208 | return copy_to_user(argp, &ident, | 212 | case WDIOC_GETBOOTSTATUS: |
| 209 | sizeof(ident)) ? -EFAULT : 0; | 213 | return put_user(0, p); |
| 210 | case WDIOC_GETSTATUS: | 214 | case WDIOC_KEEPALIVE: |
| 211 | case WDIOC_GETBOOTSTATUS: | 215 | softdog_keepalive(); |
| 212 | return put_user(0, p); | 216 | return 0; |
| 213 | case WDIOC_KEEPALIVE: | 217 | case WDIOC_SETTIMEOUT: |
| 214 | softdog_keepalive(); | 218 | if (get_user(new_margin, p)) |
| 215 | return 0; | 219 | return -EFAULT; |
| 216 | case WDIOC_SETTIMEOUT: | 220 | if (softdog_set_heartbeat(new_margin)) |
| 217 | if (get_user(new_margin, p)) | 221 | return -EINVAL; |
| 218 | return -EFAULT; | 222 | softdog_keepalive(); |
| 219 | if (softdog_set_heartbeat(new_margin)) | 223 | /* Fall */ |
| 220 | return -EINVAL; | 224 | case WDIOC_GETTIMEOUT: |
| 221 | softdog_keepalive(); | 225 | return put_user(soft_margin, p); |
| 222 | /* Fall */ | 226 | default: |
| 223 | case WDIOC_GETTIMEOUT: | 227 | return -ENOTTY; |
| 224 | return put_user(soft_margin, p); | ||
| 225 | } | 228 | } |
| 226 | } | 229 | } |
| 227 | 230 | ||
| @@ -232,10 +235,9 @@ static int softdog_ioctl(struct inode *inode, struct file *file, | |||
| 232 | static int softdog_notify_sys(struct notifier_block *this, unsigned long code, | 235 | static int softdog_notify_sys(struct notifier_block *this, unsigned long code, |
| 233 | void *unused) | 236 | void *unused) |
| 234 | { | 237 | { |
| 235 | if(code==SYS_DOWN || code==SYS_HALT) { | 238 | if (code == SYS_DOWN || code == SYS_HALT) |
| 236 | /* Turn the WDT off */ | 239 | /* Turn the WDT off */ |
| 237 | softdog_stop(); | 240 | softdog_stop(); |
| 238 | } | ||
| 239 | return NOTIFY_DONE; | 241 | return NOTIFY_DONE; |
| 240 | } | 242 | } |
| 241 | 243 | ||
| @@ -247,7 +249,7 @@ static const struct file_operations softdog_fops = { | |||
| 247 | .owner = THIS_MODULE, | 249 | .owner = THIS_MODULE, |
| 248 | .llseek = no_llseek, | 250 | .llseek = no_llseek, |
| 249 | .write = softdog_write, | 251 | .write = softdog_write, |
| 250 | .ioctl = softdog_ioctl, | 252 | .unlocked_ioctl = softdog_ioctl, |
| 251 | .open = softdog_open, | 253 | .open = softdog_open, |
| 252 | .release = softdog_release, | 254 | .release = softdog_release, |
| 253 | }; | 255 | }; |
| @@ -268,24 +270,27 @@ static int __init watchdog_init(void) | |||
| 268 | { | 270 | { |
| 269 | int ret; | 271 | int ret; |
| 270 | 272 | ||
| 271 | /* Check that the soft_margin value is within it's range ; if not reset to the default */ | 273 | /* Check that the soft_margin value is within it's range; |
| 274 | if not reset to the default */ | ||
| 272 | if (softdog_set_heartbeat(soft_margin)) { | 275 | if (softdog_set_heartbeat(soft_margin)) { |
| 273 | softdog_set_heartbeat(TIMER_MARGIN); | 276 | softdog_set_heartbeat(TIMER_MARGIN); |
| 274 | printk(KERN_INFO PFX "soft_margin value must be 0<soft_margin<65536, using %d\n", | 277 | printk(KERN_INFO PFX |
| 278 | "soft_margin must be 0 < soft_margin < 65536, using %d\n", | ||
| 275 | TIMER_MARGIN); | 279 | TIMER_MARGIN); |
| 276 | } | 280 | } |
| 277 | 281 | ||
| 278 | ret = register_reboot_notifier(&softdog_notifier); | 282 | ret = register_reboot_notifier(&softdog_notifier); |
| 279 | if (ret) { | 283 | if (ret) { |
| 280 | printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 284 | printk(KERN_ERR PFX |
| 281 | ret); | 285 | "cannot register reboot notifier (err=%d)\n", ret); |
| 282 | return ret; | 286 | return ret; |
| 283 | } | 287 | } |
| 284 | 288 | ||
| 285 | ret = misc_register(&softdog_miscdev); | 289 | ret = misc_register(&softdog_miscdev); |
| 286 | if (ret) { | 290 | if (ret) { |
| 287 | printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 291 | printk(KERN_ERR PFX |
| 288 | WATCHDOG_MINOR, ret); | 292 | "cannot register miscdev on minor=%d (err=%d)\n", |
| 293 | WATCHDOG_MINOR, ret); | ||
| 289 | unregister_reboot_notifier(&softdog_notifier); | 294 | unregister_reboot_notifier(&softdog_notifier); |
| 290 | return ret; | 295 | return ret; |
| 291 | } | 296 | } |
diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c index 57cefef27ce3..dbbc018a5f46 100644 --- a/drivers/watchdog/txx9wdt.c +++ b/drivers/watchdog/txx9wdt.c | |||
| @@ -45,27 +45,34 @@ static unsigned long txx9wdt_alive; | |||
| 45 | static int expect_close; | 45 | static int expect_close; |
| 46 | static struct txx9_tmr_reg __iomem *txx9wdt_reg; | 46 | static struct txx9_tmr_reg __iomem *txx9wdt_reg; |
| 47 | static struct clk *txx9_imclk; | 47 | static struct clk *txx9_imclk; |
| 48 | static DECLARE_LOCK(txx9_lock); | ||
| 48 | 49 | ||
| 49 | static void txx9wdt_ping(void) | 50 | static void txx9wdt_ping(void) |
| 50 | { | 51 | { |
| 52 | spin_lock(&txx9_lock); | ||
| 51 | __raw_writel(TXx9_TMWTMR_TWIE | TXx9_TMWTMR_TWC, &txx9wdt_reg->wtmr); | 53 | __raw_writel(TXx9_TMWTMR_TWIE | TXx9_TMWTMR_TWC, &txx9wdt_reg->wtmr); |
| 54 | spin_unlock(&txx9_lock); | ||
| 52 | } | 55 | } |
| 53 | 56 | ||
| 54 | static void txx9wdt_start(void) | 57 | static void txx9wdt_start(void) |
| 55 | { | 58 | { |
| 59 | spin_lock(&txx9_lock); | ||
| 56 | __raw_writel(WD_TIMER_CLK * timeout, &txx9wdt_reg->cpra); | 60 | __raw_writel(WD_TIMER_CLK * timeout, &txx9wdt_reg->cpra); |
| 57 | __raw_writel(WD_TIMER_CCD, &txx9wdt_reg->ccdr); | 61 | __raw_writel(WD_TIMER_CCD, &txx9wdt_reg->ccdr); |
| 58 | __raw_writel(0, &txx9wdt_reg->tisr); /* clear pending interrupt */ | 62 | __raw_writel(0, &txx9wdt_reg->tisr); /* clear pending interrupt */ |
| 59 | __raw_writel(TXx9_TMTCR_TCE | TXx9_TMTCR_CCDE | TXx9_TMTCR_TMODE_WDOG, | 63 | __raw_writel(TXx9_TMTCR_TCE | TXx9_TMTCR_CCDE | TXx9_TMTCR_TMODE_WDOG, |
| 60 | &txx9wdt_reg->tcr); | 64 | &txx9wdt_reg->tcr); |
| 61 | __raw_writel(TXx9_TMWTMR_TWIE | TXx9_TMWTMR_TWC, &txx9wdt_reg->wtmr); | 65 | __raw_writel(TXx9_TMWTMR_TWIE | TXx9_TMWTMR_TWC, &txx9wdt_reg->wtmr); |
| 66 | spin_unlock(&txx9_lock); | ||
| 62 | } | 67 | } |
| 63 | 68 | ||
| 64 | static void txx9wdt_stop(void) | 69 | static void txx9wdt_stop(void) |
| 65 | { | 70 | { |
| 71 | spin_lock(&txx9_lock); | ||
| 66 | __raw_writel(TXx9_TMWTMR_WDIS, &txx9wdt_reg->wtmr); | 72 | __raw_writel(TXx9_TMWTMR_WDIS, &txx9wdt_reg->wtmr); |
| 67 | __raw_writel(__raw_readl(&txx9wdt_reg->tcr) & ~TXx9_TMTCR_TCE, | 73 | __raw_writel(__raw_readl(&txx9wdt_reg->tcr) & ~TXx9_TMTCR_TCE, |
| 68 | &txx9wdt_reg->tcr); | 74 | &txx9wdt_reg->tcr); |
| 75 | spin_unlock(&txx9_lock); | ||
| 69 | } | 76 | } |
| 70 | 77 | ||
| 71 | static int txx9wdt_open(struct inode *inode, struct file *file) | 78 | static int txx9wdt_open(struct inode *inode, struct file *file) |
| @@ -120,13 +127,13 @@ static ssize_t txx9wdt_write(struct file *file, const char __user *data, | |||
| 120 | return len; | 127 | return len; |
| 121 | } | 128 | } |
| 122 | 129 | ||
| 123 | static int txx9wdt_ioctl(struct inode *inode, struct file *file, | 130 | static long txx9wdt_ioctl(struct file *file, unsigned int cmd, |
| 124 | unsigned int cmd, unsigned long arg) | 131 | unsigned long arg) |
| 125 | { | 132 | { |
| 126 | void __user *argp = (void __user *)arg; | 133 | void __user *argp = (void __user *)arg; |
| 127 | int __user *p = argp; | 134 | int __user *p = argp; |
| 128 | int new_timeout; | 135 | int new_timeout; |
| 129 | static struct watchdog_info ident = { | 136 | static const struct watchdog_info ident = { |
| 130 | .options = WDIOF_SETTIMEOUT | | 137 | .options = WDIOF_SETTIMEOUT | |
| 131 | WDIOF_KEEPALIVEPING | | 138 | WDIOF_KEEPALIVEPING | |
| 132 | WDIOF_MAGICCLOSE, | 139 | WDIOF_MAGICCLOSE, |
| @@ -135,8 +142,6 @@ static int txx9wdt_ioctl(struct inode *inode, struct file *file, | |||
| 135 | }; | 142 | }; |
| 136 | 143 | ||
| 137 | switch (cmd) { | 144 | switch (cmd) { |
| 138 | default: | ||
| 139 | return -ENOTTY; | ||
| 140 | case WDIOC_GETSUPPORT: | 145 | case WDIOC_GETSUPPORT: |
| 141 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; | 146 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; |
| 142 | case WDIOC_GETSTATUS: | 147 | case WDIOC_GETSTATUS: |
| @@ -156,6 +161,8 @@ static int txx9wdt_ioctl(struct inode *inode, struct file *file, | |||
| 156 | /* Fall */ | 161 | /* Fall */ |
| 157 | case WDIOC_GETTIMEOUT: | 162 | case WDIOC_GETTIMEOUT: |
| 158 | return put_user(timeout, p); | 163 | return put_user(timeout, p); |
| 164 | default: | ||
| 165 | return -ENOTTY; | ||
| 159 | } | 166 | } |
| 160 | } | 167 | } |
| 161 | 168 | ||
| @@ -168,22 +175,22 @@ static int txx9wdt_notify_sys(struct notifier_block *this, unsigned long code, | |||
| 168 | } | 175 | } |
| 169 | 176 | ||
| 170 | static const struct file_operations txx9wdt_fops = { | 177 | static const struct file_operations txx9wdt_fops = { |
| 171 | .owner = THIS_MODULE, | 178 | .owner = THIS_MODULE, |
| 172 | .llseek = no_llseek, | 179 | .llseek = no_llseek, |
| 173 | .write = txx9wdt_write, | 180 | .write = txx9wdt_write, |
| 174 | .ioctl = txx9wdt_ioctl, | 181 | .unlocked_ioctl = txx9wdt_ioctl, |
| 175 | .open = txx9wdt_open, | 182 | .open = txx9wdt_open, |
| 176 | .release = txx9wdt_release, | 183 | .release = txx9wdt_release, |
| 177 | }; | 184 | }; |
| 178 | 185 | ||
| 179 | static struct miscdevice txx9wdt_miscdev = { | 186 | static struct miscdevice txx9wdt_miscdev = { |
| 180 | .minor = WATCHDOG_MINOR, | 187 | .minor = WATCHDOG_MINOR, |
| 181 | .name = "watchdog", | 188 | .name = "watchdog", |
| 182 | .fops = &txx9wdt_fops, | 189 | .fops = &txx9wdt_fops, |
| 183 | }; | 190 | }; |
| 184 | 191 | ||
| 185 | static struct notifier_block txx9wdt_notifier = { | 192 | static struct notifier_block txx9wdt_notifier = { |
| 186 | .notifier_call = txx9wdt_notify_sys | 193 | .notifier_call = txx9wdt_notify_sys, |
| 187 | }; | 194 | }; |
| 188 | 195 | ||
| 189 | static int __init txx9wdt_probe(struct platform_device *dev) | 196 | static int __init txx9wdt_probe(struct platform_device *dev) |
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c index 386492821fc2..69396adaa5c3 100644 --- a/drivers/watchdog/w83627hf_wdt.c +++ b/drivers/watchdog/w83627hf_wdt.c | |||
| @@ -37,9 +37,9 @@ | |||
| 37 | #include <linux/reboot.h> | 37 | #include <linux/reboot.h> |
| 38 | #include <linux/init.h> | 38 | #include <linux/init.h> |
| 39 | #include <linux/spinlock.h> | 39 | #include <linux/spinlock.h> |
| 40 | #include <linux/io.h> | ||
| 41 | #include <linux/uaccess.h> | ||
| 40 | 42 | ||
| 41 | #include <asm/io.h> | ||
| 42 | #include <asm/uaccess.h> | ||
| 43 | #include <asm/system.h> | 43 | #include <asm/system.h> |
| 44 | 44 | ||
| 45 | #define WATCHDOG_NAME "w83627hf/thf/hg WDT" | 45 | #define WATCHDOG_NAME "w83627hf/thf/hg WDT" |
| @@ -57,22 +57,26 @@ MODULE_PARM_DESC(wdt_io, "w83627hf/thf WDT io port (default 0x2E)"); | |||
| 57 | 57 | ||
| 58 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ | 58 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ |
| 59 | module_param(timeout, int, 0); | 59 | module_param(timeout, int, 0); |
| 60 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) "."); | 60 | MODULE_PARM_DESC(timeout, |
| 61 | "Watchdog timeout in seconds. 1 <= timeout <= 255, default=" | ||
| 62 | __MODULE_STRING(WATCHDOG_TIMEOUT) "."); | ||
| 61 | 63 | ||
| 62 | static int nowayout = WATCHDOG_NOWAYOUT; | 64 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 63 | module_param(nowayout, int, 0); | 65 | module_param(nowayout, int, 0); |
| 64 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 66 | MODULE_PARM_DESC(nowayout, |
| 67 | "Watchdog cannot be stopped once started (default=" | ||
| 68 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 65 | 69 | ||
| 66 | /* | 70 | /* |
| 67 | * Kernel methods. | 71 | * Kernel methods. |
| 68 | */ | 72 | */ |
| 69 | 73 | ||
| 70 | #define WDT_EFER (wdt_io+0) /* Extended Function Enable Registers */ | 74 | #define WDT_EFER (wdt_io+0) /* Extended Function Enable Registers */ |
| 71 | #define WDT_EFIR (wdt_io+0) /* Extended Function Index Register (same as EFER) */ | 75 | #define WDT_EFIR (wdt_io+0) /* Extended Function Index Register |
| 76 | (same as EFER) */ | ||
| 72 | #define WDT_EFDR (WDT_EFIR+1) /* Extended Function Data Register */ | 77 | #define WDT_EFDR (WDT_EFIR+1) /* Extended Function Data Register */ |
| 73 | 78 | ||
| 74 | static void | 79 | static void w83627hf_select_wd_register(void) |
| 75 | w83627hf_select_wd_register(void) | ||
| 76 | { | 80 | { |
| 77 | unsigned char c; | 81 | unsigned char c; |
| 78 | outb_p(0x87, WDT_EFER); /* Enter extended function mode */ | 82 | outb_p(0x87, WDT_EFER); /* Enter extended function mode */ |
| @@ -93,43 +97,45 @@ w83627hf_select_wd_register(void) | |||
| 93 | outb_p(0x01, WDT_EFDR); /* set bit 0 to activate GPIO2 */ | 97 | outb_p(0x01, WDT_EFDR); /* set bit 0 to activate GPIO2 */ |
| 94 | } | 98 | } |
| 95 | 99 | ||
| 96 | static void | 100 | static void w83627hf_unselect_wd_register(void) |
| 97 | w83627hf_unselect_wd_register(void) | ||
| 98 | { | 101 | { |
| 99 | outb_p(0xAA, WDT_EFER); /* Leave extended function mode */ | 102 | outb_p(0xAA, WDT_EFER); /* Leave extended function mode */ |
| 100 | } | 103 | } |
| 101 | 104 | ||
| 102 | /* tyan motherboards seem to set F5 to 0x4C ? | 105 | /* tyan motherboards seem to set F5 to 0x4C ? |
| 103 | * So explicitly init to appropriate value. */ | 106 | * So explicitly init to appropriate value. */ |
| 104 | static void | 107 | |
| 105 | w83627hf_init(void) | 108 | static void w83627hf_init(void) |
| 106 | { | 109 | { |
| 107 | unsigned char t; | 110 | unsigned char t; |
| 108 | 111 | ||
| 109 | w83627hf_select_wd_register(); | 112 | w83627hf_select_wd_register(); |
| 110 | 113 | ||
| 111 | outb_p(0xF6, WDT_EFER); /* Select CRF6 */ | 114 | outb_p(0xF6, WDT_EFER); /* Select CRF6 */ |
| 112 | t=inb_p(WDT_EFDR); /* read CRF6 */ | 115 | t = inb_p(WDT_EFDR); /* read CRF6 */ |
| 113 | if (t != 0) { | 116 | if (t != 0) { |
| 114 | printk (KERN_INFO PFX "Watchdog already running. Resetting timeout to %d sec\n", timeout); | 117 | printk(KERN_INFO PFX |
| 118 | "Watchdog already running. Resetting timeout to %d sec\n", | ||
| 119 | timeout); | ||
| 115 | outb_p(timeout, WDT_EFDR); /* Write back to CRF6 */ | 120 | outb_p(timeout, WDT_EFDR); /* Write back to CRF6 */ |
| 116 | } | 121 | } |
| 117 | 122 | ||
| 118 | outb_p(0xF5, WDT_EFER); /* Select CRF5 */ | 123 | outb_p(0xF5, WDT_EFER); /* Select CRF5 */ |
| 119 | t=inb_p(WDT_EFDR); /* read CRF5 */ | 124 | t = inb_p(WDT_EFDR); /* read CRF5 */ |
| 120 | t&=~0x0C; /* set second mode & disable keyboard turning off watchdog */ | 125 | t &= ~0x0C; /* set second mode & disable keyboard |
| 126 | turning off watchdog */ | ||
| 121 | outb_p(t, WDT_EFDR); /* Write back to CRF5 */ | 127 | outb_p(t, WDT_EFDR); /* Write back to CRF5 */ |
| 122 | 128 | ||
| 123 | outb_p(0xF7, WDT_EFER); /* Select CRF7 */ | 129 | outb_p(0xF7, WDT_EFER); /* Select CRF7 */ |
| 124 | t=inb_p(WDT_EFDR); /* read CRF7 */ | 130 | t = inb_p(WDT_EFDR); /* read CRF7 */ |
| 125 | t&=~0xC0; /* disable keyboard & mouse turning off watchdog */ | 131 | t &= ~0xC0; /* disable keyboard & mouse turning off |
| 132 | watchdog */ | ||
| 126 | outb_p(t, WDT_EFDR); /* Write back to CRF7 */ | 133 | outb_p(t, WDT_EFDR); /* Write back to CRF7 */ |
| 127 | 134 | ||
| 128 | w83627hf_unselect_wd_register(); | 135 | w83627hf_unselect_wd_register(); |
| 129 | } | 136 | } |
| 130 | 137 | ||
| 131 | static void | 138 | static void wdt_ctrl(int timeout) |
| 132 | wdt_ctrl(int timeout) | ||
| 133 | { | 139 | { |
| 134 | spin_lock(&io_lock); | 140 | spin_lock(&io_lock); |
| 135 | 141 | ||
| @@ -143,32 +149,28 @@ wdt_ctrl(int timeout) | |||
| 143 | spin_unlock(&io_lock); | 149 | spin_unlock(&io_lock); |
| 144 | } | 150 | } |
| 145 | 151 | ||
| 146 | static int | 152 | static int wdt_ping(void) |
| 147 | wdt_ping(void) | ||
| 148 | { | 153 | { |
| 149 | wdt_ctrl(timeout); | 154 | wdt_ctrl(timeout); |
| 150 | return 0; | 155 | return 0; |
| 151 | } | 156 | } |
| 152 | 157 | ||
| 153 | static int | 158 | static int wdt_disable(void) |
| 154 | wdt_disable(void) | ||
| 155 | { | 159 | { |
| 156 | wdt_ctrl(0); | 160 | wdt_ctrl(0); |
| 157 | return 0; | 161 | return 0; |
| 158 | } | 162 | } |
| 159 | 163 | ||
| 160 | static int | 164 | static int wdt_set_heartbeat(int t) |
| 161 | wdt_set_heartbeat(int t) | ||
| 162 | { | 165 | { |
| 163 | if ((t < 1) || (t > 255)) | 166 | if (t < 1 || t > 255) |
| 164 | return -EINVAL; | 167 | return -EINVAL; |
| 165 | |||
| 166 | timeout = t; | 168 | timeout = t; |
| 167 | return 0; | 169 | return 0; |
| 168 | } | 170 | } |
| 169 | 171 | ||
| 170 | static ssize_t | 172 | static ssize_t wdt_write(struct file *file, const char __user *buf, |
| 171 | wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | 173 | size_t count, loff_t *ppos) |
| 172 | { | 174 | { |
| 173 | if (count) { | 175 | if (count) { |
| 174 | if (!nowayout) { | 176 | if (!nowayout) { |
| @@ -178,7 +180,7 @@ wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
| 178 | 180 | ||
| 179 | for (i = 0; i != count; i++) { | 181 | for (i = 0; i != count; i++) { |
| 180 | char c; | 182 | char c; |
| 181 | if (get_user(c, buf+i)) | 183 | if (get_user(c, buf + i)) |
| 182 | return -EFAULT; | 184 | return -EFAULT; |
| 183 | if (c == 'V') | 185 | if (c == 'V') |
| 184 | expect_close = 42; | 186 | expect_close = 42; |
| @@ -189,72 +191,61 @@ wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
| 189 | return count; | 191 | return count; |
| 190 | } | 192 | } |
| 191 | 193 | ||
| 192 | static int | 194 | static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 193 | wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | ||
| 194 | unsigned long arg) | ||
| 195 | { | 195 | { |
| 196 | void __user *argp = (void __user *)arg; | 196 | void __user *argp = (void __user *)arg; |
| 197 | int __user *p = argp; | 197 | int __user *p = argp; |
| 198 | int new_timeout; | 198 | int new_timeout; |
| 199 | static struct watchdog_info ident = { | 199 | static struct watchdog_info ident = { |
| 200 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, | 200 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | |
| 201 | WDIOF_MAGICCLOSE, | ||
| 201 | .firmware_version = 1, | 202 | .firmware_version = 1, |
| 202 | .identity = "W83627HF WDT", | 203 | .identity = "W83627HF WDT", |
| 203 | }; | 204 | }; |
| 204 | 205 | ||
| 205 | switch (cmd) { | 206 | switch (cmd) { |
| 206 | case WDIOC_GETSUPPORT: | 207 | case WDIOC_GETSUPPORT: |
| 207 | if (copy_to_user(argp, &ident, sizeof(ident))) | 208 | if (copy_to_user(argp, &ident, sizeof(ident))) |
| 208 | return -EFAULT; | 209 | return -EFAULT; |
| 209 | break; | 210 | break; |
| 210 | |||
| 211 | case WDIOC_GETSTATUS: | 211 | case WDIOC_GETSTATUS: |
| 212 | case WDIOC_GETBOOTSTATUS: | 212 | case WDIOC_GETBOOTSTATUS: |
| 213 | return put_user(0, p); | 213 | return put_user(0, p); |
| 214 | |||
| 215 | case WDIOC_KEEPALIVE: | ||
| 216 | wdt_ping(); | ||
| 217 | break; | ||
| 218 | |||
| 219 | case WDIOC_SETTIMEOUT: | ||
| 220 | if (get_user(new_timeout, p)) | ||
| 221 | return -EFAULT; | ||
| 222 | if (wdt_set_heartbeat(new_timeout)) | ||
| 223 | return -EINVAL; | ||
| 224 | wdt_ping(); | ||
| 225 | /* Fall */ | ||
| 226 | |||
| 227 | case WDIOC_GETTIMEOUT: | ||
| 228 | return put_user(timeout, p); | ||
| 229 | |||
| 230 | case WDIOC_SETOPTIONS: | 214 | case WDIOC_SETOPTIONS: |
| 231 | { | 215 | { |
| 232 | int options, retval = -EINVAL; | 216 | int options, retval = -EINVAL; |
| 233 | |||
| 234 | if (get_user(options, p)) | ||
| 235 | return -EFAULT; | ||
| 236 | |||
| 237 | if (options & WDIOS_DISABLECARD) { | ||
| 238 | wdt_disable(); | ||
| 239 | retval = 0; | ||
| 240 | } | ||
| 241 | |||
| 242 | if (options & WDIOS_ENABLECARD) { | ||
| 243 | wdt_ping(); | ||
| 244 | retval = 0; | ||
| 245 | } | ||
| 246 | 217 | ||
| 247 | return retval; | 218 | if (get_user(options, p)) |
| 219 | return -EFAULT; | ||
| 220 | if (options & WDIOS_DISABLECARD) { | ||
| 221 | wdt_disable(); | ||
| 222 | retval = 0; | ||
| 223 | } | ||
| 224 | if (options & WDIOS_ENABLECARD) { | ||
| 225 | wdt_ping(); | ||
| 226 | retval = 0; | ||
| 227 | } | ||
| 228 | return retval; | ||
| 248 | } | 229 | } |
| 249 | 230 | case WDIOC_KEEPALIVE: | |
| 231 | wdt_ping(); | ||
| 232 | break; | ||
| 233 | case WDIOC_SETTIMEOUT: | ||
| 234 | if (get_user(new_timeout, p)) | ||
| 235 | return -EFAULT; | ||
| 236 | if (wdt_set_heartbeat(new_timeout)) | ||
| 237 | return -EINVAL; | ||
| 238 | wdt_ping(); | ||
| 239 | /* Fall */ | ||
| 240 | case WDIOC_GETTIMEOUT: | ||
| 241 | return put_user(timeout, p); | ||
| 250 | default: | 242 | default: |
| 251 | return -ENOTTY; | 243 | return -ENOTTY; |
| 252 | } | 244 | } |
| 253 | return 0; | 245 | return 0; |
| 254 | } | 246 | } |
| 255 | 247 | ||
| 256 | static int | 248 | static int wdt_open(struct inode *inode, struct file *file) |
| 257 | wdt_open(struct inode *inode, struct file *file) | ||
| 258 | { | 249 | { |
| 259 | if (test_and_set_bit(0, &wdt_is_open)) | 250 | if (test_and_set_bit(0, &wdt_is_open)) |
| 260 | return -EBUSY; | 251 | return -EBUSY; |
| @@ -266,13 +257,13 @@ wdt_open(struct inode *inode, struct file *file) | |||
| 266 | return nonseekable_open(inode, file); | 257 | return nonseekable_open(inode, file); |
| 267 | } | 258 | } |
| 268 | 259 | ||
| 269 | static int | 260 | static int wdt_close(struct inode *inode, struct file *file) |
| 270 | wdt_close(struct inode *inode, struct file *file) | ||
| 271 | { | 261 | { |
| 272 | if (expect_close == 42) { | 262 | if (expect_close == 42) |
| 273 | wdt_disable(); | 263 | wdt_disable(); |
| 274 | } else { | 264 | else { |
| 275 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 265 | printk(KERN_CRIT PFX |
| 266 | "Unexpected close, not stopping watchdog!\n"); | ||
| 276 | wdt_ping(); | 267 | wdt_ping(); |
| 277 | } | 268 | } |
| 278 | expect_close = 0; | 269 | expect_close = 0; |
| @@ -284,14 +275,12 @@ wdt_close(struct inode *inode, struct file *file) | |||
| 284 | * Notifier for system down | 275 | * Notifier for system down |
| 285 | */ | 276 | */ |
| 286 | 277 | ||
| 287 | static int | 278 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, |
| 288 | wdt_notify_sys(struct notifier_block *this, unsigned long code, | ||
| 289 | void *unused) | 279 | void *unused) |
| 290 | { | 280 | { |
| 291 | if (code == SYS_DOWN || code == SYS_HALT) { | 281 | if (code == SYS_DOWN || code == SYS_HALT) |
| 292 | /* Turn the WDT off */ | 282 | wdt_disable(); /* Turn the WDT off */ |
| 293 | wdt_disable(); | 283 | |
| 294 | } | ||
| 295 | return NOTIFY_DONE; | 284 | return NOTIFY_DONE; |
| 296 | } | 285 | } |
| 297 | 286 | ||
| @@ -303,7 +292,7 @@ static const struct file_operations wdt_fops = { | |||
| 303 | .owner = THIS_MODULE, | 292 | .owner = THIS_MODULE, |
| 304 | .llseek = no_llseek, | 293 | .llseek = no_llseek, |
| 305 | .write = wdt_write, | 294 | .write = wdt_write, |
| 306 | .ioctl = wdt_ioctl, | 295 | .unlocked_ioctl = wdt_ioctl, |
| 307 | .open = wdt_open, | 296 | .open = wdt_open, |
| 308 | .release = wdt_close, | 297 | .release = wdt_close, |
| 309 | }; | 298 | }; |
| @@ -323,8 +312,7 @@ static struct notifier_block wdt_notifier = { | |||
| 323 | .notifier_call = wdt_notify_sys, | 312 | .notifier_call = wdt_notify_sys, |
| 324 | }; | 313 | }; |
| 325 | 314 | ||
| 326 | static int __init | 315 | static int __init wdt_init(void) |
| 327 | wdt_init(void) | ||
| 328 | { | 316 | { |
| 329 | int ret; | 317 | int ret; |
| 330 | 318 | ||
| @@ -332,12 +320,13 @@ wdt_init(void) | |||
| 332 | 320 | ||
| 333 | if (wdt_set_heartbeat(timeout)) { | 321 | if (wdt_set_heartbeat(timeout)) { |
| 334 | wdt_set_heartbeat(WATCHDOG_TIMEOUT); | 322 | wdt_set_heartbeat(WATCHDOG_TIMEOUT); |
| 335 | printk (KERN_INFO PFX "timeout value must be 1<=timeout<=255, using %d\n", | 323 | printk(KERN_INFO PFX |
| 336 | WATCHDOG_TIMEOUT); | 324 | "timeout value must be 1 <= timeout <= 255, using %d\n", |
| 325 | WATCHDOG_TIMEOUT); | ||
| 337 | } | 326 | } |
| 338 | 327 | ||
| 339 | if (!request_region(wdt_io, 1, WATCHDOG_NAME)) { | 328 | if (!request_region(wdt_io, 1, WATCHDOG_NAME)) { |
| 340 | printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", | 329 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", |
| 341 | wdt_io); | 330 | wdt_io); |
| 342 | ret = -EIO; | 331 | ret = -EIO; |
| 343 | goto out; | 332 | goto out; |
| @@ -347,20 +336,22 @@ wdt_init(void) | |||
| 347 | 336 | ||
| 348 | ret = register_reboot_notifier(&wdt_notifier); | 337 | ret = register_reboot_notifier(&wdt_notifier); |
| 349 | if (ret != 0) { | 338 | if (ret != 0) { |
| 350 | printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 339 | printk(KERN_ERR PFX |
| 351 | ret); | 340 | "cannot register reboot notifier (err=%d)\n", ret); |
| 352 | goto unreg_regions; | 341 | goto unreg_regions; |
| 353 | } | 342 | } |
| 354 | 343 | ||
| 355 | ret = misc_register(&wdt_miscdev); | 344 | ret = misc_register(&wdt_miscdev); |
| 356 | if (ret != 0) { | 345 | if (ret != 0) { |
| 357 | printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 346 | printk(KERN_ERR PFX |
| 358 | WATCHDOG_MINOR, ret); | 347 | "cannot register miscdev on minor=%d (err=%d)\n", |
| 348 | WATCHDOG_MINOR, ret); | ||
| 359 | goto unreg_reboot; | 349 | goto unreg_reboot; |
| 360 | } | 350 | } |
| 361 | 351 | ||
| 362 | printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", | 352 | printk(KERN_INFO PFX |
| 363 | timeout, nowayout); | 353 | "initialized. timeout=%d sec (nowayout=%d)\n", |
| 354 | timeout, nowayout); | ||
| 364 | 355 | ||
| 365 | out: | 356 | out: |
| 366 | return ret; | 357 | return ret; |
| @@ -371,12 +362,11 @@ unreg_regions: | |||
| 371 | goto out; | 362 | goto out; |
| 372 | } | 363 | } |
| 373 | 364 | ||
| 374 | static void __exit | 365 | static void __exit wdt_exit(void) |
| 375 | wdt_exit(void) | ||
| 376 | { | 366 | { |
| 377 | misc_deregister(&wdt_miscdev); | 367 | misc_deregister(&wdt_miscdev); |
| 378 | unregister_reboot_notifier(&wdt_notifier); | 368 | unregister_reboot_notifier(&wdt_notifier); |
| 379 | release_region(wdt_io,1); | 369 | release_region(wdt_io, 1); |
| 380 | } | 370 | } |
| 381 | 371 | ||
| 382 | module_init(wdt_init); | 372 | module_init(wdt_init); |
diff --git a/drivers/watchdog/w83697hf_wdt.c b/drivers/watchdog/w83697hf_wdt.c index 528b882420b6..445d30a01ed3 100644 --- a/drivers/watchdog/w83697hf_wdt.c +++ b/drivers/watchdog/w83697hf_wdt.c | |||
| @@ -36,9 +36,9 @@ | |||
| 36 | #include <linux/reboot.h> | 36 | #include <linux/reboot.h> |
| 37 | #include <linux/init.h> | 37 | #include <linux/init.h> |
| 38 | #include <linux/spinlock.h> | 38 | #include <linux/spinlock.h> |
| 39 | #include <linux/io.h> | ||
| 40 | #include <linux/uaccess.h> | ||
| 39 | 41 | ||
| 40 | #include <asm/io.h> | ||
| 41 | #include <asm/uaccess.h> | ||
| 42 | #include <asm/system.h> | 42 | #include <asm/system.h> |
| 43 | 43 | ||
| 44 | #define WATCHDOG_NAME "w83697hf/hg WDT" | 44 | #define WATCHDOG_NAME "w83697hf/hg WDT" |
| @@ -53,37 +53,43 @@ static DEFINE_SPINLOCK(io_lock); | |||
| 53 | /* You must set this - there is no sane way to probe for this board. */ | 53 | /* You must set this - there is no sane way to probe for this board. */ |
| 54 | static int wdt_io = 0x2e; | 54 | static int wdt_io = 0x2e; |
| 55 | module_param(wdt_io, int, 0); | 55 | module_param(wdt_io, int, 0); |
| 56 | MODULE_PARM_DESC(wdt_io, "w83697hf/hg WDT io port (default 0x2e, 0 = autodetect)"); | 56 | MODULE_PARM_DESC(wdt_io, |
| 57 | "w83697hf/hg WDT io port (default 0x2e, 0 = autodetect)"); | ||
| 57 | 58 | ||
| 58 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ | 59 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ |
| 59 | module_param(timeout, int, 0); | 60 | module_param(timeout, int, 0); |
| 60 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255 (default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | 61 | MODULE_PARM_DESC(timeout, |
| 62 | "Watchdog timeout in seconds. 1<= timeout <=255 (default=" | ||
| 63 | __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | ||
| 61 | 64 | ||
| 62 | static int nowayout = WATCHDOG_NOWAYOUT; | 65 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 63 | module_param(nowayout, int, 0); | 66 | module_param(nowayout, int, 0); |
| 64 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 67 | MODULE_PARM_DESC(nowayout, |
| 68 | "Watchdog cannot be stopped once started (default=" | ||
| 69 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 65 | 70 | ||
| 66 | static int early_disable = WATCHDOG_EARLY_DISABLE; | 71 | static int early_disable = WATCHDOG_EARLY_DISABLE; |
| 67 | module_param(early_disable, int, 0); | 72 | module_param(early_disable, int, 0); |
| 68 | MODULE_PARM_DESC(early_disable, "Watchdog gets disabled at boot time (default=" __MODULE_STRING(WATCHDOG_EARLY_DISABLE) ")"); | 73 | MODULE_PARM_DESC(early_disable, |
| 74 | "Watchdog gets disabled at boot time (default=" | ||
| 75 | __MODULE_STRING(WATCHDOG_EARLY_DISABLE) ")"); | ||
| 69 | 76 | ||
| 70 | /* | 77 | /* |
| 71 | * Kernel methods. | 78 | * Kernel methods. |
| 72 | */ | 79 | */ |
| 73 | 80 | ||
| 74 | #define W83697HF_EFER (wdt_io+0) /* Extended Function Enable Register */ | 81 | #define W83697HF_EFER (wdt_io + 0) /* Extended Function Enable Register */ |
| 75 | #define W83697HF_EFIR (wdt_io+0) /* Extended Function Index Register (same as EFER) */ | 82 | #define W83697HF_EFIR (wdt_io + 0) /* Extended Function Index Register |
| 76 | #define W83697HF_EFDR (wdt_io+1) /* Extended Function Data Register */ | 83 | (same as EFER) */ |
| 84 | #define W83697HF_EFDR (wdt_io + 1) /* Extended Function Data Register */ | ||
| 77 | 85 | ||
| 78 | static inline void | 86 | static inline void w83697hf_unlock(void) |
| 79 | w83697hf_unlock(void) | ||
| 80 | { | 87 | { |
| 81 | outb_p(0x87, W83697HF_EFER); /* Enter extended function mode */ | 88 | outb_p(0x87, W83697HF_EFER); /* Enter extended function mode */ |
| 82 | outb_p(0x87, W83697HF_EFER); /* Again according to manual */ | 89 | outb_p(0x87, W83697HF_EFER); /* Again according to manual */ |
| 83 | } | 90 | } |
| 84 | 91 | ||
| 85 | static inline void | 92 | static inline void w83697hf_lock(void) |
| 86 | w83697hf_lock(void) | ||
| 87 | { | 93 | { |
| 88 | outb_p(0xAA, W83697HF_EFER); /* Leave extended function mode */ | 94 | outb_p(0xAA, W83697HF_EFER); /* Leave extended function mode */ |
| 89 | } | 95 | } |
| @@ -93,41 +99,36 @@ w83697hf_lock(void) | |||
| 93 | * w83697hf_write_timeout() must be called with the device unlocked. | 99 | * w83697hf_write_timeout() must be called with the device unlocked. |
| 94 | */ | 100 | */ |
| 95 | 101 | ||
| 96 | static unsigned char | 102 | static unsigned char w83697hf_get_reg(unsigned char reg) |
| 97 | w83697hf_get_reg(unsigned char reg) | ||
| 98 | { | 103 | { |
| 99 | outb_p(reg, W83697HF_EFIR); | 104 | outb_p(reg, W83697HF_EFIR); |
| 100 | return inb_p(W83697HF_EFDR); | 105 | return inb_p(W83697HF_EFDR); |
| 101 | } | 106 | } |
| 102 | 107 | ||
| 103 | static void | 108 | static void w83697hf_set_reg(unsigned char reg, unsigned char data) |
| 104 | w83697hf_set_reg(unsigned char reg, unsigned char data) | ||
| 105 | { | 109 | { |
| 106 | outb_p(reg, W83697HF_EFIR); | 110 | outb_p(reg, W83697HF_EFIR); |
| 107 | outb_p(data, W83697HF_EFDR); | 111 | outb_p(data, W83697HF_EFDR); |
| 108 | } | 112 | } |
| 109 | 113 | ||
| 110 | static void | 114 | static void w83697hf_write_timeout(int timeout) |
| 111 | w83697hf_write_timeout(int timeout) | ||
| 112 | { | 115 | { |
| 113 | w83697hf_set_reg(0xF4, timeout); /* Write Timeout counter to CRF4 */ | 116 | /* Write Timeout counter to CRF4 */ |
| 117 | w83697hf_set_reg(0xF4, timeout); | ||
| 114 | } | 118 | } |
| 115 | 119 | ||
| 116 | static void | 120 | static void w83697hf_select_wdt(void) |
| 117 | w83697hf_select_wdt(void) | ||
| 118 | { | 121 | { |
| 119 | w83697hf_unlock(); | 122 | w83697hf_unlock(); |
| 120 | w83697hf_set_reg(0x07, 0x08); /* Switch to logic device 8 (GPIO2) */ | 123 | w83697hf_set_reg(0x07, 0x08); /* Switch to logic device 8 (GPIO2) */ |
| 121 | } | 124 | } |
| 122 | 125 | ||
| 123 | static inline void | 126 | static inline void w83697hf_deselect_wdt(void) |
| 124 | w83697hf_deselect_wdt(void) | ||
| 125 | { | 127 | { |
| 126 | w83697hf_lock(); | 128 | w83697hf_lock(); |
| 127 | } | 129 | } |
| 128 | 130 | ||
| 129 | static void | 131 | static void w83697hf_init(void) |
| 130 | w83697hf_init(void) | ||
| 131 | { | 132 | { |
| 132 | unsigned char bbuf; | 133 | unsigned char bbuf; |
| 133 | 134 | ||
| @@ -136,7 +137,9 @@ w83697hf_init(void) | |||
| 136 | bbuf = w83697hf_get_reg(0x29); | 137 | bbuf = w83697hf_get_reg(0x29); |
| 137 | bbuf &= ~0x60; | 138 | bbuf &= ~0x60; |
| 138 | bbuf |= 0x20; | 139 | bbuf |= 0x20; |
| 139 | w83697hf_set_reg(0x29, bbuf); /* Set pin 119 to WDTO# mode (= CR29, WDT0) */ | 140 | |
| 141 | /* Set pin 119 to WDTO# mode (= CR29, WDT0) */ | ||
| 142 | w83697hf_set_reg(0x29, bbuf); | ||
| 140 | 143 | ||
| 141 | bbuf = w83697hf_get_reg(0xF3); | 144 | bbuf = w83697hf_get_reg(0xF3); |
| 142 | bbuf &= ~0x04; | 145 | bbuf &= ~0x04; |
| @@ -145,8 +148,7 @@ w83697hf_init(void) | |||
| 145 | w83697hf_deselect_wdt(); | 148 | w83697hf_deselect_wdt(); |
| 146 | } | 149 | } |
| 147 | 150 | ||
| 148 | static void | 151 | static void wdt_ping(void) |
| 149 | wdt_ping(void) | ||
| 150 | { | 152 | { |
| 151 | spin_lock(&io_lock); | 153 | spin_lock(&io_lock); |
| 152 | w83697hf_select_wdt(); | 154 | w83697hf_select_wdt(); |
| @@ -157,8 +159,7 @@ wdt_ping(void) | |||
| 157 | spin_unlock(&io_lock); | 159 | spin_unlock(&io_lock); |
| 158 | } | 160 | } |
| 159 | 161 | ||
| 160 | static void | 162 | static void wdt_enable(void) |
| 161 | wdt_enable(void) | ||
| 162 | { | 163 | { |
| 163 | spin_lock(&io_lock); | 164 | spin_lock(&io_lock); |
| 164 | w83697hf_select_wdt(); | 165 | w83697hf_select_wdt(); |
| @@ -170,8 +171,7 @@ wdt_enable(void) | |||
| 170 | spin_unlock(&io_lock); | 171 | spin_unlock(&io_lock); |
| 171 | } | 172 | } |
| 172 | 173 | ||
| 173 | static void | 174 | static void wdt_disable(void) |
| 174 | wdt_disable(void) | ||
| 175 | { | 175 | { |
| 176 | spin_lock(&io_lock); | 176 | spin_lock(&io_lock); |
| 177 | w83697hf_select_wdt(); | 177 | w83697hf_select_wdt(); |
| @@ -183,8 +183,7 @@ wdt_disable(void) | |||
| 183 | spin_unlock(&io_lock); | 183 | spin_unlock(&io_lock); |
| 184 | } | 184 | } |
| 185 | 185 | ||
| 186 | static unsigned char | 186 | static unsigned char wdt_running(void) |
| 187 | wdt_running(void) | ||
| 188 | { | 187 | { |
| 189 | unsigned char t; | 188 | unsigned char t; |
| 190 | 189 | ||
| @@ -199,18 +198,17 @@ wdt_running(void) | |||
| 199 | return t; | 198 | return t; |
| 200 | } | 199 | } |
| 201 | 200 | ||
| 202 | static int | 201 | static int wdt_set_heartbeat(int t) |
| 203 | wdt_set_heartbeat(int t) | ||
| 204 | { | 202 | { |
| 205 | if ((t < 1) || (t > 255)) | 203 | if (t < 1 || t > 255) |
| 206 | return -EINVAL; | 204 | return -EINVAL; |
| 207 | 205 | ||
| 208 | timeout = t; | 206 | timeout = t; |
| 209 | return 0; | 207 | return 0; |
| 210 | } | 208 | } |
| 211 | 209 | ||
| 212 | static ssize_t | 210 | static ssize_t wdt_write(struct file *file, const char __user *buf, |
| 213 | wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | 211 | size_t count, loff_t *ppos) |
| 214 | { | 212 | { |
| 215 | if (count) { | 213 | if (count) { |
| 216 | if (!nowayout) { | 214 | if (!nowayout) { |
| @@ -220,7 +218,7 @@ wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
| 220 | 218 | ||
| 221 | for (i = 0; i != count; i++) { | 219 | for (i = 0; i != count; i++) { |
| 222 | char c; | 220 | char c; |
| 223 | if (get_user(c, buf+i)) | 221 | if (get_user(c, buf + i)) |
| 224 | return -EFAULT; | 222 | return -EFAULT; |
| 225 | if (c == 'V') | 223 | if (c == 'V') |
| 226 | expect_close = 42; | 224 | expect_close = 42; |
| @@ -231,15 +229,14 @@ wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
| 231 | return count; | 229 | return count; |
| 232 | } | 230 | } |
| 233 | 231 | ||
| 234 | static int | 232 | static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 235 | wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | ||
| 236 | unsigned long arg) | ||
| 237 | { | 233 | { |
| 238 | void __user *argp = (void __user *)arg; | 234 | void __user *argp = (void __user *)arg; |
| 239 | int __user *p = argp; | 235 | int __user *p = argp; |
| 240 | int new_timeout; | 236 | int new_timeout; |
| 241 | static struct watchdog_info ident = { | 237 | static const struct watchdog_info ident = { |
| 242 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, | 238 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
| 239 | | WDIOF_MAGICCLOSE, | ||
| 243 | .firmware_version = 1, | 240 | .firmware_version = 1, |
| 244 | .identity = "W83697HF WDT", | 241 | .identity = "W83697HF WDT", |
| 245 | }; | 242 | }; |
| @@ -254,21 +251,6 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
| 254 | case WDIOC_GETBOOTSTATUS: | 251 | case WDIOC_GETBOOTSTATUS: |
| 255 | return put_user(0, p); | 252 | return put_user(0, p); |
| 256 | 253 | ||
| 257 | case WDIOC_KEEPALIVE: | ||
| 258 | wdt_ping(); | ||
| 259 | break; | ||
| 260 | |||
| 261 | case WDIOC_SETTIMEOUT: | ||
| 262 | if (get_user(new_timeout, p)) | ||
| 263 | return -EFAULT; | ||
| 264 | if (wdt_set_heartbeat(new_timeout)) | ||
| 265 | return -EINVAL; | ||
| 266 | wdt_ping(); | ||
| 267 | /* Fall */ | ||
| 268 | |||
| 269 | case WDIOC_GETTIMEOUT: | ||
| 270 | return put_user(timeout, p); | ||
| 271 | |||
| 272 | case WDIOC_SETOPTIONS: | 254 | case WDIOC_SETOPTIONS: |
| 273 | { | 255 | { |
| 274 | int options, retval = -EINVAL; | 256 | int options, retval = -EINVAL; |
| @@ -289,14 +271,28 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
| 289 | return retval; | 271 | return retval; |
| 290 | } | 272 | } |
| 291 | 273 | ||
| 274 | case WDIOC_KEEPALIVE: | ||
| 275 | wdt_ping(); | ||
| 276 | break; | ||
| 277 | |||
| 278 | case WDIOC_SETTIMEOUT: | ||
| 279 | if (get_user(new_timeout, p)) | ||
| 280 | return -EFAULT; | ||
| 281 | if (wdt_set_heartbeat(new_timeout)) | ||
| 282 | return -EINVAL; | ||
| 283 | wdt_ping(); | ||
| 284 | /* Fall */ | ||
| 285 | |||
| 286 | case WDIOC_GETTIMEOUT: | ||
| 287 | return put_user(timeout, p); | ||
| 288 | |||
| 292 | default: | 289 | default: |
| 293 | return -ENOTTY; | 290 | return -ENOTTY; |
| 294 | } | 291 | } |
| 295 | return 0; | 292 | return 0; |
| 296 | } | 293 | } |
| 297 | 294 | ||
| 298 | static int | 295 | static int wdt_open(struct inode *inode, struct file *file) |
| 299 | wdt_open(struct inode *inode, struct file *file) | ||
| 300 | { | 296 | { |
| 301 | if (test_and_set_bit(0, &wdt_is_open)) | 297 | if (test_and_set_bit(0, &wdt_is_open)) |
| 302 | return -EBUSY; | 298 | return -EBUSY; |
| @@ -308,13 +304,13 @@ wdt_open(struct inode *inode, struct file *file) | |||
| 308 | return nonseekable_open(inode, file); | 304 | return nonseekable_open(inode, file); |
| 309 | } | 305 | } |
| 310 | 306 | ||
| 311 | static int | 307 | static int wdt_close(struct inode *inode, struct file *file) |
| 312 | wdt_close(struct inode *inode, struct file *file) | ||
| 313 | { | 308 | { |
| 314 | if (expect_close == 42) { | 309 | if (expect_close == 42) |
| 315 | wdt_disable(); | 310 | wdt_disable(); |
| 316 | } else { | 311 | else { |
| 317 | printk (KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 312 | printk(KERN_CRIT PFX |
| 313 | "Unexpected close, not stopping watchdog!\n"); | ||
| 318 | wdt_ping(); | 314 | wdt_ping(); |
| 319 | } | 315 | } |
| 320 | expect_close = 0; | 316 | expect_close = 0; |
| @@ -326,14 +322,12 @@ wdt_close(struct inode *inode, struct file *file) | |||
| 326 | * Notifier for system down | 322 | * Notifier for system down |
| 327 | */ | 323 | */ |
| 328 | 324 | ||
| 329 | static int | 325 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, |
| 330 | wdt_notify_sys(struct notifier_block *this, unsigned long code, | ||
| 331 | void *unused) | 326 | void *unused) |
| 332 | { | 327 | { |
| 333 | if (code == SYS_DOWN || code == SYS_HALT) { | 328 | if (code == SYS_DOWN || code == SYS_HALT) |
| 334 | /* Turn the WDT off */ | 329 | wdt_disable(); /* Turn the WDT off */ |
| 335 | wdt_disable(); | 330 | |
| 336 | } | ||
| 337 | return NOTIFY_DONE; | 331 | return NOTIFY_DONE; |
| 338 | } | 332 | } |
| 339 | 333 | ||
| @@ -345,7 +339,7 @@ static const struct file_operations wdt_fops = { | |||
| 345 | .owner = THIS_MODULE, | 339 | .owner = THIS_MODULE, |
| 346 | .llseek = no_llseek, | 340 | .llseek = no_llseek, |
| 347 | .write = wdt_write, | 341 | .write = wdt_write, |
| 348 | .ioctl = wdt_ioctl, | 342 | .unlocked_ioctl = wdt_ioctl, |
| 349 | .open = wdt_open, | 343 | .open = wdt_open, |
| 350 | .release = wdt_close, | 344 | .release = wdt_close, |
| 351 | }; | 345 | }; |
| @@ -365,36 +359,38 @@ static struct notifier_block wdt_notifier = { | |||
| 365 | .notifier_call = wdt_notify_sys, | 359 | .notifier_call = wdt_notify_sys, |
| 366 | }; | 360 | }; |
| 367 | 361 | ||
| 368 | static int | 362 | static int w83697hf_check_wdt(void) |
| 369 | w83697hf_check_wdt(void) | ||
| 370 | { | 363 | { |
| 371 | if (!request_region(wdt_io, 2, WATCHDOG_NAME)) { | 364 | if (!request_region(wdt_io, 2, WATCHDOG_NAME)) { |
| 372 | printk (KERN_ERR PFX "I/O address 0x%x already in use\n", wdt_io); | 365 | printk(KERN_ERR PFX |
| 366 | "I/O address 0x%x already in use\n", wdt_io); | ||
| 373 | return -EIO; | 367 | return -EIO; |
| 374 | } | 368 | } |
| 375 | 369 | ||
| 376 | printk (KERN_DEBUG PFX "Looking for watchdog at address 0x%x\n", wdt_io); | 370 | printk(KERN_DEBUG PFX |
| 371 | "Looking for watchdog at address 0x%x\n", wdt_io); | ||
| 377 | w83697hf_unlock(); | 372 | w83697hf_unlock(); |
| 378 | if (w83697hf_get_reg(0x20) == 0x60) { | 373 | if (w83697hf_get_reg(0x20) == 0x60) { |
| 379 | printk (KERN_INFO PFX "watchdog found at address 0x%x\n", wdt_io); | 374 | printk(KERN_INFO PFX |
| 375 | "watchdog found at address 0x%x\n", wdt_io); | ||
| 380 | w83697hf_lock(); | 376 | w83697hf_lock(); |
| 381 | return 0; | 377 | return 0; |
| 382 | } | 378 | } |
| 383 | w83697hf_lock(); /* Reprotect in case it was a compatible device */ | 379 | /* Reprotect in case it was a compatible device */ |
| 380 | w83697hf_lock(); | ||
| 384 | 381 | ||
| 385 | printk (KERN_INFO PFX "watchdog not found at address 0x%x\n", wdt_io); | 382 | printk(KERN_INFO PFX "watchdog not found at address 0x%x\n", wdt_io); |
| 386 | release_region(wdt_io, 2); | 383 | release_region(wdt_io, 2); |
| 387 | return -EIO; | 384 | return -EIO; |
| 388 | } | 385 | } |
| 389 | 386 | ||
| 390 | static int w83697hf_ioports[] = { 0x2e, 0x4e, 0x00 }; | 387 | static int w83697hf_ioports[] = { 0x2e, 0x4e, 0x00 }; |
| 391 | 388 | ||
| 392 | static int __init | 389 | static int __init wdt_init(void) |
| 393 | wdt_init(void) | ||
| 394 | { | 390 | { |
| 395 | int ret, i, found = 0; | 391 | int ret, i, found = 0; |
| 396 | 392 | ||
| 397 | printk (KERN_INFO PFX "WDT driver for W83697HF/HG initializing\n"); | 393 | printk(KERN_INFO PFX "WDT driver for W83697HF/HG initializing\n"); |
| 398 | 394 | ||
| 399 | if (wdt_io == 0) { | 395 | if (wdt_io == 0) { |
| 400 | /* we will autodetect the W83697HF/HG watchdog */ | 396 | /* we will autodetect the W83697HF/HG watchdog */ |
| @@ -409,7 +405,7 @@ wdt_init(void) | |||
| 409 | } | 405 | } |
| 410 | 406 | ||
| 411 | if (!found) { | 407 | if (!found) { |
| 412 | printk (KERN_ERR PFX "No W83697HF/HG could be found\n"); | 408 | printk(KERN_ERR PFX "No W83697HF/HG could be found\n"); |
| 413 | ret = -EIO; | 409 | ret = -EIO; |
| 414 | goto out; | 410 | goto out; |
| 415 | } | 411 | } |
| @@ -417,31 +413,33 @@ wdt_init(void) | |||
| 417 | w83697hf_init(); | 413 | w83697hf_init(); |
| 418 | if (early_disable) { | 414 | if (early_disable) { |
| 419 | if (wdt_running()) | 415 | if (wdt_running()) |
| 420 | printk (KERN_WARNING PFX "Stopping previously enabled watchdog until userland kicks in\n"); | 416 | printk(KERN_WARNING PFX "Stopping previously enabled watchdog until userland kicks in\n"); |
| 421 | wdt_disable(); | 417 | wdt_disable(); |
| 422 | } | 418 | } |
| 423 | 419 | ||
| 424 | if (wdt_set_heartbeat(timeout)) { | 420 | if (wdt_set_heartbeat(timeout)) { |
| 425 | wdt_set_heartbeat(WATCHDOG_TIMEOUT); | 421 | wdt_set_heartbeat(WATCHDOG_TIMEOUT); |
| 426 | printk (KERN_INFO PFX "timeout value must be 1<=timeout<=255, using %d\n", | 422 | printk(KERN_INFO PFX |
| 427 | WATCHDOG_TIMEOUT); | 423 | "timeout value must be 1 <= timeout <= 255, using %d\n", |
| 424 | WATCHDOG_TIMEOUT); | ||
| 428 | } | 425 | } |
| 429 | 426 | ||
| 430 | ret = register_reboot_notifier(&wdt_notifier); | 427 | ret = register_reboot_notifier(&wdt_notifier); |
| 431 | if (ret != 0) { | 428 | if (ret != 0) { |
| 432 | printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 429 | printk(KERN_ERR PFX |
| 433 | ret); | 430 | "cannot register reboot notifier (err=%d)\n", ret); |
| 434 | goto unreg_regions; | 431 | goto unreg_regions; |
| 435 | } | 432 | } |
| 436 | 433 | ||
| 437 | ret = misc_register(&wdt_miscdev); | 434 | ret = misc_register(&wdt_miscdev); |
| 438 | if (ret != 0) { | 435 | if (ret != 0) { |
| 439 | printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 436 | printk(KERN_ERR PFX |
| 440 | WATCHDOG_MINOR, ret); | 437 | "cannot register miscdev on minor=%d (err=%d)\n", |
| 438 | WATCHDOG_MINOR, ret); | ||
| 441 | goto unreg_reboot; | 439 | goto unreg_reboot; |
| 442 | } | 440 | } |
| 443 | 441 | ||
| 444 | printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", | 442 | printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", |
| 445 | timeout, nowayout); | 443 | timeout, nowayout); |
| 446 | 444 | ||
| 447 | out: | 445 | out: |
| @@ -453,8 +451,7 @@ unreg_regions: | |||
| 453 | goto out; | 451 | goto out; |
| 454 | } | 452 | } |
| 455 | 453 | ||
| 456 | static void __exit | 454 | static void __exit wdt_exit(void) |
| 457 | wdt_exit(void) | ||
| 458 | { | 455 | { |
| 459 | misc_deregister(&wdt_miscdev); | 456 | misc_deregister(&wdt_miscdev); |
| 460 | unregister_reboot_notifier(&wdt_notifier); | 457 | unregister_reboot_notifier(&wdt_notifier); |
diff --git a/drivers/watchdog/w83877f_wdt.c b/drivers/watchdog/w83877f_wdt.c index f510a3a595e6..24587d2060c4 100644 --- a/drivers/watchdog/w83877f_wdt.c +++ b/drivers/watchdog/w83877f_wdt.c | |||
| @@ -23,13 +23,16 @@ | |||
| 23 | * Added KERN_* tags to printks | 23 | * Added KERN_* tags to printks |
| 24 | * add CONFIG_WATCHDOG_NOWAYOUT support | 24 | * add CONFIG_WATCHDOG_NOWAYOUT support |
| 25 | * fix possible wdt_is_open race | 25 | * fix possible wdt_is_open race |
| 26 | * changed watchdog_info to correctly reflect what the driver offers | 26 | * changed watchdog_info to correctly reflect what |
| 27 | * added WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS, WDIOC_SETTIMEOUT, | 27 | * the driver offers |
| 28 | * added WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS, | ||
| 29 | * WDIOC_SETTIMEOUT, | ||
| 28 | * WDIOC_GETTIMEOUT, and WDIOC_SETOPTIONS ioctls | 30 | * WDIOC_GETTIMEOUT, and WDIOC_SETOPTIONS ioctls |
| 29 | * 09/8 - 2003 [wim@iguana.be] cleanup of trailing spaces | 31 | * 09/8 - 2003 [wim@iguana.be] cleanup of trailing spaces |
| 30 | * added extra printk's for startup problems | 32 | * added extra printk's for startup problems |
| 31 | * use module_param | 33 | * use module_param |
| 32 | * made timeout (the emulated heartbeat) a module_param | 34 | * made timeout (the emulated heartbeat) a |
| 35 | * module_param | ||
| 33 | * made the keepalive ping an internal subroutine | 36 | * made the keepalive ping an internal subroutine |
| 34 | * | 37 | * |
| 35 | * This WDT driver is different from most other Linux WDT | 38 | * This WDT driver is different from most other Linux WDT |
| @@ -51,8 +54,8 @@ | |||
| 51 | #include <linux/notifier.h> | 54 | #include <linux/notifier.h> |
| 52 | #include <linux/reboot.h> | 55 | #include <linux/reboot.h> |
| 53 | #include <linux/init.h> | 56 | #include <linux/init.h> |
| 54 | #include <asm/io.h> | 57 | #include <linux/io.h> |
| 55 | #include <asm/uaccess.h> | 58 | #include <linux/uaccess.h> |
| 56 | #include <asm/system.h> | 59 | #include <asm/system.h> |
| 57 | 60 | ||
| 58 | #define OUR_NAME "w83877f_wdt" | 61 | #define OUR_NAME "w83877f_wdt" |
| @@ -80,14 +83,19 @@ | |||
| 80 | */ | 83 | */ |
| 81 | 84 | ||
| 82 | #define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ | 85 | #define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ |
| 83 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ | 86 | /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ |
| 87 | static int timeout = WATCHDOG_TIMEOUT; | ||
| 84 | module_param(timeout, int, 0); | 88 | module_param(timeout, int, 0); |
| 85 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | 89 | MODULE_PARM_DESC(timeout, |
| 90 | "Watchdog timeout in seconds. (1<=timeout<=3600, default=" | ||
| 91 | __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | ||
| 86 | 92 | ||
| 87 | 93 | ||
| 88 | static int nowayout = WATCHDOG_NOWAYOUT; | 94 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 89 | module_param(nowayout, int, 0); | 95 | module_param(nowayout, int, 0); |
| 90 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 96 | MODULE_PARM_DESC(nowayout, |
| 97 | "Watchdog cannot be stopped once started (default=" | ||
| 98 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 91 | 99 | ||
| 92 | static void wdt_timer_ping(unsigned long); | 100 | static void wdt_timer_ping(unsigned long); |
| 93 | static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0); | 101 | static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0); |
| @@ -105,8 +113,7 @@ static void wdt_timer_ping(unsigned long data) | |||
| 105 | /* If we got a heartbeat pulse within the WDT_US_INTERVAL | 113 | /* If we got a heartbeat pulse within the WDT_US_INTERVAL |
| 106 | * we agree to ping the WDT | 114 | * we agree to ping the WDT |
| 107 | */ | 115 | */ |
| 108 | if(time_before(jiffies, next_heartbeat)) | 116 | if (time_before(jiffies, next_heartbeat)) { |
| 109 | { | ||
| 110 | /* Ping the WDT */ | 117 | /* Ping the WDT */ |
| 111 | spin_lock(&wdt_spinlock); | 118 | spin_lock(&wdt_spinlock); |
| 112 | 119 | ||
| @@ -118,9 +125,9 @@ static void wdt_timer_ping(unsigned long data) | |||
| 118 | 125 | ||
| 119 | spin_unlock(&wdt_spinlock); | 126 | spin_unlock(&wdt_spinlock); |
| 120 | 127 | ||
| 121 | } else { | 128 | } else |
| 122 | printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); | 129 | printk(KERN_WARNING PFX |
| 123 | } | 130 | "Heartbeat lost! Will not ping the watchdog\n"); |
| 124 | } | 131 | } |
| 125 | 132 | ||
| 126 | /* | 133 | /* |
| @@ -181,22 +188,21 @@ static void wdt_keepalive(void) | |||
| 181 | * /dev/watchdog handling | 188 | * /dev/watchdog handling |
| 182 | */ | 189 | */ |
| 183 | 190 | ||
| 184 | static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos) | 191 | static ssize_t fop_write(struct file *file, const char __user *buf, |
| 192 | size_t count, loff_t *ppos) | ||
| 185 | { | 193 | { |
| 186 | /* See if we got the magic character 'V' and reload the timer */ | 194 | /* See if we got the magic character 'V' and reload the timer */ |
| 187 | if(count) | 195 | if (count) { |
| 188 | { | 196 | if (!nowayout) { |
| 189 | if (!nowayout) | ||
| 190 | { | ||
| 191 | size_t ofs; | 197 | size_t ofs; |
| 192 | 198 | ||
| 193 | /* note: just in case someone wrote the magic character | 199 | /* note: just in case someone wrote the magic |
| 194 | * five months ago... */ | 200 | character five months ago... */ |
| 195 | wdt_expect_close = 0; | 201 | wdt_expect_close = 0; |
| 196 | 202 | ||
| 197 | /* scan to see whether or not we got the magic character */ | 203 | /* scan to see whether or not we got the |
| 198 | for(ofs = 0; ofs != count; ofs++) | 204 | magic character */ |
| 199 | { | 205 | for (ofs = 0; ofs != count; ofs++) { |
| 200 | char c; | 206 | char c; |
| 201 | if (get_user(c, buf + ofs)) | 207 | if (get_user(c, buf + ofs)) |
| 202 | return -EFAULT; | 208 | return -EFAULT; |
| @@ -211,10 +217,10 @@ static ssize_t fop_write(struct file * file, const char __user * buf, size_t cou | |||
| 211 | return count; | 217 | return count; |
| 212 | } | 218 | } |
| 213 | 219 | ||
| 214 | static int fop_open(struct inode * inode, struct file * file) | 220 | static int fop_open(struct inode *inode, struct file *file) |
| 215 | { | 221 | { |
| 216 | /* Just in case we're already talking to someone... */ | 222 | /* Just in case we're already talking to someone... */ |
| 217 | if(test_and_set_bit(0, &wdt_is_open)) | 223 | if (test_and_set_bit(0, &wdt_is_open)) |
| 218 | return -EBUSY; | 224 | return -EBUSY; |
| 219 | 225 | ||
| 220 | /* Good, fire up the show */ | 226 | /* Good, fire up the show */ |
| @@ -222,78 +228,78 @@ static int fop_open(struct inode * inode, struct file * file) | |||
| 222 | return nonseekable_open(inode, file); | 228 | return nonseekable_open(inode, file); |
| 223 | } | 229 | } |
| 224 | 230 | ||
| 225 | static int fop_close(struct inode * inode, struct file * file) | 231 | static int fop_close(struct inode *inode, struct file *file) |
| 226 | { | 232 | { |
| 227 | if(wdt_expect_close == 42) | 233 | if (wdt_expect_close == 42) |
| 228 | wdt_turnoff(); | 234 | wdt_turnoff(); |
| 229 | else { | 235 | else { |
| 230 | del_timer(&timer); | 236 | del_timer(&timer); |
| 231 | printk(KERN_CRIT PFX "device file closed unexpectedly. Will not stop the WDT!\n"); | 237 | printk(KERN_CRIT PFX |
| 238 | "device file closed unexpectedly. Will not stop the WDT!\n"); | ||
| 232 | } | 239 | } |
| 233 | clear_bit(0, &wdt_is_open); | 240 | clear_bit(0, &wdt_is_open); |
| 234 | wdt_expect_close = 0; | 241 | wdt_expect_close = 0; |
| 235 | return 0; | 242 | return 0; |
| 236 | } | 243 | } |
| 237 | 244 | ||
| 238 | static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 245 | static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 239 | unsigned long arg) | ||
| 240 | { | 246 | { |
| 241 | void __user *argp = (void __user *)arg; | 247 | void __user *argp = (void __user *)arg; |
| 242 | int __user *p = argp; | 248 | int __user *p = argp; |
| 243 | static struct watchdog_info ident= | 249 | static const struct watchdog_info ident = { |
| 244 | { | 250 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
| 245 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, | 251 | | WDIOF_MAGICCLOSE, |
| 246 | .firmware_version = 1, | 252 | .firmware_version = 1, |
| 247 | .identity = "W83877F", | 253 | .identity = "W83877F", |
| 248 | }; | 254 | }; |
| 249 | 255 | ||
| 250 | switch(cmd) | 256 | switch (cmd) { |
| 257 | case WDIOC_GETSUPPORT: | ||
| 258 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; | ||
| 259 | case WDIOC_GETSTATUS: | ||
| 260 | case WDIOC_GETBOOTSTATUS: | ||
| 261 | return put_user(0, p); | ||
| 262 | case WDIOC_SETOPTIONS: | ||
| 251 | { | 263 | { |
| 252 | default: | 264 | int new_options, retval = -EINVAL; |
| 253 | return -ENOTTY; | ||
| 254 | case WDIOC_GETSUPPORT: | ||
| 255 | return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; | ||
| 256 | case WDIOC_GETSTATUS: | ||
| 257 | case WDIOC_GETBOOTSTATUS: | ||
| 258 | return put_user(0, p); | ||
| 259 | case WDIOC_KEEPALIVE: | ||
| 260 | wdt_keepalive(); | ||
| 261 | return 0; | ||
| 262 | case WDIOC_SETOPTIONS: | ||
| 263 | { | ||
| 264 | int new_options, retval = -EINVAL; | ||
| 265 | |||
| 266 | if(get_user(new_options, p)) | ||
| 267 | return -EFAULT; | ||
| 268 | |||
| 269 | if(new_options & WDIOS_DISABLECARD) { | ||
| 270 | wdt_turnoff(); | ||
| 271 | retval = 0; | ||
| 272 | } | ||
| 273 | 265 | ||
| 274 | if(new_options & WDIOS_ENABLECARD) { | 266 | if (get_user(new_options, p)) |
| 275 | wdt_startup(); | 267 | return -EFAULT; |
| 276 | retval = 0; | ||
| 277 | } | ||
| 278 | 268 | ||
| 279 | return retval; | 269 | if (new_options & WDIOS_DISABLECARD) { |
| 270 | wdt_turnoff(); | ||
| 271 | retval = 0; | ||
| 280 | } | 272 | } |
| 281 | case WDIOC_SETTIMEOUT: | ||
| 282 | { | ||
| 283 | int new_timeout; | ||
| 284 | 273 | ||
| 285 | if(get_user(new_timeout, p)) | 274 | if (new_options & WDIOS_ENABLECARD) { |
| 286 | return -EFAULT; | 275 | wdt_startup(); |
| 276 | retval = 0; | ||
| 277 | } | ||
| 287 | 278 | ||
| 288 | if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */ | 279 | return retval; |
| 289 | return -EINVAL; | 280 | } |
| 281 | case WDIOC_KEEPALIVE: | ||
| 282 | wdt_keepalive(); | ||
| 283 | return 0; | ||
| 284 | case WDIOC_SETTIMEOUT: | ||
| 285 | { | ||
| 286 | int new_timeout; | ||
| 290 | 287 | ||
| 291 | timeout = new_timeout; | 288 | if (get_user(new_timeout, p)) |
| 292 | wdt_keepalive(); | 289 | return -EFAULT; |
| 293 | /* Fall through */ | 290 | |
| 294 | } | 291 | /* arbitrary upper limit */ |
| 295 | case WDIOC_GETTIMEOUT: | 292 | if (new_timeout < 1 || new_timeout > 3600) |
| 296 | return put_user(timeout, p); | 293 | return -EINVAL; |
| 294 | |||
| 295 | timeout = new_timeout; | ||
| 296 | wdt_keepalive(); | ||
| 297 | /* Fall through */ | ||
| 298 | } | ||
| 299 | case WDIOC_GETTIMEOUT: | ||
| 300 | return put_user(timeout, p); | ||
| 301 | default: | ||
| 302 | return -ENOTTY; | ||
| 297 | } | 303 | } |
| 298 | } | 304 | } |
| 299 | 305 | ||
| @@ -303,7 +309,7 @@ static const struct file_operations wdt_fops = { | |||
| 303 | .write = fop_write, | 309 | .write = fop_write, |
| 304 | .open = fop_open, | 310 | .open = fop_open, |
| 305 | .release = fop_close, | 311 | .release = fop_close, |
| 306 | .ioctl = fop_ioctl, | 312 | .unlocked_ioctl = fop_ioctl, |
| 307 | }; | 313 | }; |
| 308 | 314 | ||
| 309 | static struct miscdevice wdt_miscdev = { | 315 | static struct miscdevice wdt_miscdev = { |
| @@ -319,7 +325,7 @@ static struct miscdevice wdt_miscdev = { | |||
| 319 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, | 325 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, |
| 320 | void *unused) | 326 | void *unused) |
| 321 | { | 327 | { |
| 322 | if(code==SYS_DOWN || code==SYS_HALT) | 328 | if (code == SYS_DOWN || code == SYS_HALT) |
| 323 | wdt_turnoff(); | 329 | wdt_turnoff(); |
| 324 | return NOTIFY_DONE; | 330 | return NOTIFY_DONE; |
| 325 | } | 331 | } |
| @@ -329,8 +335,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, | |||
| 329 | * turn the timebomb registers off. | 335 | * turn the timebomb registers off. |
| 330 | */ | 336 | */ |
| 331 | 337 | ||
| 332 | static struct notifier_block wdt_notifier= | 338 | static struct notifier_block wdt_notifier = { |
| 333 | { | ||
| 334 | .notifier_call = wdt_notify_sys, | 339 | .notifier_call = wdt_notify_sys, |
| 335 | }; | 340 | }; |
| 336 | 341 | ||
| @@ -342,31 +347,29 @@ static void __exit w83877f_wdt_unload(void) | |||
| 342 | misc_deregister(&wdt_miscdev); | 347 | misc_deregister(&wdt_miscdev); |
| 343 | 348 | ||
| 344 | unregister_reboot_notifier(&wdt_notifier); | 349 | unregister_reboot_notifier(&wdt_notifier); |
| 345 | release_region(WDT_PING,1); | 350 | release_region(WDT_PING, 1); |
| 346 | release_region(ENABLE_W83877F_PORT,2); | 351 | release_region(ENABLE_W83877F_PORT, 2); |
| 347 | } | 352 | } |
| 348 | 353 | ||
| 349 | static int __init w83877f_wdt_init(void) | 354 | static int __init w83877f_wdt_init(void) |
| 350 | { | 355 | { |
| 351 | int rc = -EBUSY; | 356 | int rc = -EBUSY; |
| 352 | 357 | ||
| 353 | if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */ | 358 | if (timeout < 1 || timeout > 3600) { /* arbitrary upper limit */ |
| 354 | { | ||
| 355 | timeout = WATCHDOG_TIMEOUT; | 359 | timeout = WATCHDOG_TIMEOUT; |
| 356 | printk(KERN_INFO PFX "timeout value must be 1<=x<=3600, using %d\n", | 360 | printk(KERN_INFO PFX |
| 357 | timeout); | 361 | "timeout value must be 1 <= x <= 3600, using %d\n", |
| 362 | timeout); | ||
| 358 | } | 363 | } |
| 359 | 364 | ||
| 360 | if (!request_region(ENABLE_W83877F_PORT, 2, "W83877F WDT")) | 365 | if (!request_region(ENABLE_W83877F_PORT, 2, "W83877F WDT")) { |
| 361 | { | ||
| 362 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", | 366 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", |
| 363 | ENABLE_W83877F_PORT); | 367 | ENABLE_W83877F_PORT); |
| 364 | rc = -EIO; | 368 | rc = -EIO; |
| 365 | goto err_out; | 369 | goto err_out; |
| 366 | } | 370 | } |
| 367 | 371 | ||
| 368 | if (!request_region(WDT_PING, 1, "W8387FF WDT")) | 372 | if (!request_region(WDT_PING, 1, "W8387FF WDT")) { |
| 369 | { | ||
| 370 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", | 373 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", |
| 371 | WDT_PING); | 374 | WDT_PING); |
| 372 | rc = -EIO; | 375 | rc = -EIO; |
| @@ -374,22 +377,22 @@ static int __init w83877f_wdt_init(void) | |||
| 374 | } | 377 | } |
| 375 | 378 | ||
| 376 | rc = register_reboot_notifier(&wdt_notifier); | 379 | rc = register_reboot_notifier(&wdt_notifier); |
| 377 | if (rc) | 380 | if (rc) { |
| 378 | { | 381 | printk(KERN_ERR PFX |
| 379 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 382 | "cannot register reboot notifier (err=%d)\n", rc); |
| 380 | rc); | ||
| 381 | goto err_out_region2; | 383 | goto err_out_region2; |
| 382 | } | 384 | } |
| 383 | 385 | ||
| 384 | rc = misc_register(&wdt_miscdev); | 386 | rc = misc_register(&wdt_miscdev); |
| 385 | if (rc) | 387 | if (rc) { |
| 386 | { | 388 | printk(KERN_ERR PFX |
| 387 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 389 | "cannot register miscdev on minor=%d (err=%d)\n", |
| 388 | wdt_miscdev.minor, rc); | 390 | wdt_miscdev.minor, rc); |
| 389 | goto err_out_reboot; | 391 | goto err_out_reboot; |
| 390 | } | 392 | } |
| 391 | 393 | ||
| 392 | printk(KERN_INFO PFX "WDT driver for W83877F initialised. timeout=%d sec (nowayout=%d)\n", | 394 | printk(KERN_INFO PFX |
| 395 | "WDT driver for W83877F initialised. timeout=%d sec (nowayout=%d)\n", | ||
| 393 | timeout, nowayout); | 396 | timeout, nowayout); |
| 394 | 397 | ||
| 395 | return 0; | 398 | return 0; |
| @@ -397,9 +400,9 @@ static int __init w83877f_wdt_init(void) | |||
| 397 | err_out_reboot: | 400 | err_out_reboot: |
| 398 | unregister_reboot_notifier(&wdt_notifier); | 401 | unregister_reboot_notifier(&wdt_notifier); |
| 399 | err_out_region2: | 402 | err_out_region2: |
| 400 | release_region(WDT_PING,1); | 403 | release_region(WDT_PING, 1); |
| 401 | err_out_region1: | 404 | err_out_region1: |
| 402 | release_region(ENABLE_W83877F_PORT,2); | 405 | release_region(ENABLE_W83877F_PORT, 2); |
| 403 | err_out: | 406 | err_out: |
| 404 | return rc; | 407 | return rc; |
| 405 | } | 408 | } |
diff --git a/drivers/watchdog/w83977f_wdt.c b/drivers/watchdog/w83977f_wdt.c index b209bcd7f789..2525da5080ca 100644 --- a/drivers/watchdog/w83977f_wdt.c +++ b/drivers/watchdog/w83977f_wdt.c | |||
| @@ -26,10 +26,10 @@ | |||
| 26 | #include <linux/watchdog.h> | 26 | #include <linux/watchdog.h> |
| 27 | #include <linux/notifier.h> | 27 | #include <linux/notifier.h> |
| 28 | #include <linux/reboot.h> | 28 | #include <linux/reboot.h> |
| 29 | #include <linux/uaccess.h> | ||
| 30 | #include <linux/io.h> | ||
| 29 | 31 | ||
| 30 | #include <asm/io.h> | ||
| 31 | #include <asm/system.h> | 32 | #include <asm/system.h> |
| 32 | #include <asm/uaccess.h> | ||
| 33 | 33 | ||
| 34 | #define WATCHDOG_VERSION "1.00" | 34 | #define WATCHDOG_VERSION "1.00" |
| 35 | #define WATCHDOG_NAME "W83977F WDT" | 35 | #define WATCHDOG_NAME "W83977F WDT" |
| @@ -53,13 +53,17 @@ static char expect_close; | |||
| 53 | static DEFINE_SPINLOCK(spinlock); | 53 | static DEFINE_SPINLOCK(spinlock); |
| 54 | 54 | ||
| 55 | module_param(timeout, int, 0); | 55 | module_param(timeout, int, 0); |
| 56 | MODULE_PARM_DESC(timeout,"Watchdog timeout in seconds (15..7635), default=" __MODULE_STRING(DEFAULT_TIMEOUT) ")"); | 56 | MODULE_PARM_DESC(timeout, |
| 57 | "Watchdog timeout in seconds (15..7635), default=" | ||
| 58 | __MODULE_STRING(DEFAULT_TIMEOUT) ")"); | ||
| 57 | module_param(testmode, int, 0); | 59 | module_param(testmode, int, 0); |
| 58 | MODULE_PARM_DESC(testmode,"Watchdog testmode (1 = no reboot), default=0"); | 60 | MODULE_PARM_DESC(testmode, "Watchdog testmode (1 = no reboot), default=0"); |
| 59 | 61 | ||
| 60 | static int nowayout = WATCHDOG_NOWAYOUT; | 62 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 61 | module_param(nowayout, int, 0); | 63 | module_param(nowayout, int, 0); |
| 62 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 64 | MODULE_PARM_DESC(nowayout, |
| 65 | "Watchdog cannot be stopped once started (default=" | ||
| 66 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 63 | 67 | ||
| 64 | /* | 68 | /* |
| 65 | * Start the watchdog | 69 | * Start the watchdog |
| @@ -72,8 +76,8 @@ static int wdt_start(void) | |||
| 72 | spin_lock_irqsave(&spinlock, flags); | 76 | spin_lock_irqsave(&spinlock, flags); |
| 73 | 77 | ||
| 74 | /* Unlock the SuperIO chip */ | 78 | /* Unlock the SuperIO chip */ |
| 75 | outb_p(UNLOCK_DATA,IO_INDEX_PORT); | 79 | outb_p(UNLOCK_DATA, IO_INDEX_PORT); |
| 76 | outb_p(UNLOCK_DATA,IO_INDEX_PORT); | 80 | outb_p(UNLOCK_DATA, IO_INDEX_PORT); |
| 77 | 81 | ||
| 78 | /* | 82 | /* |
| 79 | * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4. | 83 | * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4. |
| @@ -81,50 +85,49 @@ static int wdt_start(void) | |||
| 81 | * F3 is set to enable watchdog LED blink at timeout. | 85 | * F3 is set to enable watchdog LED blink at timeout. |
| 82 | * F4 is used to just clear the TIMEOUT'ed state (bit 0). | 86 | * F4 is used to just clear the TIMEOUT'ed state (bit 0). |
| 83 | */ | 87 | */ |
| 84 | outb_p(DEVICE_REGISTER,IO_INDEX_PORT); | 88 | outb_p(DEVICE_REGISTER, IO_INDEX_PORT); |
| 85 | outb_p(0x08,IO_DATA_PORT); | 89 | outb_p(0x08, IO_DATA_PORT); |
| 86 | outb_p(0xF2,IO_INDEX_PORT); | 90 | outb_p(0xF2, IO_INDEX_PORT); |
| 87 | outb_p(timeoutW,IO_DATA_PORT); | 91 | outb_p(timeoutW, IO_DATA_PORT); |
| 88 | outb_p(0xF3,IO_INDEX_PORT); | 92 | outb_p(0xF3, IO_INDEX_PORT); |
| 89 | outb_p(0x08,IO_DATA_PORT); | 93 | outb_p(0x08, IO_DATA_PORT); |
| 90 | outb_p(0xF4,IO_INDEX_PORT); | 94 | outb_p(0xF4, IO_INDEX_PORT); |
| 91 | outb_p(0x00,IO_DATA_PORT); | 95 | outb_p(0x00, IO_DATA_PORT); |
| 92 | 96 | ||
| 93 | /* Set device Aux2 active */ | 97 | /* Set device Aux2 active */ |
| 94 | outb_p(0x30,IO_INDEX_PORT); | 98 | outb_p(0x30, IO_INDEX_PORT); |
| 95 | outb_p(0x01,IO_DATA_PORT); | 99 | outb_p(0x01, IO_DATA_PORT); |
| 96 | 100 | ||
| 97 | /* | 101 | /* |
| 98 | * Select device Aux1 (dev=7) to set GP16 as the watchdog output | 102 | * Select device Aux1 (dev=7) to set GP16 as the watchdog output |
| 99 | * (in reg E6) and GP13 as the watchdog LED output (in reg E3). | 103 | * (in reg E6) and GP13 as the watchdog LED output (in reg E3). |
| 100 | * Map GP16 at pin 119. | 104 | * Map GP16 at pin 119. |
| 101 | * In test mode watch the bit 0 on F4 to indicate "triggered" or | 105 | * In test mode watch the bit 0 on F4 to indicate "triggered" or |
| 102 | * check watchdog LED on SBC. | 106 | * check watchdog LED on SBC. |
| 103 | */ | 107 | */ |
| 104 | outb_p(DEVICE_REGISTER,IO_INDEX_PORT); | 108 | outb_p(DEVICE_REGISTER, IO_INDEX_PORT); |
| 105 | outb_p(0x07,IO_DATA_PORT); | 109 | outb_p(0x07, IO_DATA_PORT); |
| 106 | if (!testmode) | 110 | if (!testmode) { |
| 107 | { | ||
| 108 | unsigned pin_map; | 111 | unsigned pin_map; |
| 109 | 112 | ||
| 110 | outb_p(0xE6,IO_INDEX_PORT); | 113 | outb_p(0xE6, IO_INDEX_PORT); |
| 111 | outb_p(0x0A,IO_DATA_PORT); | 114 | outb_p(0x0A, IO_DATA_PORT); |
| 112 | outb_p(0x2C,IO_INDEX_PORT); | 115 | outb_p(0x2C, IO_INDEX_PORT); |
| 113 | pin_map = inb_p(IO_DATA_PORT); | 116 | pin_map = inb_p(IO_DATA_PORT); |
| 114 | pin_map |= 0x10; | 117 | pin_map |= 0x10; |
| 115 | pin_map &= ~(0x20); | 118 | pin_map &= ~(0x20); |
| 116 | outb_p(0x2C,IO_INDEX_PORT); | 119 | outb_p(0x2C, IO_INDEX_PORT); |
| 117 | outb_p(pin_map,IO_DATA_PORT); | 120 | outb_p(pin_map, IO_DATA_PORT); |
| 118 | } | 121 | } |
| 119 | outb_p(0xE3,IO_INDEX_PORT); | 122 | outb_p(0xE3, IO_INDEX_PORT); |
| 120 | outb_p(0x08,IO_DATA_PORT); | 123 | outb_p(0x08, IO_DATA_PORT); |
| 121 | 124 | ||
| 122 | /* Set device Aux1 active */ | 125 | /* Set device Aux1 active */ |
| 123 | outb_p(0x30,IO_INDEX_PORT); | 126 | outb_p(0x30, IO_INDEX_PORT); |
| 124 | outb_p(0x01,IO_DATA_PORT); | 127 | outb_p(0x01, IO_DATA_PORT); |
| 125 | 128 | ||
| 126 | /* Lock the SuperIO chip */ | 129 | /* Lock the SuperIO chip */ |
| 127 | outb_p(LOCK_DATA,IO_INDEX_PORT); | 130 | outb_p(LOCK_DATA, IO_INDEX_PORT); |
| 128 | 131 | ||
| 129 | spin_unlock_irqrestore(&spinlock, flags); | 132 | spin_unlock_irqrestore(&spinlock, flags); |
| 130 | 133 | ||
| @@ -144,42 +147,41 @@ static int wdt_stop(void) | |||
| 144 | spin_lock_irqsave(&spinlock, flags); | 147 | spin_lock_irqsave(&spinlock, flags); |
| 145 | 148 | ||
| 146 | /* Unlock the SuperIO chip */ | 149 | /* Unlock the SuperIO chip */ |
| 147 | outb_p(UNLOCK_DATA,IO_INDEX_PORT); | 150 | outb_p(UNLOCK_DATA, IO_INDEX_PORT); |
| 148 | outb_p(UNLOCK_DATA,IO_INDEX_PORT); | 151 | outb_p(UNLOCK_DATA, IO_INDEX_PORT); |
| 149 | 152 | ||
| 150 | /* | 153 | /* |
| 151 | * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4. | 154 | * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4. |
| 152 | * F2 is reset to its default value (watchdog timer disabled). | 155 | * F2 is reset to its default value (watchdog timer disabled). |
| 153 | * F3 is reset to its default state. | 156 | * F3 is reset to its default state. |
| 154 | * F4 clears the TIMEOUT'ed state (bit 0) - back to default. | 157 | * F4 clears the TIMEOUT'ed state (bit 0) - back to default. |
| 155 | */ | 158 | */ |
| 156 | outb_p(DEVICE_REGISTER,IO_INDEX_PORT); | 159 | outb_p(DEVICE_REGISTER, IO_INDEX_PORT); |
| 157 | outb_p(0x08,IO_DATA_PORT); | 160 | outb_p(0x08, IO_DATA_PORT); |
| 158 | outb_p(0xF2,IO_INDEX_PORT); | 161 | outb_p(0xF2, IO_INDEX_PORT); |
| 159 | outb_p(0xFF,IO_DATA_PORT); | 162 | outb_p(0xFF, IO_DATA_PORT); |
| 160 | outb_p(0xF3,IO_INDEX_PORT); | 163 | outb_p(0xF3, IO_INDEX_PORT); |
| 161 | outb_p(0x00,IO_DATA_PORT); | 164 | outb_p(0x00, IO_DATA_PORT); |
| 162 | outb_p(0xF4,IO_INDEX_PORT); | 165 | outb_p(0xF4, IO_INDEX_PORT); |
| 163 | outb_p(0x00,IO_DATA_PORT); | 166 | outb_p(0x00, IO_DATA_PORT); |
| 164 | outb_p(0xF2,IO_INDEX_PORT); | 167 | outb_p(0xF2, IO_INDEX_PORT); |
| 165 | outb_p(0x00,IO_DATA_PORT); | 168 | outb_p(0x00, IO_DATA_PORT); |
| 166 | 169 | ||
| 167 | /* | 170 | /* |
| 168 | * Select device Aux1 (dev=7) to set GP16 (in reg E6) and | 171 | * Select device Aux1 (dev=7) to set GP16 (in reg E6) and |
| 169 | * Gp13 (in reg E3) as inputs. | 172 | * Gp13 (in reg E3) as inputs. |
| 170 | */ | 173 | */ |
| 171 | outb_p(DEVICE_REGISTER,IO_INDEX_PORT); | 174 | outb_p(DEVICE_REGISTER, IO_INDEX_PORT); |
| 172 | outb_p(0x07,IO_DATA_PORT); | 175 | outb_p(0x07, IO_DATA_PORT); |
| 173 | if (!testmode) | 176 | if (!testmode) { |
| 174 | { | 177 | outb_p(0xE6, IO_INDEX_PORT); |
| 175 | outb_p(0xE6,IO_INDEX_PORT); | 178 | outb_p(0x01, IO_DATA_PORT); |
| 176 | outb_p(0x01,IO_DATA_PORT); | ||
| 177 | } | 179 | } |
| 178 | outb_p(0xE3,IO_INDEX_PORT); | 180 | outb_p(0xE3, IO_INDEX_PORT); |
| 179 | outb_p(0x01,IO_DATA_PORT); | 181 | outb_p(0x01, IO_DATA_PORT); |
| 180 | 182 | ||
| 181 | /* Lock the SuperIO chip */ | 183 | /* Lock the SuperIO chip */ |
| 182 | outb_p(LOCK_DATA,IO_INDEX_PORT); | 184 | outb_p(LOCK_DATA, IO_INDEX_PORT); |
| 183 | 185 | ||
| 184 | spin_unlock_irqrestore(&spinlock, flags); | 186 | spin_unlock_irqrestore(&spinlock, flags); |
| 185 | 187 | ||
| @@ -200,17 +202,17 @@ static int wdt_keepalive(void) | |||
| 200 | spin_lock_irqsave(&spinlock, flags); | 202 | spin_lock_irqsave(&spinlock, flags); |
| 201 | 203 | ||
| 202 | /* Unlock the SuperIO chip */ | 204 | /* Unlock the SuperIO chip */ |
| 203 | outb_p(UNLOCK_DATA,IO_INDEX_PORT); | 205 | outb_p(UNLOCK_DATA, IO_INDEX_PORT); |
| 204 | outb_p(UNLOCK_DATA,IO_INDEX_PORT); | 206 | outb_p(UNLOCK_DATA, IO_INDEX_PORT); |
| 205 | 207 | ||
| 206 | /* Select device Aux2 (device=8) to kick watchdog reg F2 */ | 208 | /* Select device Aux2 (device=8) to kick watchdog reg F2 */ |
| 207 | outb_p(DEVICE_REGISTER,IO_INDEX_PORT); | 209 | outb_p(DEVICE_REGISTER, IO_INDEX_PORT); |
| 208 | outb_p(0x08,IO_DATA_PORT); | 210 | outb_p(0x08, IO_DATA_PORT); |
| 209 | outb_p(0xF2,IO_INDEX_PORT); | 211 | outb_p(0xF2, IO_INDEX_PORT); |
| 210 | outb_p(timeoutW,IO_DATA_PORT); | 212 | outb_p(timeoutW, IO_DATA_PORT); |
| 211 | 213 | ||
| 212 | /* Lock the SuperIO chip */ | 214 | /* Lock the SuperIO chip */ |
| 213 | outb_p(LOCK_DATA,IO_INDEX_PORT); | 215 | outb_p(LOCK_DATA, IO_INDEX_PORT); |
| 214 | 216 | ||
| 215 | spin_unlock_irqrestore(&spinlock, flags); | 217 | spin_unlock_irqrestore(&spinlock, flags); |
| 216 | 218 | ||
| @@ -227,7 +229,7 @@ static int wdt_set_timeout(int t) | |||
| 227 | 229 | ||
| 228 | /* | 230 | /* |
| 229 | * Convert seconds to watchdog counter time units, rounding up. | 231 | * Convert seconds to watchdog counter time units, rounding up. |
| 230 | * On PCM-5335 watchdog units are 30 seconds/step with 15 sec startup | 232 | * On PCM-5335 watchdog units are 30 seconds/step with 15 sec startup |
| 231 | * value. This information is supplied in the PCM-5335 manual and was | 233 | * value. This information is supplied in the PCM-5335 manual and was |
| 232 | * checked by me on a real board. This is a bit strange because W83977f | 234 | * checked by me on a real board. This is a bit strange because W83977f |
| 233 | * datasheet says counter unit is in minutes! | 235 | * datasheet says counter unit is in minutes! |
| @@ -241,7 +243,7 @@ static int wdt_set_timeout(int t) | |||
| 241 | return -EINVAL; | 243 | return -EINVAL; |
| 242 | 244 | ||
| 243 | /* | 245 | /* |
| 244 | * timeout is the timeout in seconds, | 246 | * timeout is the timeout in seconds, |
| 245 | * timeoutW is the timeout in watchdog counter units. | 247 | * timeoutW is the timeout in watchdog counter units. |
| 246 | */ | 248 | */ |
| 247 | timeoutW = tmrval; | 249 | timeoutW = tmrval; |
| @@ -261,17 +263,17 @@ static int wdt_get_status(int *status) | |||
| 261 | spin_lock_irqsave(&spinlock, flags); | 263 | spin_lock_irqsave(&spinlock, flags); |
| 262 | 264 | ||
| 263 | /* Unlock the SuperIO chip */ | 265 | /* Unlock the SuperIO chip */ |
| 264 | outb_p(UNLOCK_DATA,IO_INDEX_PORT); | 266 | outb_p(UNLOCK_DATA, IO_INDEX_PORT); |
| 265 | outb_p(UNLOCK_DATA,IO_INDEX_PORT); | 267 | outb_p(UNLOCK_DATA, IO_INDEX_PORT); |
| 266 | 268 | ||
| 267 | /* Select device Aux2 (device=8) to read watchdog reg F4 */ | 269 | /* Select device Aux2 (device=8) to read watchdog reg F4 */ |
| 268 | outb_p(DEVICE_REGISTER,IO_INDEX_PORT); | 270 | outb_p(DEVICE_REGISTER, IO_INDEX_PORT); |
| 269 | outb_p(0x08,IO_DATA_PORT); | 271 | outb_p(0x08, IO_DATA_PORT); |
| 270 | outb_p(0xF4,IO_INDEX_PORT); | 272 | outb_p(0xF4, IO_INDEX_PORT); |
| 271 | new_status = inb_p(IO_DATA_PORT); | 273 | new_status = inb_p(IO_DATA_PORT); |
| 272 | 274 | ||
| 273 | /* Lock the SuperIO chip */ | 275 | /* Lock the SuperIO chip */ |
| 274 | outb_p(LOCK_DATA,IO_INDEX_PORT); | 276 | outb_p(LOCK_DATA, IO_INDEX_PORT); |
| 275 | 277 | ||
| 276 | spin_unlock_irqrestore(&spinlock, flags); | 278 | spin_unlock_irqrestore(&spinlock, flags); |
| 277 | 279 | ||
| @@ -290,7 +292,7 @@ static int wdt_get_status(int *status) | |||
| 290 | static int wdt_open(struct inode *inode, struct file *file) | 292 | static int wdt_open(struct inode *inode, struct file *file) |
| 291 | { | 293 | { |
| 292 | /* If the watchdog is alive we don't need to start it again */ | 294 | /* If the watchdog is alive we don't need to start it again */ |
| 293 | if( test_and_set_bit(0, &timer_alive) ) | 295 | if (test_and_set_bit(0, &timer_alive)) |
| 294 | return -EBUSY; | 296 | return -EBUSY; |
| 295 | 297 | ||
| 296 | if (nowayout) | 298 | if (nowayout) |
| @@ -306,13 +308,13 @@ static int wdt_release(struct inode *inode, struct file *file) | |||
| 306 | * Shut off the timer. | 308 | * Shut off the timer. |
| 307 | * Lock it in if it's a module and we set nowayout | 309 | * Lock it in if it's a module and we set nowayout |
| 308 | */ | 310 | */ |
| 309 | if (expect_close == 42) | 311 | if (expect_close == 42) { |
| 310 | { | ||
| 311 | wdt_stop(); | 312 | wdt_stop(); |
| 312 | clear_bit(0, &timer_alive); | 313 | clear_bit(0, &timer_alive); |
| 313 | } else { | 314 | } else { |
| 314 | wdt_keepalive(); | 315 | wdt_keepalive(); |
| 315 | printk(KERN_CRIT PFX "unexpected close, not stopping watchdog!\n"); | 316 | printk(KERN_CRIT PFX |
| 317 | "unexpected close, not stopping watchdog!\n"); | ||
| 316 | } | 318 | } |
| 317 | expect_close = 0; | 319 | expect_close = 0; |
| 318 | return 0; | 320 | return 0; |
| @@ -333,24 +335,22 @@ static ssize_t wdt_write(struct file *file, const char __user *buf, | |||
| 333 | size_t count, loff_t *ppos) | 335 | size_t count, loff_t *ppos) |
| 334 | { | 336 | { |
| 335 | /* See if we got the magic character 'V' and reload the timer */ | 337 | /* See if we got the magic character 'V' and reload the timer */ |
| 336 | if(count) | 338 | if (count) { |
| 337 | { | 339 | if (!nowayout) { |
| 338 | if (!nowayout) | ||
| 339 | { | ||
| 340 | size_t ofs; | 340 | size_t ofs; |
| 341 | 341 | ||
| 342 | /* note: just in case someone wrote the magic character long ago */ | 342 | /* note: just in case someone wrote the |
| 343 | magic character long ago */ | ||
| 343 | expect_close = 0; | 344 | expect_close = 0; |
| 344 | 345 | ||
| 345 | /* scan to see whether or not we got the magic character */ | 346 | /* scan to see whether or not we got the |
| 346 | for(ofs = 0; ofs != count; ofs++) | 347 | magic character */ |
| 347 | { | 348 | for (ofs = 0; ofs != count; ofs++) { |
| 348 | char c; | 349 | char c; |
| 349 | if (get_user(c, buf + ofs)) | 350 | if (get_user(c, buf + ofs)) |
| 350 | return -EFAULT; | 351 | return -EFAULT; |
| 351 | if (c == 'V') { | 352 | if (c == 'V') |
| 352 | expect_close = 42; | 353 | expect_close = 42; |
| 353 | } | ||
| 354 | } | 354 | } |
| 355 | } | 355 | } |
| 356 | 356 | ||
| @@ -377,8 +377,7 @@ static struct watchdog_info ident = { | |||
| 377 | .identity = WATCHDOG_NAME, | 377 | .identity = WATCHDOG_NAME, |
| 378 | }; | 378 | }; |
| 379 | 379 | ||
| 380 | static int wdt_ioctl(struct inode *inode, struct file *file, | 380 | static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 381 | unsigned int cmd, unsigned long arg) | ||
| 382 | { | 381 | { |
| 383 | int status; | 382 | int status; |
| 384 | int new_options, retval = -EINVAL; | 383 | int new_options, retval = -EINVAL; |
| @@ -390,13 +389,10 @@ static int wdt_ioctl(struct inode *inode, struct file *file, | |||
| 390 | 389 | ||
| 391 | uarg.i = (int __user *)arg; | 390 | uarg.i = (int __user *)arg; |
| 392 | 391 | ||
| 393 | switch(cmd) | 392 | switch (cmd) { |
| 394 | { | ||
| 395 | default: | ||
| 396 | return -ENOTTY; | ||
| 397 | |||
| 398 | case WDIOC_GETSUPPORT: | 393 | case WDIOC_GETSUPPORT: |
| 399 | return copy_to_user(uarg.ident, &ident, sizeof(ident)) ? -EFAULT : 0; | 394 | return copy_to_user(uarg.ident, &ident, |
| 395 | sizeof(ident)) ? -EFAULT : 0; | ||
| 400 | 396 | ||
| 401 | case WDIOC_GETSTATUS: | 397 | case WDIOC_GETSTATUS: |
| 402 | wdt_get_status(&status); | 398 | wdt_get_status(&status); |
| @@ -405,12 +401,8 @@ static int wdt_ioctl(struct inode *inode, struct file *file, | |||
| 405 | case WDIOC_GETBOOTSTATUS: | 401 | case WDIOC_GETBOOTSTATUS: |
| 406 | return put_user(0, uarg.i); | 402 | return put_user(0, uarg.i); |
| 407 | 403 | ||
| 408 | case WDIOC_KEEPALIVE: | ||
| 409 | wdt_keepalive(); | ||
| 410 | return 0; | ||
| 411 | |||
| 412 | case WDIOC_SETOPTIONS: | 404 | case WDIOC_SETOPTIONS: |
| 413 | if (get_user (new_options, uarg.i)) | 405 | if (get_user(new_options, uarg.i)) |
| 414 | return -EFAULT; | 406 | return -EFAULT; |
| 415 | 407 | ||
| 416 | if (new_options & WDIOS_DISABLECARD) { | 408 | if (new_options & WDIOS_DISABLECARD) { |
| @@ -425,6 +417,10 @@ static int wdt_ioctl(struct inode *inode, struct file *file, | |||
| 425 | 417 | ||
| 426 | return retval; | 418 | return retval; |
| 427 | 419 | ||
| 420 | case WDIOC_KEEPALIVE: | ||
| 421 | wdt_keepalive(); | ||
| 422 | return 0; | ||
| 423 | |||
| 428 | case WDIOC_SETTIMEOUT: | 424 | case WDIOC_SETTIMEOUT: |
| 429 | if (get_user(new_timeout, uarg.i)) | 425 | if (get_user(new_timeout, uarg.i)) |
| 430 | return -EFAULT; | 426 | return -EFAULT; |
| @@ -438,29 +434,30 @@ static int wdt_ioctl(struct inode *inode, struct file *file, | |||
| 438 | case WDIOC_GETTIMEOUT: | 434 | case WDIOC_GETTIMEOUT: |
| 439 | return put_user(timeout, uarg.i); | 435 | return put_user(timeout, uarg.i); |
| 440 | 436 | ||
| 437 | default: | ||
| 438 | return -ENOTTY; | ||
| 439 | |||
| 441 | } | 440 | } |
| 442 | } | 441 | } |
| 443 | 442 | ||
| 444 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, | 443 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, |
| 445 | void *unused) | 444 | void *unused) |
| 446 | { | 445 | { |
| 447 | if (code==SYS_DOWN || code==SYS_HALT) | 446 | if (code == SYS_DOWN || code == SYS_HALT) |
| 448 | wdt_stop(); | 447 | wdt_stop(); |
| 449 | return NOTIFY_DONE; | 448 | return NOTIFY_DONE; |
| 450 | } | 449 | } |
| 451 | 450 | ||
| 452 | static const struct file_operations wdt_fops= | 451 | static const struct file_operations wdt_fops = { |
| 453 | { | ||
| 454 | .owner = THIS_MODULE, | 452 | .owner = THIS_MODULE, |
| 455 | .llseek = no_llseek, | 453 | .llseek = no_llseek, |
| 456 | .write = wdt_write, | 454 | .write = wdt_write, |
| 457 | .ioctl = wdt_ioctl, | 455 | .unlocked_ioctl = wdt_ioctl, |
| 458 | .open = wdt_open, | 456 | .open = wdt_open, |
| 459 | .release = wdt_release, | 457 | .release = wdt_release, |
| 460 | }; | 458 | }; |
| 461 | 459 | ||
| 462 | static struct miscdevice wdt_miscdev= | 460 | static struct miscdevice wdt_miscdev = { |
| 463 | { | ||
| 464 | .minor = WATCHDOG_MINOR, | 461 | .minor = WATCHDOG_MINOR, |
| 465 | .name = "watchdog", | 462 | .name = "watchdog", |
| 466 | .fops = &wdt_fops, | 463 | .fops = &wdt_fops, |
| @@ -474,20 +471,20 @@ static int __init w83977f_wdt_init(void) | |||
| 474 | { | 471 | { |
| 475 | int rc; | 472 | int rc; |
| 476 | 473 | ||
| 477 | printk(KERN_INFO PFX DRIVER_VERSION); | 474 | printk(KERN_INFO PFX DRIVER_VERSION); |
| 478 | 475 | ||
| 479 | /* | 476 | /* |
| 480 | * Check that the timeout value is within it's range ; | 477 | * Check that the timeout value is within it's range; |
| 481 | * if not reset to the default | 478 | * if not reset to the default |
| 482 | */ | 479 | */ |
| 483 | if (wdt_set_timeout(timeout)) { | 480 | if (wdt_set_timeout(timeout)) { |
| 484 | wdt_set_timeout(DEFAULT_TIMEOUT); | 481 | wdt_set_timeout(DEFAULT_TIMEOUT); |
| 485 | printk(KERN_INFO PFX "timeout value must be 15<=timeout<=7635, using %d\n", | 482 | printk(KERN_INFO PFX |
| 486 | DEFAULT_TIMEOUT); | 483 | "timeout value must be 15 <= timeout <= 7635, using %d\n", |
| 484 | DEFAULT_TIMEOUT); | ||
| 487 | } | 485 | } |
| 488 | 486 | ||
| 489 | if (!request_region(IO_INDEX_PORT, 2, WATCHDOG_NAME)) | 487 | if (!request_region(IO_INDEX_PORT, 2, WATCHDOG_NAME)) { |
| 490 | { | ||
| 491 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", | 488 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", |
| 492 | IO_INDEX_PORT); | 489 | IO_INDEX_PORT); |
| 493 | rc = -EIO; | 490 | rc = -EIO; |
| @@ -495,30 +492,30 @@ static int __init w83977f_wdt_init(void) | |||
| 495 | } | 492 | } |
| 496 | 493 | ||
| 497 | rc = register_reboot_notifier(&wdt_notifier); | 494 | rc = register_reboot_notifier(&wdt_notifier); |
| 498 | if (rc) | 495 | if (rc) { |
| 499 | { | 496 | printk(KERN_ERR PFX |
| 500 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 497 | "cannot register reboot notifier (err=%d)\n", rc); |
| 501 | rc); | ||
| 502 | goto err_out_region; | 498 | goto err_out_region; |
| 503 | } | 499 | } |
| 504 | 500 | ||
| 505 | rc = misc_register(&wdt_miscdev); | 501 | rc = misc_register(&wdt_miscdev); |
| 506 | if (rc) | 502 | if (rc) { |
| 507 | { | 503 | printk(KERN_ERR PFX |
| 508 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 504 | "cannot register miscdev on minor=%d (err=%d)\n", |
| 509 | wdt_miscdev.minor, rc); | 505 | wdt_miscdev.minor, rc); |
| 510 | goto err_out_reboot; | 506 | goto err_out_reboot; |
| 511 | } | 507 | } |
| 512 | 508 | ||
| 513 | printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d testmode=%d)\n", | 509 | printk(KERN_INFO PFX |
| 514 | timeout, nowayout, testmode); | 510 | "initialized. timeout=%d sec (nowayout=%d testmode=%d)\n", |
| 511 | timeout, nowayout, testmode); | ||
| 515 | 512 | ||
| 516 | return 0; | 513 | return 0; |
| 517 | 514 | ||
| 518 | err_out_reboot: | 515 | err_out_reboot: |
| 519 | unregister_reboot_notifier(&wdt_notifier); | 516 | unregister_reboot_notifier(&wdt_notifier); |
| 520 | err_out_region: | 517 | err_out_region: |
| 521 | release_region(IO_INDEX_PORT,2); | 518 | release_region(IO_INDEX_PORT, 2); |
| 522 | err_out: | 519 | err_out: |
| 523 | return rc; | 520 | return rc; |
| 524 | } | 521 | } |
| @@ -528,7 +525,7 @@ static void __exit w83977f_wdt_exit(void) | |||
| 528 | wdt_stop(); | 525 | wdt_stop(); |
| 529 | misc_deregister(&wdt_miscdev); | 526 | misc_deregister(&wdt_miscdev); |
| 530 | unregister_reboot_notifier(&wdt_notifier); | 527 | unregister_reboot_notifier(&wdt_notifier); |
| 531 | release_region(IO_INDEX_PORT,2); | 528 | release_region(IO_INDEX_PORT, 2); |
| 532 | } | 529 | } |
| 533 | 530 | ||
| 534 | module_init(w83977f_wdt_init); | 531 | module_init(w83977f_wdt_init); |
diff --git a/drivers/watchdog/wafer5823wdt.c b/drivers/watchdog/wafer5823wdt.c index 9e368091f799..68377ae171ff 100644 --- a/drivers/watchdog/wafer5823wdt.c +++ b/drivers/watchdog/wafer5823wdt.c | |||
| @@ -1,11 +1,11 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * ICP Wafer 5823 Single Board Computer WDT driver | 2 | * ICP Wafer 5823 Single Board Computer WDT driver |
| 3 | * http://www.icpamerica.com/wafer_5823.php | 3 | * http://www.icpamerica.com/wafer_5823.php |
| 4 | * May also work on other similar models | 4 | * May also work on other similar models |
| 5 | * | 5 | * |
| 6 | * (c) Copyright 2002 Justin Cormack <justin@street-vision.com> | 6 | * (c) Copyright 2002 Justin Cormack <justin@street-vision.com> |
| 7 | * | 7 | * |
| 8 | * Release 0.02 | 8 | * Release 0.02 |
| 9 | * | 9 | * |
| 10 | * Based on advantechwdt.c which is based on wdt.c. | 10 | * Based on advantechwdt.c which is based on wdt.c. |
| 11 | * Original copyright messages: | 11 | * Original copyright messages: |
| @@ -36,8 +36,8 @@ | |||
| 36 | #include <linux/reboot.h> | 36 | #include <linux/reboot.h> |
| 37 | #include <linux/init.h> | 37 | #include <linux/init.h> |
| 38 | #include <linux/spinlock.h> | 38 | #include <linux/spinlock.h> |
| 39 | #include <asm/io.h> | 39 | #include <linux/io.h> |
| 40 | #include <asm/uaccess.h> | 40 | #include <linux/uaccess.h> |
| 41 | 41 | ||
| 42 | #define WATCHDOG_NAME "Wafer 5823 WDT" | 42 | #define WATCHDOG_NAME "Wafer 5823 WDT" |
| 43 | #define PFX WATCHDOG_NAME ": " | 43 | #define PFX WATCHDOG_NAME ": " |
| @@ -50,10 +50,10 @@ static DEFINE_SPINLOCK(wafwdt_lock); | |||
| 50 | /* | 50 | /* |
| 51 | * You must set these - there is no sane way to probe for this board. | 51 | * You must set these - there is no sane way to probe for this board. |
| 52 | * | 52 | * |
| 53 | * To enable, write the timeout value in seconds (1 to 255) to I/O | 53 | * To enable, write the timeout value in seconds (1 to 255) to I/O |
| 54 | * port WDT_START, then read the port to start the watchdog. To pat | 54 | * port WDT_START, then read the port to start the watchdog. To pat |
| 55 | * the dog, read port WDT_STOP to stop the timer, then read WDT_START | 55 | * the dog, read port WDT_STOP to stop the timer, then read WDT_START |
| 56 | * to restart it again. | 56 | * to restart it again. |
| 57 | */ | 57 | */ |
| 58 | 58 | ||
| 59 | static int wdt_stop = 0x843; | 59 | static int wdt_stop = 0x843; |
| @@ -61,11 +61,15 @@ static int wdt_start = 0x443; | |||
| 61 | 61 | ||
| 62 | static int timeout = WD_TIMO; /* in seconds */ | 62 | static int timeout = WD_TIMO; /* in seconds */ |
| 63 | module_param(timeout, int, 0); | 63 | module_param(timeout, int, 0); |
| 64 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255, default=" __MODULE_STRING(WD_TIMO) "."); | 64 | MODULE_PARM_DESC(timeout, |
| 65 | "Watchdog timeout in seconds. 1 <= timeout <= 255, default=" | ||
| 66 | __MODULE_STRING(WD_TIMO) "."); | ||
| 65 | 67 | ||
| 66 | static int nowayout = WATCHDOG_NOWAYOUT; | 68 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 67 | module_param(nowayout, int, 0); | 69 | module_param(nowayout, int, 0); |
| 68 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 70 | MODULE_PARM_DESC(nowayout, |
| 71 | "Watchdog cannot be stopped once started (default=" | ||
| 72 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 69 | 73 | ||
| 70 | static void wafwdt_ping(void) | 74 | static void wafwdt_ping(void) |
| 71 | { | 75 | { |
| @@ -83,14 +87,14 @@ static void wafwdt_start(void) | |||
| 83 | inb_p(wdt_start); | 87 | inb_p(wdt_start); |
| 84 | } | 88 | } |
| 85 | 89 | ||
| 86 | static void | 90 | static void wafwdt_stop(void) |
| 87 | wafwdt_stop(void) | ||
| 88 | { | 91 | { |
| 89 | /* stop watchdog */ | 92 | /* stop watchdog */ |
| 90 | inb_p(wdt_stop); | 93 | inb_p(wdt_stop); |
| 91 | } | 94 | } |
| 92 | 95 | ||
| 93 | static ssize_t wafwdt_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) | 96 | static ssize_t wafwdt_write(struct file *file, const char __user *buf, |
| 97 | size_t count, loff_t *ppos) | ||
| 94 | { | 98 | { |
| 95 | /* See if we got the magic character 'V' and reload the timer */ | 99 | /* See if we got the magic character 'V' and reload the timer */ |
| 96 | if (count) { | 100 | if (count) { |
| @@ -100,7 +104,8 @@ static ssize_t wafwdt_write(struct file *file, const char __user *buf, size_t co | |||
| 100 | /* In case it was set long ago */ | 104 | /* In case it was set long ago */ |
| 101 | expect_close = 0; | 105 | expect_close = 0; |
| 102 | 106 | ||
| 103 | /* scan to see whether or not we got the magic character */ | 107 | /* scan to see whether or not we got the magic |
| 108 | character */ | ||
| 104 | for (i = 0; i != count; i++) { | 109 | for (i = 0; i != count; i++) { |
| 105 | char c; | 110 | char c; |
| 106 | if (get_user(c, buf + i)) | 111 | if (get_user(c, buf + i)) |
| @@ -109,27 +114,29 @@ static ssize_t wafwdt_write(struct file *file, const char __user *buf, size_t co | |||
| 109 | expect_close = 42; | 114 | expect_close = 42; |
| 110 | } | 115 | } |
| 111 | } | 116 | } |
| 112 | /* Well, anyhow someone wrote to us, we should return that favour */ | 117 | /* Well, anyhow someone wrote to us, we should |
| 118 | return that favour */ | ||
| 113 | wafwdt_ping(); | 119 | wafwdt_ping(); |
| 114 | } | 120 | } |
| 115 | return count; | 121 | return count; |
| 116 | } | 122 | } |
| 117 | 123 | ||
| 118 | static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 124 | static long wafwdt_ioctl(struct file *file, unsigned int cmd, |
| 119 | unsigned long arg) | 125 | unsigned long arg) |
| 120 | { | 126 | { |
| 121 | int new_timeout; | 127 | int new_timeout; |
| 122 | void __user *argp = (void __user *)arg; | 128 | void __user *argp = (void __user *)arg; |
| 123 | int __user *p = argp; | 129 | int __user *p = argp; |
| 124 | static struct watchdog_info ident = { | 130 | static const struct watchdog_info ident = { |
| 125 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, | 131 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | |
| 132 | WDIOF_MAGICCLOSE, | ||
| 126 | .firmware_version = 1, | 133 | .firmware_version = 1, |
| 127 | .identity = "Wafer 5823 WDT", | 134 | .identity = "Wafer 5823 WDT", |
| 128 | }; | 135 | }; |
| 129 | 136 | ||
| 130 | switch (cmd) { | 137 | switch (cmd) { |
| 131 | case WDIOC_GETSUPPORT: | 138 | case WDIOC_GETSUPPORT: |
| 132 | if (copy_to_user(argp, &ident, sizeof (ident))) | 139 | if (copy_to_user(argp, &ident, sizeof(ident))) |
| 133 | return -EFAULT; | 140 | return -EFAULT; |
| 134 | break; | 141 | break; |
| 135 | 142 | ||
| @@ -137,22 +144,6 @@ static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
| 137 | case WDIOC_GETBOOTSTATUS: | 144 | case WDIOC_GETBOOTSTATUS: |
| 138 | return put_user(0, p); | 145 | return put_user(0, p); |
| 139 | 146 | ||
| 140 | case WDIOC_KEEPALIVE: | ||
| 141 | wafwdt_ping(); | ||
| 142 | break; | ||
| 143 | |||
| 144 | case WDIOC_SETTIMEOUT: | ||
| 145 | if (get_user(new_timeout, p)) | ||
| 146 | return -EFAULT; | ||
| 147 | if ((new_timeout < 1) || (new_timeout > 255)) | ||
| 148 | return -EINVAL; | ||
| 149 | timeout = new_timeout; | ||
| 150 | wafwdt_stop(); | ||
| 151 | wafwdt_start(); | ||
| 152 | /* Fall */ | ||
| 153 | case WDIOC_GETTIMEOUT: | ||
| 154 | return put_user(timeout, p); | ||
| 155 | |||
| 156 | case WDIOC_SETOPTIONS: | 147 | case WDIOC_SETOPTIONS: |
| 157 | { | 148 | { |
| 158 | int options, retval = -EINVAL; | 149 | int options, retval = -EINVAL; |
| @@ -173,6 +164,22 @@ static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
| 173 | return retval; | 164 | return retval; |
| 174 | } | 165 | } |
| 175 | 166 | ||
| 167 | case WDIOC_KEEPALIVE: | ||
| 168 | wafwdt_ping(); | ||
| 169 | break; | ||
| 170 | |||
| 171 | case WDIOC_SETTIMEOUT: | ||
| 172 | if (get_user(new_timeout, p)) | ||
| 173 | return -EFAULT; | ||
| 174 | if ((new_timeout < 1) || (new_timeout > 255)) | ||
| 175 | return -EINVAL; | ||
| 176 | timeout = new_timeout; | ||
| 177 | wafwdt_stop(); | ||
| 178 | wafwdt_start(); | ||
| 179 | /* Fall */ | ||
| 180 | case WDIOC_GETTIMEOUT: | ||
| 181 | return put_user(timeout, p); | ||
| 182 | |||
| 176 | default: | 183 | default: |
| 177 | return -ENOTTY; | 184 | return -ENOTTY; |
| 178 | } | 185 | } |
| @@ -191,13 +198,13 @@ static int wafwdt_open(struct inode *inode, struct file *file) | |||
| 191 | return nonseekable_open(inode, file); | 198 | return nonseekable_open(inode, file); |
| 192 | } | 199 | } |
| 193 | 200 | ||
| 194 | static int | 201 | static int wafwdt_close(struct inode *inode, struct file *file) |
| 195 | wafwdt_close(struct inode *inode, struct file *file) | ||
| 196 | { | 202 | { |
| 197 | if (expect_close == 42) { | 203 | if (expect_close == 42) |
| 198 | wafwdt_stop(); | 204 | wafwdt_stop(); |
| 199 | } else { | 205 | else { |
| 200 | printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n"); | 206 | printk(KERN_CRIT PFX |
| 207 | "WDT device closed unexpectedly. WDT will not stop!\n"); | ||
| 201 | wafwdt_ping(); | 208 | wafwdt_ping(); |
| 202 | } | 209 | } |
| 203 | clear_bit(0, &wafwdt_is_open); | 210 | clear_bit(0, &wafwdt_is_open); |
| @@ -209,12 +216,11 @@ wafwdt_close(struct inode *inode, struct file *file) | |||
| 209 | * Notifier for system down | 216 | * Notifier for system down |
| 210 | */ | 217 | */ |
| 211 | 218 | ||
| 212 | static int wafwdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) | 219 | static int wafwdt_notify_sys(struct notifier_block *this, unsigned long code, |
| 220 | void *unused) | ||
| 213 | { | 221 | { |
| 214 | if (code == SYS_DOWN || code == SYS_HALT) { | 222 | if (code == SYS_DOWN || code == SYS_HALT) |
| 215 | /* Turn the WDT off */ | ||
| 216 | wafwdt_stop(); | 223 | wafwdt_stop(); |
| 217 | } | ||
| 218 | return NOTIFY_DONE; | 224 | return NOTIFY_DONE; |
| 219 | } | 225 | } |
| 220 | 226 | ||
| @@ -226,7 +232,7 @@ static const struct file_operations wafwdt_fops = { | |||
| 226 | .owner = THIS_MODULE, | 232 | .owner = THIS_MODULE, |
| 227 | .llseek = no_llseek, | 233 | .llseek = no_llseek, |
| 228 | .write = wafwdt_write, | 234 | .write = wafwdt_write, |
| 229 | .ioctl = wafwdt_ioctl, | 235 | .unlocked_ioctl = wafwdt_ioctl, |
| 230 | .open = wafwdt_open, | 236 | .open = wafwdt_open, |
| 231 | .release = wafwdt_close, | 237 | .release = wafwdt_close, |
| 232 | }; | 238 | }; |
| @@ -250,25 +256,28 @@ static int __init wafwdt_init(void) | |||
| 250 | { | 256 | { |
| 251 | int ret; | 257 | int ret; |
| 252 | 258 | ||
| 253 | printk(KERN_INFO "WDT driver for Wafer 5823 single board computer initialising.\n"); | 259 | printk(KERN_INFO |
| 260 | "WDT driver for Wafer 5823 single board computer initialising.\n"); | ||
| 254 | 261 | ||
| 255 | if (timeout < 1 || timeout > 255) { | 262 | if (timeout < 1 || timeout > 255) { |
| 256 | timeout = WD_TIMO; | 263 | timeout = WD_TIMO; |
| 257 | printk (KERN_INFO PFX "timeout value must be 1<=x<=255, using %d\n", | 264 | printk(KERN_INFO PFX |
| 258 | timeout); | 265 | "timeout value must be 1 <= x <= 255, using %d\n", |
| 266 | timeout); | ||
| 259 | } | 267 | } |
| 260 | 268 | ||
| 261 | if (wdt_stop != wdt_start) { | 269 | if (wdt_stop != wdt_start) { |
| 262 | if(!request_region(wdt_stop, 1, "Wafer 5823 WDT")) { | 270 | if (!request_region(wdt_stop, 1, "Wafer 5823 WDT")) { |
| 263 | printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", | 271 | printk(KERN_ERR PFX |
| 264 | wdt_stop); | 272 | "I/O address 0x%04x already in use\n", |
| 273 | wdt_stop); | ||
| 265 | ret = -EIO; | 274 | ret = -EIO; |
| 266 | goto error; | 275 | goto error; |
| 267 | } | 276 | } |
| 268 | } | 277 | } |
| 269 | 278 | ||
| 270 | if(!request_region(wdt_start, 1, "Wafer 5823 WDT")) { | 279 | if (!request_region(wdt_start, 1, "Wafer 5823 WDT")) { |
| 271 | printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", | 280 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", |
| 272 | wdt_start); | 281 | wdt_start); |
| 273 | ret = -EIO; | 282 | ret = -EIO; |
| 274 | goto error2; | 283 | goto error2; |
| @@ -276,19 +285,20 @@ static int __init wafwdt_init(void) | |||
| 276 | 285 | ||
| 277 | ret = register_reboot_notifier(&wafwdt_notifier); | 286 | ret = register_reboot_notifier(&wafwdt_notifier); |
| 278 | if (ret != 0) { | 287 | if (ret != 0) { |
| 279 | printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 288 | printk(KERN_ERR PFX |
| 280 | ret); | 289 | "cannot register reboot notifier (err=%d)\n", ret); |
| 281 | goto error3; | 290 | goto error3; |
| 282 | } | 291 | } |
| 283 | 292 | ||
| 284 | ret = misc_register(&wafwdt_miscdev); | 293 | ret = misc_register(&wafwdt_miscdev); |
| 285 | if (ret != 0) { | 294 | if (ret != 0) { |
| 286 | printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 295 | printk(KERN_ERR PFX |
| 287 | WATCHDOG_MINOR, ret); | 296 | "cannot register miscdev on minor=%d (err=%d)\n", |
| 297 | WATCHDOG_MINOR, ret); | ||
| 288 | goto error4; | 298 | goto error4; |
| 289 | } | 299 | } |
| 290 | 300 | ||
| 291 | printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", | 301 | printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", |
| 292 | timeout, nowayout); | 302 | timeout, nowayout); |
| 293 | 303 | ||
| 294 | return ret; | 304 | return ret; |
| @@ -307,7 +317,7 @@ static void __exit wafwdt_exit(void) | |||
| 307 | { | 317 | { |
| 308 | misc_deregister(&wafwdt_miscdev); | 318 | misc_deregister(&wafwdt_miscdev); |
| 309 | unregister_reboot_notifier(&wafwdt_notifier); | 319 | unregister_reboot_notifier(&wafwdt_notifier); |
| 310 | if(wdt_stop != wdt_start) | 320 | if (wdt_stop != wdt_start) |
| 311 | release_region(wdt_stop, 1); | 321 | release_region(wdt_stop, 1); |
| 312 | release_region(wdt_start, 1); | 322 | release_region(wdt_start, 1); |
| 313 | } | 323 | } |
diff --git a/drivers/watchdog/wd501p.h b/drivers/watchdog/wd501p.h index a4504f40394d..db34853c28ae 100644 --- a/drivers/watchdog/wd501p.h +++ b/drivers/watchdog/wd501p.h | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | * http://www.cymru.net | 12 | * http://www.cymru.net |
| 13 | * | 13 | * |
| 14 | * This driver is provided under the GNU General Public License, incorporated | 14 | * This driver is provided under the GNU General Public License, incorporated |
| 15 | * herein by reference. The driver is provided without warranty or | 15 | * herein by reference. The driver is provided without warranty or |
| 16 | * support. | 16 | * support. |
| 17 | * | 17 | * |
| 18 | * Release 0.04. | 18 | * Release 0.04. |
diff --git a/drivers/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c index 1d64e277567d..5d3b1a8e28b0 100644 --- a/drivers/watchdog/wdrtas.c +++ b/drivers/watchdog/wdrtas.c | |||
| @@ -35,9 +35,9 @@ | |||
| 35 | #include <linux/reboot.h> | 35 | #include <linux/reboot.h> |
| 36 | #include <linux/types.h> | 36 | #include <linux/types.h> |
| 37 | #include <linux/watchdog.h> | 37 | #include <linux/watchdog.h> |
| 38 | #include <linux/uaccess.h> | ||
| 38 | 39 | ||
| 39 | #include <asm/rtas.h> | 40 | #include <asm/rtas.h> |
| 40 | #include <asm/uaccess.h> | ||
| 41 | 41 | ||
| 42 | #define WDRTAS_MAGIC_CHAR 42 | 42 | #define WDRTAS_MAGIC_CHAR 42 |
| 43 | #define WDRTAS_SUPPORTED_MASK (WDIOF_SETTIMEOUT | \ | 43 | #define WDRTAS_SUPPORTED_MASK (WDIOF_SETTIMEOUT | \ |
| @@ -56,7 +56,7 @@ static int wdrtas_nowayout = 0; | |||
| 56 | #endif | 56 | #endif |
| 57 | 57 | ||
| 58 | static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0); | 58 | static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0); |
| 59 | static char wdrtas_expect_close = 0; | 59 | static char wdrtas_expect_close; |
| 60 | 60 | ||
| 61 | static int wdrtas_interval; | 61 | static int wdrtas_interval; |
| 62 | 62 | ||
| @@ -86,8 +86,8 @@ static char wdrtas_logbuffer[WDRTAS_LOGBUFFER_LEN]; | |||
| 86 | * RTAS function set-indicator (surveillance). The unit of interval is | 86 | * RTAS function set-indicator (surveillance). The unit of interval is |
| 87 | * seconds. | 87 | * seconds. |
| 88 | */ | 88 | */ |
| 89 | static int | 89 | |
| 90 | wdrtas_set_interval(int interval) | 90 | static int wdrtas_set_interval(int interval) |
| 91 | { | 91 | { |
| 92 | long result; | 92 | long result; |
| 93 | static int print_msg = 10; | 93 | static int print_msg = 10; |
| @@ -97,7 +97,7 @@ wdrtas_set_interval(int interval) | |||
| 97 | 97 | ||
| 98 | result = rtas_call(wdrtas_token_set_indicator, 3, 1, NULL, | 98 | result = rtas_call(wdrtas_token_set_indicator, 3, 1, NULL, |
| 99 | WDRTAS_SURVEILLANCE_IND, 0, interval); | 99 | WDRTAS_SURVEILLANCE_IND, 0, interval); |
| 100 | if ( (result < 0) && (print_msg) ) { | 100 | if (result < 0 && print_msg) { |
| 101 | printk(KERN_ERR "wdrtas: setting the watchdog to %i " | 101 | printk(KERN_ERR "wdrtas: setting the watchdog to %i " |
| 102 | "timeout failed: %li\n", interval, result); | 102 | "timeout failed: %li\n", interval, result); |
| 103 | print_msg--; | 103 | print_msg--; |
| @@ -116,16 +116,14 @@ wdrtas_set_interval(int interval) | |||
| 116 | * as reported by the RTAS function ibm,get-system-parameter. The unit | 116 | * as reported by the RTAS function ibm,get-system-parameter. The unit |
| 117 | * of the return value is seconds. | 117 | * of the return value is seconds. |
| 118 | */ | 118 | */ |
| 119 | static int | 119 | static int wdrtas_get_interval(int fallback_value) |
| 120 | wdrtas_get_interval(int fallback_value) | ||
| 121 | { | 120 | { |
| 122 | long result; | 121 | long result; |
| 123 | char value[4]; | 122 | char value[4]; |
| 124 | 123 | ||
| 125 | result = rtas_call(wdrtas_token_get_sp, 3, 1, NULL, | 124 | result = rtas_call(wdrtas_token_get_sp, 3, 1, NULL, |
| 126 | WDRTAS_SP_SPI, (void *)__pa(&value), 4); | 125 | WDRTAS_SP_SPI, (void *)__pa(&value), 4); |
| 127 | if ( (value[0] != 0) || (value[1] != 2) || (value[3] != 0) || | 126 | if (value[0] != 0 || value[1] != 2 || value[3] != 0 || result < 0) { |
| 128 | (result < 0) ) { | ||
| 129 | printk(KERN_WARNING "wdrtas: could not get sp_spi watchdog " | 127 | printk(KERN_WARNING "wdrtas: could not get sp_spi watchdog " |
| 130 | "timeout (%li). Continuing\n", result); | 128 | "timeout (%li). Continuing\n", result); |
| 131 | return fallback_value; | 129 | return fallback_value; |
| @@ -141,8 +139,7 @@ wdrtas_get_interval(int fallback_value) | |||
| 141 | * wdrtas_timer_start starts the watchdog by calling the RTAS function | 139 | * wdrtas_timer_start starts the watchdog by calling the RTAS function |
| 142 | * set-interval (surveillance) | 140 | * set-interval (surveillance) |
| 143 | */ | 141 | */ |
| 144 | static void | 142 | static void wdrtas_timer_start(void) |
| 145 | wdrtas_timer_start(void) | ||
| 146 | { | 143 | { |
| 147 | wdrtas_set_interval(wdrtas_interval); | 144 | wdrtas_set_interval(wdrtas_interval); |
| 148 | } | 145 | } |
| @@ -153,8 +150,7 @@ wdrtas_timer_start(void) | |||
| 153 | * wdrtas_timer_stop stops the watchdog timer by calling the RTAS function | 150 | * wdrtas_timer_stop stops the watchdog timer by calling the RTAS function |
| 154 | * set-interval (surveillance) | 151 | * set-interval (surveillance) |
| 155 | */ | 152 | */ |
| 156 | static void | 153 | static void wdrtas_timer_stop(void) |
| 157 | wdrtas_timer_stop(void) | ||
| 158 | { | 154 | { |
| 159 | wdrtas_set_interval(0); | 155 | wdrtas_set_interval(0); |
| 160 | } | 156 | } |
| @@ -165,8 +161,7 @@ wdrtas_timer_stop(void) | |||
| 165 | * wdrtas_log_scanned_event prints a message to the log buffer dumping | 161 | * wdrtas_log_scanned_event prints a message to the log buffer dumping |
| 166 | * the results of the last event-scan call | 162 | * the results of the last event-scan call |
| 167 | */ | 163 | */ |
| 168 | static void | 164 | static void wdrtas_log_scanned_event(void) |
| 169 | wdrtas_log_scanned_event(void) | ||
| 170 | { | 165 | { |
| 171 | int i; | 166 | int i; |
| 172 | 167 | ||
| @@ -175,13 +170,13 @@ wdrtas_log_scanned_event(void) | |||
| 175 | "%02x %02x %02x %02x %02x %02x %02x %02x " | 170 | "%02x %02x %02x %02x %02x %02x %02x %02x " |
| 176 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", | 171 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", |
| 177 | (i / 16) + 1, (WDRTAS_LOGBUFFER_LEN / 16), | 172 | (i / 16) + 1, (WDRTAS_LOGBUFFER_LEN / 16), |
| 178 | wdrtas_logbuffer[i + 0], wdrtas_logbuffer[i + 1], | 173 | wdrtas_logbuffer[i + 0], wdrtas_logbuffer[i + 1], |
| 179 | wdrtas_logbuffer[i + 2], wdrtas_logbuffer[i + 3], | 174 | wdrtas_logbuffer[i + 2], wdrtas_logbuffer[i + 3], |
| 180 | wdrtas_logbuffer[i + 4], wdrtas_logbuffer[i + 5], | 175 | wdrtas_logbuffer[i + 4], wdrtas_logbuffer[i + 5], |
| 181 | wdrtas_logbuffer[i + 6], wdrtas_logbuffer[i + 7], | 176 | wdrtas_logbuffer[i + 6], wdrtas_logbuffer[i + 7], |
| 182 | wdrtas_logbuffer[i + 8], wdrtas_logbuffer[i + 9], | 177 | wdrtas_logbuffer[i + 8], wdrtas_logbuffer[i + 9], |
| 183 | wdrtas_logbuffer[i + 10], wdrtas_logbuffer[i + 11], | 178 | wdrtas_logbuffer[i + 10], wdrtas_logbuffer[i + 11], |
| 184 | wdrtas_logbuffer[i + 12], wdrtas_logbuffer[i + 13], | 179 | wdrtas_logbuffer[i + 12], wdrtas_logbuffer[i + 13], |
| 185 | wdrtas_logbuffer[i + 14], wdrtas_logbuffer[i + 15]); | 180 | wdrtas_logbuffer[i + 14], wdrtas_logbuffer[i + 15]); |
| 186 | } | 181 | } |
| 187 | 182 | ||
| @@ -192,8 +187,7 @@ wdrtas_log_scanned_event(void) | |||
| 192 | * RTAS function event-scan and repeats these calls as long as there are | 187 | * RTAS function event-scan and repeats these calls as long as there are |
| 193 | * events available. All events will be dumped. | 188 | * events available. All events will be dumped. |
| 194 | */ | 189 | */ |
| 195 | static void | 190 | static void wdrtas_timer_keepalive(void) |
| 196 | wdrtas_timer_keepalive(void) | ||
| 197 | { | 191 | { |
| 198 | long result; | 192 | long result; |
| 199 | 193 | ||
| @@ -218,8 +212,7 @@ wdrtas_timer_keepalive(void) | |||
| 218 | * wdrtas_get_temperature returns the current temperature in Fahrenheit. It | 212 | * wdrtas_get_temperature returns the current temperature in Fahrenheit. It |
| 219 | * uses the RTAS call get-sensor-state, token 3 to do so | 213 | * uses the RTAS call get-sensor-state, token 3 to do so |
| 220 | */ | 214 | */ |
| 221 | static int | 215 | static int wdrtas_get_temperature(void) |
| 222 | wdrtas_get_temperature(void) | ||
| 223 | { | 216 | { |
| 224 | long result; | 217 | long result; |
| 225 | int temperature = 0; | 218 | int temperature = 0; |
| @@ -243,8 +236,7 @@ wdrtas_get_temperature(void) | |||
| 243 | * returns a bitmask of defines WDIOF_... as defined in | 236 | * returns a bitmask of defines WDIOF_... as defined in |
| 244 | * include/linux/watchdog.h | 237 | * include/linux/watchdog.h |
| 245 | */ | 238 | */ |
| 246 | static int | 239 | static int wdrtas_get_status(void) |
| 247 | wdrtas_get_status(void) | ||
| 248 | { | 240 | { |
| 249 | return 0; /* TODO */ | 241 | return 0; /* TODO */ |
| 250 | } | 242 | } |
| @@ -255,8 +247,7 @@ wdrtas_get_status(void) | |||
| 255 | * returns a bitmask of defines WDIOF_... as defined in | 247 | * returns a bitmask of defines WDIOF_... as defined in |
| 256 | * include/linux/watchdog.h, indicating why the watchdog rebooted the system | 248 | * include/linux/watchdog.h, indicating why the watchdog rebooted the system |
| 257 | */ | 249 | */ |
| 258 | static int | 250 | static int wdrtas_get_boot_status(void) |
| 259 | wdrtas_get_boot_status(void) | ||
| 260 | { | 251 | { |
| 261 | return 0; /* TODO */ | 252 | return 0; /* TODO */ |
| 262 | } | 253 | } |
| @@ -276,8 +267,7 @@ wdrtas_get_boot_status(void) | |||
| 276 | * character 'V'. This character allows the watchdog device to be closed | 267 | * character 'V'. This character allows the watchdog device to be closed |
| 277 | * properly. | 268 | * properly. |
| 278 | */ | 269 | */ |
| 279 | static ssize_t | 270 | static ssize_t wdrtas_write(struct file *file, const char __user *buf, |
| 280 | wdrtas_write(struct file *file, const char __user *buf, | ||
| 281 | size_t len, loff_t *ppos) | 271 | size_t len, loff_t *ppos) |
| 282 | { | 272 | { |
| 283 | int i; | 273 | int i; |
| @@ -306,7 +296,6 @@ out: | |||
| 306 | 296 | ||
| 307 | /** | 297 | /** |
| 308 | * wdrtas_ioctl - ioctl function for the watchdog device | 298 | * wdrtas_ioctl - ioctl function for the watchdog device |
| 309 | * @inode: inode structure | ||
| 310 | * @file: file structure | 299 | * @file: file structure |
| 311 | * @cmd: command for ioctl | 300 | * @cmd: command for ioctl |
| 312 | * @arg: argument pointer | 301 | * @arg: argument pointer |
| @@ -315,16 +304,16 @@ out: | |||
| 315 | * | 304 | * |
| 316 | * wdrtas_ioctl implements the watchdog API ioctls | 305 | * wdrtas_ioctl implements the watchdog API ioctls |
| 317 | */ | 306 | */ |
| 318 | static int | 307 | |
| 319 | wdrtas_ioctl(struct inode *inode, struct file *file, | 308 | static long wdrtas_ioctl(struct file *file, unsigned int cmd, |
| 320 | unsigned int cmd, unsigned long arg) | 309 | unsigned long arg) |
| 321 | { | 310 | { |
| 322 | int __user *argp = (void __user *)arg; | 311 | int __user *argp = (void __user *)arg; |
| 323 | int i; | 312 | int i; |
| 324 | static struct watchdog_info wdinfo = { | 313 | static struct watchdog_info wdinfo = { |
| 325 | .options = WDRTAS_SUPPORTED_MASK, | 314 | .options = WDRTAS_SUPPORTED_MASK, |
| 326 | .firmware_version = 0, | 315 | .firmware_version = 0, |
| 327 | .identity = "wdrtas" | 316 | .identity = "wdrtas", |
| 328 | }; | 317 | }; |
| 329 | 318 | ||
| 330 | switch (cmd) { | 319 | switch (cmd) { |
| @@ -357,9 +346,9 @@ wdrtas_ioctl(struct inode *inode, struct file *file, | |||
| 357 | wdrtas_timer_keepalive(); | 346 | wdrtas_timer_keepalive(); |
| 358 | wdrtas_timer_start(); | 347 | wdrtas_timer_start(); |
| 359 | } | 348 | } |
| 349 | /* not implemented. Done by H8 | ||
| 360 | if (i & WDIOS_TEMPPANIC) { | 350 | if (i & WDIOS_TEMPPANIC) { |
| 361 | /* not implemented. Done by H8 */ | 351 | } */ |
| 362 | } | ||
| 363 | return 0; | 352 | return 0; |
| 364 | 353 | ||
| 365 | case WDIOC_KEEPALIVE: | 354 | case WDIOC_KEEPALIVE: |
| @@ -399,8 +388,7 @@ wdrtas_ioctl(struct inode *inode, struct file *file, | |||
| 399 | * | 388 | * |
| 400 | * function called when watchdog device is opened | 389 | * function called when watchdog device is opened |
| 401 | */ | 390 | */ |
| 402 | static int | 391 | static int wdrtas_open(struct inode *inode, struct file *file) |
| 403 | wdrtas_open(struct inode *inode, struct file *file) | ||
| 404 | { | 392 | { |
| 405 | /* only open once */ | 393 | /* only open once */ |
| 406 | if (atomic_inc_return(&wdrtas_miscdev_open) > 1) { | 394 | if (atomic_inc_return(&wdrtas_miscdev_open) > 1) { |
| @@ -423,8 +411,7 @@ wdrtas_open(struct inode *inode, struct file *file) | |||
| 423 | * | 411 | * |
| 424 | * close function. Always succeeds | 412 | * close function. Always succeeds |
| 425 | */ | 413 | */ |
| 426 | static int | 414 | static int wdrtas_close(struct inode *inode, struct file *file) |
| 427 | wdrtas_close(struct inode *inode, struct file *file) | ||
| 428 | { | 415 | { |
| 429 | /* only stop watchdog, if this was announced using 'V' before */ | 416 | /* only stop watchdog, if this was announced using 'V' before */ |
| 430 | if (wdrtas_expect_close == WDRTAS_MAGIC_CHAR) | 417 | if (wdrtas_expect_close == WDRTAS_MAGIC_CHAR) |
| @@ -453,8 +440,7 @@ wdrtas_close(struct inode *inode, struct file *file) | |||
| 453 | * wdrtas_temp_read gives the temperature to the users by copying this | 440 | * wdrtas_temp_read gives the temperature to the users by copying this |
| 454 | * value as one byte into the user space buffer. The unit is Fahrenheit... | 441 | * value as one byte into the user space buffer. The unit is Fahrenheit... |
| 455 | */ | 442 | */ |
| 456 | static ssize_t | 443 | static ssize_t wdrtas_temp_read(struct file *file, char __user *buf, |
| 457 | wdrtas_temp_read(struct file *file, char __user *buf, | ||
| 458 | size_t count, loff_t *ppos) | 444 | size_t count, loff_t *ppos) |
| 459 | { | 445 | { |
| 460 | int temperature = 0; | 446 | int temperature = 0; |
| @@ -478,8 +464,7 @@ wdrtas_temp_read(struct file *file, char __user *buf, | |||
| 478 | * | 464 | * |
| 479 | * function called when temperature device is opened | 465 | * function called when temperature device is opened |
| 480 | */ | 466 | */ |
| 481 | static int | 467 | static int wdrtas_temp_open(struct inode *inode, struct file *file) |
| 482 | wdrtas_temp_open(struct inode *inode, struct file *file) | ||
| 483 | { | 468 | { |
| 484 | return nonseekable_open(inode, file); | 469 | return nonseekable_open(inode, file); |
| 485 | } | 470 | } |
| @@ -493,8 +478,7 @@ wdrtas_temp_open(struct inode *inode, struct file *file) | |||
| 493 | * | 478 | * |
| 494 | * close function. Always succeeds | 479 | * close function. Always succeeds |
| 495 | */ | 480 | */ |
| 496 | static int | 481 | static int wdrtas_temp_close(struct inode *inode, struct file *file) |
| 497 | wdrtas_temp_close(struct inode *inode, struct file *file) | ||
| 498 | { | 482 | { |
| 499 | return 0; | 483 | return 0; |
| 500 | } | 484 | } |
| @@ -509,10 +493,10 @@ wdrtas_temp_close(struct inode *inode, struct file *file) | |||
| 509 | * | 493 | * |
| 510 | * wdrtas_reboot stops the watchdog in case of a reboot | 494 | * wdrtas_reboot stops the watchdog in case of a reboot |
| 511 | */ | 495 | */ |
| 512 | static int | 496 | static int wdrtas_reboot(struct notifier_block *this, |
| 513 | wdrtas_reboot(struct notifier_block *this, unsigned long code, void *ptr) | 497 | unsigned long code, void *ptr) |
| 514 | { | 498 | { |
| 515 | if ( (code==SYS_DOWN) || (code==SYS_HALT) ) | 499 | if (code == SYS_DOWN || code == SYS_HALT) |
| 516 | wdrtas_timer_stop(); | 500 | wdrtas_timer_stop(); |
| 517 | 501 | ||
| 518 | return NOTIFY_DONE; | 502 | return NOTIFY_DONE; |
| @@ -524,7 +508,7 @@ static const struct file_operations wdrtas_fops = { | |||
| 524 | .owner = THIS_MODULE, | 508 | .owner = THIS_MODULE, |
| 525 | .llseek = no_llseek, | 509 | .llseek = no_llseek, |
| 526 | .write = wdrtas_write, | 510 | .write = wdrtas_write, |
| 527 | .ioctl = wdrtas_ioctl, | 511 | .unlocked_ioctl = wdrtas_ioctl, |
| 528 | .open = wdrtas_open, | 512 | .open = wdrtas_open, |
| 529 | .release = wdrtas_close, | 513 | .release = wdrtas_close, |
| 530 | }; | 514 | }; |
| @@ -562,8 +546,7 @@ static struct notifier_block wdrtas_notifier = { | |||
| 562 | * this watchdog driver. It tolerates, if "get-sensor-state" and | 546 | * this watchdog driver. It tolerates, if "get-sensor-state" and |
| 563 | * "ibm,get-system-parameter" are not available. | 547 | * "ibm,get-system-parameter" are not available. |
| 564 | */ | 548 | */ |
| 565 | static int | 549 | static int wdrtas_get_tokens(void) |
| 566 | wdrtas_get_tokens(void) | ||
| 567 | { | 550 | { |
| 568 | wdrtas_token_get_sensor_state = rtas_token("get-sensor-state"); | 551 | wdrtas_token_get_sensor_state = rtas_token("get-sensor-state"); |
| 569 | if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE) { | 552 | if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE) { |
| @@ -603,8 +586,7 @@ wdrtas_get_tokens(void) | |||
| 603 | * wdrtas_register_devs unregisters the watchdog and temperature watchdog | 586 | * wdrtas_register_devs unregisters the watchdog and temperature watchdog |
| 604 | * misc devs | 587 | * misc devs |
| 605 | */ | 588 | */ |
| 606 | static void | 589 | static void wdrtas_unregister_devs(void) |
| 607 | wdrtas_unregister_devs(void) | ||
| 608 | { | 590 | { |
| 609 | misc_deregister(&wdrtas_miscdev); | 591 | misc_deregister(&wdrtas_miscdev); |
| 610 | if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE) | 592 | if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE) |
| @@ -619,8 +601,7 @@ wdrtas_unregister_devs(void) | |||
| 619 | * wdrtas_register_devs registers the watchdog and temperature watchdog | 601 | * wdrtas_register_devs registers the watchdog and temperature watchdog |
| 620 | * misc devs | 602 | * misc devs |
| 621 | */ | 603 | */ |
| 622 | static int | 604 | static int wdrtas_register_devs(void) |
| 623 | wdrtas_register_devs(void) | ||
| 624 | { | 605 | { |
| 625 | int result; | 606 | int result; |
| 626 | 607 | ||
| @@ -651,8 +632,7 @@ wdrtas_register_devs(void) | |||
| 651 | * | 632 | * |
| 652 | * registers the file handlers and the reboot notifier | 633 | * registers the file handlers and the reboot notifier |
| 653 | */ | 634 | */ |
| 654 | static int __init | 635 | static int __init wdrtas_init(void) |
| 655 | wdrtas_init(void) | ||
| 656 | { | 636 | { |
| 657 | if (wdrtas_get_tokens()) | 637 | if (wdrtas_get_tokens()) |
| 658 | return -ENODEV; | 638 | return -ENODEV; |
| @@ -680,8 +660,7 @@ wdrtas_init(void) | |||
| 680 | * | 660 | * |
| 681 | * unregisters the file handlers and the reboot notifier | 661 | * unregisters the file handlers and the reboot notifier |
| 682 | */ | 662 | */ |
| 683 | static void __exit | 663 | static void __exit wdrtas_exit(void) |
| 684 | wdrtas_exit(void) | ||
| 685 | { | 664 | { |
| 686 | if (!wdrtas_nowayout) | 665 | if (!wdrtas_nowayout) |
| 687 | wdrtas_timer_stop(); | 666 | wdrtas_timer_stop(); |
diff --git a/drivers/watchdog/wdt.c b/drivers/watchdog/wdt.c index 53a6b18bcb9a..deeebb2b13ea 100644 --- a/drivers/watchdog/wdt.c +++ b/drivers/watchdog/wdt.c | |||
| @@ -373,8 +373,6 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 373 | #endif /* CONFIG_WDT_501 */ | 373 | #endif /* CONFIG_WDT_501 */ |
| 374 | 374 | ||
| 375 | switch (cmd) { | 375 | switch (cmd) { |
| 376 | default: | ||
| 377 | return -ENOTTY; | ||
| 378 | case WDIOC_GETSUPPORT: | 376 | case WDIOC_GETSUPPORT: |
| 379 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; | 377 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; |
| 380 | case WDIOC_GETSTATUS: | 378 | case WDIOC_GETSTATUS: |
| @@ -394,6 +392,8 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 394 | /* Fall */ | 392 | /* Fall */ |
| 395 | case WDIOC_GETTIMEOUT: | 393 | case WDIOC_GETTIMEOUT: |
| 396 | return put_user(heartbeat, p); | 394 | return put_user(heartbeat, p); |
| 395 | default: | ||
| 396 | return -ENOTTY; | ||
| 397 | } | 397 | } |
| 398 | } | 398 | } |
| 399 | 399 | ||
diff --git a/drivers/watchdog/wdt285.c b/drivers/watchdog/wdt285.c index 94e2d91c9ac9..c8d7f1b2df02 100644 --- a/drivers/watchdog/wdt285.c +++ b/drivers/watchdog/wdt285.c | |||
| @@ -26,10 +26,10 @@ | |||
| 26 | #include <linux/reboot.h> | 26 | #include <linux/reboot.h> |
| 27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
| 28 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
| 29 | 29 | #include <linux/uaccess.h> | |
| 30 | #include <asm/irq.h> | 30 | #include <linux/irq.h> |
| 31 | #include <asm/uaccess.h> | ||
| 32 | #include <mach/hardware.h> | 31 | #include <mach/hardware.h> |
| 32 | |||
| 33 | #include <asm/mach-types.h> | 33 | #include <asm/mach-types.h> |
| 34 | #include <asm/hardware/dec21285.h> | 34 | #include <asm/hardware/dec21285.h> |
| 35 | 35 | ||
| @@ -115,8 +115,8 @@ static int watchdog_release(struct inode *inode, struct file *file) | |||
| 115 | return 0; | 115 | return 0; |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | static ssize_t | 118 | static ssize_t watchdog_write(struct file *file, const char *data, |
| 119 | watchdog_write(struct file *file, const char *data, size_t len, loff_t *ppos) | 119 | size_t len, loff_t *ppos) |
| 120 | { | 120 | { |
| 121 | /* | 121 | /* |
| 122 | * Refresh the timer. | 122 | * Refresh the timer. |
| @@ -127,19 +127,18 @@ watchdog_write(struct file *file, const char *data, size_t len, loff_t *ppos) | |||
| 127 | return len; | 127 | return len; |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | static struct watchdog_info ident = { | 130 | static const struct watchdog_info ident = { |
| 131 | .options = WDIOF_SETTIMEOUT, | 131 | .options = WDIOF_SETTIMEOUT, |
| 132 | .identity = "Footbridge Watchdog", | 132 | .identity = "Footbridge Watchdog", |
| 133 | }; | 133 | }; |
| 134 | 134 | ||
| 135 | static int | 135 | static long watchdog_ioctl(struct file *file, unsigned int cmd, |
| 136 | watchdog_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 136 | unsigned long arg) |
| 137 | unsigned long arg) | ||
| 138 | { | 137 | { |
| 139 | unsigned int new_margin; | 138 | unsigned int new_margin; |
| 140 | int ret = -ENOTTY; | 139 | int ret = -ENOTTY; |
| 141 | 140 | ||
| 142 | switch(cmd) { | 141 | switch (cmd) { |
| 143 | case WDIOC_GETSUPPORT: | 142 | case WDIOC_GETSUPPORT: |
| 144 | ret = 0; | 143 | ret = 0; |
| 145 | if (copy_to_user((void *)arg, &ident, sizeof(ident))) | 144 | if (copy_to_user((void *)arg, &ident, sizeof(ident))) |
| @@ -148,7 +147,7 @@ watchdog_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
| 148 | 147 | ||
| 149 | case WDIOC_GETSTATUS: | 148 | case WDIOC_GETSTATUS: |
| 150 | case WDIOC_GETBOOTSTATUS: | 149 | case WDIOC_GETBOOTSTATUS: |
| 151 | ret = put_user(0,(int *)arg); | 150 | ret = put_user(0, (int *)arg); |
| 152 | break; | 151 | break; |
| 153 | 152 | ||
| 154 | case WDIOC_KEEPALIVE: | 153 | case WDIOC_KEEPALIVE: |
| @@ -182,7 +181,7 @@ static const struct file_operations watchdog_fops = { | |||
| 182 | .owner = THIS_MODULE, | 181 | .owner = THIS_MODULE, |
| 183 | .llseek = no_llseek, | 182 | .llseek = no_llseek, |
| 184 | .write = watchdog_write, | 183 | .write = watchdog_write, |
| 185 | .ioctl = watchdog_ioctl, | 184 | .unlocked_ioctl = watchdog_ioctl, |
| 186 | .open = watchdog_open, | 185 | .open = watchdog_open, |
| 187 | .release = watchdog_release, | 186 | .release = watchdog_release, |
| 188 | }; | 187 | }; |
| @@ -204,11 +203,13 @@ static int __init footbridge_watchdog_init(void) | |||
| 204 | if (retval < 0) | 203 | if (retval < 0) |
| 205 | return retval; | 204 | return retval; |
| 206 | 205 | ||
| 207 | printk("Footbridge Watchdog Timer: 0.01, timer margin: %d sec\n", | 206 | printk(KERN_INFO |
| 208 | soft_margin); | 207 | "Footbridge Watchdog Timer: 0.01, timer margin: %d sec\n", |
| 208 | soft_margin); | ||
| 209 | 209 | ||
| 210 | if (machine_is_cats()) | 210 | if (machine_is_cats()) |
| 211 | printk("Warning: Watchdog reset may not work on this machine.\n"); | 211 | printk(KERN_WARN |
| 212 | "Warning: Watchdog reset may not work on this machine.\n"); | ||
| 212 | return 0; | 213 | return 0; |
| 213 | } | 214 | } |
| 214 | 215 | ||
| @@ -223,7 +224,7 @@ MODULE_LICENSE("GPL"); | |||
| 223 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | 224 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); |
| 224 | 225 | ||
| 225 | module_param(soft_margin, int, 0); | 226 | module_param(soft_margin, int, 0); |
| 226 | MODULE_PARM_DESC(soft_margin,"Watchdog timeout in seconds"); | 227 | MODULE_PARM_DESC(soft_margin, "Watchdog timeout in seconds"); |
| 227 | 228 | ||
| 228 | module_init(footbridge_watchdog_init); | 229 | module_init(footbridge_watchdog_init); |
| 229 | module_exit(footbridge_watchdog_exit); | 230 | module_exit(footbridge_watchdog_exit); |
diff --git a/drivers/watchdog/wdt977.c b/drivers/watchdog/wdt977.c index fb4b876c9fda..60e28d49ff52 100644 --- a/drivers/watchdog/wdt977.c +++ b/drivers/watchdog/wdt977.c | |||
| @@ -19,7 +19,8 @@ | |||
| 19 | * 07-Jul-2003 Daniele Bellucci: Audit return code of misc_register in | 19 | * 07-Jul-2003 Daniele Bellucci: Audit return code of misc_register in |
| 20 | * nwwatchdog_init. | 20 | * nwwatchdog_init. |
| 21 | * 25-Oct-2005 Woody Suwalski: Convert addresses to #defs, add spinlocks | 21 | * 25-Oct-2005 Woody Suwalski: Convert addresses to #defs, add spinlocks |
| 22 | * remove limitiation to be used on Netwinders only | 22 | * remove limitiation to be used on |
| 23 | * Netwinders only | ||
| 23 | */ | 24 | */ |
| 24 | 25 | ||
| 25 | #include <linux/module.h> | 26 | #include <linux/module.h> |
| @@ -33,11 +34,11 @@ | |||
| 33 | #include <linux/watchdog.h> | 34 | #include <linux/watchdog.h> |
| 34 | #include <linux/notifier.h> | 35 | #include <linux/notifier.h> |
| 35 | #include <linux/reboot.h> | 36 | #include <linux/reboot.h> |
| 37 | #include <linux/io.h> | ||
| 38 | #include <linux/uaccess.h> | ||
| 36 | 39 | ||
| 37 | #include <asm/io.h> | ||
| 38 | #include <asm/system.h> | 40 | #include <asm/system.h> |
| 39 | #include <asm/mach-types.h> | 41 | #include <asm/mach-types.h> |
| 40 | #include <asm/uaccess.h> | ||
| 41 | 42 | ||
| 42 | #define WATCHDOG_VERSION "0.04" | 43 | #define WATCHDOG_VERSION "0.04" |
| 43 | #define WATCHDOG_NAME "Wdt977" | 44 | #define WATCHDOG_NAME "Wdt977" |
| @@ -45,7 +46,7 @@ | |||
| 45 | #define DRIVER_VERSION WATCHDOG_NAME " driver, v" WATCHDOG_VERSION "\n" | 46 | #define DRIVER_VERSION WATCHDOG_NAME " driver, v" WATCHDOG_VERSION "\n" |
| 46 | 47 | ||
| 47 | #define IO_INDEX_PORT 0x370 /* on some systems it can be 0x3F0 */ | 48 | #define IO_INDEX_PORT 0x370 /* on some systems it can be 0x3F0 */ |
| 48 | #define IO_DATA_PORT (IO_INDEX_PORT+1) | 49 | #define IO_DATA_PORT (IO_INDEX_PORT + 1) |
| 49 | 50 | ||
| 50 | #define UNLOCK_DATA 0x87 | 51 | #define UNLOCK_DATA 0x87 |
| 51 | #define LOCK_DATA 0xAA | 52 | #define LOCK_DATA 0xAA |
| @@ -62,13 +63,16 @@ static char expect_close; | |||
| 62 | static DEFINE_SPINLOCK(spinlock); | 63 | static DEFINE_SPINLOCK(spinlock); |
| 63 | 64 | ||
| 64 | module_param(timeout, int, 0); | 65 | module_param(timeout, int, 0); |
| 65 | MODULE_PARM_DESC(timeout,"Watchdog timeout in seconds (60..15300), default=" __MODULE_STRING(DEFAULT_TIMEOUT) ")"); | 66 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (60..15300), default=" |
| 67 | __MODULE_STRING(DEFAULT_TIMEOUT) ")"); | ||
| 66 | module_param(testmode, int, 0); | 68 | module_param(testmode, int, 0); |
| 67 | MODULE_PARM_DESC(testmode,"Watchdog testmode (1 = no reboot), default=0"); | 69 | MODULE_PARM_DESC(testmode, "Watchdog testmode (1 = no reboot), default=0"); |
| 68 | 70 | ||
| 69 | static int nowayout = WATCHDOG_NOWAYOUT; | 71 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 70 | module_param(nowayout, int, 0); | 72 | module_param(nowayout, int, 0); |
| 71 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 73 | MODULE_PARM_DESC(nowayout, |
| 74 | "Watchdog cannot be stopped once started (default=" | ||
| 75 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
| 72 | 76 | ||
| 73 | /* | 77 | /* |
| 74 | * Start the watchdog | 78 | * Start the watchdog |
| @@ -95,14 +99,16 @@ static int wdt977_start(void) | |||
| 95 | outb_p(0xF2, IO_INDEX_PORT); | 99 | outb_p(0xF2, IO_INDEX_PORT); |
| 96 | outb_p(timeoutM, IO_DATA_PORT); | 100 | outb_p(timeoutM, IO_DATA_PORT); |
| 97 | outb_p(0xF3, IO_INDEX_PORT); | 101 | outb_p(0xF3, IO_INDEX_PORT); |
| 98 | outb_p(0x00, IO_DATA_PORT); /* another setting is 0E for kbd/mouse/LED */ | 102 | outb_p(0x00, IO_DATA_PORT); /* another setting is 0E for |
| 103 | kbd/mouse/LED */ | ||
| 99 | outb_p(0xF4, IO_INDEX_PORT); | 104 | outb_p(0xF4, IO_INDEX_PORT); |
| 100 | outb_p(0x00, IO_DATA_PORT); | 105 | outb_p(0x00, IO_DATA_PORT); |
| 101 | 106 | ||
| 102 | /* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */ | 107 | /* At last select device Aux1 (dev=7) and set GP16 as a |
| 103 | /* in test mode watch the bit 1 on F4 to indicate "triggered" */ | 108 | * watchdog output. In test mode watch the bit 1 on F4 to |
| 104 | if (!testmode) | 109 | * indicate "triggered" |
| 105 | { | 110 | */ |
| 111 | if (!testmode) { | ||
| 106 | outb_p(DEVICE_REGISTER, IO_INDEX_PORT); | 112 | outb_p(DEVICE_REGISTER, IO_INDEX_PORT); |
| 107 | outb_p(0x07, IO_DATA_PORT); | 113 | outb_p(0x07, IO_DATA_PORT); |
| 108 | outb_p(0xE6, IO_INDEX_PORT); | 114 | outb_p(0xE6, IO_INDEX_PORT); |
| @@ -147,7 +153,8 @@ static int wdt977_stop(void) | |||
| 147 | outb_p(0xF2, IO_INDEX_PORT); | 153 | outb_p(0xF2, IO_INDEX_PORT); |
| 148 | outb_p(0x00, IO_DATA_PORT); | 154 | outb_p(0x00, IO_DATA_PORT); |
| 149 | 155 | ||
| 150 | /* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */ | 156 | /* at last select device Aux1 (dev=7) and set |
| 157 | GP16 as a watchdog output */ | ||
| 151 | outb_p(DEVICE_REGISTER, IO_INDEX_PORT); | 158 | outb_p(DEVICE_REGISTER, IO_INDEX_PORT); |
| 152 | outb_p(0x07, IO_DATA_PORT); | 159 | outb_p(0x07, IO_DATA_PORT); |
| 153 | outb_p(0xE6, IO_INDEX_PORT); | 160 | outb_p(0xE6, IO_INDEX_PORT); |
| @@ -202,16 +209,18 @@ static int wdt977_set_timeout(int t) | |||
| 202 | tmrval = (t + 59) / 60; | 209 | tmrval = (t + 59) / 60; |
| 203 | 210 | ||
| 204 | if (machine_is_netwinder()) { | 211 | if (machine_is_netwinder()) { |
| 205 | /* we have a hw bug somewhere, so each 977 minute is actually only 30sec | 212 | /* we have a hw bug somewhere, so each 977 minute is actually |
| 206 | * this limits the max timeout to half of device max of 255 minutes... | 213 | * only 30sec. This limits the max timeout to half of device |
| 214 | * max of 255 minutes... | ||
| 207 | */ | 215 | */ |
| 208 | tmrval += tmrval; | 216 | tmrval += tmrval; |
| 209 | } | 217 | } |
| 210 | 218 | ||
| 211 | if ((tmrval < 1) || (tmrval > 255)) | 219 | if (tmrval < 1 || tmrval > 255) |
| 212 | return -EINVAL; | 220 | return -EINVAL; |
| 213 | 221 | ||
| 214 | /* timeout is the timeout in seconds, timeoutM is the timeout in minutes) */ | 222 | /* timeout is the timeout in seconds, timeoutM is |
| 223 | the timeout in minutes) */ | ||
| 215 | timeout = t; | 224 | timeout = t; |
| 216 | timeoutM = tmrval; | 225 | timeoutM = tmrval; |
| 217 | return 0; | 226 | return 0; |
| @@ -243,7 +252,7 @@ static int wdt977_get_status(int *status) | |||
| 243 | 252 | ||
| 244 | spin_unlock_irqrestore(&spinlock, flags); | 253 | spin_unlock_irqrestore(&spinlock, flags); |
| 245 | 254 | ||
| 246 | *status=0; | 255 | *status = 0; |
| 247 | if (new_status & 1) | 256 | if (new_status & 1) |
| 248 | *status |= WDIOF_CARDRESET; | 257 | *status |= WDIOF_CARDRESET; |
| 249 | 258 | ||
| @@ -258,7 +267,7 @@ static int wdt977_get_status(int *status) | |||
| 258 | static int wdt977_open(struct inode *inode, struct file *file) | 267 | static int wdt977_open(struct inode *inode, struct file *file) |
| 259 | { | 268 | { |
| 260 | /* If the watchdog is alive we don't need to start it again */ | 269 | /* If the watchdog is alive we don't need to start it again */ |
| 261 | if( test_and_set_bit(0,&timer_alive) ) | 270 | if (test_and_set_bit(0, &timer_alive)) |
| 262 | return -EBUSY; | 271 | return -EBUSY; |
| 263 | 272 | ||
| 264 | if (nowayout) | 273 | if (nowayout) |
| @@ -274,13 +283,13 @@ static int wdt977_release(struct inode *inode, struct file *file) | |||
| 274 | * Shut off the timer. | 283 | * Shut off the timer. |
| 275 | * Lock it in if it's a module and we set nowayout | 284 | * Lock it in if it's a module and we set nowayout |
| 276 | */ | 285 | */ |
| 277 | if (expect_close == 42) | 286 | if (expect_close == 42) { |
| 278 | { | ||
| 279 | wdt977_stop(); | 287 | wdt977_stop(); |
| 280 | clear_bit(0,&timer_alive); | 288 | clear_bit(0, &timer_alive); |
| 281 | } else { | 289 | } else { |
| 282 | wdt977_keepalive(); | 290 | wdt977_keepalive(); |
| 283 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 291 | printk(KERN_CRIT PFX |
| 292 | "Unexpected close, not stopping watchdog!\n"); | ||
| 284 | } | 293 | } |
| 285 | expect_close = 0; | 294 | expect_close = 0; |
| 286 | return 0; | 295 | return 0; |
| @@ -301,17 +310,14 @@ static int wdt977_release(struct inode *inode, struct file *file) | |||
| 301 | static ssize_t wdt977_write(struct file *file, const char __user *buf, | 310 | static ssize_t wdt977_write(struct file *file, const char __user *buf, |
| 302 | size_t count, loff_t *ppos) | 311 | size_t count, loff_t *ppos) |
| 303 | { | 312 | { |
| 304 | if (count) | 313 | if (count) { |
| 305 | { | 314 | if (!nowayout) { |
| 306 | if (!nowayout) | ||
| 307 | { | ||
| 308 | size_t i; | 315 | size_t i; |
| 309 | 316 | ||
| 310 | /* In case it was set long ago */ | 317 | /* In case it was set long ago */ |
| 311 | expect_close = 0; | 318 | expect_close = 0; |
| 312 | 319 | ||
| 313 | for (i = 0; i != count; i++) | 320 | for (i = 0; i != count; i++) { |
| 314 | { | ||
| 315 | char c; | 321 | char c; |
| 316 | if (get_user(c, buf + i)) | 322 | if (get_user(c, buf + i)) |
| 317 | return -EFAULT; | 323 | return -EFAULT; |
| @@ -326,6 +332,14 @@ static ssize_t wdt977_write(struct file *file, const char __user *buf, | |||
| 326 | return count; | 332 | return count; |
| 327 | } | 333 | } |
| 328 | 334 | ||
| 335 | static const struct watchdog_info ident = { | ||
| 336 | .options = WDIOF_SETTIMEOUT | | ||
| 337 | WDIOF_MAGICCLOSE | | ||
| 338 | WDIOF_KEEPALIVEPING, | ||
| 339 | .firmware_version = 1, | ||
| 340 | .identity = WATCHDOG_NAME, | ||
| 341 | }; | ||
| 342 | |||
| 329 | /* | 343 | /* |
| 330 | * wdt977_ioctl: | 344 | * wdt977_ioctl: |
| 331 | * @inode: inode of the device | 345 | * @inode: inode of the device |
| @@ -337,16 +351,8 @@ static ssize_t wdt977_write(struct file *file, const char __user *buf, | |||
| 337 | * according to their available features. | 351 | * according to their available features. |
| 338 | */ | 352 | */ |
| 339 | 353 | ||
| 340 | static struct watchdog_info ident = { | 354 | static long wdt977_ioctl(struct file *file, unsigned int cmd, |
| 341 | .options = WDIOF_SETTIMEOUT | | 355 | unsigned long arg) |
| 342 | WDIOF_MAGICCLOSE | | ||
| 343 | WDIOF_KEEPALIVEPING, | ||
| 344 | .firmware_version = 1, | ||
| 345 | .identity = WATCHDOG_NAME, | ||
| 346 | }; | ||
| 347 | |||
| 348 | static int wdt977_ioctl(struct inode *inode, struct file *file, | ||
| 349 | unsigned int cmd, unsigned long arg) | ||
| 350 | { | 356 | { |
| 351 | int status; | 357 | int status; |
| 352 | int new_options, retval = -EINVAL; | 358 | int new_options, retval = -EINVAL; |
| @@ -358,11 +364,7 @@ static int wdt977_ioctl(struct inode *inode, struct file *file, | |||
| 358 | 364 | ||
| 359 | uarg.i = (int __user *)arg; | 365 | uarg.i = (int __user *)arg; |
| 360 | 366 | ||
| 361 | switch(cmd) | 367 | switch (cmd) { |
| 362 | { | ||
| 363 | default: | ||
| 364 | return -ENOTTY; | ||
| 365 | |||
| 366 | case WDIOC_GETSUPPORT: | 368 | case WDIOC_GETSUPPORT: |
| 367 | return copy_to_user(uarg.ident, &ident, | 369 | return copy_to_user(uarg.ident, &ident, |
| 368 | sizeof(ident)) ? -EFAULT : 0; | 370 | sizeof(ident)) ? -EFAULT : 0; |
| @@ -374,12 +376,8 @@ static int wdt977_ioctl(struct inode *inode, struct file *file, | |||
| 374 | case WDIOC_GETBOOTSTATUS: | 376 | case WDIOC_GETBOOTSTATUS: |
| 375 | return put_user(0, uarg.i); | 377 | return put_user(0, uarg.i); |
| 376 | 378 | ||
| 377 | case WDIOC_KEEPALIVE: | ||
| 378 | wdt977_keepalive(); | ||
| 379 | return 0; | ||
| 380 | |||
| 381 | case WDIOC_SETOPTIONS: | 379 | case WDIOC_SETOPTIONS: |
| 382 | if (get_user (new_options, uarg.i)) | 380 | if (get_user(new_options, uarg.i)) |
| 383 | return -EFAULT; | 381 | return -EFAULT; |
| 384 | 382 | ||
| 385 | if (new_options & WDIOS_DISABLECARD) { | 383 | if (new_options & WDIOS_DISABLECARD) { |
| @@ -394,6 +392,10 @@ static int wdt977_ioctl(struct inode *inode, struct file *file, | |||
| 394 | 392 | ||
| 395 | return retval; | 393 | return retval; |
| 396 | 394 | ||
| 395 | case WDIOC_KEEPALIVE: | ||
| 396 | wdt977_keepalive(); | ||
| 397 | return 0; | ||
| 398 | |||
| 397 | case WDIOC_SETTIMEOUT: | 399 | case WDIOC_SETTIMEOUT: |
| 398 | if (get_user(new_timeout, uarg.i)) | 400 | if (get_user(new_timeout, uarg.i)) |
| 399 | return -EFAULT; | 401 | return -EFAULT; |
| @@ -407,29 +409,30 @@ static int wdt977_ioctl(struct inode *inode, struct file *file, | |||
| 407 | case WDIOC_GETTIMEOUT: | 409 | case WDIOC_GETTIMEOUT: |
| 408 | return put_user(timeout, uarg.i); | 410 | return put_user(timeout, uarg.i); |
| 409 | 411 | ||
| 412 | default: | ||
| 413 | return -ENOTTY; | ||
| 414 | |||
| 410 | } | 415 | } |
| 411 | } | 416 | } |
| 412 | 417 | ||
| 413 | static int wdt977_notify_sys(struct notifier_block *this, unsigned long code, | 418 | static int wdt977_notify_sys(struct notifier_block *this, unsigned long code, |
| 414 | void *unused) | 419 | void *unused) |
| 415 | { | 420 | { |
| 416 | if(code==SYS_DOWN || code==SYS_HALT) | 421 | if (code == SYS_DOWN || code == SYS_HALT) |
| 417 | wdt977_stop(); | 422 | wdt977_stop(); |
| 418 | return NOTIFY_DONE; | 423 | return NOTIFY_DONE; |
| 419 | } | 424 | } |
| 420 | 425 | ||
| 421 | static const struct file_operations wdt977_fops= | 426 | static const struct file_operations wdt977_fops = { |
| 422 | { | ||
| 423 | .owner = THIS_MODULE, | 427 | .owner = THIS_MODULE, |
| 424 | .llseek = no_llseek, | 428 | .llseek = no_llseek, |
| 425 | .write = wdt977_write, | 429 | .write = wdt977_write, |
| 426 | .ioctl = wdt977_ioctl, | 430 | .unlocked_ioctl = wdt977_ioctl, |
| 427 | .open = wdt977_open, | 431 | .open = wdt977_open, |
| 428 | .release = wdt977_release, | 432 | .release = wdt977_release, |
| 429 | }; | 433 | }; |
| 430 | 434 | ||
| 431 | static struct miscdevice wdt977_miscdev= | 435 | static struct miscdevice wdt977_miscdev = { |
| 432 | { | ||
| 433 | .minor = WATCHDOG_MINOR, | 436 | .minor = WATCHDOG_MINOR, |
| 434 | .name = "watchdog", | 437 | .name = "watchdog", |
| 435 | .fops = &wdt977_fops, | 438 | .fops = &wdt977_fops, |
| @@ -443,51 +446,48 @@ static int __init wd977_init(void) | |||
| 443 | { | 446 | { |
| 444 | int rc; | 447 | int rc; |
| 445 | 448 | ||
| 446 | //if (!machine_is_netwinder()) | ||
| 447 | // return -ENODEV; | ||
| 448 | |||
| 449 | printk(KERN_INFO PFX DRIVER_VERSION); | 449 | printk(KERN_INFO PFX DRIVER_VERSION); |
| 450 | 450 | ||
| 451 | /* Check that the timeout value is within it's range ; if not reset to the default */ | 451 | /* Check that the timeout value is within its range; |
| 452 | if (wdt977_set_timeout(timeout)) | 452 | if not reset to the default */ |
| 453 | { | 453 | if (wdt977_set_timeout(timeout)) { |
| 454 | wdt977_set_timeout(DEFAULT_TIMEOUT); | 454 | wdt977_set_timeout(DEFAULT_TIMEOUT); |
| 455 | printk(KERN_INFO PFX "timeout value must be 60<timeout<15300, using %d\n", | 455 | printk(KERN_INFO PFX |
| 456 | DEFAULT_TIMEOUT); | 456 | "timeout value must be 60 < timeout < 15300, using %d\n", |
| 457 | DEFAULT_TIMEOUT); | ||
| 457 | } | 458 | } |
| 458 | 459 | ||
| 459 | /* on Netwinder the IOports are already reserved by | 460 | /* on Netwinder the IOports are already reserved by |
| 460 | * arch/arm/mach-footbridge/netwinder-hw.c | 461 | * arch/arm/mach-footbridge/netwinder-hw.c |
| 461 | */ | 462 | */ |
| 462 | if (!machine_is_netwinder()) | 463 | if (!machine_is_netwinder()) { |
| 463 | { | 464 | if (!request_region(IO_INDEX_PORT, 2, WATCHDOG_NAME)) { |
| 464 | if (!request_region(IO_INDEX_PORT, 2, WATCHDOG_NAME)) | 465 | printk(KERN_ERR PFX |
| 465 | { | 466 | "I/O address 0x%04x already in use\n", |
| 466 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", | 467 | IO_INDEX_PORT); |
| 467 | IO_INDEX_PORT); | ||
| 468 | rc = -EIO; | 468 | rc = -EIO; |
| 469 | goto err_out; | 469 | goto err_out; |
| 470 | } | 470 | } |
| 471 | } | 471 | } |
| 472 | 472 | ||
| 473 | rc = register_reboot_notifier(&wdt977_notifier); | 473 | rc = register_reboot_notifier(&wdt977_notifier); |
| 474 | if (rc) | 474 | if (rc) { |
| 475 | { | 475 | printk(KERN_ERR PFX |
| 476 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 476 | "cannot register reboot notifier (err=%d)\n", rc); |
| 477 | rc); | ||
| 478 | goto err_out_region; | 477 | goto err_out_region; |
| 479 | } | 478 | } |
| 480 | 479 | ||
| 481 | rc = misc_register(&wdt977_miscdev); | 480 | rc = misc_register(&wdt977_miscdev); |
| 482 | if (rc) | 481 | if (rc) { |
| 483 | { | 482 | printk(KERN_ERR PFX |
| 484 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 483 | "cannot register miscdev on minor=%d (err=%d)\n", |
| 485 | wdt977_miscdev.minor, rc); | 484 | wdt977_miscdev.minor, rc); |
| 486 | goto err_out_reboot; | 485 | goto err_out_reboot; |
| 487 | } | 486 | } |
| 488 | 487 | ||
| 489 | printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d, testmode=%i)\n", | 488 | printk(KERN_INFO PFX |
| 490 | timeout, nowayout, testmode); | 489 | "initialized. timeout=%d sec (nowayout=%d, testmode=%i)\n", |
| 490 | timeout, nowayout, testmode); | ||
| 491 | 491 | ||
| 492 | return 0; | 492 | return 0; |
| 493 | 493 | ||
| @@ -495,7 +495,7 @@ err_out_reboot: | |||
| 495 | unregister_reboot_notifier(&wdt977_notifier); | 495 | unregister_reboot_notifier(&wdt977_notifier); |
| 496 | err_out_region: | 496 | err_out_region: |
| 497 | if (!machine_is_netwinder()) | 497 | if (!machine_is_netwinder()) |
| 498 | release_region(IO_INDEX_PORT,2); | 498 | release_region(IO_INDEX_PORT, 2); |
| 499 | err_out: | 499 | err_out: |
| 500 | return rc; | 500 | return rc; |
| 501 | } | 501 | } |
| @@ -505,7 +505,7 @@ static void __exit wd977_exit(void) | |||
| 505 | wdt977_stop(); | 505 | wdt977_stop(); |
| 506 | misc_deregister(&wdt977_miscdev); | 506 | misc_deregister(&wdt977_miscdev); |
| 507 | unregister_reboot_notifier(&wdt977_notifier); | 507 | unregister_reboot_notifier(&wdt977_notifier); |
| 508 | release_region(IO_INDEX_PORT,2); | 508 | release_region(IO_INDEX_PORT, 2); |
| 509 | } | 509 | } |
| 510 | 510 | ||
| 511 | module_init(wd977_init); | 511 | module_init(wd977_init); |
diff --git a/drivers/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c index 5d922fd6eafc..ed02bdb38c09 100644 --- a/drivers/watchdog/wdt_pci.c +++ b/drivers/watchdog/wdt_pci.c | |||
| @@ -381,7 +381,7 @@ static ssize_t wdtpci_write(struct file *file, const char __user *buf, | |||
| 381 | 381 | ||
| 382 | for (i = 0; i != count; i++) { | 382 | for (i = 0; i != count; i++) { |
| 383 | char c; | 383 | char c; |
| 384 | if (get_user(c, buf+i)) | 384 | if (get_user(c, buf + i)) |
| 385 | return -EFAULT; | 385 | return -EFAULT; |
| 386 | if (c == 'V') | 386 | if (c == 'V') |
| 387 | expect_close = 42; | 387 | expect_close = 42; |
| @@ -428,8 +428,6 @@ static long wdtpci_ioctl(struct file *file, unsigned int cmd, | |||
| 428 | #endif /* CONFIG_WDT_501_PCI */ | 428 | #endif /* CONFIG_WDT_501_PCI */ |
| 429 | 429 | ||
| 430 | switch (cmd) { | 430 | switch (cmd) { |
| 431 | default: | ||
| 432 | return -ENOTTY; | ||
| 433 | case WDIOC_GETSUPPORT: | 431 | case WDIOC_GETSUPPORT: |
| 434 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; | 432 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; |
| 435 | case WDIOC_GETSTATUS: | 433 | case WDIOC_GETSTATUS: |
| @@ -449,7 +447,9 @@ static long wdtpci_ioctl(struct file *file, unsigned int cmd, | |||
| 449 | /* Fall */ | 447 | /* Fall */ |
| 450 | case WDIOC_GETTIMEOUT: | 448 | case WDIOC_GETTIMEOUT: |
| 451 | return put_user(heartbeat, p); | 449 | return put_user(heartbeat, p); |
| 452 | } | 450 | default: |
| 451 | return -ENOTTY; | ||
| 452 | } | ||
| 453 | } | 453 | } |
| 454 | 454 | ||
| 455 | /** | 455 | /** |
| @@ -77,11 +77,8 @@ struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned long *idx, struct | |||
| 77 | */ | 77 | */ |
| 78 | 78 | ||
| 79 | bvl = mempool_alloc(bs->bvec_pools[*idx], gfp_mask); | 79 | bvl = mempool_alloc(bs->bvec_pools[*idx], gfp_mask); |
| 80 | if (bvl) { | 80 | if (bvl) |
| 81 | struct biovec_slab *bp = bvec_slabs + *idx; | 81 | memset(bvl, 0, bvec_nr_vecs(*idx) * sizeof(struct bio_vec)); |
| 82 | |||
| 83 | memset(bvl, 0, bp->nr_vecs * sizeof(struct bio_vec)); | ||
| 84 | } | ||
| 85 | 82 | ||
| 86 | return bvl; | 83 | return bvl; |
| 87 | } | 84 | } |
| @@ -149,7 +146,7 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) | |||
| 149 | goto out; | 146 | goto out; |
| 150 | } | 147 | } |
| 151 | bio->bi_flags |= idx << BIO_POOL_OFFSET; | 148 | bio->bi_flags |= idx << BIO_POOL_OFFSET; |
| 152 | bio->bi_max_vecs = bvec_slabs[idx].nr_vecs; | 149 | bio->bi_max_vecs = bvec_nr_vecs(idx); |
| 153 | } | 150 | } |
| 154 | bio->bi_io_vec = bvl; | 151 | bio->bi_io_vec = bvl; |
| 155 | } | 152 | } |
diff --git a/include/linux/mlx4/cq.h b/include/linux/mlx4/cq.h index 071cf96cf01f..6f65b2c8bb89 100644 --- a/include/linux/mlx4/cq.h +++ b/include/linux/mlx4/cq.h | |||
| @@ -39,17 +39,18 @@ | |||
| 39 | #include <linux/mlx4/doorbell.h> | 39 | #include <linux/mlx4/doorbell.h> |
| 40 | 40 | ||
| 41 | struct mlx4_cqe { | 41 | struct mlx4_cqe { |
| 42 | __be32 my_qpn; | 42 | __be32 vlan_my_qpn; |
| 43 | __be32 immed_rss_invalid; | 43 | __be32 immed_rss_invalid; |
| 44 | __be32 g_mlpath_rqpn; | 44 | __be32 g_mlpath_rqpn; |
| 45 | u8 sl; | 45 | __be16 sl_vid; |
| 46 | u8 reserved1; | ||
| 47 | __be16 rlid; | 46 | __be16 rlid; |
| 48 | __be32 ipoib_status; | 47 | __be16 status; |
| 48 | u8 ipv6_ext_mask; | ||
| 49 | u8 badfcs_enc; | ||
| 49 | __be32 byte_cnt; | 50 | __be32 byte_cnt; |
| 50 | __be16 wqe_index; | 51 | __be16 wqe_index; |
| 51 | __be16 checksum; | 52 | __be16 checksum; |
| 52 | u8 reserved2[3]; | 53 | u8 reserved[3]; |
| 53 | u8 owner_sr_opcode; | 54 | u8 owner_sr_opcode; |
| 54 | }; | 55 | }; |
| 55 | 56 | ||
| @@ -64,6 +65,11 @@ struct mlx4_err_cqe { | |||
| 64 | }; | 65 | }; |
| 65 | 66 | ||
| 66 | enum { | 67 | enum { |
| 68 | MLX4_CQE_VLAN_PRESENT_MASK = 1 << 29, | ||
| 69 | MLX4_CQE_QPN_MASK = 0xffffff, | ||
| 70 | }; | ||
| 71 | |||
| 72 | enum { | ||
| 67 | MLX4_CQE_OWNER_MASK = 0x80, | 73 | MLX4_CQE_OWNER_MASK = 0x80, |
| 68 | MLX4_CQE_IS_SEND_MASK = 0x40, | 74 | MLX4_CQE_IS_SEND_MASK = 0x40, |
| 69 | MLX4_CQE_OPCODE_MASK = 0x1f | 75 | MLX4_CQE_OPCODE_MASK = 0x1f |
| @@ -86,13 +92,19 @@ enum { | |||
| 86 | }; | 92 | }; |
| 87 | 93 | ||
| 88 | enum { | 94 | enum { |
| 89 | MLX4_CQE_IPOIB_STATUS_IPV4 = 1 << 22, | 95 | MLX4_CQE_STATUS_IPV4 = 1 << 6, |
| 90 | MLX4_CQE_IPOIB_STATUS_IPV4F = 1 << 23, | 96 | MLX4_CQE_STATUS_IPV4F = 1 << 7, |
| 91 | MLX4_CQE_IPOIB_STATUS_IPV6 = 1 << 24, | 97 | MLX4_CQE_STATUS_IPV6 = 1 << 8, |
| 92 | MLX4_CQE_IPOIB_STATUS_IPV4OPT = 1 << 25, | 98 | MLX4_CQE_STATUS_IPV4OPT = 1 << 9, |
| 93 | MLX4_CQE_IPOIB_STATUS_TCP = 1 << 26, | 99 | MLX4_CQE_STATUS_TCP = 1 << 10, |
| 94 | MLX4_CQE_IPOIB_STATUS_UDP = 1 << 27, | 100 | MLX4_CQE_STATUS_UDP = 1 << 11, |
| 95 | MLX4_CQE_IPOIB_STATUS_IPOK = 1 << 28, | 101 | MLX4_CQE_STATUS_IPOK = 1 << 12, |
| 102 | }; | ||
| 103 | |||
| 104 | enum { | ||
| 105 | MLX4_CQE_LLC = 1, | ||
| 106 | MLX4_CQE_SNAP = 1 << 1, | ||
| 107 | MLX4_CQE_BAD_FCS = 1 << 4, | ||
| 96 | }; | 108 | }; |
| 97 | 109 | ||
| 98 | static inline void mlx4_cq_arm(struct mlx4_cq *cq, u32 cmd, | 110 | static inline void mlx4_cq_arm(struct mlx4_cq *cq, u32 cmd, |
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index fd31756e1a00..ea7416c901d1 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h | |||
| @@ -172,7 +172,7 @@ static inline void ptrace_init_task(struct task_struct *child, bool ptrace) | |||
| 172 | child->ptrace = 0; | 172 | child->ptrace = 0; |
| 173 | if (unlikely(ptrace)) { | 173 | if (unlikely(ptrace)) { |
| 174 | child->ptrace = current->ptrace; | 174 | child->ptrace = current->ptrace; |
| 175 | __ptrace_link(child, current->parent); | 175 | ptrace_link(child, current->parent); |
| 176 | } | 176 | } |
| 177 | } | 177 | } |
| 178 | 178 | ||
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index ab3ef7aefa95..b48d81969574 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h | |||
| @@ -280,7 +280,7 @@ static inline void tracehook_report_clone(int trace, struct pt_regs *regs, | |||
| 280 | unsigned long clone_flags, | 280 | unsigned long clone_flags, |
| 281 | pid_t pid, struct task_struct *child) | 281 | pid_t pid, struct task_struct *child) |
| 282 | { | 282 | { |
| 283 | if (unlikely(trace)) { | 283 | if (unlikely(trace) || unlikely(clone_flags & CLONE_PTRACE)) { |
| 284 | /* | 284 | /* |
| 285 | * The child starts up with an immediate SIGSTOP. | 285 | * The child starts up with an immediate SIGSTOP. |
| 286 | */ | 286 | */ |
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 1de98f150e99..d548de326722 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | 14 | ||
| 15 | #include <linux/videodev2.h> | 15 | #include <linux/videodev2.h> |
| 16 | #include <media/videobuf-core.h> | 16 | #include <media/videobuf-core.h> |
| 17 | #include <linux/pm.h> | ||
| 17 | 18 | ||
| 18 | struct soc_camera_device { | 19 | struct soc_camera_device { |
| 19 | struct list_head list; | 20 | struct list_head list; |
| @@ -63,6 +64,8 @@ struct soc_camera_host_ops { | |||
| 63 | struct module *owner; | 64 | struct module *owner; |
| 64 | int (*add)(struct soc_camera_device *); | 65 | int (*add)(struct soc_camera_device *); |
| 65 | void (*remove)(struct soc_camera_device *); | 66 | void (*remove)(struct soc_camera_device *); |
| 67 | int (*suspend)(struct soc_camera_device *, pm_message_t state); | ||
| 68 | int (*resume)(struct soc_camera_device *); | ||
| 66 | int (*set_fmt_cap)(struct soc_camera_device *, __u32, | 69 | int (*set_fmt_cap)(struct soc_camera_device *, __u32, |
| 67 | struct v4l2_rect *); | 70 | struct v4l2_rect *); |
| 68 | int (*try_fmt_cap)(struct soc_camera_device *, struct v4l2_format *); | 71 | int (*try_fmt_cap)(struct soc_camera_device *, struct v4l2_format *); |
| @@ -111,6 +114,8 @@ struct soc_camera_ops { | |||
| 111 | struct module *owner; | 114 | struct module *owner; |
| 112 | int (*probe)(struct soc_camera_device *); | 115 | int (*probe)(struct soc_camera_device *); |
| 113 | void (*remove)(struct soc_camera_device *); | 116 | void (*remove)(struct soc_camera_device *); |
| 117 | int (*suspend)(struct soc_camera_device *, pm_message_t state); | ||
| 118 | int (*resume)(struct soc_camera_device *); | ||
| 114 | int (*init)(struct soc_camera_device *); | 119 | int (*init)(struct soc_camera_device *); |
| 115 | int (*release)(struct soc_camera_device *); | 120 | int (*release)(struct soc_camera_device *); |
| 116 | int (*start_capture)(struct soc_camera_device *); | 121 | int (*start_capture)(struct soc_camera_device *); |
diff --git a/include/rdma/rdma_cm.h b/include/rdma/rdma_cm.h index df7faf09d66f..c6b2962315b3 100644 --- a/include/rdma/rdma_cm.h +++ b/include/rdma/rdma_cm.h | |||
| @@ -71,12 +71,8 @@ enum rdma_port_space { | |||
| 71 | }; | 71 | }; |
| 72 | 72 | ||
| 73 | struct rdma_addr { | 73 | struct rdma_addr { |
| 74 | struct sockaddr src_addr; | 74 | struct sockaddr_storage src_addr; |
| 75 | u8 src_pad[sizeof(struct sockaddr_in6) - | 75 | struct sockaddr_storage dst_addr; |
| 76 | sizeof(struct sockaddr)]; | ||
| 77 | struct sockaddr dst_addr; | ||
| 78 | u8 dst_pad[sizeof(struct sockaddr_in6) - | ||
| 79 | sizeof(struct sockaddr)]; | ||
| 80 | struct rdma_dev_addr dev_addr; | 76 | struct rdma_dev_addr dev_addr; |
| 81 | }; | 77 | }; |
| 82 | 78 | ||
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 28a2980ee435..757ca983fd99 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
| @@ -17,7 +17,7 @@ | |||
| 17 | #include <linux/mutex.h> | 17 | #include <linux/mutex.h> |
| 18 | #include <linux/bootmem.h> | 18 | #include <linux/bootmem.h> |
| 19 | #include <linux/sysfs.h> | 19 | #include <linux/sysfs.h> |
| 20 | #include <asm/io.h> | 20 | |
| 21 | #include <asm/page.h> | 21 | #include <asm/page.h> |
| 22 | #include <asm/pgtable.h> | 22 | #include <asm/pgtable.h> |
| 23 | #include <asm/io.h> | 23 | #include <asm/io.h> |
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index 7ceea2bba1f5..d2d3da9729f2 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c | |||
| @@ -327,14 +327,75 @@ static int fsl_dma_new(struct snd_card *card, struct snd_soc_dai *dai, | |||
| 327 | * fsl_dma_open: open a new substream. | 327 | * fsl_dma_open: open a new substream. |
| 328 | * | 328 | * |
| 329 | * Each substream has its own DMA buffer. | 329 | * Each substream has its own DMA buffer. |
| 330 | * | ||
| 331 | * ALSA divides the DMA buffer into N periods. We create NUM_DMA_LINKS link | ||
| 332 | * descriptors that ping-pong from one period to the next. For example, if | ||
| 333 | * there are six periods and two link descriptors, this is how they look | ||
| 334 | * before playback starts: | ||
| 335 | * | ||
| 336 | * The last link descriptor | ||
| 337 | * ____________ points back to the first | ||
| 338 | * | | | ||
| 339 | * V | | ||
| 340 | * ___ ___ | | ||
| 341 | * | |->| |->| | ||
| 342 | * |___| |___| | ||
| 343 | * | | | ||
| 344 | * | | | ||
| 345 | * V V | ||
| 346 | * _________________________________________ | ||
| 347 | * | | | | | | | The DMA buffer is | ||
| 348 | * | | | | | | | divided into 6 parts | ||
| 349 | * |______|______|______|______|______|______| | ||
| 350 | * | ||
| 351 | * and here's how they look after the first period is finished playing: | ||
| 352 | * | ||
| 353 | * ____________ | ||
| 354 | * | | | ||
| 355 | * V | | ||
| 356 | * ___ ___ | | ||
| 357 | * | |->| |->| | ||
| 358 | * |___| |___| | ||
| 359 | * | | | ||
| 360 | * |______________ | ||
| 361 | * | | | ||
| 362 | * V V | ||
| 363 | * _________________________________________ | ||
| 364 | * | | | | | | | | ||
| 365 | * | | | | | | | | ||
| 366 | * |______|______|______|______|______|______| | ||
| 367 | * | ||
| 368 | * The first link descriptor now points to the third period. The DMA | ||
| 369 | * controller is currently playing the second period. When it finishes, it | ||
| 370 | * will jump back to the first descriptor and play the third period. | ||
| 371 | * | ||
| 372 | * There are four reasons we do this: | ||
| 373 | * | ||
| 374 | * 1. The only way to get the DMA controller to automatically restart the | ||
| 375 | * transfer when it gets to the end of the buffer is to use chaining | ||
| 376 | * mode. Basic direct mode doesn't offer that feature. | ||
| 377 | * 2. We need to receive an interrupt at the end of every period. The DMA | ||
| 378 | * controller can generate an interrupt at the end of every link transfer | ||
| 379 | * (aka segment). Making each period into a DMA segment will give us the | ||
| 380 | * interrupts we need. | ||
| 381 | * 3. By creating only two link descriptors, regardless of the number of | ||
| 382 | * periods, we do not need to reallocate the link descriptors if the | ||
| 383 | * number of periods changes. | ||
| 384 | * 4. All of the audio data is still stored in a single, contiguous DMA | ||
| 385 | * buffer, which is what ALSA expects. We're just dividing it into | ||
| 386 | * contiguous parts, and creating a link descriptor for each one. | ||
| 330 | */ | 387 | */ |
| 331 | static int fsl_dma_open(struct snd_pcm_substream *substream) | 388 | static int fsl_dma_open(struct snd_pcm_substream *substream) |
| 332 | { | 389 | { |
| 333 | struct snd_pcm_runtime *runtime = substream->runtime; | 390 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 334 | struct fsl_dma_private *dma_private; | 391 | struct fsl_dma_private *dma_private; |
| 392 | struct ccsr_dma_channel __iomem *dma_channel; | ||
| 335 | dma_addr_t ld_buf_phys; | 393 | dma_addr_t ld_buf_phys; |
| 394 | u64 temp_link; /* Pointer to next link descriptor */ | ||
| 395 | u32 mr; | ||
| 336 | unsigned int channel; | 396 | unsigned int channel; |
| 337 | int ret = 0; | 397 | int ret = 0; |
| 398 | unsigned int i; | ||
| 338 | 399 | ||
| 339 | /* | 400 | /* |
| 340 | * Reject any DMA buffer whose size is not a multiple of the period | 401 | * Reject any DMA buffer whose size is not a multiple of the period |
| @@ -395,68 +456,74 @@ static int fsl_dma_open(struct snd_pcm_substream *substream) | |||
| 395 | snd_soc_set_runtime_hwparams(substream, &fsl_dma_hardware); | 456 | snd_soc_set_runtime_hwparams(substream, &fsl_dma_hardware); |
| 396 | runtime->private_data = dma_private; | 457 | runtime->private_data = dma_private; |
| 397 | 458 | ||
| 459 | /* Program the fixed DMA controller parameters */ | ||
| 460 | |||
| 461 | dma_channel = dma_private->dma_channel; | ||
| 462 | |||
| 463 | temp_link = dma_private->ld_buf_phys + | ||
| 464 | sizeof(struct fsl_dma_link_descriptor); | ||
| 465 | |||
| 466 | for (i = 0; i < NUM_DMA_LINKS; i++) { | ||
| 467 | struct fsl_dma_link_descriptor *link = &dma_private->link[i]; | ||
| 468 | |||
| 469 | link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); | ||
| 470 | link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); | ||
| 471 | link->next = cpu_to_be64(temp_link); | ||
| 472 | |||
| 473 | temp_link += sizeof(struct fsl_dma_link_descriptor); | ||
| 474 | } | ||
| 475 | /* The last link descriptor points to the first */ | ||
| 476 | dma_private->link[i - 1].next = cpu_to_be64(dma_private->ld_buf_phys); | ||
| 477 | |||
| 478 | /* Tell the DMA controller where the first link descriptor is */ | ||
| 479 | out_be32(&dma_channel->clndar, | ||
| 480 | CCSR_DMA_CLNDAR_ADDR(dma_private->ld_buf_phys)); | ||
| 481 | out_be32(&dma_channel->eclndar, | ||
| 482 | CCSR_DMA_ECLNDAR_ADDR(dma_private->ld_buf_phys)); | ||
| 483 | |||
| 484 | /* The manual says the BCR must be clear before enabling EMP */ | ||
| 485 | out_be32(&dma_channel->bcr, 0); | ||
| 486 | |||
| 487 | /* | ||
| 488 | * Program the mode register for interrupts, external master control, | ||
| 489 | * and source/destination hold. Also clear the Channel Abort bit. | ||
| 490 | */ | ||
| 491 | mr = in_be32(&dma_channel->mr) & | ||
| 492 | ~(CCSR_DMA_MR_CA | CCSR_DMA_MR_DAHE | CCSR_DMA_MR_SAHE); | ||
| 493 | |||
| 494 | /* | ||
| 495 | * We want External Master Start and External Master Pause enabled, | ||
| 496 | * because the SSI is controlling the DMA controller. We want the DMA | ||
| 497 | * controller to be set up in advance, and then we signal only the SSI | ||
| 498 | * to start transferring. | ||
| 499 | * | ||
| 500 | * We want End-Of-Segment Interrupts enabled, because this will generate | ||
| 501 | * an interrupt at the end of each segment (each link descriptor | ||
| 502 | * represents one segment). Each DMA segment is the same thing as an | ||
| 503 | * ALSA period, so this is how we get an interrupt at the end of every | ||
| 504 | * period. | ||
| 505 | * | ||
| 506 | * We want Error Interrupt enabled, so that we can get an error if | ||
| 507 | * the DMA controller is mis-programmed somehow. | ||
| 508 | */ | ||
| 509 | mr |= CCSR_DMA_MR_EOSIE | CCSR_DMA_MR_EIE | CCSR_DMA_MR_EMP_EN | | ||
| 510 | CCSR_DMA_MR_EMS_EN; | ||
| 511 | |||
| 512 | /* For playback, we want the destination address to be held. For | ||
| 513 | capture, set the source address to be held. */ | ||
| 514 | mr |= (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? | ||
| 515 | CCSR_DMA_MR_DAHE : CCSR_DMA_MR_SAHE; | ||
| 516 | |||
| 517 | out_be32(&dma_channel->mr, mr); | ||
| 518 | |||
| 398 | return 0; | 519 | return 0; |
| 399 | } | 520 | } |
| 400 | 521 | ||
| 401 | /** | 522 | /** |
| 402 | * fsl_dma_hw_params: allocate the DMA buffer and the DMA link descriptors. | 523 | * fsl_dma_hw_params: continue initializing the DMA links |
| 403 | * | ||
| 404 | * ALSA divides the DMA buffer into N periods. We create NUM_DMA_LINKS link | ||
| 405 | * descriptors that ping-pong from one period to the next. For example, if | ||
| 406 | * there are six periods and two link descriptors, this is how they look | ||
| 407 | * before playback starts: | ||
| 408 | * | ||
| 409 | * The last link descriptor | ||
| 410 | * ____________ points back to the first | ||
| 411 | * | | | ||
| 412 | * V | | ||
| 413 | * ___ ___ | | ||
| 414 | * | |->| |->| | ||
| 415 | * |___| |___| | ||
| 416 | * | | | ||
| 417 | * | | | ||
| 418 | * V V | ||
| 419 | * _________________________________________ | ||
| 420 | * | | | | | | | The DMA buffer is | ||
| 421 | * | | | | | | | divided into 6 parts | ||
| 422 | * |______|______|______|______|______|______| | ||
| 423 | * | ||
| 424 | * and here's how they look after the first period is finished playing: | ||
| 425 | * | ||
| 426 | * ____________ | ||
| 427 | * | | | ||
| 428 | * V | | ||
| 429 | * ___ ___ | | ||
| 430 | * | |->| |->| | ||
| 431 | * |___| |___| | ||
| 432 | * | | | ||
| 433 | * |______________ | ||
| 434 | * | | | ||
| 435 | * V V | ||
| 436 | * _________________________________________ | ||
| 437 | * | | | | | | | | ||
| 438 | * | | | | | | | | ||
| 439 | * |______|______|______|______|______|______| | ||
| 440 | * | 524 | * |
| 441 | * The first link descriptor now points to the third period. The DMA | 525 | * This function obtains hardware parameters about the opened stream and |
| 442 | * controller is currently playing the second period. When it finishes, it | 526 | * programs the DMA controller accordingly. |
| 443 | * will jump back to the first descriptor and play the third period. | ||
| 444 | * | ||
| 445 | * There are four reasons we do this: | ||
| 446 | * | ||
| 447 | * 1. The only way to get the DMA controller to automatically restart the | ||
| 448 | * transfer when it gets to the end of the buffer is to use chaining | ||
| 449 | * mode. Basic direct mode doesn't offer that feature. | ||
| 450 | * 2. We need to receive an interrupt at the end of every period. The DMA | ||
| 451 | * controller can generate an interrupt at the end of every link transfer | ||
| 452 | * (aka segment). Making each period into a DMA segment will give us the | ||
| 453 | * interrupts we need. | ||
| 454 | * 3. By creating only two link descriptors, regardless of the number of | ||
| 455 | * periods, we do not need to reallocate the link descriptors if the | ||
| 456 | * number of periods changes. | ||
| 457 | * 4. All of the audio data is still stored in a single, contiguous DMA | ||
| 458 | * buffer, which is what ALSA expects. We're just dividing it into | ||
| 459 | * contiguous parts, and creating a link descriptor for each one. | ||
| 460 | * | 527 | * |
| 461 | * Note that due to a quirk of the SSI's STX register, the target address | 528 | * Note that due to a quirk of the SSI's STX register, the target address |
| 462 | * for the DMA operations depends on the sample size. So we don't program | 529 | * for the DMA operations depends on the sample size. So we don't program |
| @@ -468,11 +535,8 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream, | |||
| 468 | { | 535 | { |
| 469 | struct snd_pcm_runtime *runtime = substream->runtime; | 536 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 470 | struct fsl_dma_private *dma_private = runtime->private_data; | 537 | struct fsl_dma_private *dma_private = runtime->private_data; |
| 471 | struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel; | ||
| 472 | 538 | ||
| 473 | dma_addr_t temp_addr; /* Pointer to next period */ | 539 | dma_addr_t temp_addr; /* Pointer to next period */ |
| 474 | u64 temp_link; /* Pointer to next link descriptor */ | ||
| 475 | u32 mr; /* Temporary variable for MR register */ | ||
| 476 | 540 | ||
| 477 | unsigned int i; | 541 | unsigned int i; |
| 478 | 542 | ||
| @@ -490,8 +554,6 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream, | |||
| 490 | dma_private->dma_buf_next = dma_private->dma_buf_phys; | 554 | dma_private->dma_buf_next = dma_private->dma_buf_phys; |
| 491 | 555 | ||
| 492 | /* | 556 | /* |
| 493 | * Initialize each link descriptor. | ||
| 494 | * | ||
| 495 | * The actual address in STX0 (destination for playback, source for | 557 | * The actual address in STX0 (destination for playback, source for |
| 496 | * capture) is based on the sample size, but we don't know the sample | 558 | * capture) is based on the sample size, but we don't know the sample |
| 497 | * size in this function, so we'll have to adjust that later. See | 559 | * size in this function, so we'll have to adjust that later. See |
| @@ -507,16 +569,11 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream, | |||
| 507 | * buffer itself. | 569 | * buffer itself. |
| 508 | */ | 570 | */ |
| 509 | temp_addr = substream->dma_buffer.addr; | 571 | temp_addr = substream->dma_buffer.addr; |
| 510 | temp_link = dma_private->ld_buf_phys + | ||
| 511 | sizeof(struct fsl_dma_link_descriptor); | ||
| 512 | 572 | ||
| 513 | for (i = 0; i < NUM_DMA_LINKS; i++) { | 573 | for (i = 0; i < NUM_DMA_LINKS; i++) { |
| 514 | struct fsl_dma_link_descriptor *link = &dma_private->link[i]; | 574 | struct fsl_dma_link_descriptor *link = &dma_private->link[i]; |
| 515 | 575 | ||
| 516 | link->count = cpu_to_be32(period_size); | 576 | link->count = cpu_to_be32(period_size); |
| 517 | link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); | ||
| 518 | link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); | ||
| 519 | link->next = cpu_to_be64(temp_link); | ||
| 520 | 577 | ||
| 521 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 578 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
| 522 | link->source_addr = cpu_to_be32(temp_addr); | 579 | link->source_addr = cpu_to_be32(temp_addr); |
| @@ -524,51 +581,7 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream, | |||
| 524 | link->dest_addr = cpu_to_be32(temp_addr); | 581 | link->dest_addr = cpu_to_be32(temp_addr); |
| 525 | 582 | ||
| 526 | temp_addr += period_size; | 583 | temp_addr += period_size; |
| 527 | temp_link += sizeof(struct fsl_dma_link_descriptor); | ||
| 528 | } | 584 | } |
| 529 | /* The last link descriptor points to the first */ | ||
| 530 | dma_private->link[i - 1].next = cpu_to_be64(dma_private->ld_buf_phys); | ||
| 531 | |||
| 532 | /* Tell the DMA controller where the first link descriptor is */ | ||
| 533 | out_be32(&dma_channel->clndar, | ||
| 534 | CCSR_DMA_CLNDAR_ADDR(dma_private->ld_buf_phys)); | ||
| 535 | out_be32(&dma_channel->eclndar, | ||
| 536 | CCSR_DMA_ECLNDAR_ADDR(dma_private->ld_buf_phys)); | ||
| 537 | |||
| 538 | /* The manual says the BCR must be clear before enabling EMP */ | ||
| 539 | out_be32(&dma_channel->bcr, 0); | ||
| 540 | |||
| 541 | /* | ||
| 542 | * Program the mode register for interrupts, external master control, | ||
| 543 | * and source/destination hold. Also clear the Channel Abort bit. | ||
| 544 | */ | ||
| 545 | mr = in_be32(&dma_channel->mr) & | ||
| 546 | ~(CCSR_DMA_MR_CA | CCSR_DMA_MR_DAHE | CCSR_DMA_MR_SAHE); | ||
| 547 | |||
| 548 | /* | ||
| 549 | * We want External Master Start and External Master Pause enabled, | ||
| 550 | * because the SSI is controlling the DMA controller. We want the DMA | ||
| 551 | * controller to be set up in advance, and then we signal only the SSI | ||
| 552 | * to start transfering. | ||
| 553 | * | ||
| 554 | * We want End-Of-Segment Interrupts enabled, because this will generate | ||
| 555 | * an interrupt at the end of each segment (each link descriptor | ||
| 556 | * represents one segment). Each DMA segment is the same thing as an | ||
| 557 | * ALSA period, so this is how we get an interrupt at the end of every | ||
| 558 | * period. | ||
| 559 | * | ||
| 560 | * We want Error Interrupt enabled, so that we can get an error if | ||
| 561 | * the DMA controller is mis-programmed somehow. | ||
| 562 | */ | ||
| 563 | mr |= CCSR_DMA_MR_EOSIE | CCSR_DMA_MR_EIE | CCSR_DMA_MR_EMP_EN | | ||
| 564 | CCSR_DMA_MR_EMS_EN; | ||
| 565 | |||
| 566 | /* For playback, we want the destination address to be held. For | ||
| 567 | capture, set the source address to be held. */ | ||
| 568 | mr |= (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? | ||
| 569 | CCSR_DMA_MR_DAHE : CCSR_DMA_MR_SAHE; | ||
| 570 | |||
| 571 | out_be32(&dma_channel->mr, mr); | ||
| 572 | 585 | ||
| 573 | return 0; | 586 | return 0; |
| 574 | } | 587 | } |
