Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfashe...
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Sat, 5 May 2007 03:44:54 +0000 (20:44 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Sat, 5 May 2007 03:44:54 +0000 (20:44 -0700)
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2:
  ocfs2: Force use of GFP_NOFS in ocfs2_write()
  ocfs2: fix sparse warnings in fs/ocfs2/cluster
  ocfs2: fix sparse warnings in fs/ocfs2/dlm
  ocfs2: fix sparse warnings in fs/ocfs2
  [PATCH] Copy i_flags to ocfs2 inode flags on write
  [PATCH] ocfs2: use __set_current_state()
  ocfs2: Wrap access of directory allocations with ip_alloc_sem.
  [PATCH] fs/ocfs2/: make 3 functions static
  ocfs2: Implement compat_ioctl()

671 files changed:
Documentation/driver-model/devres.txt
Documentation/feature-removal-schedule.txt
Documentation/i2c/busses/i2c-nforce2
Documentation/i2c/porting-clients
Documentation/i2c/summary
Documentation/i2c/writing-clients
Documentation/input/input-programming.txt
Documentation/pci.txt
Documentation/power/interface.txt
Documentation/power/pci.txt
Documentation/power/states.txt
Documentation/power/swsusp.txt
Documentation/usb/usb-serial.txt
MAINTAINERS
arch/alpha/kernel/err_common.c
arch/alpha/kernel/err_ev6.c
arch/alpha/kernel/err_ev7.c
arch/arm/Kconfig
arch/arm/common/sharpsl_pm.c
arch/arm/mach-at91/pm.c
arch/arm/mach-omap1/pm.c
arch/arm/mach-omap2/pm.c
arch/arm/mach-pnx4008/pm.c
arch/arm/mach-pxa/pm.c
arch/arm/mach-sa1100/pm.c
arch/arm/plat-s3c24xx/pm.c
arch/i386/Kconfig
arch/i386/kernel/cpu/cpufreq/longhaul.c
arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
arch/i386/kernel/cpu/cpufreq/powernow-k8.c
arch/i386/kernel/cpu/cpufreq/powernow-k8.h
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
arch/i386/kernel/io_apic.c
arch/i386/pci/fixup.c
arch/i386/pci/i386.c
arch/ia64/Kconfig
arch/ia64/sn/kernel/huberror.c
arch/ia64/sn/kernel/msi_sn.c
arch/ia64/sn/kernel/xpnet.c
arch/m68k/Kconfig
arch/m68k/Makefile
arch/m68k/amiga/config.c
arch/m68k/atari/Makefile
arch/m68k/atari/atakeyb.c [new file with mode: 0644]
arch/m68k/atari/config.c
arch/m68k/atari/debug.c
arch/m68k/kernel/entry.S
arch/m68k/kernel/head.S
arch/m68k/kernel/setup.c
arch/m68k/lib/checksum.c
arch/m68k/mac/baboon.c
arch/m68k/mac/config.c
arch/m68k/mac/debug.c
arch/m68k/mac/oss.c
arch/m68k/mac/psc.c
arch/m68k/mac/via.c
arch/m68k/q40/config.c
arch/m68k/sun3/sun3ints.c
arch/m68k/sun3x/prom.c
arch/m68knommu/kernel/dma.c
arch/mips/cobalt/Makefile
arch/mips/cobalt/buttons.c [new file with mode: 0644]
arch/mips/lib/iomap.c
arch/powerpc/kernel/pci_64.c
arch/powerpc/kernel/vio.c
arch/powerpc/platforms/powermac/cpufreq_32.c
arch/powerpc/platforms/pseries/power.c
arch/powerpc/platforms/pseries/ras.c
arch/ppc/8260_io/enet.c
arch/ppc/8260_io/fcc_enet.c
arch/ppc/8xx_io/enet.c
arch/ppc/syslib/ppc4xx_sgdma.c
arch/s390/appldata/appldata_net_sum.c
arch/s390/crypto/aes_s390.c
arch/s390/kernel/ipl.c
arch/s390/kernel/kprobes.c
arch/s390/kernel/setup.c
arch/s390/mm/fault.c
arch/sh/boards/hp6xx/pm.c
arch/sh64/mach-cayman/iomap.c
arch/sparc64/Kconfig
arch/sparc64/kernel/pci.c
arch/sparc64/kernel/pci_sun4v.c
arch/sparc64/solaris/ioctl.c
arch/x86_64/Kconfig
arch/x86_64/kernel/cpufreq/Kconfig
arch/x86_64/kernel/io_apic.c
arch/xtensa/kernel/xtensa_ksyms.c
arch/xtensa/platform-iss/setup.c
block/genhd.c
crypto/Kconfig
crypto/Makefile
crypto/ablkcipher.c [new file with mode: 0644]
crypto/algapi.c
crypto/blkcipher.c
crypto/cbc.c
crypto/cryptd.c [new file with mode: 0644]
crypto/cryptomgr.c
crypto/ecb.c
crypto/hash.c
crypto/hmac.c
crypto/lrw.c
crypto/pcbc.c
crypto/tcrypt.c
crypto/xcbc.c
drivers/Makefile
drivers/acpi/processor_perflib.c
drivers/acpi/sleep/main.c
drivers/ata/libata-sff.c
drivers/atm/adummy.c
drivers/base/base.h
drivers/base/bus.c
drivers/base/class.c
drivers/base/core.c
drivers/base/dd.c
drivers/base/firmware.c
drivers/base/platform.c
drivers/base/power/shutdown.c
drivers/base/sys.c
drivers/block/aoe/aoecmd.c
drivers/char/agp/ali-agp.c
drivers/char/agp/alpha-agp.c
drivers/char/agp/generic.c
drivers/char/agp/intel-agp.c
drivers/char/agp/nvidia-agp.c
drivers/char/agp/parisc-agp.c
drivers/char/agp/sgi-agp.c
drivers/char/agp/sis-agp.c
drivers/char/agp/sworks-agp.c
drivers/char/hw_random/via-rng.c
drivers/char/keyboard.c
drivers/char/pcmcia/synclink_cs.c
drivers/char/tpm/tpm.h
drivers/char/watchdog/sc1200wdt.c
drivers/char/watchdog/scx200_wdt.c
drivers/cpufreq/Kconfig
drivers/cpufreq/cpufreq.c
drivers/crypto/Kconfig
drivers/crypto/Makefile
drivers/crypto/padlock.c [deleted file]
drivers/firmware/efivars.c
drivers/i2c/Kconfig
drivers/i2c/Makefile
drivers/i2c/algos/Kconfig
drivers/i2c/algos/i2c-algo-bit.c
drivers/i2c/algos/i2c-algo-sgi.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/Makefile
drivers/i2c/busses/i2c-ali1535.c
drivers/i2c/busses/i2c-ali15x3.c
drivers/i2c/busses/i2c-amd8111.c
drivers/i2c/busses/i2c-at91.c
drivers/i2c/busses/i2c-bfin-twi.c [new file with mode: 0644]
drivers/i2c/busses/i2c-elektor.c
drivers/i2c/busses/i2c-gpio.c [new file with mode: 0644]
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-isa.c
drivers/i2c/busses/i2c-ixp2000.c
drivers/i2c/busses/i2c-ixp4xx.c
drivers/i2c/busses/i2c-mpc.c
drivers/i2c/busses/i2c-mv64xxx.c
drivers/i2c/busses/i2c-nforce2.c
drivers/i2c/busses/i2c-omap.c
drivers/i2c/busses/i2c-parport-light.c
drivers/i2c/busses/i2c-parport.c
drivers/i2c/busses/i2c-pasemi.c
drivers/i2c/busses/i2c-pca-isa.c
drivers/i2c/busses/i2c-piix4.c
drivers/i2c/busses/i2c-pxa.c
drivers/i2c/busses/i2c-s3c2410.c
drivers/i2c/busses/i2c-simtec.c [new file with mode: 0644]
drivers/i2c/busses/i2c-sis96x.c
drivers/i2c/busses/i2c-tiny-usb.c [new file with mode: 0644]
drivers/i2c/busses/i2c-viapro.c
drivers/i2c/busses/scx200_acb.c
drivers/i2c/chips/Kconfig
drivers/i2c/i2c-boardinfo.c [new file with mode: 0644]
drivers/i2c/i2c-core.c
drivers/i2c/i2c-core.h [new file with mode: 0644]
drivers/ieee1394/hosts.c
drivers/infiniband/core/cm.c
drivers/infiniband/core/iwcm.c
drivers/infiniband/core/mad_priv.h
drivers/infiniband/core/multicast.c
drivers/infiniband/core/sa_query.c
drivers/infiniband/core/user_mad.c
drivers/infiniband/hw/ipath/ipath_fs.c
drivers/infiniband/hw/ipath/ipath_layer.c
drivers/infiniband/hw/ipath/ipath_stats.c
drivers/infiniband/hw/ipath/ipath_sysfs.c
drivers/infiniband/hw/mthca/mthca_memfree.h
drivers/infiniband/ulp/ipoib/ipoib.h
drivers/input/Makefile
drivers/input/evbug.c
drivers/input/evdev.c
drivers/input/input.c
drivers/input/joydev.c
drivers/input/joystick/a3d.c
drivers/input/joystick/adi.c
drivers/input/joystick/analog.c
drivers/input/joystick/cobra.c
drivers/input/joystick/db9.c
drivers/input/joystick/gamecon.c
drivers/input/joystick/gf2k.c
drivers/input/joystick/grip.c
drivers/input/joystick/grip_mp.c
drivers/input/joystick/guillemot.c
drivers/input/joystick/iforce/iforce-ff.c
drivers/input/joystick/iforce/iforce-main.c
drivers/input/joystick/iforce/iforce-packets.c
drivers/input/joystick/iforce/iforce-serio.c
drivers/input/joystick/iforce/iforce-usb.c
drivers/input/joystick/iforce/iforce.h
drivers/input/joystick/interact.c
drivers/input/joystick/magellan.c
drivers/input/joystick/sidewinder.c
drivers/input/joystick/spaceball.c
drivers/input/joystick/spaceorb.c
drivers/input/joystick/stinger.c
drivers/input/joystick/tmdc.c
drivers/input/joystick/turbografx.c
drivers/input/joystick/twidjoy.c
drivers/input/joystick/warrior.c
drivers/input/keyboard/Kconfig
drivers/input/keyboard/Makefile
drivers/input/keyboard/aaed2000_kbd.c
drivers/input/keyboard/atakbd.c [new file with mode: 0644]
drivers/input/keyboard/atkbd.c
drivers/input/keyboard/corgikbd.c
drivers/input/keyboard/gpio_keys.c
drivers/input/keyboard/hil_kbd.c
drivers/input/keyboard/hilkbd.c
drivers/input/keyboard/lkkbd.c
drivers/input/keyboard/locomokbd.c
drivers/input/keyboard/newtonkbd.c
drivers/input/keyboard/omap-keypad.c
drivers/input/keyboard/pxa27x_keyboard.c [new file with mode: 0644]
drivers/input/keyboard/spitzkbd.c
drivers/input/keyboard/stowaway.c
drivers/input/keyboard/sunkbd.c
drivers/input/keyboard/xtkbd.c
drivers/input/misc/Kconfig
drivers/input/misc/Makefile
drivers/input/misc/cobalt_btns.c [new file with mode: 0644]
drivers/input/misc/input-polldev.c [new file with mode: 0644]
drivers/input/misc/ixp4xx-beeper.c
drivers/input/misc/m68kspkr.c
drivers/input/misc/pcspkr.c
drivers/input/misc/sparcspkr.c
drivers/input/misc/uinput.c
drivers/input/misc/wistron_btns.c
drivers/input/mouse/Kconfig
drivers/input/mouse/Makefile
drivers/input/mouse/alps.c
drivers/input/mouse/alps.h
drivers/input/mouse/atarimouse.c [new file with mode: 0644]
drivers/input/mouse/hil_ptr.c
drivers/input/mouse/lifebook.c
drivers/input/mouse/lifebook.h
drivers/input/mouse/logips2pp.c
drivers/input/mouse/logips2pp.h
drivers/input/mouse/psmouse-base.c
drivers/input/mouse/psmouse.h
drivers/input/mouse/sermouse.c
drivers/input/mouse/synaptics.c
drivers/input/mouse/synaptics.h
drivers/input/mouse/touchkit_ps2.c [new file with mode: 0644]
drivers/input/mouse/touchkit_ps2.h [new file with mode: 0644]
drivers/input/mouse/trackpoint.h
drivers/input/mouse/vsxxxaa.c
drivers/input/mousedev.c
drivers/input/power.c [deleted file]
drivers/input/serio/hil_mlc.c
drivers/input/serio/hp_sdc.c
drivers/input/serio/hp_sdc_mlc.c
drivers/input/serio/i8042-x86ia64io.h
drivers/input/serio/i8042.c
drivers/input/touchscreen/ads7846.c
drivers/input/touchscreen/corgi_ts.c
drivers/input/touchscreen/elo.c
drivers/input/touchscreen/gunze.c
drivers/input/touchscreen/h3600_ts_input.c
drivers/input/touchscreen/mtouch.c
drivers/input/touchscreen/penmount.c
drivers/input/touchscreen/touchright.c
drivers/input/touchscreen/touchwin.c
drivers/input/touchscreen/ucb1400_ts.c
drivers/input/tsdev.c
drivers/isdn/hisax/netjet.c
drivers/isdn/hysdn/hysdn_proclog.c
drivers/macintosh/therm_windtunnel.c
drivers/macintosh/via-cuda.c
drivers/macintosh/via-macii.c
drivers/macintosh/via-pmu68k.c
drivers/media/dvb/b2c2/flexcop-i2c.c
drivers/media/dvb/cinergyT2/cinergyT2.c
drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
drivers/media/dvb/frontends/dibx000_common.c
drivers/media/video/adv7170.c
drivers/media/video/adv7175.c
drivers/media/video/bt819.c
drivers/media/video/bt856.c
drivers/media/video/bt866.c
drivers/media/video/cx2341x.c
drivers/media/video/cx88/cx88-tvaudio.c
drivers/media/video/em28xx/em28xx-cards.c
drivers/media/video/ovcamchip/ovcamchip_priv.h
drivers/media/video/saa7111.c
drivers/media/video/saa7114.c
drivers/media/video/saa711x.c
drivers/media/video/saa7185.c
drivers/media/video/usbvision/usbvision-cards.c
drivers/misc/hdpuftrs/hdpu_cpustate.c
drivers/misc/hdpuftrs/hdpu_nexus.c
drivers/mtd/devices/doc2000.c
drivers/mtd/devices/doc2001.c
drivers/mtd/devices/doc2001plus.c
drivers/mtd/devices/docecc.c
drivers/mtd/inftlmount.c
drivers/mtd/nand/cs553x_nand.c
drivers/mtd/nftlcore.c
drivers/net/7990.c
drivers/net/Kconfig
drivers/net/Space.c
drivers/net/a2065.c
drivers/net/ariadne.c
drivers/net/atl1/atl1_param.c
drivers/net/au1000_eth.c
drivers/net/bnx2.c
drivers/net/bnx2.h
drivers/net/bnx2_fw.h
drivers/net/bnx2_fw2.h
drivers/net/fec_8xx/fec_main.c
drivers/net/fec_8xx/fec_mii.c
drivers/net/fs_enet/fs_enet-main.c
drivers/net/fs_enet/mac-fcc.c
drivers/net/fs_enet/mac-fec.c
drivers/net/fs_enet/mac-scc.c
drivers/net/fs_enet/mii-bitbang.c
drivers/net/fs_enet/mii-fec.c
drivers/net/ibm_emac/ibm_emac_core.c
drivers/net/ixgb/ixgb_osdep.h
drivers/net/jazzsonic.c
drivers/net/lasi_82596.c
drivers/net/mac8390.c
drivers/net/mac89x0.c
drivers/net/macmace.c
drivers/net/macsonic.c
drivers/net/sonic.c
drivers/net/sun3_82586.c
drivers/net/tokenring/madgemc.c
drivers/net/tokenring/smctr.c
drivers/net/tulip/21142.c
drivers/net/tulip/pnic.c
drivers/net/tulip/pnic2.c
drivers/net/tulip/timer.c
drivers/net/tulip/tulip.h
drivers/net/wan/lmc/lmc_media.c
drivers/net/wan/lmc/lmc_proto.c
drivers/net/wan/pc300_tty.c
drivers/net/wireless/strip.c
drivers/parisc/hppb.c
drivers/parisc/led.c
drivers/parisc/pdc_stable.c
drivers/pci/Kconfig
drivers/pci/bus.c
drivers/pci/hotplug/Kconfig
drivers/pci/hotplug/acpiphp_ibm.c
drivers/pci/hotplug/cpcihp_zt5550.c
drivers/pci/hotplug/fakephp.c
drivers/pci/hotplug/pci_hotplug_core.c
drivers/pci/hotplug/pciehp.h
drivers/pci/hotplug/pciehp_core.c
drivers/pci/hotplug/pciehp_ctrl.c
drivers/pci/hotplug/pciehp_hpc.c
drivers/pci/hotplug/rpadlpar_core.c
drivers/pci/hotplug/rpaphp.h
drivers/pci/hotplug/rpaphp_core.c
drivers/pci/hotplug/rpaphp_pci.c
drivers/pci/hotplug/rpaphp_slot.c
drivers/pci/hotplug/shpchp.h
drivers/pci/hotplug/shpchp_core.c
drivers/pci/hotplug/shpchp_ctrl.c
drivers/pci/msi.c
drivers/pci/pci-driver.c
drivers/pci/pci-sysfs.c
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/probe.c
drivers/pci/quirks.c
drivers/pci/search.c
drivers/pci/setup-bus.c
drivers/pci/setup-res.c
drivers/pcmcia/cs.c
drivers/pcmcia/socket_sysfs.c
drivers/ps3/ps3av.c
drivers/ps3/ps3av_cmd.c
drivers/s390/block/dasd.c
drivers/s390/block/dasd_eckd.c
drivers/s390/block/dasd_fba.c
drivers/s390/block/dasd_int.h
drivers/s390/char/tape.h
drivers/s390/char/tape_3590.c
drivers/s390/char/tape_3590.h
drivers/s390/char/tape_core.c
drivers/s390/cio/qdio.c
drivers/s390/cio/qdio.h
drivers/s390/net/qeth.h
drivers/s390/net/qeth_main.c
drivers/s390/net/qeth_mpc.h
drivers/sbus/sbus.c
drivers/scsi/Kconfig
drivers/scsi/aacraid/dpcsup.c
drivers/scsi/aacraid/sa.c
drivers/scsi/aha1542.c
drivers/scsi/aic94xx/aic94xx_scb.c
drivers/scsi/arcmsr/arcmsr_attr.c
drivers/scsi/atari_NCR5380.c
drivers/scsi/atari_scsi.c
drivers/scsi/atari_scsi.h
drivers/scsi/libsas/sas_expander.c
drivers/scsi/libsrp.c
drivers/scsi/megaraid.c
drivers/usb/input/Makefile
drivers/usb/input/acecad.c
drivers/usb/input/aiptek.c
drivers/usb/input/appletouch.c
drivers/usb/input/ati_remote.c
drivers/usb/input/ati_remote2.c
drivers/usb/input/gtco.c
drivers/usb/input/itmtouch.c [deleted file]
drivers/usb/input/kbtab.c
drivers/usb/input/keyspan_remote.c
drivers/usb/input/mtouchusb.c [deleted file]
drivers/usb/input/powermate.c
drivers/usb/input/touchkitusb.c [deleted file]
drivers/usb/input/usbtouchscreen.c
drivers/usb/input/wacom_sys.c
drivers/usb/input/xpad.c
drivers/usb/input/yealink.c
drivers/usb/net/kaweth.c
drivers/video/Kconfig
drivers/video/Makefile
drivers/video/atafb.c
drivers/video/atafb.h [new file with mode: 0644]
drivers/video/atafb_iplan2p2.c [new file with mode: 0644]
drivers/video/atafb_iplan2p4.c [new file with mode: 0644]
drivers/video/atafb_iplan2p8.c [new file with mode: 0644]
drivers/video/atafb_mfb.c [new file with mode: 0644]
drivers/video/atafb_utils.h [new file with mode: 0644]
drivers/video/aty/radeon_i2c.c
drivers/video/g364fb.c
drivers/video/intelfb/intelfb_i2c.c
drivers/video/matrox/i2c-matroxfb.c
drivers/video/platinumfb.c
drivers/video/ps3fb.c
drivers/video/stifb.c
drivers/video/valkyriefb.c
drivers/zorro/proc.c
drivers/zorro/zorro-sysfs.c
drivers/zorro/zorro.c
fs/Kconfig
fs/afs/Makefile
fs/afs/callback.c
fs/afs/cmservice.c
fs/afs/fsclient.c
fs/afs/internal.h
fs/afs/main.c
fs/afs/netdevices.c [new file with mode: 0644]
fs/afs/super.c
fs/afs/use-rtnetlink.c [deleted file]
fs/afs/vlocation.c
fs/configfs/mount.c
fs/debugfs/inode.c
fs/dlm/lockspace.c
fs/ecryptfs/main.c
fs/fuse/inode.c
fs/gfs2/locking/dlm/sysfs.c
fs/gfs2/sys.c
fs/lockd/mon.c
fs/lockd/xdr.c
fs/lockd/xdr4.c
fs/nfs/client.c
fs/nfs/dir.c
fs/nfs/direct.c
fs/nfs/internal.h
fs/nfs/mount_clnt.c
fs/nfs/nfs2xdr.c
fs/nfs/nfs3xdr.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4xdr.c
fs/nfs/nfsroot.c
fs/nfs/pagelist.c
fs/nfs/read.c
fs/nfs/super.c
fs/nfs/write.c
fs/nfsd/nfs4callback.c
fs/ocfs2/cluster/masklog.c
fs/ocfs2/cluster/masklog.h
fs/ocfs2/cluster/sys.c
fs/partitions/check.c
fs/reiserfs/xattr.c
fs/sysfs/bin.c
fs/sysfs/file.c
include/acpi/acpi_bus.h
include/asm-alpha/scatterlist.h
include/asm-arm/arch-ixp4xx/dma.h
include/asm-arm/arch-pxa/pxa27x_keyboard.h [new file with mode: 0644]
include/asm-avr32/scatterlist.h
include/asm-frv/scatterlist.h
include/asm-h8300/scatterlist.h
include/asm-i386/agp.h
include/asm-i386/scatterlist.h
include/asm-ia64/scatterlist.h
include/asm-m32r/scatterlist.h
include/asm-m68k/adb.h [deleted file]
include/asm-m68k/atarikb.h
include/asm-m68knommu/scatterlist.h
include/asm-mips/scatterlist.h
include/asm-parisc/scatterlist.h
include/asm-powerpc/ps3av.h
include/asm-s390/ccwdev.h
include/asm-s390/elf.h
include/asm-s390/kdebug.h
include/asm-s390/kprobes.h
include/asm-s390/lowcore.h
include/asm-sh/scatterlist.h
include/asm-sh64/scatterlist.h
include/asm-sparc64/scatterlist.h
include/asm-v850/scatterlist.h
include/asm-x86_64/agp.h
include/asm-x86_64/scatterlist.h
include/asm-xtensa/scatterlist.h
include/crypto/algapi.h
include/linux/cpufreq.h
include/linux/crypto.h
include/linux/device.h
include/linux/ethtool.h
include/linux/fs.h
include/linux/gpio_keys.h
include/linux/highmem.h
include/linux/hp_sdc.h
include/linux/i2c-algo-bit.h
include/linux/i2c-gpio.h [new file with mode: 0644]
include/linux/i2c-id.h
include/linux/i2c.h
include/linux/input-polldev.h [new file with mode: 0644]
include/linux/input.h
include/linux/interrupt.h
include/linux/kallsyms.h
include/linux/kernel.h
include/linux/kobject.h
include/linux/lockd/lockd.h
include/linux/module.h
include/linux/msi.h
include/linux/netdevice.h
include/linux/netfilter/nf_conntrack_proto_gre.h
include/linux/netfilter_bridge.h
include/linux/nfs_fs.h
include/linux/nfs_mount.h
include/linux/nfs_page.h
include/linux/nubus.h
include/linux/parser.h
include/linux/pci.h
include/linux/pci_hotplug.h
include/linux/pci_ids.h
include/linux/pm.h
include/linux/skbuff.h
include/linux/sunrpc/clnt.h
include/linux/sunrpc/debug.h
include/linux/sunrpc/msg_prot.h
include/linux/sunrpc/sched.h
include/linux/sunrpc/xprt.h
include/linux/writeback.h
include/linux/xfrm.h
include/media/ovcamchip.h
include/media/tuner.h
include/net/ipv6.h
include/net/iucv/af_iucv.h
include/net/sctp/command.h
include/net/sctp/sctp.h
include/net/sctp/structs.h
include/net/tcp.h
include/net/xfrm.h
include/rdma/ib_mad.h
kernel/irq/chip.c
kernel/kallsyms.c
kernel/ksysfs.c
kernel/module.c
kernel/params.c
kernel/power/disk.c
kernel/power/main.c
kernel/power/power.h
lib/iomap.c
lib/kobject.c
lib/parser.c
lib/vsprintf.c
net/8021q/vlan.c
net/8021q/vlanproc.c
net/bridge/br_if.c
net/bridge/br_ioctl.c
net/bridge/br_netfilter.c
net/bridge/br_netlink.c
net/core/dev.c
net/core/dev_mcast.c
net/core/rtnetlink.c
net/decnet/af_decnet.c
net/decnet/dn_dev.c
net/decnet/dn_fib.c
net/decnet/dn_route.c
net/ipv4/devinet.c
net/ipv4/igmp.c
net/ipv4/ipconfig.c
net/ipv4/netfilter/nf_nat_proto_gre.c
net/ipv4/netfilter/nf_nat_rule.c
net/ipv4/netfilter/nf_nat_sip.c
net/ipv4/tcp.c
net/ipv4/tcp_highspeed.c
net/ipv4/tcp_yeah.h [deleted file]
net/ipv4/udp.c
net/ipv6/addrconf.c
net/ipv6/anycast.c
net/ipv6/mcast.c
net/iucv/af_iucv.c
net/iucv/iucv.c
net/llc/llc_core.c
net/netlink/af_netlink.c
net/netrom/nr_route.c
net/rose/rose_route.c
net/rxrpc/Kconfig
net/rxrpc/ar-ack.c
net/rxrpc/ar-error.c
net/rxrpc/ar-output.c
net/rxrpc/ar-peer.c
net/sched/sch_api.c
net/sctp/associola.c
net/sctp/ipv6.c
net/sctp/protocol.c
net/sctp/sm_make_chunk.c
net/sctp/sm_sideeffect.c
net/sctp/sm_statefuns.c
net/sctp/socket.c
net/sunrpc/Makefile
net/sunrpc/auth_gss/gss_spkm3_seal.c
net/sunrpc/clnt.c
net/sunrpc/pmap_clnt.c [deleted file]
net/sunrpc/rpcb_clnt.c [new file with mode: 0644]
net/sunrpc/sched.c
net/sunrpc/svc.c
net/sunrpc/xprt.c
net/sunrpc/xprtsock.c
net/tipc/eth_media.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_state.c
net/xfrm/xfrm_user.c
security/inode.c
sound/core/init.c
sound/oss/au1550_ac97.c
sound/oss/dmasound/tas_ioctl.h
sound/oss/soundcard.c
sound/pci/ca0106/ca0106_mixer.c
sound/pci/ca0106/ca0106_proc.c
sound/pci/cs46xx/dsp_spos.c
sound/pci/cs46xx/dsp_spos_scb_lib.c
sound/pci/hda/hda_generic.c
sound/pci/hda/hda_proc.c
sound/pci/hda/patch_atihdmi.c
sound/pci/hda/patch_si3054.c
sound/pci/hda/patch_via.c

index 5163b85308f5935c85bb150a1b166d77f746fb07..6c8d8f27db34f9bddd339f7392a257511493c4fb 100644 (file)
@@ -182,7 +182,7 @@ For example, you can do something like the following.
 
        ...
 
-       devres_close_group(dev, my_midlayer_something);
+       devres_close_group(dev, my_midlayer_create_something);
        return 0;
   }
 
index 5c88ba1ea2625661b7860240b3949e1b007b83e4..5f96cb33743e44d6a3f1ea1ba055150e9e88fb47 100644 (file)
@@ -117,13 +117,6 @@ Who:   Adrian Bunk <bunk@stusta.de>
 
 ---------------------------
 
-What:  pci_module_init(driver)
-When:  January 2007
-Why:   Is replaced by pci_register_driver(pci_driver).
-Who:   Richard Knutsson <ricknu-0@student.ltu.se> and Greg Kroah-Hartman <gregkh@suse.de>
-
----------------------------
-
 What:  Usage of invalid timevals in setitimer
 When:  March 2007
 Why:   POSIX requires to validate timevals in the setitimer call. This
@@ -190,18 +183,10 @@ Who:      Jean Delvare <khali@linux-fr.org>
 
 ---------------------------
 
-What:  i2c_adapter.dev
-       i2c_adapter.list
+What:  i2c_adapter.list
 When:  July 2007
-Why:   Superfluous, given i2c_adapter.class_dev:
-         * The "dev" was a stand-in for the physical device node that legacy
-           drivers would not have; but now it's almost always present.  Any
-           remaining legacy drivers must upgrade (they now trigger warnings).
-         * The "list" duplicates class device children.
-       The delay in removing this is so upgraded lm_sensors and libsensors
-       can get deployed.  (Removal causes minor changes in the sysfs layout,
-       notably the location of the adapter type name and parenting the i2c
-       client hardware directly from their controller.)
+Why:   Superfluous, this list duplicates the one maintained by the driver
+       core.
 Who:   Jean Delvare <khali@linux-fr.org>,
        David Brownell <dbrownell@users.sourceforge.net>
 
@@ -314,3 +299,27 @@ Why:       Code was merged, then submitter immediately disappeared leaving
 Who:   David S. Miller <davem@davemloft.net>
 
 ---------------------------
+
+What:  read_dev_chars(), read_conf_data{,_lpm}() (s390 common I/O layer)
+When:  December 2007
+Why:   These functions are a leftover from 2.4 times. They have several
+       problems:
+       - Duplication of checks that are done in the device driver's
+         interrupt handler
+       - common I/O layer can't do device specific error recovery
+       - device driver can't be notified for conditions happening during
+         execution of the function
+       Device drivers should issue the read device characteristics and read
+       configuration data ccws and do the appropriate error handling
+       themselves.
+Who:   Cornelia Huck <cornelia.huck@de.ibm.com>
+
+---------------------------
+
+What:  i2c-ixp2000, i2c-ixp4xx and scx200_i2c drivers
+When:  September 2007
+Why:   Obsolete. The new i2c-gpio driver replaces all hardware-specific
+       I2C-over-GPIO drivers.
+Who:   Jean Delvare <khali@linux-fr.org>
+
+---------------------------
index 7f61fbc03f7f51e294054fbff4037dec5995e9fa..fae3495bcbaf39c94efc4b4273367d10d21f16b6 100644 (file)
@@ -9,6 +9,8 @@ Supported adapters:
   * nForce4 MCP-04             10de:0034
   * nForce4 MCP51              10de:0264
   * nForce4 MCP55              10de:0368
+  * nForce4 MCP61              10de:03EB
+  * nForce4 MCP65              10de:0446
 
 Datasheet: not publicly available, but seems to be similar to the
            AMD-8111 SMBus 2.0 adapter.
index ca272b263a92e5f2aefaf0158c30145ba7119a9f..7bf82c08f6ca71a7376fb3a104c3d327f9c59659 100644 (file)
@@ -1,4 +1,4 @@
-Revision 6, 2005-11-20
+Revision 7, 2007-04-19
 Jean Delvare <khali@linux-fr.org>
 Greg KH <greg@kroah.com>
 
@@ -20,6 +20,10 @@ yours for best results.
 
 Technical changes:
 
+* [Driver type] Any driver that was relying on i2c-isa has to be
+  converted to a proper isa, platform or pci driver. This is not
+  covered by this guide.
+
 * [Includes] Get rid of "version.h" and <linux/i2c-proc.h>.
   Includes typically look like that:
   #include <linux/module.h>
@@ -27,12 +31,10 @@ Technical changes:
   #include <linux/slab.h>
   #include <linux/jiffies.h>
   #include <linux/i2c.h>
-  #include <linux/i2c-isa.h>   /* for ISA drivers */
   #include <linux/hwmon.h>     /* for hardware monitoring drivers */
   #include <linux/hwmon-sysfs.h>
   #include <linux/hwmon-vid.h> /* if you need VRM support */
   #include <linux/err.h>       /* for class registration */
-  #include <asm/io.h>          /* if you have I/O operations */
   Please respect this inclusion order. Some extra headers may be
   required for a given driver (e.g. "lm75.h").
 
@@ -69,20 +71,16 @@ Technical changes:
   sensors mailing list <lm-sensors@lm-sensors.org> by providing a
   patch to the Documentation/hwmon/sysfs-interface file.
 
-* [Attach] For I2C drivers, the attach function should make sure
-  that the adapter's class has I2C_CLASS_HWMON (or whatever class is
-  suitable for your driver), using the following construct:
+* [Attach] The attach function should make sure that the adapter's
+  class has I2C_CLASS_HWMON (or whatever class is suitable for your
+  driver), using the following construct:
   if (!(adapter->class & I2C_CLASS_HWMON))
           return 0;
-  ISA-only drivers of course don't need this.
   Call i2c_probe() instead of i2c_detect().
 
 * [Detect] As mentioned earlier, the flags parameter is gone.
   The type_name and client_name strings are replaced by a single
   name string, which will be filled with a lowercase, short string.
-  In i2c-only drivers, drop the i2c_is_isa_adapter check, it's
-  useless. Same for isa-only drivers, as the test would always be
-  true. Only hybrid drivers (which are quite rare) still need it.
   The labels used for error paths are reduced to the number needed.
   It is advised that the labels are given descriptive names such as
   exit and exit_free. Don't forget to properly set err before
index 41dde877679135ed161cd72a9a87f1673e5a43cd..aea60bf7e8f0847370e17beec79880307754a5d5 100644 (file)
@@ -4,17 +4,23 @@ I2C and SMBus
 =============
 
 I2C (pronounce: I squared C) is a protocol developed by Philips. It is a 
-slow two-wire protocol (10-400 kHz), but it suffices for many types of 
-devices.
+slow two-wire protocol (variable speed, up to 400 kHz), with a high speed
+extension (3.4 MHz).  It provides an inexpensive bus for connecting many
+types of devices with infrequent or low bandwidth communications needs.
+I2C is widely used with embedded systems.  Some systems use variants that
+don't meet branding requirements, and so are not advertised as being I2C.
 
-SMBus (System Management Bus) is a subset of the I2C protocol. Many
-modern mainboards have a System Management Bus. There are a lot of 
-devices which can be connected to a SMBus; the most notable are modern 
-memory chips with EEPROM memories and chips for hardware monitoring.
+SMBus (System Management Bus) is based on the I2C protocol, and is mostly
+a subset of I2C protocols and signaling.  Many I2C devices will work on an
+SMBus, but some SMBus protocols add semantics beyond what is required to
+achieve I2C branding.  Modern PC mainboards rely on SMBus.  The most common
+devices connected through SMBus are RAM modules configured using I2C EEPROMs,
+and hardware monitoring chips.
 
-Because the SMBus is just a special case of the generalized I2C bus, we
-can simulate the SMBus protocol on plain I2C busses. The reverse is
-regretfully impossible.
+Because the SMBus is mostly a subset of the generalized I2C bus, we can
+use its protocols on many I2C systems.  However, there are systems that don't
+meet both SMBus and I2C electrical constraints; and others which can't
+implement all the common SMBus protocol semantics or messages.
 
 
 Terminology
@@ -29,6 +35,7 @@ When we talk about I2C, we use the following terms:
 An Algorithm driver contains general code that can be used for a whole class
 of I2C adapters. Each specific adapter driver depends on one algorithm
 driver.
+
 A Driver driver (yes, this sounds ridiculous, sorry) contains the general
 code to access some type of device. Each detected device gets its own
 data in the Client structure. Usually, Driver and Client are more closely
@@ -40,6 +47,10 @@ a separate Adapter and Algorithm driver), and drivers for your I2C devices
 in this package. See the lm_sensors project http://www.lm-sensors.nu
 for device drivers.
 
+At this time, Linux only operates I2C (or SMBus) in master mode; you can't
+use these APIs to make a Linux system behave as a slave/device, either to
+speak a custom protocol or to emulate some other device.
+
 
 Included Bus Drivers
 ====================
index fbcff96f4ca1f8881d8459ff94c74ac1e38e6417..3d8d36b0ad1262f0a8b4c0fc2fbce21faf07d318 100644 (file)
@@ -1,5 +1,5 @@
 This is a small guide for those who want to write kernel drivers for I2C
-or SMBus devices.
+or SMBus devices, using Linux as the protocol host/master (not slave).
 
 To set up a driver, you need to do several things. Some are optional, and
 some things can be done slightly or completely different. Use this as a
@@ -29,8 +29,16 @@ static struct i2c_driver foo_driver = {
        .driver = {
                .name   = "foo",
        },
+
+       /* iff driver uses driver model ("new style") binding model: */
+       .probe          = foo_probe,
+       .remove         = foo_remove,
+
+       /* else, driver uses "legacy" binding model: */
        .attach_adapter = foo_attach_adapter,
        .detach_client  = foo_detach_client,
+
+       /* these may be used regardless of the driver binding model */
        .shutdown       = foo_shutdown, /* optional */
        .suspend        = foo_suspend,  /* optional */
        .resume         = foo_resume,   /* optional */
@@ -40,7 +48,8 @@ static struct i2c_driver foo_driver = {
 The name field is the driver name, and must not contain spaces.  It
 should match the module name (if the driver can be compiled as a module),
 although you can use MODULE_ALIAS (passing "foo" in this example) to add
-another name for the module.
+another name for the module.  If the driver name doesn't match the module
+name, the module won't be automatically loaded (hotplug/coldplug).
 
 All other fields are for call-back functions which will be explained 
 below.
@@ -65,16 +74,13 @@ An example structure is below.
 
   struct foo_data {
     struct i2c_client client;
-    struct semaphore lock; /* For ISA access in `sensors' drivers. */
-    int sysctl_id;         /* To keep the /proc directory entry for 
-                              `sensors' drivers. */
     enum chips type;       /* To keep the chips type for `sensors' drivers. */
    
     /* Because the i2c bus is slow, it is often useful to cache the read
        information of a chip for some time (for example, 1 or 2 seconds).
        It depends of course on the device whether this is really worthwhile
        or even sensible. */
-    struct semaphore update_lock; /* When we are reading lots of information,
+    struct mutex update_lock;     /* When we are reading lots of information,
                                      another process should not update the
                                      below information */
     char valid;                   /* != 0 if the following fields are valid. */
@@ -95,8 +101,7 @@ some obscure clients). But we need generic reading and writing routines.
 I have found it useful to define foo_read and foo_write function for this.
 For some cases, it will be easier to call the i2c functions directly,
 but many chips have some kind of register-value idea that can easily
-be encapsulated. Also, some chips have both ISA and I2C interfaces, and
-it useful to abstract from this (only for `sensors' drivers).
+be encapsulated.
 
 The below functions are simple examples, and should not be copied
 literally.
@@ -119,28 +124,101 @@ literally.
       return i2c_smbus_write_word_data(client,reg,value);
   }
 
-For sensors code, you may have to cope with ISA registers too. Something
-like the below often works. Note the locking! 
-
-  int foo_read_value(struct i2c_client *client, u8 reg)
-  {
-    int res;
-    if (i2c_is_isa_client(client)) {
-      down(&(((struct foo_data *) (client->data)) -> lock));
-      outb_p(reg,client->addr + FOO_ADDR_REG_OFFSET);
-      res = inb_p(client->addr + FOO_DATA_REG_OFFSET);
-      up(&(((struct foo_data *) (client->data)) -> lock));
-      return res;
-    } else
-      return i2c_smbus_read_byte_data(client,reg);
-  }
-
-Writing is done the same way.
-
 
 Probing and attaching
 =====================
 
+The Linux I2C stack was originally written to support access to hardware
+monitoring chips on PC motherboards, and thus it embeds some assumptions
+that are more appropriate to SMBus (and PCs) than to I2C.  One of these
+assumptions is that most adapters and devices drivers support the SMBUS_QUICK
+protocol to probe device presence.  Another is that devices and their drivers
+can be sufficiently configured using only such probe primitives.
+
+As Linux and its I2C stack became more widely used in embedded systems
+and complex components such as DVB adapters, those assumptions became more
+problematic.  Drivers for I2C devices that issue interrupts need more (and
+different) configuration information, as do drivers handling chip variants
+that can't be distinguished by protocol probing, or which need some board
+specific information to operate correctly.
+
+Accordingly, the I2C stack now has two models for associating I2C devices
+with their drivers:  the original "legacy" model, and a newer one that's
+fully compatible with the Linux 2.6 driver model.  These models do not mix,
+since the "legacy" model requires drivers to create "i2c_client" device
+objects after SMBus style probing, while the Linux driver model expects
+drivers to be given such device objects in their probe() routines.
+
+
+Standard Driver Model Binding ("New Style")
+-------------------------------------------
+
+System infrastructure, typically board-specific initialization code or
+boot firmware, reports what I2C devices exist.  For example, there may be
+a table, in the kernel or from the boot loader, identifying I2C devices
+and linking them to board-specific configuration information about IRQs
+and other wiring artifacts, chip type, and so on.  That could be used to
+create i2c_client objects for each I2C device.
+
+I2C device drivers using this binding model work just like any other
+kind of driver in Linux:  they provide a probe() method to bind to
+those devices, and a remove() method to unbind.
+
+       static int foo_probe(struct i2c_client *client);
+       static int foo_remove(struct i2c_client *client);
+
+Remember that the i2c_driver does not create those client handles.  The
+handle may be used during foo_probe().  If foo_probe() reports success
+(zero not a negative status code) it may save the handle and use it until
+foo_remove() returns.  That binding model is used by most Linux drivers.
+
+Drivers match devices when i2c_client.driver_name and the driver name are
+the same; this approach is used in several other busses that don't have
+device typing support in the hardware.  The driver and module name should
+match, so hotplug/coldplug mechanisms will modprobe the driver.
+
+
+Device Creation (Standard driver model)
+---------------------------------------
+
+If you know for a fact that an I2C device is connected to a given I2C bus,
+you can instantiate that device by simply filling an i2c_board_info
+structure with the device address and driver name, and calling
+i2c_new_device().  This will create the device, then the driver core will
+take care of finding the right driver and will call its probe() method.
+If a driver supports different device types, you can specify the type you
+want using the type field.  You can also specify an IRQ and platform data
+if needed.
+
+Sometimes you know that a device is connected to a given I2C bus, but you
+don't know the exact address it uses.  This happens on TV adapters for
+example, where the same driver supports dozens of slightly different
+models, and I2C device addresses change from one model to the next.  In
+that case, you can use the i2c_new_probed_device() variant, which is
+similar to i2c_new_device(), except that it takes an additional list of
+possible I2C addresses to probe.  A device is created for the first
+responsive address in the list.  If you expect more than one device to be
+present in the address range, simply call i2c_new_probed_device() that
+many times.
+
+The call to i2c_new_device() or i2c_new_probed_device() typically happens
+in the I2C bus driver. You may want to save the returned i2c_client
+reference for later use.
+
+
+Device Deletion (Standard driver model)
+---------------------------------------
+
+Each I2C device which has been created using i2c_new_device() or
+i2c_new_probed_device() can be unregistered by calling
+i2c_unregister_device().  If you don't call it explicitly, it will be
+called automatically before the underlying I2C bus itself is removed, as a
+device can't survive its parent in the device driver model.
+
+
+Legacy Driver Binding Model
+---------------------------
+
 Most i2c devices can be present on several i2c addresses; for some this
 is determined in hardware (by soldering some chip pins to Vcc or Ground),
 for others this can be changed in software (by writing to specific client
@@ -157,13 +235,9 @@ detection algorithm.
 You do not have to use this parameter interface; but don't try to use
 function i2c_probe() if you don't.
 
-NOTE: If you want to write a `sensors' driver, the interface is slightly
-      different! See below.
-
 
-
-Probing classes
----------------
+Probing classes (Legacy model)
+------------------------------
 
 All parameters are given as lists of unsigned 16-bit integers. Lists are
 terminated by I2C_CLIENT_END.
@@ -210,8 +284,8 @@ Note that you *have* to call the defined variable `normal_i2c',
 without any prefix!
 
 
-Attaching to an adapter
------------------------
+Attaching to an adapter (Legacy model)
+--------------------------------------
 
 Whenever a new adapter is inserted, or for all adapters if the driver is
 being registered, the callback attach_adapter() is called. Now is the
@@ -237,17 +311,13 @@ them (unless a `force' parameter was used). In addition, addresses that
 are already in use (by some other registered client) are skipped.
 
 
-The detect client function
---------------------------
+The detect client function (Legacy model)
+-----------------------------------------
 
 The detect client function is called by i2c_probe. The `kind' parameter
 contains -1 for a probed detection, 0 for a forced detection, or a positive
 number for a forced detection with a chip type forced.
 
-Below, some things are only needed if this is a `sensors' driver. Those
-parts are between /* SENSORS ONLY START */ and /* SENSORS ONLY END */
-markers. 
-
 Returning an error different from -ENODEV in a detect function will cause
 the detection to stop: other addresses and adapters won't be scanned.
 This should only be done on fatal or internal errors, such as a memory
@@ -256,64 +326,20 @@ shortage or i2c_attach_client failing.
 For now, you can ignore the `flags' parameter. It is there for future use.
 
   int foo_detect_client(struct i2c_adapter *adapter, int address, 
-                        unsigned short flags, int kind)
+                        int kind)
   {
     int err = 0;
     int i;
-    struct i2c_client *new_client;
+    struct i2c_client *client;
     struct foo_data *data;
-    const char *client_name = ""; /* For non-`sensors' drivers, put the real
-                                     name here! */
+    const char *name = "";
    
     /* Let's see whether this adapter can support what we need.
-       Please substitute the things you need here! 
-       For `sensors' drivers, add `! is_isa &&' to the if statement */
+       Please substitute the things you need here! */
     if (!i2c_check_functionality(adapter,I2C_FUNC_SMBUS_WORD_DATA |
                                         I2C_FUNC_SMBUS_WRITE_BYTE))
        goto ERROR0;
 
-    /* SENSORS ONLY START */
-    const char *type_name = "";
-    int is_isa = i2c_is_isa_adapter(adapter);
-
-    /* Do this only if the chip can additionally be found on the ISA bus
-       (hybrid chip). */
-
-    if (is_isa) {
-
-      /* Discard immediately if this ISA range is already used */
-      /* FIXME: never use check_region(), only request_region() */
-      if (check_region(address,FOO_EXTENT))
-        goto ERROR0;
-
-      /* Probe whether there is anything on this address.
-         Some example code is below, but you will have to adapt this
-         for your own driver */
-
-      if (kind < 0) /* Only if no force parameter was used */ {
-        /* We may need long timeouts at least for some chips. */
-        #define REALLY_SLOW_IO
-        i = inb_p(address + 1);
-        if (inb_p(address + 2) != i)
-          goto ERROR0;
-        if (inb_p(address + 3) != i)
-          goto ERROR0;
-        if (inb_p(address + 7) != i)
-          goto ERROR0;
-        #undef REALLY_SLOW_IO
-
-        /* Let's just hope nothing breaks here */
-        i = inb_p(address + 5) & 0x7f;
-        outb_p(~i & 0x7f,address+5);
-        if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) {
-          outb_p(i,address+5);
-          return 0;
-        }
-      }
-    }
-
-    /* SENSORS ONLY END */
-
     /* OK. For now, we presume we have a valid client. We now create the
        client structure, even though we cannot fill it completely yet.
        But it allows us to access several i2c functions safely */
@@ -323,13 +349,12 @@ For now, you can ignore the `flags' parameter. It is there for future use.
       goto ERROR0;
     }
 
-    new_client = &data->client;
-    i2c_set_clientdata(new_client, data);
+    client = &data->client;
+    i2c_set_clientdata(client, data);
 
-    new_client->addr = address;
-    new_client->adapter = adapter;
-    new_client->driver = &foo_driver;
-    new_client->flags = 0;
+    client->addr = address;
+    client->adapter = adapter;
+    client->driver = &foo_driver;
 
     /* Now, we do the remaining detection. If no `force' parameter is used. */
 
@@ -337,19 +362,17 @@ For now, you can ignore the `flags' parameter. It is there for future use.
        parameter was used. */
     if (kind < 0) {
       /* The below is of course bogus */
-      if (foo_read(new_client,FOO_REG_GENERIC) != FOO_GENERIC_VALUE)
+      if (foo_read(client, FOO_REG_GENERIC) != FOO_GENERIC_VALUE)
          goto ERROR1;
     }
 
-    /* SENSORS ONLY START */
-
     /* Next, specific detection. This is especially important for `sensors'
        devices. */
 
     /* Determine the chip type. Not needed if a `force_CHIPTYPE' parameter
        was used. */
     if (kind <= 0) {
-      i = foo_read(new_client,FOO_REG_CHIPTYPE);
+      i = foo_read(client, FOO_REG_CHIPTYPE);
       if (i == FOO_TYPE_1) 
         kind = chip1; /* As defined in the enum */
       else if (i == FOO_TYPE_2)
@@ -363,63 +386,31 @@ For now, you can ignore the `flags' parameter. It is there for future use.
 
     /* Now set the type and chip names */
     if (kind == chip1) {
-      type_name = "chip1"; /* For /proc entry */
-      client_name = "CHIP 1";
+      name = "chip1";
     } else if (kind == chip2) {
-      type_name = "chip2"; /* For /proc entry */
-      client_name = "CHIP 2";
+      name = "chip2";
     }
    
-    /* Reserve the ISA region */
-    if (is_isa)
-      request_region(address,FOO_EXTENT,type_name);
-
-    /* SENSORS ONLY END */
-
     /* Fill in the remaining client fields. */
-    strcpy(new_client->name,client_name);
-
-    /* SENSORS ONLY BEGIN */
+    strlcpy(client->name, name, I2C_NAME_SIZE);
     data->type = kind;
-    /* SENSORS ONLY END */
-
-    data->valid = 0; /* Only if you use this field */
-    init_MUTEX(&data->update_lock); /* Only if you use this field */
+    mutex_init(&data->update_lock); /* Only if you use this field */
 
     /* Any other initializations in data must be done here too. */
 
-    /* Tell the i2c layer a new client has arrived */
-    if ((err = i2c_attach_client(new_client)))
-      goto ERROR3;
-
-    /* SENSORS ONLY BEGIN */
-    /* Register a new directory entry with module sensors. See below for
-       the `template' structure. */
-    if ((i = i2c_register_entry(new_client, type_name,
-                                    foo_dir_table_template,THIS_MODULE)) < 0) {
-      err = i;
-      goto ERROR4;
-    }
-    data->sysctl_id = i;
-
-    /* SENSORS ONLY END */
-
     /* This function can write default values to the client registers, if
        needed. */
-    foo_init_client(new_client);
+    foo_init_client(client);
+
+    /* Tell the i2c layer a new client has arrived */
+    if ((err = i2c_attach_client(client)))
+      goto ERROR1;
+
     return 0;
 
     /* OK, this is not exactly good programming practice, usually. But it is
        very code-efficient in this case. */
 
-    ERROR4:
-      i2c_detach_client(new_client);
-    ERROR3:
-    ERROR2:
-    /* SENSORS ONLY START */
-      if (is_isa)
-        release_region(address,FOO_EXTENT);
-    /* SENSORS ONLY END */
     ERROR1:
       kfree(data);
     ERROR0:
@@ -427,8 +418,8 @@ For now, you can ignore the `flags' parameter. It is there for future use.
   }
 
 
-Removing the client
-===================
+Removing the client (Legacy model)
+==================================
 
 The detach_client call back function is called when a client should be
 removed. It may actually fail, but only when panicking. This code is
@@ -436,22 +427,12 @@ much simpler than the attachment code, fortunately!
 
   int foo_detach_client(struct i2c_client *client)
   {
-    int err,i;
-
-    /* SENSORS ONLY START */
-    /* Deregister with the `i2c-proc' module. */
-    i2c_deregister_entry(((struct lm78_data *)(client->data))->sysctl_id);
-    /* SENSORS ONLY END */
+    int err;
 
     /* Try to detach the client from i2c space */
     if ((err = i2c_detach_client(client)))
       return err;
 
-    /* HYBRID SENSORS CHIP ONLY START */
-    if i2c_is_isa_client(client)
-      release_region(client->addr,LM78_EXTENT);
-    /* HYBRID SENSORS CHIP ONLY END */
-
     kfree(i2c_get_clientdata(client));
     return 0;
   }
@@ -464,45 +445,34 @@ When the kernel is booted, or when your foo driver module is inserted,
 you have to do some initializing. Fortunately, just attaching (registering)
 the driver module is usually enough.
 
-  /* Keep track of how far we got in the initialization process. If several
-     things have to initialized, and we fail halfway, only those things
-     have to be cleaned up! */
-  static int __initdata foo_initialized = 0;
-
   static int __init foo_init(void)
   {
     int res;
-    printk("foo version %s (%s)\n",FOO_VERSION,FOO_DATE);
     
     if ((res = i2c_add_driver(&foo_driver))) {
       printk("foo: Driver registration failed, module not inserted.\n");
-      foo_cleanup();
       return res;
     }
-    foo_initialized ++;
     return 0;
   }
 
-  void foo_cleanup(void)
+  static void __exit foo_cleanup(void)
   {
-    if (foo_initialized == 1) {
-      if ((res = i2c_del_driver(&foo_driver))) {
-        printk("foo: Driver registration failed, module not removed.\n");
-        return;
-      }
-      foo_initialized --;
-    }
+    i2c_del_driver(&foo_driver);
   }
 
   /* Substitute your own name and email address */
   MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"
   MODULE_DESCRIPTION("Driver for Barf Inc. Foo I2C devices");
 
+  /* a few non-GPL license types are also allowed */
+  MODULE_LICENSE("GPL");
+
   module_init(foo_init);
   module_exit(foo_cleanup);
 
 Note that some functions are marked by `__init', and some data structures
-by `__init_data'.  Hose functions and structures can be removed after
+by `__initdata'.  These functions and structures can be removed after
 kernel booting (or module loading) is completed.
 
 
@@ -632,110 +602,7 @@ General purpose routines
 Below all general purpose routines are listed, that were not mentioned
 before.
 
-  /* This call returns a unique low identifier for each registered adapter,
-   * or -1 if the adapter was not registered.
+  /* This call returns a unique low identifier for each registered adapter.
    */
   extern int i2c_adapter_id(struct i2c_adapter *adap);
 
-
-The sensors sysctl/proc interface
-=================================
-
-This section only applies if you write `sensors' drivers.
-
-Each sensors driver creates a directory in /proc/sys/dev/sensors for each
-registered client. The directory is called something like foo-i2c-4-65.
-The sensors module helps you to do this as easily as possible.
-
-The template
-------------
-
-You will need to define a ctl_table template. This template will automatically
-be copied to a newly allocated structure and filled in where necessary when
-you call sensors_register_entry.
-
-First, I will give an example definition.
-  static ctl_table foo_dir_table_template[] = {
-    { FOO_SYSCTL_FUNC1, "func1", NULL, 0, 0644, NULL, &i2c_proc_real,
-      &i2c_sysctl_real,NULL,&foo_func },
-    { FOO_SYSCTL_FUNC2, "func2", NULL, 0, 0644, NULL, &i2c_proc_real,
-      &i2c_sysctl_real,NULL,&foo_func },
-    { FOO_SYSCTL_DATA, "data", NULL, 0, 0644, NULL, &i2c_proc_real,
-      &i2c_sysctl_real,NULL,&foo_data },
-    { 0 }
-  };
-
-In the above example, three entries are defined. They can either be
-accessed through the /proc interface, in the /proc/sys/dev/sensors/*
-directories, as files named func1, func2 and data, or alternatively 
-through the sysctl interface, in the appropriate table, with identifiers
-FOO_SYSCTL_FUNC1, FOO_SYSCTL_FUNC2 and FOO_SYSCTL_DATA.
-
-The third, sixth and ninth parameters should always be NULL, and the
-fourth should always be 0. The fifth is the mode of the /proc file;
-0644 is safe, as the file will be owned by root:root. 
-
-The seventh and eighth parameters should be &i2c_proc_real and
-&i2c_sysctl_real if you want to export lists of reals (scaled
-integers). You can also use your own function for them, as usual.
-Finally, the last parameter is the call-back to gather the data
-(see below) if you use the *_proc_real functions. 
-
-
-Gathering the data
-------------------
-
-The call back functions (foo_func and foo_data in the above example)
-can be called in several ways; the operation parameter determines
-what should be done:
-
-  * If operation == SENSORS_PROC_REAL_INFO, you must return the
-    magnitude (scaling) in nrels_mag;
-  * If operation == SENSORS_PROC_REAL_READ, you must read information
-    from the chip and return it in results. The number of integers
-    to display should be put in nrels_mag;
-  * If operation == SENSORS_PROC_REAL_WRITE, you must write the
-    supplied information to the chip. nrels_mag will contain the number
-    of integers, results the integers themselves.
-
-The *_proc_real functions will display the elements as reals for the
-/proc interface. If you set the magnitude to 2, and supply 345 for
-SENSORS_PROC_REAL_READ, it would display 3.45; and if the user would
-write 45.6 to the /proc file, it would be returned as 4560 for
-SENSORS_PROC_REAL_WRITE. A magnitude may even be negative!
-
-An example function:
-
-  /* FOO_FROM_REG and FOO_TO_REG translate between scaled values and
-     register values. Note the use of the read cache. */
-  void foo_in(struct i2c_client *client, int operation, int ctl_name, 
-              int *nrels_mag, long *results)
-  {
-    struct foo_data *data = client->data;
-    int nr = ctl_name - FOO_SYSCTL_FUNC1; /* reduce to 0 upwards */
-    
-    if (operation == SENSORS_PROC_REAL_INFO)
-      *nrels_mag = 2;
-    else if (operation == SENSORS_PROC_REAL_READ) {
-      /* Update the readings cache (if necessary) */
-      foo_update_client(client);
-      /* Get the readings from the cache */
-      results[0] = FOO_FROM_REG(data->foo_func_base[nr]);
-      results[1] = FOO_FROM_REG(data->foo_func_more[nr]);
-      results[2] = FOO_FROM_REG(data->foo_func_readonly[nr]);
-      *nrels_mag = 2;
-    } else if (operation == SENSORS_PROC_REAL_WRITE) {
-      if (*nrels_mag >= 1) {
-        /* Update the cache */
-        data->foo_base[nr] = FOO_TO_REG(results[0]);
-        /* Update the chip */
-        foo_write_value(client,FOO_REG_FUNC_BASE(nr),data->foo_base[nr]);
-      }
-      if (*nrels_mag >= 2) {
-        /* Update the cache */
-        data->foo_more[nr] = FOO_TO_REG(results[1]);
-        /* Update the chip */
-        foo_write_value(client,FOO_REG_FUNC_MORE(nr),data->foo_more[nr]);
-      }
-    }
-  }
index 180e0689676ce4d7899e69c07b181f09a57130f4..d9d523099bb7d69d3dd3e4124167e5dd9bad1fc4 100644 (file)
@@ -1,5 +1,3 @@
-$Id: input-programming.txt,v 1.4 2001/05/04 09:47:14 vojtech Exp $
-
 Programming input drivers
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -20,28 +18,51 @@ pressed or released a BUTTON_IRQ happens. The driver could look like:
 #include <asm/irq.h>
 #include <asm/io.h>
 
+static struct input_dev *button_dev;
+
 static void button_interrupt(int irq, void *dummy, struct pt_regs *fp)
 {
-       input_report_key(&button_dev, BTN_1, inb(BUTTON_PORT) & 1);
-       input_sync(&button_dev);
+       input_report_key(button_dev, BTN_1, inb(BUTTON_PORT) & 1);
+       input_sync(button_dev);
 }
 
 static int __init button_init(void)
 {
+       int error;
+
        if (request_irq(BUTTON_IRQ, button_interrupt, 0, "button", NULL)) {
                 printk(KERN_ERR "button.c: Can't allocate irq %d\n", button_irq);
                 return -EBUSY;
         }
-       
-       button_dev.evbit[0] = BIT(EV_KEY);
-       button_dev.keybit[LONG(BTN_0)] = BIT(BTN_0);
-       
-       input_register_device(&button_dev);
+
+       button_dev = input_allocate_device();
+       if (!button_dev) {
+               printk(KERN_ERR "button.c: Not enough memory\n");
+               error = -ENOMEM;
+               goto err_free_irq;
+       }
+
+       button_dev->evbit[0] = BIT(EV_KEY);
+       button_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
+
+       error = input_register_device(button_dev);
+       if (error) {
+               printk(KERN_ERR "button.c: Failed to register device\n");
+               goto err_free_dev;
+       }
+
+       return 0;
+
+ err_free_dev:
+       input_free_device(button_dev);
+ err_free_irq:
+       free_irq(BUTTON_IRQ, button_interrupt);
+       return error;
 }
 
 static void __exit button_exit(void)
 {
-        input_unregister_device(&button_dev);
+        input_unregister_device(button_dev);
        free_irq(BUTTON_IRQ, button_interrupt);
 }
 
@@ -58,17 +79,18 @@ In the _init function, which is called either upon module load or when
 booting the kernel, it grabs the required resources (it should also check
 for the presence of the device).
 
-Then it sets the input bitfields. This way the device driver tells the other
+Then it allocates a new input device structure with input_aloocate_device()
+and sets up input bitfields. This way the device driver tells the other
 parts of the input systems what it is - what events can be generated or
-accepted by this input device. Our example device can only generate EV_KEY type
-events, and from those only BTN_0 event code. Thus we only set these two
-bits. We could have used
+accepted by this input device. Our example device can only generate EV_KEY
+type events, and from those only BTN_0 event code. Thus we only set these
+two bits. We could have used
 
        set_bit(EV_KEY, button_dev.evbit);
        set_bit(BTN_0, button_dev.keybit);
 
 as well, but with more than single bits the first approach tends to be
-shorter. 
+shorter.
 
 Then the example driver registers the input device structure by calling
 
@@ -76,16 +98,15 @@ Then the example driver registers the input device structure by calling
 
 This adds the button_dev structure to linked lists of the input driver and
 calls device handler modules _connect functions to tell them a new input
-device has appeared. Because the _connect functions may call kmalloc(,
-GFP_KERNEL), which can sleep, input_register_device() must not be called
-from an interrupt or with a spinlock held.
+device has appeared. input_register_device() may sleep and therefore must
+not be called from an interrupt or with a spinlock held.
 
 While in use, the only used function of the driver is
 
        button_interrupt()
 
 which upon every interrupt from the button checks its state and reports it
-via the 
+via the
 
        input_report_key()
 
@@ -113,16 +134,10 @@ can use the open and close callback to know when it can stop polling or
 release the interrupt and when it must resume polling or grab the interrupt
 again. To do that, we would add this to our example driver:
 
-int button_used = 0;
-
 static int button_open(struct input_dev *dev)
 {
-        if (button_used++)
-                return 0;
-
        if (request_irq(BUTTON_IRQ, button_interrupt, 0, "button", NULL)) {
                 printk(KERN_ERR "button.c: Can't allocate irq %d\n", button_irq);
-                button_used--;
                 return -EBUSY;
         }
 
@@ -131,20 +146,21 @@ static int button_open(struct input_dev *dev)
 
 static void button_close(struct input_dev *dev)
 {
-        if (!--button_used)
-                free_irq(IRQ_AMIGA_VERTB, button_interrupt);
+        free_irq(IRQ_AMIGA_VERTB, button_interrupt);
 }
 
 static int __init button_init(void)
 {
        ...
-       button_dev.open = button_open;
-       button_dev.close = button_close;
+       button_dev->open = button_open;
+       button_dev->close = button_close;
        ...
 }
 
-Note the button_used variable - we have to track how many times the open
-function was called to know when exactly our device stops being used.
+Note that input core keeps track of number of users for the device and
+makes sure that dev->open() is called only when the first user connects
+to the device and that dev->close() is called when the very last user
+disconnects. Calls to both callbacks are serialized.
 
 The open() callback should return a 0 in case of success or any nonzero value
 in case of failure. The close() callback (which is void) must always succeed.
@@ -175,7 +191,7 @@ set the corresponding bits and call the
 
        input_report_rel(struct input_dev *dev, int code, int value)
 
-function. Events are generated only for nonzero value. 
+function. Events are generated only for nonzero value.
 
 However EV_ABS requires a little special care. Before calling
 input_register_device, you have to fill additional fields in the input_dev
@@ -187,6 +203,10 @@ the ABS_X axis:
        button_dev.absfuzz[ABS_X] = 4;
        button_dev.absflat[ABS_X] = 8;
 
+Or, you can just say:
+
+       input_set_abs_params(button_dev, ABS_X, 0, 255, 4, 8);
+
 This setting would be appropriate for a joystick X axis, with the minimum of
 0, maximum of 255 (which the joystick *must* be able to reach, no problem if
 it sometimes reports more, but it must be able to always reach the min and
@@ -197,14 +217,7 @@ If you don't need absfuzz and absflat, you can set them to zero, which mean
 that the thing is precise and always returns to exactly the center position
 (if it has any).
 
-1.4 The void *private field
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This field in the input structure can be used to point to any private data
-structures in the input device driver, in case the driver handles more than
-one device. You'll need it in the open and close callbacks.
-
-1.5 NBITS(), LONG(), BIT()
+1.4 NBITS(), LONG(), BIT()
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 These three macros from input.h help some bitfield computations:
@@ -213,13 +226,9 @@ These three macros from input.h help some bitfield computations:
        LONG(x)  - returns the index in the array in longs for bit x
        BIT(x)   - returns the index in a long for bit x
 
-1.6 The number, id* and name fields
+1.5 The id* and name fields
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The dev->number is assigned by the input system to the input device when it
-is registered. It has no use except for identifying the device to the user
-in system messages.
-
 The dev->name should be set before registering the input device by the input
 device driver. It's a string like 'Generic button device' containing a
 user friendly name of the device.
@@ -234,15 +243,25 @@ driver.
 
 The id and name fields can be passed to userland via the evdev interface.
 
-1.7 The keycode, keycodemax, keycodesize fields
+1.6 The keycode, keycodemax, keycodesize fields
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-These two fields will be used for any input devices that report their data
-as scancodes. If not all scancodes can be known by autodetection, they may
-need to be set by userland utilities. The keycode array then is an array
-used to map from scancodes to input system keycodes. The keycode max will
-contain the size of the array and keycodesize the size of each entry in it
-(in bytes).
+These three fields should be used by input devices that have dense keymaps.
+The keycode is an array used to map from scancodes to input system keycodes.
+The keycode max should contain the size of the array and keycodesize the
+size of each entry in it (in bytes).
+
+Userspace can query and alter current scancode to keycode mappings using
+EVIOCGKEYCODE and EVIOCSKEYCODE ioctls on corresponding evdev interface.
+When a device has all 3 aforementioned fields filled in, the driver may
+rely on kernel's default implementation of setting and querying keycode
+mappings.
+
+1.7 dev->getkeycode() and dev->setkeycode()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+getkeycode() and setkeycode() callbacks allow drivers to override default
+keycode/keycodesize/keycodemax mapping mechanism provided by input core
+and implement sparse keycode maps.
 
 1.8 Key autorepeat
 ~~~~~~~~~~~~~~~~~~
@@ -266,7 +285,7 @@ direction - from the system to the input device driver. If your input device
 driver can handle these events, it has to set the respective bits in evbit,
 *and* also the callback routine:
 
-       button_dev.event = button_event;
+       button_dev->event = button_event;
 
 int button_event(struct input_dev *dev, unsigned int type, unsigned int code, int value);
 {
index cdf2f3c0ab14f8398bee52c1e4a39c41984b28b6..e2c9d0a0c43de9de21efbbc5c6e74fe7f544aa06 100644 (file)
@@ -124,10 +124,6 @@ initialization with a pointer to a structure describing the driver
 
        err_handler     See Documentation/pci-error-recovery.txt
 
-       multithread_probe       Enable multi-threaded probe/scan. Driver must
-                       provide its own locking/syncronization for init
-                       operations if this is enabled.
-
 
 The ID table is an array of struct pci_device_id entries ending with an
 all-zero entry.  Each entry consists of:
@@ -163,9 +159,9 @@ echo "vendor device subvendor subdevice class class_mask driver_data" > \
 /sys/bus/pci/drivers/{driver}/new_id
 
 All fields are passed in as hexadecimal values (no leading 0x).
-Users need pass only as many fields as necessary:
-       o vendor, device, subvendor, and subdevice fields default
-         to PCI_ANY_ID (FFFFFFFF),
+The vendor and device fields are mandatory, the others are optional. Users
+need pass only as many optional fields as necessary:
+       o subvendor and subdevice fields default to PCI_ANY_ID (FFFFFFFF)
        o class and classmask fields default to 0
        o driver_data defaults to 0UL.
 
@@ -549,8 +545,6 @@ pci_find_slot()                     Find pci_dev corresponding to given bus and
 pci_set_power_state()          Set PCI Power Management state (0=D0 ... 3=D3)
 pci_find_capability()          Find specified capability in device's capability
                                list.
-pci_module_init()              Inline helper function for ensuring correct
-                               pci_driver initialization and error handling.
 pci_resource_start()           Returns bus start address for a given PCI region
 pci_resource_end()             Returns bus end address for a given PCI region
 pci_resource_len()             Returns the byte length of a PCI region
index 74311d7e0f3c9a9d250de17d241953114b335abe..8c5b41bf3f363e386181f8adccd33cc2b97f81b2 100644 (file)
@@ -18,17 +18,10 @@ states.
 
 
 /sys/power/disk controls the operating mode of the suspend-to-disk
-mechanism. Suspend-to-disk can be handled in several ways. The
-greatest distinction is who writes memory to disk - the firmware or
-the kernel. If the firmware does it, we assume that it also handles
-suspending the system. 
-
-If the kernel does it, then we have three options for putting the system
-to sleep - using the platform driver (e.g. ACPI or other PM
-registers), powering off the system or rebooting the system (for
-testing). The system will support either 'firmware' or 'platform', and
-that is known a priori. But, the user may choose 'shutdown' or
-'reboot' as alternatives. 
+mechanism. Suspend-to-disk can be handled in several ways. We have a
+few options for putting the system to sleep - using the platform driver
+(e.g. ACPI or other pm_ops), powering off the system or rebooting the
+system (for testing).
 
 Additionally, /sys/power/disk can be used to turn on one of the two testing
 modes of the suspend-to-disk mechanism: 'testproc' or 'test'.  If the
@@ -44,16 +37,12 @@ is being slow and which device drivers are misbehaving.
 Reading from this file will display what the mode is currently set
 to. Writing to this file will accept one of
 
-       'firmware'
-       'platform'
+       'platform' (only if the platform supports it)
        'shutdown'
        'reboot'
        'testproc'
        'test'
 
-It will only change to 'firmware' or 'platform' if the system supports
-it. 
-
 /sys/power/image_size controls the size of the image created by
 the suspend-to-disk mechanism.  It can be written a string
 representing a non-negative integer that will be used as an upper
index b6a3cbf7e846d3d8dbd8fc4b133578c03ac6e07e..e00b099a4b8678844edc3f91427f1a184afe8648 100644 (file)
@@ -203,7 +203,7 @@ resume
 
 Usage:
 
-if (dev->driver && dev->driver->suspend)
+if (dev->driver && dev->driver->resume)
        dev->driver->resume(dev)
 
 The resume callback may be called from any power state, and is always meant to
index 0931a330d362c59dd2cb4ddf7d0fb4eb864f247b..34800cc521bfd6c26cf56bfdae81791ad670425d 100644 (file)
@@ -62,17 +62,18 @@ setup via another operating system for it to use. Despite the
 inconvenience, this method requires minimal work by the kernel, since
 the firmware will also handle restoring memory contents on resume. 
 
-If the kernel is responsible for persistently saving state, a mechanism
-called 'swsusp' (Swap Suspend) is used to write memory contents to
-free swap space. swsusp has some restrictive requirements, but should
-work in most cases. Some, albeit outdated, documentation can be found
-in Documentation/power/swsusp.txt. 
+For suspend-to-disk, a mechanism called swsusp called 'swsusp' (Swap
+Suspend) is used to write memory contents to free swap space.
+swsusp has some restrictive requirements, but should work in most
+cases. Some, albeit outdated, documentation can be found in
+Documentation/power/swsusp.txt. Alternatively, userspace can do most
+of the actual suspend to disk work, see userland-swsusp.txt.
 
 Once memory state is written to disk, the system may either enter a
 low-power state (like ACPI S4), or it may simply power down. Powering
 down offers greater savings, and allows this mechanism to work on any
 system. However, entering a real low-power state allows the user to
-trigger wake up events (e.g. pressing a key or opening a laptop lid). 
+trigger wake up events (e.g. pressing a key or opening a laptop lid).
 
 A transition from Suspend-to-Disk to the On state should take about 30
 seconds, though it's typically a bit more with the current
index 0761ff6c57eddf65779e11d4991e751c250fe340..c55bd5079b90e4ddc654fb8755e93bfca8144560 100644 (file)
@@ -156,8 +156,7 @@ instead set the PF_NOFREEZE process flag when creating the thread (and
 be very careful).
 
 
-Q: What is the difference between "platform", "shutdown" and
-"firmware" in /sys/power/disk?
+Q: What is the difference between "platform" and "shutdown"?
 
 A:
 
@@ -166,11 +165,8 @@ shutdown: save state in linux, then tell bios to powerdown
 platform: save state in linux, then tell bios to powerdown and blink
           "suspended led"
 
-firmware: tell bios to save state itself [needs BIOS-specific suspend
-         partition, and has very little to do with swsusp]
-
-"platform" is actually right thing to do, but "shutdown" is most
-reliable.
+"platform" is actually right thing to do where supported, but
+"shutdown" is most reliable (except on ACPI systems).
 
 Q: I do not understand why you have such strong objections to idea of
 selective suspend.
@@ -388,8 +384,8 @@ while the system is asleep, maintaining the connection, using true sleep
 modes like "suspend-to-RAM" or "standby".  (Don't write "disk" to the
 /sys/power/state file; write "standby" or "mem".)  We've not seen any
 hardware that can use these modes through software suspend, although in
-theory some systems might support "platform" or "firmware" modes that
-won't break the USB connections.
+theory some systems might support "platform" modes that won't break the
+USB connections.
 
 Remember that it's always a bad idea to unplug a disk drive containing a
 mounted filesystem.  That's true even when your system is asleep!  The
index d61f6e7865def51b2ba281daa01d4c873f7311c9..b18e86a225068c212e18a141a940b2481be59209 100644 (file)
@@ -42,7 +42,7 @@ ConnectTech WhiteHEAT 4 port converter
   http://www.connecttech.com
 
   For any questions or problems with this driver, please contact
-  Stuart MacDonald at stuartm@connecttech.com
+  Connect Tech's Support Department at support@connecttech.com
 
 
 HandSpring Visor, Palm USB, and CliĆ© USB driver
index af1c7926c1530e16da6e2bb4d196707d4d5c77cb..1e8c37054ea291db9311b56b7cc2253c46649b8e 100644 (file)
@@ -733,6 +733,13 @@ M: tigran@aivazian.fsnet.co.uk
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
 
+BLACKFIN I2C TWI DRIVER
+P:     Sonic Zhang
+M:     sonic.zhang@analog.com
+L:     uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
+W:     http://blackfin.uclinux.org/
+S:     Supported
+
 BLOCK LAYER
 P:     Jens Axboe
 M:     axboe@kernel.dk
@@ -1459,6 +1466,11 @@ L:       linux-scsi@vger.kernel.org
 W:     http://www.icp-vortex.com/
 S:     Supported
 
+GENERIC GPIO I2C DRIVER
+P:     Haavard Skinnemoen
+M:     hskinnemoen@atmel.com
+S:     Supported
+
 GENERIC HDLC DRIVER, N2, C101, PCI200SYN and WANXL DRIVERS
 P:     Krzysztof Halasa
 M:     khc@pm.waw.pl
@@ -1631,6 +1643,13 @@ L:       i2c@lm-sensors.org
 T:     quilt http://khali.linux-fr.org/devel/linux-2.6/jdelvare-i2c/
 S:     Maintained
 
+I2C-TINY-USB DRIVER
+P:     Till Harbaum
+M:     till@harbaum.org
+L:     i2c@lm-sensors.org
+T:     http://www.harbaum.org/till/i2c_tiny_usb
+S:     Maintained
+
 i386 BOOT CODE
 P:     Riley H. Williams
 M:     Riley@Williams.Name
@@ -3627,8 +3646,8 @@ W:        http://www.kroah.com/linux/
 S:     Maintained
 
 USB SERIAL WHITEHEAT DRIVER
-P:     Stuart MacDonald
-M:     stuartm@connecttech.com
+P:     Support Department
+M:     support@connecttech.com
 L:     linux-usb-users@lists.sourceforge.net
 L:     linux-usb-devel@lists.sourceforge.net
 W:     http://www.connecttech.com
index 687580b16b41ce590d3c760288b1d432d35a57fe..13d53b1c9657f7ceaa855d99ad6cd31f7753bab0 100644 (file)
@@ -7,7 +7,6 @@
  */
 
 #include <linux/init.h>
-#include <linux/pci.h>
 #include <linux/sched.h>
 
 #include <asm/io.h>
index 69b5f4ea735531903f2af37d747361f00a6356df..11aee012a8aed0986b7e744c7a43a0f7ac275814 100644 (file)
@@ -7,7 +7,6 @@
  */
 
 #include <linux/init.h>
-#include <linux/pci.h>
 #include <linux/sched.h>
 
 #include <asm/io.h>
index 95463ab1cf358aebd5df0b9a4f5839ee79cbb182..bc799f72d8c1ae6cb6e490e0c5bb15db179f8a11 100644 (file)
@@ -7,7 +7,6 @@
  */
 
 #include <linux/init.h>
-#include <linux/pci.h>
 #include <linux/sched.h>
 
 #include <asm/io.h>
index e7baca29f3fb47f59cab05cf016b3f5cf25ebb26..db00376aca15ff32c75b808dc843accb81d0f002 100644 (file)
@@ -255,6 +255,7 @@ config ARCH_IOP13XX
        depends on MMU
        select PLAT_IOP
        select PCI
+       select ARCH_SUPPORTS_MSI
        help
          Support for Intel's IOP13XX (XScale) family of processors.
 
index a9bc5b52218fe9513cda477860dd0a5f90aca20a..5972df2b9af479a6f54f770baddca6419ad5f3bd 100644 (file)
@@ -766,10 +766,10 @@ static void sharpsl_apm_get_power_status(struct apm_power_info *info)
 }
 
 static struct pm_ops sharpsl_pm_ops = {
-       .pm_disk_mode   = PM_DISK_FIRMWARE,
        .prepare        = pxa_pm_prepare,
        .enter          = corgi_pxa_pm_enter,
        .finish         = pxa_pm_finish,
+       .valid          = pm_valid_only_mem,
 };
 
 static int __init sharpsl_pm_probe(struct platform_device *pdev)
index b49bfda53d7fdb1bbc97964b6695dda6a8a2804e..ff8db29e989e2f39c420a9de219f63b435ace081 100644 (file)
@@ -201,7 +201,6 @@ error:
 
 
 static struct pm_ops at91_pm_ops ={
-       .pm_disk_mode   = 0,
        .valid          = at91_pm_valid_state,
        .prepare        = at91_pm_prepare,
        .enter          = at91_pm_enter,
index 49efe903dacda7c98e8b1043b7b761fa62c73298..6f4ea4bda5e0708ece8eadacea6550f90862171c 100644 (file)
@@ -72,12 +72,12 @@ static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
 
 static unsigned short enable_dyn_sleep = 1;
 
-static ssize_t omap_pm_sleep_while_idle_show(struct subsystem * subsys, char *buf)
+static ssize_t omap_pm_sleep_while_idle_show(struct kset *kset, char *buf)
 {
        return sprintf(buf, "%hu\n", enable_dyn_sleep);
 }
 
-static ssize_t omap_pm_sleep_while_idle_store(struct subsystem * subsys,
+static ssize_t omap_pm_sleep_while_idle_store(struct kset *kset,
                                              const char * buf,
                                              size_t n)
 {
@@ -100,7 +100,7 @@ static struct subsys_attribute sleep_while_idle_attr = {
        .store  = omap_pm_sleep_while_idle_store,
 };
 
-extern struct subsystem power_subsys;
+extern struct kset power_subsys;
 static void (*omap_sram_idle)(void) = NULL;
 static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL;
 
@@ -698,10 +698,10 @@ static struct irqaction omap_wakeup_irq = {
 
 
 static struct pm_ops omap_pm_ops ={
-       .pm_disk_mode   = 0,
        .prepare        = omap_pm_prepare,
        .enter          = omap_pm_enter,
        .finish         = omap_pm_finish,
+       .valid          = pm_valid_only_mem,
 };
 
 static int __init omap_pm_init(void)
index d7eee99b7e3fef12029d700f9550e6e0a96a3df7..6f4a5436d0ce858f33598f3f6fb77800614a6318 100644 (file)
@@ -370,10 +370,10 @@ static int omap2_pm_finish(suspend_state_t state)
 }
 
 static struct pm_ops omap_pm_ops = {
-       .pm_disk_mode   = 0,
        .prepare        = omap2_pm_prepare,
        .enter          = omap2_pm_enter,
        .finish         = omap2_pm_finish,
+       .valid          = pm_valid_only_mem,
 };
 
 int __init omap2_pm_init(void)
index 3649cd3dfc9af4abe0ffe07cf1bbd66dc352aef8..2a137f33f752698daac232049e4fcd3309d30581 100644 (file)
@@ -107,50 +107,19 @@ static int pnx4008_pm_enter(suspend_state_t state)
        case PM_SUSPEND_MEM:
                pnx4008_suspend();
                break;
-       case PM_SUSPEND_DISK:
-               return -ENOTSUPP;
-       default:
-               return -EINVAL;
        }
        return 0;
 }
 
-/*
- * Called after processes are frozen, but before we shut down devices.
- */
-static int pnx4008_pm_prepare(suspend_state_t state)
-{
-       switch (state) {
-       case PM_SUSPEND_STANDBY:
-       case PM_SUSPEND_MEM:
-               break;
-
-       case PM_SUSPEND_DISK:
-               return -ENOTSUPP;
-               break;
-
-       default:
-               return -EINVAL;
-               break;
-       }
-       return 0;
-}
-
-/*
- * Called after devices are re-setup, but before processes are thawed.
- */
-static int pnx4008_pm_finish(suspend_state_t state)
+static int pnx4008_pm_valid(suspend_state_t state)
 {
-       return 0;
+       return (state == PM_SUSPEND_STANDBY) ||
+              (state == PM_SUSPEND_MEM);
 }
 
-/*
- * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
- */
 static struct pm_ops pnx4008_pm_ops = {
-       .prepare = pnx4008_pm_prepare,
        .enter = pnx4008_pm_enter,
-       .finish = pnx4008_pm_finish,
+       .valid = pnx4008_pm_valid,
 };
 
 static int __init pnx4008_pm_init(void)
index b4d8276d6050b1e34d16c06153228f03c0b113a3..6bf15ae73848efc667689d28661944e00a84d167 100644 (file)
@@ -223,14 +223,11 @@ int pxa_pm_finish(suspend_state_t state)
 
 EXPORT_SYMBOL_GPL(pxa_pm_finish);
 
-/*
- * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
- */
 static struct pm_ops pxa_pm_ops = {
-       .pm_disk_mode   = PM_DISK_FIRMWARE,
        .prepare        = pxa_pm_prepare,
        .enter          = pxa_pm_enter,
        .finish         = pxa_pm_finish,
+       .valid          = pm_valid_only_mem,
 };
 
 static int __init pxa_pm_init(void)
index 786c8534231f8e258858cfab996be37128c46a90..d674cf3431567c88bdf5181ef99a7ab17c04fb36 100644 (file)
@@ -59,9 +59,6 @@ static int sa11x0_pm_enter(suspend_state_t state)
        unsigned long gpio, sleep_save[SLEEP_SAVE_SIZE];
        struct timespec delta, rtc;
 
-       if (state != PM_SUSPEND_MEM)
-               return -EINVAL;
-
        /* preserve current time */
        rtc.tv_sec = RCNR;
        rtc.tv_nsec = 0;
@@ -134,12 +131,9 @@ unsigned long sleep_phys_sp(void *sp)
        return virt_to_phys(sp);
 }
 
-/*
- * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
- */
 static struct pm_ops sa11x0_pm_ops = {
-       .pm_disk_mode   = PM_DISK_FIRMWARE,
        .enter          = sa11x0_pm_enter,
+       .valid          = pm_valid_only_mem,
 };
 
 static int __init sa11x0_pm_init(void)
index ecf68d611904d4098e80962adb25c289101803c6..c6b03f8ab2602076c58c86a7ae6d7a8318b095b7 100644 (file)
@@ -511,11 +511,6 @@ static int s3c2410_pm_enter(suspend_state_t state)
                return -EINVAL;
        }
 
-       if (state != PM_SUSPEND_MEM) {
-               printk(KERN_ERR PFX "error: only PM_SUSPEND_MEM supported\n");
-               return -EINVAL;
-       }
-
        /* check if we have anything to wake-up with... bad things seem
         * to happen if you suspend with no wakeup (system will often
         * require a full power-cycle)
@@ -617,30 +612,9 @@ static int s3c2410_pm_enter(suspend_state_t state)
        return 0;
 }
 
-/*
- * Called after processes are frozen, but before we shut down devices.
- */
-static int s3c2410_pm_prepare(suspend_state_t state)
-{
-       return 0;
-}
-
-/*
- * Called after devices are re-setup, but before processes are thawed.
- */
-static int s3c2410_pm_finish(suspend_state_t state)
-{
-       return 0;
-}
-
-/*
- * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
- */
 static struct pm_ops s3c2410_pm_ops = {
-       .pm_disk_mode   = PM_DISK_FIRMWARE,
-       .prepare        = s3c2410_pm_prepare,
        .enter          = s3c2410_pm_enter,
-       .finish         = s3c2410_pm_finish,
+       .valid          = pm_valid_only_mem,
 };
 
 /* s3c2410_pm_init
index 53d62373a5240d149e0604bc4b1458a5c440e0f5..bcf2fc408a1a8ae0ca3f3d6c0ee32c9d63cd66ba 100644 (file)
@@ -1073,6 +1073,7 @@ config PCI
        bool "PCI support" if !X86_VISWS
        depends on !X86_VOYAGER
        default y if X86_VISWS
+       select ARCH_SUPPORTS_MSI if (X86_LOCAL_APIC && X86_IO_APIC)
        help
          Find out whether you have a PCI motherboard. PCI is the name of a
          bus system, i.e. the way the CPU talks to the other stuff inside
index 2b030d6ccbf7336d6cb6f14c813ea049d3d60184..a3df9c039bd4221ecb3e80fdda4e71a8b4d9581d 100644 (file)
@@ -590,20 +590,23 @@ static acpi_status longhaul_walk_callback(acpi_handle obj_handle,
 static int enable_arbiter_disable(void)
 {
        struct pci_dev *dev;
+       int status;
        int reg;
        u8 pci_cmd;
 
+       status = 1;
        /* Find PLE133 host bridge */
        reg = 0x78;
-       dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0, NULL);
+       dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0,
+                            NULL);
        /* Find CLE266 host bridge */
        if (dev == NULL) {
                reg = 0x76;
-               dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_862X_0, NULL);
+               dev = pci_get_device(PCI_VENDOR_ID_VIA,
+                                    PCI_DEVICE_ID_VIA_862X_0, NULL);
                /* Find CN400 V-Link host bridge */
                if (dev == NULL)
-                       dev = pci_find_device(PCI_VENDOR_ID_VIA, 0x7259, NULL);
-
+                       dev = pci_get_device(PCI_VENDOR_ID_VIA, 0x7259, NULL);
        }
        if (dev != NULL) {
                /* Enable access to port 0x22 */
@@ -615,10 +618,11 @@ static int enable_arbiter_disable(void)
                        if (!(pci_cmd & 1<<7)) {
                                printk(KERN_ERR PFX
                                        "Can't enable access to port 0x22.\n");
-                               return 0;
+                               status = 0;
                        }
                }
-               return 1;
+               pci_dev_put(dev);
+               return status;
        }
        return 0;
 }
@@ -629,7 +633,7 @@ static int longhaul_setup_vt8235(void)
        u8 pci_cmd;
 
        /* Find VT8235 southbridge */
-       dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, NULL);
+       dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, NULL);
        if (dev != NULL) {
                /* Set transition time to max */
                pci_read_config_byte(dev, 0xec, &pci_cmd);
@@ -641,6 +645,7 @@ static int longhaul_setup_vt8235(void)
                pci_read_config_byte(dev, 0xe5, &pci_cmd);
                pci_cmd |= 1 << 7;
                pci_write_config_byte(dev, 0xe5, pci_cmd);
+               pci_dev_put(dev);
                return 1;
        }
        return 0;
@@ -678,7 +683,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
                                sizeof(samuel2_eblcr));
                        break;
                case 1 ... 15:
-                       longhaul_version = TYPE_LONGHAUL_V2;
+                       longhaul_version = TYPE_LONGHAUL_V1;
                        if (c->x86_mask < 8) {
                                cpu_model = CPU_SAMUEL2;
                                cpuname = "C3 'Samuel 2' [C5B]";
index 4786fedca6ebfcc94897f6e8d84581f61189c2e4..4c76b511e1944d16ed420343cb57db0dafb1f943 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/cpufreq.h>
 #include <linux/slab.h>
 #include <linux/cpumask.h>
-#include <linux/sched.h>       /* current / set_cpus_allowed() */
 
 #include <asm/processor.h>
 #include <asm/msr.h>
@@ -62,7 +61,7 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
        if (!cpu_online(cpu) || (newstate > DC_DISABLE) || (newstate == DC_RESV))
                return -EINVAL;
 
-       rdmsr(MSR_IA32_THERM_STATUS, l, h);
+       rdmsr_on_cpu(cpu, MSR_IA32_THERM_STATUS, &l, &h);
 
        if (l & 0x01)
                dprintk("CPU#%d currently thermal throttled\n", cpu);
@@ -70,10 +69,10 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
        if (has_N44_O17_errata[cpu] && (newstate == DC_25PT || newstate == DC_DFLT))
                newstate = DC_38PT;
 
-       rdmsr(MSR_IA32_THERM_CONTROL, l, h);
+       rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, &l, &h);
        if (newstate == DC_DISABLE) {
                dprintk("CPU#%d disabling modulation\n", cpu);
-               wrmsr(MSR_IA32_THERM_CONTROL, l & ~(1<<4), h);
+               wrmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, l & ~(1<<4), h);
        } else {
                dprintk("CPU#%d setting duty cycle to %d%%\n",
                        cpu, ((125 * newstate) / 10));
@@ -84,7 +83,7 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
                 */
                l = (l & ~14);
                l = l | (1<<4) | ((newstate & 0x7)<<1);
-               wrmsr(MSR_IA32_THERM_CONTROL, l, h);
+               wrmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, l, h);
        }
 
        return 0;
@@ -111,7 +110,6 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy,
 {
        unsigned int    newstate = DC_RESV;
        struct cpufreq_freqs freqs;
-       cpumask_t cpus_allowed;
        int i;
 
        if (cpufreq_frequency_table_target(policy, &p4clockmod_table[0], target_freq, relation, &newstate))
@@ -132,17 +130,8 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy,
        /* run on each logical CPU, see section 13.15.3 of IA32 Intel Architecture Software
         * Developer's Manual, Volume 3
         */
-       cpus_allowed = current->cpus_allowed;
-
-       for_each_cpu_mask(i, policy->cpus) {
-               cpumask_t this_cpu = cpumask_of_cpu(i);
-
-               set_cpus_allowed(current, this_cpu);
-               BUG_ON(smp_processor_id() != i);
-
+       for_each_cpu_mask(i, policy->cpus)
                cpufreq_p4_setdc(i, p4clockmod_table[newstate].index);
-       }
-       set_cpus_allowed(current, cpus_allowed);
 
        /* notifiers */
        for_each_cpu_mask(i, policy->cpus) {
@@ -256,17 +245,9 @@ static int cpufreq_p4_cpu_exit(struct cpufreq_policy *policy)
 
 static unsigned int cpufreq_p4_get(unsigned int cpu)
 {
-       cpumask_t cpus_allowed;
        u32 l, h;
 
-       cpus_allowed = current->cpus_allowed;
-
-       set_cpus_allowed(current, cpumask_of_cpu(cpu));
-       BUG_ON(smp_processor_id() != cpu);
-
-       rdmsr(MSR_IA32_THERM_CONTROL, l, h);
-
-       set_cpus_allowed(current, cpus_allowed);
+       rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, &l, &h);
 
        if (l & 0x10) {
                l = l >> 1;
index fe3b67005ebbb1d04ea17c20e804b47cf8cede7e..7cf3d207b6b393b8215c1469bafedc93e16f4524 100644 (file)
@@ -661,7 +661,8 @@ static int fill_powernow_table(struct powernow_k8_data *data, struct pst_s *pst,
 
        dprintk("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid);
        data->powernow_table = powernow_table;
-       print_basics(data);
+       if (first_cpu(cpu_core_map[data->cpu]) == data->cpu)
+               print_basics(data);
 
        for (j = 0; j < data->numps; j++)
                if ((pst[j].fid==data->currfid) && (pst[j].vid==data->currvid))
@@ -814,7 +815,8 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
 
        /* fill in data */
        data->numps = data->acpi_data.state_count;
-       print_basics(data);
+       if (first_cpu(cpu_core_map[data->cpu]) == data->cpu)
+               print_basics(data);
        powernow_k8_acpi_pst_values(data, 0);
 
        /* notify BIOS that we exist */
index 0fb2a3001ba5505c8dbf743bc290f87d1b888641..95be5013c984a7355d3668e35daec66cf30cfc88 100644 (file)
@@ -215,8 +215,10 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid);
 
 static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index);
 
+#ifdef CONFIG_X86_POWERNOW_K8_ACPI
 static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table);
 static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table);
+#endif
 
 #ifdef CONFIG_SMP
 static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[])
index f43b987f952b0870c36d114924960ffc65ffa92c..35489fd68852306a14f3e8235857f0d85a08107d 100644 (file)
@@ -720,6 +720,7 @@ static int centrino_target (struct cpufreq_policy *policy,
                        cpu_set(j, set_mask);
 
                set_cpus_allowed(current, set_mask);
+               preempt_disable();
                if (unlikely(!cpu_isset(smp_processor_id(), set_mask))) {
                        dprintk("couldn't limit to CPUs in this domain\n");
                        retval = -EAGAIN;
@@ -727,6 +728,7 @@ static int centrino_target (struct cpufreq_policy *policy,
                                /* We haven't started the transition yet. */
                                goto migrate_end;
                        }
+                       preempt_enable();
                        break;
                }
 
@@ -761,10 +763,13 @@ static int centrino_target (struct cpufreq_policy *policy,
                }
 
                wrmsr(MSR_IA32_PERF_CTL, oldmsr, h);
-               if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY)
+               if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
+                       preempt_enable();
                        break;
+               }
 
                cpu_set(j, covered_cpus);
+               preempt_enable();
        }
 
        for_each_cpu_mask(k, online_policy_cpus) {
@@ -796,8 +801,11 @@ static int centrino_target (struct cpufreq_policy *policy,
                        cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
                }
        }
+       set_cpus_allowed(current, saved_mask);
+       return 0;
 
 migrate_end:
+       preempt_enable();
        set_cpus_allowed(current, saved_mask);
        return 0;
 }
index d59277c00911cf0e64ac4bc53323b8296deeba35..b1acc8ce3167c8f02d0747f7282fc8b685e1d94a 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
-#include <linux/pci.h>
 #include <linux/slab.h>
 
 #include <asm/msr.h>
index ff0d89806114b63b8db4010664cf410352c7ba80..e1c509aa3054ef5dc7f453c3f665b5dcf1cdfa8e 100644 (file)
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
-#include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <asm/ist.h>
+#include <asm/io.h>
 
 #include "speedstep-lib.h"
 
index b3ab8ffebd27fc05ca5f96bbfe2b8bf419b32ca8..89d85d244926d2db60a3f69a9575eaa47f9d9f16 100644 (file)
@@ -2611,19 +2611,19 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
        if (irq < 0)
                return irq;
 
-       set_irq_msi(irq, desc);
        ret = msi_compose_msg(dev, irq, &msg);
        if (ret < 0) {
                destroy_irq(irq);
                return ret;
        }
 
+       set_irq_msi(irq, desc);
        write_msi_msg(irq, &msg);
 
        set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq,
                                      "edge");
 
-       return irq;
+       return 0;
 }
 
 void arch_teardown_msi_irq(unsigned int irq)
index 8053b17ab64753541d9684369c6999f166ccecd7..b62eafb997bce2b1bf4dcd379ef06ca954bceae7 100644 (file)
@@ -354,7 +354,7 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev)
                printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev));
        }
 }
-DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
+DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
 
 /*
  * Some Toshiba laptops need extra code to enable their TI TSB43AB22/A.
index 43005f04442424173db59704f39091306bf50c59..bcd2f94b732c59ebd998cad10dd64225d8283303 100644 (file)
@@ -246,8 +246,8 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask)
                        continue;
                if (!r->start && r->end) {
                        printk(KERN_ERR "PCI: Device %s not available "
-                               "because of resource collisions\n",
-                               pci_name(dev));
+                               "because of resource %d collisions\n",
+                               pci_name(dev), idx);
                        return -EINVAL;
                }
                if (r->flags & IORESOURCE_IO)
index e19185d2655484b1f4f8131025ba8ed497a99050..3b71f97d0b603a7a3b112e9ea1561eab06e6265f 100644 (file)
@@ -14,6 +14,7 @@ config IA64
        select PCI if (!IA64_HP_SIM)
        select ACPI if (!IA64_HP_SIM)
        select PM if (!IA64_HP_SIM)
+       select ARCH_SUPPORTS_MSI
        default y
        help
          The Itanium Processor Family is Intel's 64-bit successor to
index fcf7f93c4b615f83bdd1cd0296a74515e11f595b..2c3f9dfca78bad85826c945864060ec43f8c582f 100644 (file)
@@ -8,7 +8,6 @@
 
 #include <linux/types.h>
 #include <linux/interrupt.h>
-#include <linux/pci.h>
 #include <asm/delay.h>
 #include <asm/sn/sn_sal.h>
 #include "ioerror.h"
index 49873aa4a37dcb2e1705e70081dfb7e9c11d291d..83f190ffe35078dd062266727c20025d00b3a7fa 100644 (file)
@@ -87,7 +87,6 @@ int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry)
        if (irq < 0)
                return irq;
 
-       set_irq_msi(irq, entry);
        /*
         * Set up the vector plumbing.  Let the prom (via sn_intr_alloc)
         * decide which cpu to direct this msi at by default.
@@ -144,10 +143,11 @@ int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry)
         */
        msg.data = 0x100 + irq;
 
+       set_irq_msi(irq, entry);
        write_msi_msg(irq, &msg);
        set_irq_chip_and_handler(irq, &sn_msi_chip, handle_edge_irq);
 
-       return irq;
+       return 0;
 }
 
 #ifdef CONFIG_SMP
index 5419acb89a8c6a2cbd48217217be77ede841c655..88fad85ceeff5b6f2ce18c39f05b5f3581bbedb2 100644 (file)
@@ -24,7 +24,6 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/netdevice.h>
index a8e1e604dfa81427b19d77a1ae3d81fdfb9841c8..b8536c7c0877577541f1a7ab0b977f29a44b82b0 100644 (file)
@@ -409,6 +409,9 @@ config STRAM_PROC
        help
          Say Y here to report ST-RAM usage statistics in /proc/stram.
 
+config ATARI_KBD_CORE
+       bool
+
 config HEARTBEAT
        bool "Use power LED as a heartbeat" if AMIGA || APOLLO || ATARI || MAC ||Q40
        default y if !AMIGA && !APOLLO && !ATARI && !MAC && !Q40 && HP300
index 34d826d10f1b6f1683b04d0daa254c6f8ce1b969..c20831a7e1a9e1a064261ab861d5ea960ea322a9 100644 (file)
@@ -21,7 +21,7 @@ AS += -m68020
 LDFLAGS := -m m68kelf
 ifneq ($(COMPILE_ARCH),$(ARCH))
        # prefix for cross-compiling binaries
-       CROSS_COMPILE = m68k-linux-
+       CROSS_COMPILE = m68k-linux-gnu-
 endif
 
 ifdef CONFIG_SUN3
index 3204f412cad8c32cca0fdc81ad10696218062f5d..35748531327dac74710c653017395b73348014fc 100644 (file)
@@ -22,9 +22,7 @@
 #include <linux/vt_kern.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
-#ifdef CONFIG_ZORRO
 #include <linux/zorro.h>
-#endif
 
 #include <asm/bootinfo.h>
 #include <asm/setup.h>
@@ -62,55 +60,51 @@ static char s_cdtv[] __initdata = "CDTV";
 static char s_cd32[] __initdata = "CD32";
 static char s_draco[] __initdata = "Draco";
 static char *amiga_models[] __initdata = {
-    [AMI_500-AMI_500]          = s_a500,
-    [AMI_500PLUS-AMI_500]      = s_a500p,
-    [AMI_600-AMI_500]          = s_a600,
-    [AMI_1000-AMI_500]         = s_a1000,
-    [AMI_1200-AMI_500]         = s_a1200,
-    [AMI_2000-AMI_500]         = s_a2000,
-    [AMI_2500-AMI_500]         = s_a2500,
-    [AMI_3000-AMI_500]         = s_a3000,
-    [AMI_3000T-AMI_500]                = s_a3000t,
-    [AMI_3000PLUS-AMI_500]     = s_a3000p,
-    [AMI_4000-AMI_500]         = s_a4000,
-    [AMI_4000T-AMI_500]                = s_a4000t,
-    [AMI_CDTV-AMI_500]         = s_cdtv,
-    [AMI_CD32-AMI_500]         = s_cd32,
-    [AMI_DRACO-AMI_500]                = s_draco,
+       [AMI_500-AMI_500]       = s_a500,
+       [AMI_500PLUS-AMI_500]   = s_a500p,
+       [AMI_600-AMI_500]       = s_a600,
+       [AMI_1000-AMI_500]      = s_a1000,
+       [AMI_1200-AMI_500]      = s_a1200,
+       [AMI_2000-AMI_500]      = s_a2000,
+       [AMI_2500-AMI_500]      = s_a2500,
+       [AMI_3000-AMI_500]      = s_a3000,
+       [AMI_3000T-AMI_500]     = s_a3000t,
+       [AMI_3000PLUS-AMI_500]  = s_a3000p,
+       [AMI_4000-AMI_500]      = s_a4000,
+       [AMI_4000T-AMI_500]     = s_a4000t,
+       [AMI_CDTV-AMI_500]      = s_cdtv,
+       [AMI_CD32-AMI_500]      = s_cd32,
+       [AMI_DRACO-AMI_500]     = s_draco,
 };
 
 static char amiga_model_name[13] = "Amiga ";
 
-extern char m68k_debug_device[];
-
 static void amiga_sched_init(irq_handler_t handler);
 /* amiga specific irq functions */
-extern void amiga_init_IRQ (void);
+extern void amiga_init_IRQ(void);
 static void amiga_get_model(char *model);
 static int amiga_get_hardware_list(char *buffer);
 /* amiga specific timer functions */
-static unsigned long amiga_gettimeoffset (void);
-static int a3000_hwclk (int, struct rtc_time *);
-static int a2000_hwclk (int, struct rtc_time *);
-static int amiga_set_clock_mmss (unsigned long);
-static unsigned int amiga_get_ss (void);
-extern void amiga_mksound( unsigned int count, unsigned int ticks );
-static void amiga_reset (void);
+static unsigned long amiga_gettimeoffset(void);
+static int a3000_hwclk(int, struct rtc_time *);
+static int a2000_hwclk(int, struct rtc_time *);
+static int amiga_set_clock_mmss(unsigned long);
+static unsigned int amiga_get_ss(void);
+extern void amiga_mksound(unsigned int count, unsigned int ticks);
+static void amiga_reset(void);
 extern void amiga_init_sound(void);
-static void amiga_savekmsg_init(void);
 static void amiga_mem_console_write(struct console *co, const char *b,
                                    unsigned int count);
 void amiga_serial_console_write(struct console *co, const char *s,
                                unsigned int count);
-static void amiga_debug_init(void);
 #ifdef CONFIG_HEARTBEAT
 static void amiga_heartbeat(int on);
 #endif
 
 static struct console amiga_console_driver = {
-       .name =         "debug",
-       .flags =        CON_PRINTBUFFER,
-       .index =        -1,
+       .name   = "debug",
+       .flags  = CON_PRINTBUFFER,
+       .index  = -1,
 };
 
 
@@ -119,24 +113,24 @@ static struct console amiga_console_driver = {
      */
 
 static struct {
-    struct resource _ciab, _ciaa, _custom, _kickstart;
+       struct resource _ciab, _ciaa, _custom, _kickstart;
 } mb_resources = {
-    ._ciab = {
-       .name = "CIA B", .start = 0x00bfd000, .end = 0x00bfdfff
-    },
-    ._ciaa = {
-       .name = "CIA A", .start = 0x00bfe000, .end = 0x00bfefff
-    },
-    ._custom = {
-       .name = "Custom I/O", .start = 0x00dff000, .end = 0x00dfffff
-    },
-    ._kickstart = {
-       .name = "Kickstart ROM", .start = 0x00f80000, .end = 0x00ffffff
-    }
+       ._ciab = {
+               .name = "CIA B", .start = 0x00bfd000, .end = 0x00bfdfff
+       },
+       ._ciaa = {
+               .name = "CIA A", .start = 0x00bfe000, .end = 0x00bfefff
+       },
+       ._custom = {
+               .name = "Custom I/O", .start = 0x00dff000, .end = 0x00dfffff
+       },
+       ._kickstart = {
+               .name = "Kickstart ROM", .start = 0x00f80000, .end = 0x00ffffff
+       }
 };
 
 static struct resource rtc_resource = {
-    .start = 0x00dc0000, .end = 0x00dcffff
+       .start = 0x00dc0000, .end = 0x00dcffff
 };
 
 static struct resource ram_resource[NUM_MEMINFO];
@@ -148,57 +142,57 @@ static struct resource ram_resource[NUM_MEMINFO];
 
 int amiga_parse_bootinfo(const struct bi_record *record)
 {
-    int unknown = 0;
-    const unsigned long *data = record->data;
+       int unknown = 0;
+       const unsigned long *data = record->data;
 
-    switch (record->tag) {
+       switch (record->tag) {
        case BI_AMIGA_MODEL:
-           amiga_model = *data;
-           break;
+               amiga_model = *data;
+               break;
 
        case BI_AMIGA_ECLOCK:
-           amiga_eclock = *data;
-           break;
+               amiga_eclock = *data;
+               break;
 
        case BI_AMIGA_CHIPSET:
-           amiga_chipset = *data;
-           break;
+               amiga_chipset = *data;
+               break;
 
        case BI_AMIGA_CHIP_SIZE:
-           amiga_chip_size = *(const int *)data;
-           break;
+               amiga_chip_size = *(const int *)data;
+               break;
 
        case BI_AMIGA_VBLANK:
-           amiga_vblank = *(const unsigned char *)data;
-           break;
+               amiga_vblank = *(const unsigned char *)data;
+               break;
 
        case BI_AMIGA_PSFREQ:
-           amiga_psfreq = *(const unsigned char *)data;
-           break;
+               amiga_psfreq = *(const unsigned char *)data;
+               break;
 
        case BI_AMIGA_AUTOCON:
 #ifdef CONFIG_ZORRO
-           if (zorro_num_autocon < ZORRO_NUM_AUTO) {
-               const struct ConfigDev *cd = (struct ConfigDev *)data;
-               struct zorro_dev *dev = &zorro_autocon[zorro_num_autocon++];
-               dev->rom = cd->cd_Rom;
-               dev->slotaddr = cd->cd_SlotAddr;
-               dev->slotsize = cd->cd_SlotSize;
-               dev->resource.start = (unsigned long)cd->cd_BoardAddr;
-               dev->resource.end = dev->resource.start+cd->cd_BoardSize-1;
-           } else
-               printk("amiga_parse_bootinfo: too many AutoConfig devices\n");
+               if (zorro_num_autocon < ZORRO_NUM_AUTO) {
+                       const struct ConfigDev *cd = (struct ConfigDev *)data;
+                       struct zorro_dev *dev = &zorro_autocon[zorro_num_autocon++];
+                       dev->rom = cd->cd_Rom;
+                       dev->slotaddr = cd->cd_SlotAddr;
+                       dev->slotsize = cd->cd_SlotSize;
+                       dev->resource.start = (unsigned long)cd->cd_BoardAddr;
+                       dev->resource.end = dev->resource.start + cd->cd_BoardSize - 1;
+               } else
+                       printk("amiga_parse_bootinfo: too many AutoConfig devices\n");
 #endif /* CONFIG_ZORRO */
-           break;
+               break;
 
        case BI_AMIGA_SERPER:
-           /* serial port period: ignored here */
-           break;
+               /* serial port period: ignored here */
+               break;
 
        default:
-           unknown = 1;
-    }
-    return(unknown);
+               unknown = 1;
+       }
+       return unknown;
 }
 
     /*
@@ -207,159 +201,159 @@ int amiga_parse_bootinfo(const struct bi_record *record)
 
 static void __init amiga_identify(void)
 {
-  /* Fill in some default values, if necessary */
-  if (amiga_eclock == 0)
-    amiga_eclock = 709379;
-
-  memset(&amiga_hw_present, 0, sizeof(amiga_hw_present));
-
-  printk("Amiga hardware found: ");
-  if (amiga_model >= AMI_500 && amiga_model <= AMI_DRACO) {
-    printk("[%s] ", amiga_models[amiga_model-AMI_500]);
-    strcat(amiga_model_name, amiga_models[amiga_model-AMI_500]);
-  }
-
-  switch(amiga_model) {
-  case AMI_UNKNOWN:
-    goto Generic;
-
-  case AMI_600:
-  case AMI_1200:
-    AMIGAHW_SET(A1200_IDE);
-    AMIGAHW_SET(PCMCIA);
-  case AMI_500:
-  case AMI_500PLUS:
-  case AMI_1000:
-  case AMI_2000:
-  case AMI_2500:
-    AMIGAHW_SET(A2000_CLK);    /* Is this correct for all models? */
-    goto Generic;
-
-  case AMI_3000:
-  case AMI_3000T:
-    AMIGAHW_SET(AMBER_FF);
-    AMIGAHW_SET(MAGIC_REKICK);
-    /* fall through */
-  case AMI_3000PLUS:
-    AMIGAHW_SET(A3000_SCSI);
-    AMIGAHW_SET(A3000_CLK);
-    AMIGAHW_SET(ZORRO3);
-    goto Generic;
-
-  case AMI_4000T:
-    AMIGAHW_SET(A4000_SCSI);
-    /* fall through */
-  case AMI_4000:
-    AMIGAHW_SET(A4000_IDE);
-    AMIGAHW_SET(A3000_CLK);
-    AMIGAHW_SET(ZORRO3);
-    goto Generic;
-
-  case AMI_CDTV:
-  case AMI_CD32:
-    AMIGAHW_SET(CD_ROM);
-    AMIGAHW_SET(A2000_CLK);             /* Is this correct? */
-    goto Generic;
-
-  Generic:
-    AMIGAHW_SET(AMI_VIDEO);
-    AMIGAHW_SET(AMI_BLITTER);
-    AMIGAHW_SET(AMI_AUDIO);
-    AMIGAHW_SET(AMI_FLOPPY);
-    AMIGAHW_SET(AMI_KEYBOARD);
-    AMIGAHW_SET(AMI_MOUSE);
-    AMIGAHW_SET(AMI_SERIAL);
-    AMIGAHW_SET(AMI_PARALLEL);
-    AMIGAHW_SET(CHIP_RAM);
-    AMIGAHW_SET(PAULA);
-
-    switch(amiga_chipset) {
-    case CS_OCS:
-    case CS_ECS:
-    case CS_AGA:
-      switch (amiga_custom.deniseid & 0xf) {
-      case 0x0c:
-       AMIGAHW_SET(DENISE_HR);
-       break;
-      case 0x08:
-       AMIGAHW_SET(LISA);
-       break;
-      }
-      break;
-    default:
-      AMIGAHW_SET(DENISE);
-      break;
-    }
-    switch ((amiga_custom.vposr>>8) & 0x7f) {
-    case 0x00:
-      AMIGAHW_SET(AGNUS_PAL);
-      break;
-    case 0x10:
-      AMIGAHW_SET(AGNUS_NTSC);
-      break;
-    case 0x20:
-    case 0x21:
-      AMIGAHW_SET(AGNUS_HR_PAL);
-      break;
-    case 0x30:
-    case 0x31:
-      AMIGAHW_SET(AGNUS_HR_NTSC);
-      break;
-    case 0x22:
-    case 0x23:
-      AMIGAHW_SET(ALICE_PAL);
-      break;
-    case 0x32:
-    case 0x33:
-      AMIGAHW_SET(ALICE_NTSC);
-      break;
-    }
-    AMIGAHW_SET(ZORRO);
-    break;
-
-  case AMI_DRACO:
-    panic("No support for Draco yet");
-
-  default:
-    panic("Unknown Amiga Model");
-  }
+       /* Fill in some default values, if necessary */
+       if (amiga_eclock == 0)
+               amiga_eclock = 709379;
 
-#define AMIGAHW_ANNOUNCE(name, str)                    \
-  if (AMIGAHW_PRESENT(name))                           \
-    printk(str)
-
-  AMIGAHW_ANNOUNCE(AMI_VIDEO, "VIDEO ");
-  AMIGAHW_ANNOUNCE(AMI_BLITTER, "BLITTER ");
-  AMIGAHW_ANNOUNCE(AMBER_FF, "AMBER_FF ");
-  AMIGAHW_ANNOUNCE(AMI_AUDIO, "AUDIO ");
-  AMIGAHW_ANNOUNCE(AMI_FLOPPY, "FLOPPY ");
-  AMIGAHW_ANNOUNCE(A3000_SCSI, "A3000_SCSI ");
-  AMIGAHW_ANNOUNCE(A4000_SCSI, "A4000_SCSI ");
-  AMIGAHW_ANNOUNCE(A1200_IDE, "A1200_IDE ");
-  AMIGAHW_ANNOUNCE(A4000_IDE, "A4000_IDE ");
-  AMIGAHW_ANNOUNCE(CD_ROM, "CD_ROM ");
-  AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "KEYBOARD ");
-  AMIGAHW_ANNOUNCE(AMI_MOUSE, "MOUSE ");
-  AMIGAHW_ANNOUNCE(AMI_SERIAL, "SERIAL ");
-  AMIGAHW_ANNOUNCE(AMI_PARALLEL, "PARALLEL ");
-  AMIGAHW_ANNOUNCE(A2000_CLK, "A2000_CLK ");
-  AMIGAHW_ANNOUNCE(A3000_CLK, "A3000_CLK ");
-  AMIGAHW_ANNOUNCE(CHIP_RAM, "CHIP_RAM ");
-  AMIGAHW_ANNOUNCE(PAULA, "PAULA ");
-  AMIGAHW_ANNOUNCE(DENISE, "DENISE ");
-  AMIGAHW_ANNOUNCE(DENISE_HR, "DENISE_HR ");
-  AMIGAHW_ANNOUNCE(LISA, "LISA ");
-  AMIGAHW_ANNOUNCE(AGNUS_PAL, "AGNUS_PAL ");
-  AMIGAHW_ANNOUNCE(AGNUS_NTSC, "AGNUS_NTSC ");
-  AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "AGNUS_HR_PAL ");
-  AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "AGNUS_HR_NTSC ");
-  AMIGAHW_ANNOUNCE(ALICE_PAL, "ALICE_PAL ");
-  AMIGAHW_ANNOUNCE(ALICE_NTSC, "ALICE_NTSC ");
-  AMIGAHW_ANNOUNCE(MAGIC_REKICK, "MAGIC_REKICK ");
-  AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA ");
-  if (AMIGAHW_PRESENT(ZORRO))
-    printk("ZORRO%s ", AMIGAHW_PRESENT(ZORRO3) ? "3" : "");
-  printk("\n");
+       memset(&amiga_hw_present, 0, sizeof(amiga_hw_present));
+
+       printk("Amiga hardware found: ");
+       if (amiga_model >= AMI_500 && amiga_model <= AMI_DRACO) {
+               printk("[%s] ", amiga_models[amiga_model-AMI_500]);
+               strcat(amiga_model_name, amiga_models[amiga_model-AMI_500]);
+       }
+
+       switch (amiga_model) {
+       case AMI_UNKNOWN:
+               goto Generic;
+
+       case AMI_600:
+       case AMI_1200:
+               AMIGAHW_SET(A1200_IDE);
+               AMIGAHW_SET(PCMCIA);
+       case AMI_500:
+       case AMI_500PLUS:
+       case AMI_1000:
+       case AMI_2000:
+       case AMI_2500:
+               AMIGAHW_SET(A2000_CLK); /* Is this correct for all models? */
+               goto Generic;
+
+       case AMI_3000:
+       case AMI_3000T:
+               AMIGAHW_SET(AMBER_FF);
+               AMIGAHW_SET(MAGIC_REKICK);
+               /* fall through */
+       case AMI_3000PLUS:
+               AMIGAHW_SET(A3000_SCSI);
+               AMIGAHW_SET(A3000_CLK);
+               AMIGAHW_SET(ZORRO3);
+               goto Generic;
+
+       case AMI_4000T:
+               AMIGAHW_SET(A4000_SCSI);
+               /* fall through */
+       case AMI_4000:
+               AMIGAHW_SET(A4000_IDE);
+               AMIGAHW_SET(A3000_CLK);
+               AMIGAHW_SET(ZORRO3);
+               goto Generic;
+
+       case AMI_CDTV:
+       case AMI_CD32:
+               AMIGAHW_SET(CD_ROM);
+               AMIGAHW_SET(A2000_CLK);             /* Is this correct? */
+               goto Generic;
+
+       Generic:
+               AMIGAHW_SET(AMI_VIDEO);
+               AMIGAHW_SET(AMI_BLITTER);
+               AMIGAHW_SET(AMI_AUDIO);
+               AMIGAHW_SET(AMI_FLOPPY);
+               AMIGAHW_SET(AMI_KEYBOARD);
+               AMIGAHW_SET(AMI_MOUSE);
+               AMIGAHW_SET(AMI_SERIAL);
+               AMIGAHW_SET(AMI_PARALLEL);
+               AMIGAHW_SET(CHIP_RAM);
+               AMIGAHW_SET(PAULA);
+
+               switch (amiga_chipset) {
+               case CS_OCS:
+               case CS_ECS:
+               case CS_AGA:
+                       switch (amiga_custom.deniseid & 0xf) {
+                       case 0x0c:
+                               AMIGAHW_SET(DENISE_HR);
+                               break;
+                       case 0x08:
+                               AMIGAHW_SET(LISA);
+                               break;
+                       }
+                       break;
+               default:
+                       AMIGAHW_SET(DENISE);
+                       break;
+               }
+               switch ((amiga_custom.vposr>>8) & 0x7f) {
+               case 0x00:
+                       AMIGAHW_SET(AGNUS_PAL);
+                       break;
+               case 0x10:
+                       AMIGAHW_SET(AGNUS_NTSC);
+                       break;
+               case 0x20:
+               case 0x21:
+                       AMIGAHW_SET(AGNUS_HR_PAL);
+                       break;
+               case 0x30:
+               case 0x31:
+                       AMIGAHW_SET(AGNUS_HR_NTSC);
+                       break;
+               case 0x22:
+               case 0x23:
+                       AMIGAHW_SET(ALICE_PAL);
+                       break;
+               case 0x32:
+               case 0x33:
+                       AMIGAHW_SET(ALICE_NTSC);
+                       break;
+               }
+               AMIGAHW_SET(ZORRO);
+               break;
+
+       case AMI_DRACO:
+               panic("No support for Draco yet");
+
+       default:
+               panic("Unknown Amiga Model");
+       }
+
+#define AMIGAHW_ANNOUNCE(name, str)            \
+       if (AMIGAHW_PRESENT(name))              \
+               printk(str)
+
+       AMIGAHW_ANNOUNCE(AMI_VIDEO, "VIDEO ");
+       AMIGAHW_ANNOUNCE(AMI_BLITTER, "BLITTER ");
+       AMIGAHW_ANNOUNCE(AMBER_FF, "AMBER_FF ");
+       AMIGAHW_ANNOUNCE(AMI_AUDIO, "AUDIO ");
+       AMIGAHW_ANNOUNCE(AMI_FLOPPY, "FLOPPY ");
+       AMIGAHW_ANNOUNCE(A3000_SCSI, "A3000_SCSI ");
+       AMIGAHW_ANNOUNCE(A4000_SCSI, "A4000_SCSI ");
+       AMIGAHW_ANNOUNCE(A1200_IDE, "A1200_IDE ");
+       AMIGAHW_ANNOUNCE(A4000_IDE, "A4000_IDE ");
+       AMIGAHW_ANNOUNCE(CD_ROM, "CD_ROM ");
+       AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "KEYBOARD ");
+       AMIGAHW_ANNOUNCE(AMI_MOUSE, "MOUSE ");
+       AMIGAHW_ANNOUNCE(AMI_SERIAL, "SERIAL ");
+       AMIGAHW_ANNOUNCE(AMI_PARALLEL, "PARALLEL ");
+       AMIGAHW_ANNOUNCE(A2000_CLK, "A2000_CLK ");
+       AMIGAHW_ANNOUNCE(A3000_CLK, "A3000_CLK ");
+       AMIGAHW_ANNOUNCE(CHIP_RAM, "CHIP_RAM ");
+       AMIGAHW_ANNOUNCE(PAULA, "PAULA ");
+       AMIGAHW_ANNOUNCE(DENISE, "DENISE ");
+       AMIGAHW_ANNOUNCE(DENISE_HR, "DENISE_HR ");
+       AMIGAHW_ANNOUNCE(LISA, "LISA ");
+       AMIGAHW_ANNOUNCE(AGNUS_PAL, "AGNUS_PAL ");
+       AMIGAHW_ANNOUNCE(AGNUS_NTSC, "AGNUS_NTSC ");
+       AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "AGNUS_HR_PAL ");
+       AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "AGNUS_HR_NTSC ");
+       AMIGAHW_ANNOUNCE(ALICE_PAL, "ALICE_PAL ");
+       AMIGAHW_ANNOUNCE(ALICE_NTSC, "ALICE_NTSC ");
+       AMIGAHW_ANNOUNCE(MAGIC_REKICK, "MAGIC_REKICK ");
+       AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA ");
+       if (AMIGAHW_PRESENT(ZORRO))
+               printk("ZORRO%s ", AMIGAHW_PRESENT(ZORRO3) ? "3" : "");
+       printk("\n");
 
 #undef AMIGAHW_ANNOUNCE
 }
@@ -370,119 +364,105 @@ static void __init amiga_identify(void)
 
 void __init config_amiga(void)
 {
-  int i;
-
-  amiga_debug_init();
-  amiga_identify();
-
-  /* Yuk, we don't have PCI memory */
-  iomem_resource.name = "Memory";
-  for (i = 0; i < 4; i++)
-    request_resource(&iomem_resource, &((struct resource *)&mb_resources)[i]);
-
-  mach_sched_init      = amiga_sched_init;
-  mach_init_IRQ        = amiga_init_IRQ;
-  mach_get_model       = amiga_get_model;
-  mach_get_hardware_list = amiga_get_hardware_list;
-  mach_gettimeoffset   = amiga_gettimeoffset;
-  if (AMIGAHW_PRESENT(A3000_CLK)){
-    mach_hwclk         = a3000_hwclk;
-    rtc_resource.name = "A3000 RTC";
-    request_resource(&iomem_resource, &rtc_resource);
-  }
-  else{ /* if (AMIGAHW_PRESENT(A2000_CLK)) */
-    mach_hwclk         = a2000_hwclk;
-    rtc_resource.name = "A2000 RTC";
-    request_resource(&iomem_resource, &rtc_resource);
-  }
-
-  mach_max_dma_address = 0xffffffff; /*
-                                     * default MAX_DMA=0xffffffff
-                                     * on all machines. If we don't
-                                     * do so, the SCSI code will not
-                                     * be able to allocate any mem
-                                     * for transfers, unless we are
-                                     * dealing with a Z2 mem only
-                                     * system.                  /Jes
-                                     */
-
-  mach_set_clock_mmss  = amiga_set_clock_mmss;
-  mach_get_ss          = amiga_get_ss;
-  mach_reset           = amiga_reset;
+       int i;
+
+       amiga_identify();
+
+       /* Yuk, we don't have PCI memory */
+       iomem_resource.name = "Memory";
+       for (i = 0; i < 4; i++)
+               request_resource(&iomem_resource, &((struct resource *)&mb_resources)[i]);
+
+       mach_sched_init      = amiga_sched_init;
+       mach_init_IRQ        = amiga_init_IRQ;
+       mach_get_model       = amiga_get_model;
+       mach_get_hardware_list = amiga_get_hardware_list;
+       mach_gettimeoffset   = amiga_gettimeoffset;
+       if (AMIGAHW_PRESENT(A3000_CLK)) {
+               mach_hwclk         = a3000_hwclk;
+               rtc_resource.name = "A3000 RTC";
+               request_resource(&iomem_resource, &rtc_resource);
+       } else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ {
+               mach_hwclk         = a2000_hwclk;
+               rtc_resource.name = "A2000 RTC";
+               request_resource(&iomem_resource, &rtc_resource);
+       }
+
+       /*
+        * default MAX_DMA=0xffffffff on all machines. If we don't do so, the SCSI
+        * code will not be able to allocate any mem for transfers, unless we are
+        * dealing with a Z2 mem only system.                  /Jes
+        */
+       mach_max_dma_address = 0xffffffff;
+
+       mach_set_clock_mmss  = amiga_set_clock_mmss;
+       mach_get_ss          = amiga_get_ss;
+       mach_reset           = amiga_reset;
 #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)
-  mach_beep            = amiga_mksound;
+       mach_beep            = amiga_mksound;
 #endif
 
 #ifdef CONFIG_HEARTBEAT
-  mach_heartbeat = amiga_heartbeat;
+       mach_heartbeat = amiga_heartbeat;
 #endif
 
-  /* Fill in the clock values (based on the 700 kHz E-Clock) */
-  amiga_masterclock = 40*amiga_eclock; /* 28 MHz */
-  amiga_colorclock = 5*amiga_eclock;   /* 3.5 MHz */
-
-  /* clear all DMA bits */
-  amiga_custom.dmacon = DMAF_ALL;
-  /* ensure that the DMA master bit is set */
-  amiga_custom.dmacon = DMAF_SETCLR | DMAF_MASTER;
-
-  /* don't use Z2 RAM as system memory on Z3 capable machines */
-  if (AMIGAHW_PRESENT(ZORRO3)) {
-    int i, j;
-    u32 disabled_z2mem = 0;
-    for (i = 0; i < m68k_num_memory; i++)
-      if (m68k_memory[i].addr < 16*1024*1024) {
-       if (i == 0) {
-         /* don't cut off the branch we're sitting on */
-         printk("Warning: kernel runs in Zorro II memory\n");
-         continue;
+       /* Fill in the clock values (based on the 700 kHz E-Clock) */
+       amiga_masterclock = 40*amiga_eclock;    /* 28 MHz */
+       amiga_colorclock = 5*amiga_eclock;      /* 3.5 MHz */
+
+       /* clear all DMA bits */
+       amiga_custom.dmacon = DMAF_ALL;
+       /* ensure that the DMA master bit is set */
+       amiga_custom.dmacon = DMAF_SETCLR | DMAF_MASTER;
+
+       /* don't use Z2 RAM as system memory on Z3 capable machines */
+       if (AMIGAHW_PRESENT(ZORRO3)) {
+               int i, j;
+               u32 disabled_z2mem = 0;
+
+               for (i = 0; i < m68k_num_memory; i++) {
+                       if (m68k_memory[i].addr < 16*1024*1024) {
+                               if (i == 0) {
+                                       /* don't cut off the branch we're sitting on */
+                                       printk("Warning: kernel runs in Zorro II memory\n");
+                                       continue;
+                               }
+                               disabled_z2mem += m68k_memory[i].size;
+                               m68k_num_memory--;
+                               for (j = i; j < m68k_num_memory; j++)
+                                       m68k_memory[j] = m68k_memory[j+1];
+                               i--;
+                       }
+               }
+               if (disabled_z2mem)
+               printk("%dK of Zorro II memory will not be used as system memory\n",
+               disabled_z2mem>>10);
        }
-       disabled_z2mem += m68k_memory[i].size;
-       m68k_num_memory--;
-       for (j = i; j < m68k_num_memory; j++)
-         m68k_memory[j] = m68k_memory[j+1];
-       i--;
-      }
-    if (disabled_z2mem)
-      printk("%dK of Zorro II memory will not be used as system memory\n",
-            disabled_z2mem>>10);
-  }
-
-  /* request all RAM */
-  for (i = 0; i < m68k_num_memory; i++) {
-    ram_resource[i].name =
-      (m68k_memory[i].addr >= 0x01000000) ? "32-bit Fast RAM" :
-      (m68k_memory[i].addr < 0x00c00000) ? "16-bit Fast RAM" :
-      "16-bit Slow RAM";
-    ram_resource[i].start = m68k_memory[i].addr;
-    ram_resource[i].end = m68k_memory[i].addr+m68k_memory[i].size-1;
-    request_resource(&iomem_resource, &ram_resource[i]);
-  }
-
-  /* initialize chipram allocator */
-  amiga_chip_init ();
-
-  /* debugging using chipram */
-  if (!strcmp( m68k_debug_device, "mem" )){
-         if (!AMIGAHW_PRESENT(CHIP_RAM))
-                 printk("Warning: no chipram present for debugging\n");
-         else {
-                 amiga_savekmsg_init();
-                 amiga_console_driver.write = amiga_mem_console_write;
-                 register_console(&amiga_console_driver);
-         }
-  }
-
-  /* our beloved beeper */
-  if (AMIGAHW_PRESENT(AMI_AUDIO))
-         amiga_init_sound();
-
-  /*
-   * if it is an A3000, set the magic bit that forces
-   * a hard rekick
-   */
-  if (AMIGAHW_PRESENT(MAGIC_REKICK))
-         *(unsigned char *)ZTWO_VADDR(0xde0002) |= 0x80;
+
+       /* request all RAM */
+       for (i = 0; i < m68k_num_memory; i++) {
+               ram_resource[i].name =
+                       (m68k_memory[i].addr >= 0x01000000) ? "32-bit Fast RAM" :
+                       (m68k_memory[i].addr < 0x00c00000) ? "16-bit Fast RAM" :
+                       "16-bit Slow RAM";
+               ram_resource[i].start = m68k_memory[i].addr;
+               ram_resource[i].end = m68k_memory[i].addr+m68k_memory[i].size-1;
+               request_resource(&iomem_resource, &ram_resource[i]);
+       }
+
+       /* initialize chipram allocator */
+       amiga_chip_init();
+
+       /* our beloved beeper */
+       if (AMIGAHW_PRESENT(AMI_AUDIO))
+               amiga_init_sound();
+
+       /*
+        * if it is an A3000, set the magic bit that forces
+        * a hard rekick
+        */
+       if (AMIGAHW_PRESENT(MAGIC_REKICK))
+               *(unsigned char *)ZTWO_VADDR(0xde0002) |= 0x80;
 }
 
 static unsigned short jiffy_ticks;
@@ -490,12 +470,12 @@ static unsigned short jiffy_ticks;
 static void __init amiga_sched_init(irq_handler_t timer_routine)
 {
        static struct resource sched_res = {
-           .name = "timer", .start = 0x00bfd400, .end = 0x00bfd5ff,
+               .name = "timer", .start = 0x00bfd400, .end = 0x00bfd5ff,
        };
        jiffy_ticks = (amiga_eclock+HZ/2)/HZ;
 
        if (request_resource(&mb_resources._ciab, &sched_res))
-           printk("Cannot allocate ciab.ta{lo,hi}\n");
+               printk("Cannot allocate ciab.ta{lo,hi}\n");
        ciab.cra &= 0xC0;   /* turn off timer A, continuous mode, from Eclk */
        ciab.talo = jiffy_ticks % 256;
        ciab.tahi = jiffy_ticks / 256;
@@ -513,7 +493,7 @@ static void __init amiga_sched_init(irq_handler_t timer_routine)
 #define TICK_SIZE 10000
 
 /* This is always executed with interrupts disabled.  */
-static unsigned long amiga_gettimeoffset (void)
+static unsigned long amiga_gettimeoffset(void)
 {
        unsigned short hi, lo, hi2;
        unsigned long ticks, offset = 0;
@@ -585,15 +565,15 @@ static int a2000_hwclk(int op, struct rtc_time *t)
 
        tod_2000.cntrl1 = TOD2000_CNTRL1_HOLD;
 
-       while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--)
-       {
-               tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD;
-               udelay(70);
-               tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD;
+       while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) {
+               tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD;
+               udelay(70);
+               tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD;
        }
 
        if (!cnt)
-               printk(KERN_INFO "hwclk: timed out waiting for RTC (0x%x)\n", tod_2000.cntrl1);
+               printk(KERN_INFO "hwclk: timed out waiting for RTC (0x%x)\n",
+                       tod_2000.cntrl1);
 
        if (!op) { /* read */
                t->tm_sec  = tod_2000.second1     * 10 + tod_2000.second2;
@@ -606,7 +586,7 @@ static int a2000_hwclk(int op, struct rtc_time *t)
                if (t->tm_year <= 69)
                        t->tm_year += 100;
 
-               if (!(tod_2000.cntrl3 & TOD2000_CNTRL3_24HMODE)){
+               if (!(tod_2000.cntrl3 & TOD2000_CNTRL3_24HMODE)) {
                        if (!(tod_2000.hour1 & TOD2000_HOUR1_PM) && t->tm_hour == 12)
                                t->tm_hour = 0;
                        else if ((tod_2000.hour1 & TOD2000_HOUR1_PM) && t->tm_hour != 12)
@@ -642,7 +622,7 @@ static int a2000_hwclk(int op, struct rtc_time *t)
        return 0;
 }
 
-static int amiga_set_clock_mmss (unsigned long nowtime)
+static int amiga_set_clock_mmss(unsigned long nowtime)
 {
        short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
 
@@ -660,8 +640,7 @@ static int amiga_set_clock_mmss (unsigned long nowtime)
 
                tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD;
 
-               while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--)
-               {
+               while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) {
                        tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD;
                        udelay(70);
                        tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD;
@@ -681,7 +660,7 @@ static int amiga_set_clock_mmss (unsigned long nowtime)
        return 0;
 }
 
-static unsigned int amiga_get_ss( void )
+static unsigned int amiga_get_ss(void)
 {
        unsigned int s;
 
@@ -695,71 +674,72 @@ static unsigned int amiga_get_ss( void )
        return s;
 }
 
-static NORET_TYPE void amiga_reset( void )
+static NORET_TYPE void amiga_reset(void)
     ATTRIB_NORET;
 
-static void amiga_reset (void)
+static void amiga_reset(void)
 {
-  unsigned long jmp_addr040 = virt_to_phys(&&jmp_addr_label040);
-  unsigned long jmp_addr = virt_to_phys(&&jmp_addr_label);
-
-  local_irq_disable();
-  if (CPU_IS_040_OR_060)
-    /* Setup transparent translation registers for mapping
-     * of 16 MB kernel segment before disabling translation
-     */
-    __asm__ __volatile__
-      ("movel    %0,%/d0\n\t"
-       "andl     #0xff000000,%/d0\n\t"
-       "orw      #0xe020,%/d0\n\t"   /* map 16 MB, enable, cacheable */
-       ".chip    68040\n\t"
-       "movec    %%d0,%%itt0\n\t"
-       "movec    %%d0,%%dtt0\n\t"
-       ".chip    68k\n\t"
-       "jmp      %0@\n\t"
-       : /* no outputs */
-       : "a" (jmp_addr040));
-  else
-    /* for 680[23]0, just disable translation and jump to the physical
-     * address of the label
-     */
-    __asm__ __volatile__
-      ("pmove  %/tc,%@\n\t"
-       "bclr   #7,%@\n\t"
-       "pmove  %@,%/tc\n\t"
-       "jmp    %0@\n\t"
-       : /* no outputs */
-       : "a" (jmp_addr));
- jmp_addr_label040:
-  /* disable translation on '040 now */
-  __asm__ __volatile__
-    ("moveq #0,%/d0\n\t"
-     ".chip 68040\n\t"
-     "movec %%d0,%%tc\n\t"     /* disable MMU */
-     ".chip 68k\n\t"
-     : /* no outputs */
-     : /* no inputs */
-     : "d0");
-
- jmp_addr_label:
-  /* pickup reset address from AmigaOS ROM, reset devices and jump
-   * to reset address
-   */
-  __asm__ __volatile__
-    ("movew #0x2700,%/sr\n\t"
-     "leal  0x01000000,%/a0\n\t"
-     "subl  %/a0@(-0x14),%/a0\n\t"
-     "movel %/a0@(4),%/a0\n\t"
-     "subql #2,%/a0\n\t"
-     "bra   1f\n\t"
-     /* align on a longword boundary */
-     __ALIGN_STR "\n"
-     "1:\n\t"
-     "reset\n\t"
-     "jmp   %/a0@" : /* Just that gcc scans it for % escapes */ );
-
-  for (;;);
-
+       unsigned long jmp_addr040 = virt_to_phys(&&jmp_addr_label040);
+       unsigned long jmp_addr = virt_to_phys(&&jmp_addr_label);
+
+       local_irq_disable();
+       if (CPU_IS_040_OR_060)
+               /* Setup transparent translation registers for mapping
+                * of 16 MB kernel segment before disabling translation
+                */
+               asm volatile ("\n"
+                       "       move.l  %0,%%d0\n"
+                       "       and.l   #0xff000000,%%d0\n"
+                       "       or.w    #0xe020,%%d0\n"   /* map 16 MB, enable, cacheable */
+                       "       .chip   68040\n"
+                       "       movec   %%d0,%%itt0\n"
+                       "       movec   %%d0,%%dtt0\n"
+                       "       .chip   68k\n"
+                       "       jmp     %0@\n"
+                       : /* no outputs */
+                       : "a" (jmp_addr040)
+                       : "d0");
+       else
+               /* for 680[23]0, just disable translation and jump to the physical
+                * address of the label
+                */
+               asm volatile ("\n"
+                       "       pmove   %%tc,%@\n"
+                       "       bclr    #7,%@\n"
+                       "       pmove   %@,%%tc\n"
+                       "       jmp     %0@\n"
+                       : /* no outputs */
+                       : "a" (jmp_addr));
+jmp_addr_label040:
+       /* disable translation on '040 now */
+       asm volatile ("\n"
+               "       moveq   #0,%%d0\n"
+               "       .chip   68040\n"
+               "       movec   %%d0,%%tc\n"    /* disable MMU */
+               "       .chip   68k\n"
+               : /* no outputs */
+               : /* no inputs */
+               : "d0");
+
+       jmp_addr_label:
+       /* pickup reset address from AmigaOS ROM, reset devices and jump
+        * to reset address
+        */
+       asm volatile ("\n"
+               "       move.w  #0x2700,%sr\n"
+               "       lea     0x01000000,%a0\n"
+               "       sub.l   %a0@(-0x14),%a0\n"
+               "       move.l  %a0@(4),%a0\n"
+               "       subq.l  #2,%a0\n"
+               "       jra     1f\n"
+               /* align on a longword boundary */
+               "       " __ALIGN_STR "\n"
+               "1:\n"
+               "       reset\n"
+               "       jmp   %a0@");
+
+       for (;;)
+               ;
 }
 
 
@@ -773,11 +753,11 @@ static void amiga_reset (void)
 #define SAVEKMSG_MAGIC2                0x4B4D5347      /* 'KMSG' */
 
 struct savekmsg {
-    unsigned long magic1;              /* SAVEKMSG_MAGIC1 */
-    unsigned long magic2;              /* SAVEKMSG_MAGIC2 */
-    unsigned long magicptr;            /* address of magic1 */
-    unsigned long size;
-    char data[0];
+       unsigned long magic1;           /* SAVEKMSG_MAGIC1 */
+       unsigned long magic2;           /* SAVEKMSG_MAGIC2 */
+       unsigned long magicptr;         /* address of magic1 */
+       unsigned long size;
+       char data[0];
 };
 
 static struct savekmsg *savekmsg;
@@ -785,113 +765,132 @@ static struct savekmsg *savekmsg;
 static void amiga_mem_console_write(struct console *co, const char *s,
                                    unsigned int count)
 {
-    if (savekmsg->size+count <= SAVEKMSG_MAXMEM-sizeof(struct savekmsg)) {
-        memcpy(savekmsg->data+savekmsg->size, s, count);
-        savekmsg->size += count;
-    }
+       if (savekmsg->size + count <= SAVEKMSG_MAXMEM-sizeof(struct savekmsg)) {
+               memcpy(savekmsg->data + savekmsg->size, s, count);
+               savekmsg->size += count;
+       }
 }
 
-static void amiga_savekmsg_init(void)
+static int __init amiga_savekmsg_setup(char *arg)
 {
-    static struct resource debug_res = { .name = "Debug" };
+       static struct resource debug_res = { .name = "Debug" };
+
+       if (!MACH_IS_AMIGA || strcmp(arg, "mem"))
+               goto done;
+
+       if (!AMIGAHW_PRESENT(CHIP_RAM)) {
+               printk("Warning: no chipram present for debugging\n");
+               goto done;
+       }
 
-    savekmsg = amiga_chip_alloc_res(SAVEKMSG_MAXMEM, &debug_res);
-    savekmsg->magic1 = SAVEKMSG_MAGIC1;
-    savekmsg->magic2 = SAVEKMSG_MAGIC2;
-    savekmsg->magicptr = ZTWO_PADDR(savekmsg);
-    savekmsg->size = 0;
+       savekmsg = amiga_chip_alloc_res(SAVEKMSG_MAXMEM, &debug_res);
+       savekmsg->magic1 = SAVEKMSG_MAGIC1;
+       savekmsg->magic2 = SAVEKMSG_MAGIC2;
+       savekmsg->magicptr = ZTWO_PADDR(savekmsg);
+       savekmsg->size = 0;
+
+       amiga_console_driver.write = amiga_mem_console_write;
+       register_console(&amiga_console_driver);
+
+done:
+       return 0;
 }
 
+early_param("debug", amiga_savekmsg_setup);
+
 static void amiga_serial_putc(char c)
 {
-    amiga_custom.serdat = (unsigned char)c | 0x100;
-    while (!(amiga_custom.serdatr & 0x2000))
-       ;
+       amiga_custom.serdat = (unsigned char)c | 0x100;
+       while (!(amiga_custom.serdatr & 0x2000))
+               ;
 }
 
 void amiga_serial_console_write(struct console *co, const char *s,
-                                      unsigned int count)
+                               unsigned int count)
 {
-    while (count--) {
-       if (*s == '\n')
-           amiga_serial_putc('\r');
-       amiga_serial_putc(*s++);
-    }
+       while (count--) {
+               if (*s == '\n')
+                       amiga_serial_putc('\r');
+               amiga_serial_putc(*s++);
+       }
 }
 
 #ifdef CONFIG_SERIAL_CONSOLE
 void amiga_serial_puts(const char *s)
 {
-    amiga_serial_console_write(NULL, s, strlen(s));
+       amiga_serial_console_write(NULL, s, strlen(s));
 }
 
 int amiga_serial_console_wait_key(struct console *co)
 {
-    int ch;
-
-    while (!(amiga_custom.intreqr & IF_RBF))
-       barrier();
-    ch = amiga_custom.serdatr & 0xff;
-    /* clear the interrupt, so that another character can be read */
-    amiga_custom.intreq = IF_RBF;
-    return ch;
+       int ch;
+
+       while (!(amiga_custom.intreqr & IF_RBF))
+               barrier();
+       ch = amiga_custom.serdatr & 0xff;
+       /* clear the interrupt, so that another character can be read */
+       amiga_custom.intreq = IF_RBF;
+       return ch;
 }
 
 void amiga_serial_gets(struct console *co, char *s, int len)
 {
-    int ch, cnt = 0;
-
-    while (1) {
-       ch = amiga_serial_console_wait_key(co);
-
-       /* Check for backspace. */
-       if (ch == 8 || ch == 127) {
-           if (cnt == 0) {
-               amiga_serial_putc('\007');
-               continue;
-           }
-           cnt--;
-           amiga_serial_puts("\010 \010");
-           continue;
-       }
+       int ch, cnt = 0;
+
+       while (1) {
+               ch = amiga_serial_console_wait_key(co);
+
+               /* Check for backspace. */
+               if (ch == 8 || ch == 127) {
+                       if (cnt == 0) {
+                               amiga_serial_putc('\007');
+                               continue;
+                       }
+                       cnt--;
+                       amiga_serial_puts("\010 \010");
+                       continue;
+               }
 
-       /* Check for enter. */
-       if (ch == 10 || ch == 13)
-           break;
+               /* Check for enter. */
+               if (ch == 10 || ch == 13)
+                       break;
 
-       /* See if line is too long. */
-       if (cnt >= len + 1) {
-           amiga_serial_putc(7);
-           cnt--;
-           continue;
-       }
+               /* See if line is too long. */
+               if (cnt >= len + 1) {
+                       amiga_serial_putc(7);
+                       cnt--;
+                       continue;
+               }
 
-       /* Store and echo character. */
-       s[cnt++] = ch;
-       amiga_serial_putc(ch);
-    }
-    /* Print enter. */
-    amiga_serial_puts("\r\n");
-    s[cnt] = 0;
+               /* Store and echo character. */
+               s[cnt++] = ch;
+               amiga_serial_putc(ch);
+       }
+       /* Print enter. */
+       amiga_serial_puts("\r\n");
+       s[cnt] = 0;
 }
 #endif
 
-static void __init amiga_debug_init(void)
+static int __init amiga_debug_setup(char *arg)
 {
-       if (!strcmp( m68k_debug_device, "ser" )) {
+       if (MACH_IS_AMIGA && !strcmp(arg, "ser")) {
                /* no initialization required (?) */
                amiga_console_driver.write = amiga_serial_console_write;
                register_console(&amiga_console_driver);
        }
+       return 0;
 }
 
+early_param("debug", amiga_debug_setup);
+
 #ifdef CONFIG_HEARTBEAT
 static void amiga_heartbeat(int on)
 {
-    if (on)
-       ciaa.pra &= ~2;
-    else
-       ciaa.pra |= 2;
+       if (on)
+               ciaa.pra &= ~2;
+       else
+               ciaa.pra |= 2;
 }
 #endif
 
@@ -901,81 +900,81 @@ static void amiga_heartbeat(int on)
 
 static void amiga_get_model(char *model)
 {
-    strcpy(model, amiga_model_name);
+       strcpy(model, amiga_model_name);
 }
 
 
 static int amiga_get_hardware_list(char *buffer)
 {
-    int len = 0;
-
-    if (AMIGAHW_PRESENT(CHIP_RAM))
-       len += sprintf(buffer+len, "Chip RAM:\t%ldK\n", amiga_chip_size>>10);
-    len += sprintf(buffer+len, "PS Freq:\t%dHz\nEClock Freq:\t%ldHz\n",
-                  amiga_psfreq, amiga_eclock);
-    if (AMIGAHW_PRESENT(AMI_VIDEO)) {
-       char *type;
-       switch(amiga_chipset) {
-           case CS_OCS:
-               type = "OCS";
-               break;
-           case CS_ECS:
-               type = "ECS";
-               break;
-           case CS_AGA:
-               type = "AGA";
-               break;
-           default:
-               type = "Old or Unknown";
-               break;
+       int len = 0;
+
+       if (AMIGAHW_PRESENT(CHIP_RAM))
+               len += sprintf(buffer+len, "Chip RAM:\t%ldK\n", amiga_chip_size>>10);
+       len += sprintf(buffer+len, "PS Freq:\t%dHz\nEClock Freq:\t%ldHz\n",
+                       amiga_psfreq, amiga_eclock);
+       if (AMIGAHW_PRESENT(AMI_VIDEO)) {
+               char *type;
+               switch (amiga_chipset) {
+               case CS_OCS:
+                       type = "OCS";
+                       break;
+               case CS_ECS:
+                       type = "ECS";
+                       break;
+               case CS_AGA:
+                       type = "AGA";
+                       break;
+               default:
+                       type = "Old or Unknown";
+                       break;
+               }
+               len += sprintf(buffer+len, "Graphics:\t%s\n", type);
        }
-       len += sprintf(buffer+len, "Graphics:\t%s\n", type);
-    }
 
 #define AMIGAHW_ANNOUNCE(name, str)                    \
-    if (AMIGAHW_PRESENT(name))                         \
-       len += sprintf (buffer+len, "\t%s\n", str)
-
-    len += sprintf (buffer + len, "Detected hardware:\n");
-
-    AMIGAHW_ANNOUNCE(AMI_VIDEO, "Amiga Video");
-    AMIGAHW_ANNOUNCE(AMI_BLITTER, "Blitter");
-    AMIGAHW_ANNOUNCE(AMBER_FF, "Amber Flicker Fixer");
-    AMIGAHW_ANNOUNCE(AMI_AUDIO, "Amiga Audio");
-    AMIGAHW_ANNOUNCE(AMI_FLOPPY, "Floppy Controller");
-    AMIGAHW_ANNOUNCE(A3000_SCSI, "SCSI Controller WD33C93 (A3000 style)");
-    AMIGAHW_ANNOUNCE(A4000_SCSI, "SCSI Controller NCR53C710 (A4000T style)");
-    AMIGAHW_ANNOUNCE(A1200_IDE, "IDE Interface (A1200 style)");
-    AMIGAHW_ANNOUNCE(A4000_IDE, "IDE Interface (A4000 style)");
-    AMIGAHW_ANNOUNCE(CD_ROM, "Internal CD ROM drive");
-    AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "Keyboard");
-    AMIGAHW_ANNOUNCE(AMI_MOUSE, "Mouse Port");
-    AMIGAHW_ANNOUNCE(AMI_SERIAL, "Serial Port");
-    AMIGAHW_ANNOUNCE(AMI_PARALLEL, "Parallel Port");
-    AMIGAHW_ANNOUNCE(A2000_CLK, "Hardware Clock (A2000 style)");
-    AMIGAHW_ANNOUNCE(A3000_CLK, "Hardware Clock (A3000 style)");
-    AMIGAHW_ANNOUNCE(CHIP_RAM, "Chip RAM");
-    AMIGAHW_ANNOUNCE(PAULA, "Paula 8364");
-    AMIGAHW_ANNOUNCE(DENISE, "Denise 8362");
-    AMIGAHW_ANNOUNCE(DENISE_HR, "Denise 8373");
-    AMIGAHW_ANNOUNCE(LISA, "Lisa 8375");
-    AMIGAHW_ANNOUNCE(AGNUS_PAL, "Normal/Fat PAL Agnus 8367/8371");
-    AMIGAHW_ANNOUNCE(AGNUS_NTSC, "Normal/Fat NTSC Agnus 8361/8370");
-    AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "Fat Hires PAL Agnus 8372");
-    AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "Fat Hires NTSC Agnus 8372");
-    AMIGAHW_ANNOUNCE(ALICE_PAL, "PAL Alice 8374");
-    AMIGAHW_ANNOUNCE(ALICE_NTSC, "NTSC Alice 8374");
-    AMIGAHW_ANNOUNCE(MAGIC_REKICK, "Magic Hard Rekick");
-    AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA Slot");
+       if (AMIGAHW_PRESENT(name))                      \
+               len += sprintf (buffer+len, "\t%s\n", str)
+
+       len += sprintf (buffer + len, "Detected hardware:\n");
+
+       AMIGAHW_ANNOUNCE(AMI_VIDEO, "Amiga Video");
+       AMIGAHW_ANNOUNCE(AMI_BLITTER, "Blitter");
+       AMIGAHW_ANNOUNCE(AMBER_FF, "Amber Flicker Fixer");
+       AMIGAHW_ANNOUNCE(AMI_AUDIO, "Amiga Audio");
+       AMIGAHW_ANNOUNCE(AMI_FLOPPY, "Floppy Controller");
+       AMIGAHW_ANNOUNCE(A3000_SCSI, "SCSI Controller WD33C93 (A3000 style)");
+       AMIGAHW_ANNOUNCE(A4000_SCSI, "SCSI Controller NCR53C710 (A4000T style)");
+       AMIGAHW_ANNOUNCE(A1200_IDE, "IDE Interface (A1200 style)");
+       AMIGAHW_ANNOUNCE(A4000_IDE, "IDE Interface (A4000 style)");
+       AMIGAHW_ANNOUNCE(CD_ROM, "Internal CD ROM drive");
+       AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "Keyboard");
+       AMIGAHW_ANNOUNCE(AMI_MOUSE, "Mouse Port");
+       AMIGAHW_ANNOUNCE(AMI_SERIAL, "Serial Port");
+       AMIGAHW_ANNOUNCE(AMI_PARALLEL, "Parallel Port");
+       AMIGAHW_ANNOUNCE(A2000_CLK, "Hardware Clock (A2000 style)");
+       AMIGAHW_ANNOUNCE(A3000_CLK, "Hardware Clock (A3000 style)");
+       AMIGAHW_ANNOUNCE(CHIP_RAM, "Chip RAM");
+       AMIGAHW_ANNOUNCE(PAULA, "Paula 8364");
+       AMIGAHW_ANNOUNCE(DENISE, "Denise 8362");
+       AMIGAHW_ANNOUNCE(DENISE_HR, "Denise 8373");
+       AMIGAHW_ANNOUNCE(LISA, "Lisa 8375");
+       AMIGAHW_ANNOUNCE(AGNUS_PAL, "Normal/Fat PAL Agnus 8367/8371");
+       AMIGAHW_ANNOUNCE(AGNUS_NTSC, "Normal/Fat NTSC Agnus 8361/8370");
+       AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "Fat Hires PAL Agnus 8372");
+       AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "Fat Hires NTSC Agnus 8372");
+       AMIGAHW_ANNOUNCE(ALICE_PAL, "PAL Alice 8374");
+       AMIGAHW_ANNOUNCE(ALICE_NTSC, "NTSC Alice 8374");
+       AMIGAHW_ANNOUNCE(MAGIC_REKICK, "Magic Hard Rekick");
+       AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA Slot");
 #ifdef CONFIG_ZORRO
-    if (AMIGAHW_PRESENT(ZORRO))
-       len += sprintf(buffer+len, "\tZorro II%s AutoConfig: %d Expansion "
-                                  "Device%s\n",
-                      AMIGAHW_PRESENT(ZORRO3) ? "I" : "",
-                      zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s");
+       if (AMIGAHW_PRESENT(ZORRO))
+               len += sprintf(buffer+len, "\tZorro II%s AutoConfig: %d Expansion "
+                               "Device%s\n",
+                               AMIGAHW_PRESENT(ZORRO3) ? "I" : "",
+                               zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s");
 #endif /* CONFIG_ZORRO */
 
 #undef AMIGAHW_ANNOUNCE
 
-    return(len);
+       return len;
 }
index 8cb6236b39db4751d1a62209941d3119d02baac6..2cb86191f0aab653f2449b7df16af28346d96d54 100644 (file)
@@ -8,3 +8,4 @@ obj-y           := config.o time.o debug.o ataints.o stdma.o \
 ifeq ($(CONFIG_PCI),y)
 obj-$(CONFIG_HADES)    += hades-pci.o
 endif
+obj-$(CONFIG_ATARI_KBD_CORE)   += atakeyb.o
diff --git a/arch/m68k/atari/atakeyb.c b/arch/m68k/atari/atakeyb.c
new file mode 100644 (file)
index 0000000..1c29603
--- /dev/null
@@ -0,0 +1,730 @@
+/*
+ * linux/atari/atakeyb.c
+ *
+ * Atari Keyboard driver for 680x0 Linux
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ * Atari support by Robert de Vries
+ * enhanced by Bjoern Brauel and Roman Hodek
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/keyboard.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/kd.h>
+#include <linux/random.h>
+#include <linux/init.h>
+#include <linux/kbd_kern.h>
+
+#include <asm/atariints.h>
+#include <asm/atarihw.h>
+#include <asm/atarikb.h>
+#include <asm/atari_joystick.h>
+#include <asm/irq.h>
+
+static void atakeyb_rep(unsigned long ignore);
+extern unsigned int keymap_count;
+
+/* Hook for MIDI serial driver */
+void (*atari_MIDI_interrupt_hook) (void);
+/* Hook for mouse driver */
+void (*atari_mouse_interrupt_hook) (char *);
+/* Hook for keyboard inputdev  driver */
+void (*atari_input_keyboard_interrupt_hook) (unsigned char, char);
+/* Hook for mouse inputdev  driver */
+void (*atari_input_mouse_interrupt_hook) (char *);
+
+/* variables for IKBD self test: */
+
+/* state: 0: off; >0: in progress; >1: 0xf1 received */
+static volatile int ikbd_self_test;
+/* timestamp when last received a char */
+static volatile unsigned long self_test_last_rcv;
+/* bitmap of keys reported as broken */
+static unsigned long broken_keys[128/(sizeof(unsigned long)*8)] = { 0, };
+
+#define BREAK_MASK     (0x80)
+
+/*
+ * ++roman: The following changes were applied manually:
+ *
+ *  - The Alt (= Meta) key works in combination with Shift and
+ *    Control, e.g. Alt+Shift+a sends Meta-A (0xc1), Alt+Control+A sends
+ *    Meta-Ctrl-A (0x81) ...
+ *
+ *  - The parentheses on the keypad send '(' and ')' with all
+ *    modifiers (as would do e.g. keypad '+'), but they cannot be used as
+ *    application keys (i.e. sending Esc O c).
+ *
+ *  - HELP and UNDO are mapped to be F21 and F24, resp, that send the
+ *    codes "\E[M" and "\E[P". (This is better than the old mapping to
+ *    F11 and F12, because these codes are on Shift+F1/2 anyway.) This
+ *    way, applications that allow their own keyboard mappings
+ *    (e.g. tcsh, X Windows) can be configured to use them in the way
+ *    the label suggests (providing help or undoing).
+ *
+ *  - Console switching is done with Alt+Fx (consoles 1..10) and
+ *    Shift+Alt+Fx (consoles 11..20).
+ *
+ *  - The misc. special function implemented in the kernel are mapped
+ *    to the following key combinations:
+ *
+ *      ClrHome          -> Home/Find
+ *      Shift + ClrHome  -> End/Select
+ *      Shift + Up       -> Page Up
+ *      Shift + Down     -> Page Down
+ *      Alt + Help       -> show system status
+ *      Shift + Help     -> show memory info
+ *      Ctrl + Help      -> show registers
+ *      Ctrl + Alt + Del -> Reboot
+ *      Alt + Undo       -> switch to last console
+ *      Shift + Undo     -> send interrupt
+ *      Alt + Insert     -> stop/start output (same as ^S/^Q)
+ *      Alt + Up         -> Scroll back console (if implemented)
+ *      Alt + Down       -> Scroll forward console (if implemented)
+ *      Alt + CapsLock   -> NumLock
+ *
+ * ++Andreas:
+ *
+ *  - Help mapped to K_HELP
+ *  - Undo mapped to K_UNDO (= K_F246)
+ *  - Keypad Left/Right Parenthesis mapped to new K_PPAREN[LR]
+ */
+
+static u_short ataplain_map[NR_KEYS] __initdata = {
+       0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036,
+       0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf008, 0xf009,
+       0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
+       0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73,
+       0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b,
+       0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76,
+       0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf200,
+       0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
+       0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf200, 0xf200, 0xf114,
+       0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
+       0xf600, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf200, 0xf200,
+       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+       0xf200, 0xf1ff, 0xf11b, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf307,
+       0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
+       0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
+};
+
+typedef enum kb_state_t {
+       KEYBOARD, AMOUSE, RMOUSE, JOYSTICK, CLOCK, RESYNC
+} KB_STATE_T;
+
+#define        IS_SYNC_CODE(sc)        ((sc) >= 0x04 && (sc) <= 0xfb)
+
+typedef struct keyboard_state {
+       unsigned char buf[6];
+       int len;
+       KB_STATE_T state;
+} KEYBOARD_STATE;
+
+KEYBOARD_STATE kb_state;
+
+#define        DEFAULT_KEYB_REP_DELAY  (HZ/4)
+#define        DEFAULT_KEYB_REP_RATE   (HZ/25)
+
+/* These could be settable by some ioctl() in future... */
+static unsigned int key_repeat_delay = DEFAULT_KEYB_REP_DELAY;
+static unsigned int key_repeat_rate = DEFAULT_KEYB_REP_RATE;
+
+static unsigned char rep_scancode;
+static struct timer_list atakeyb_rep_timer = {
+       .function = atakeyb_rep,
+};
+
+static void atakeyb_rep(unsigned long ignore)
+{
+       /* Disable keyboard for the time we call handle_scancode(), else a race
+        * in the keyboard tty queue may happen */
+       atari_disable_irq(IRQ_MFP_ACIA);
+       del_timer(&atakeyb_rep_timer);
+
+       /* A keyboard int may have come in before we disabled the irq, so
+        * double-check whether rep_scancode is still != 0 */
+       if (rep_scancode) {
+               init_timer(&atakeyb_rep_timer);
+               atakeyb_rep_timer.expires = jiffies + key_repeat_rate;
+               add_timer(&atakeyb_rep_timer);
+
+               //handle_scancode(rep_scancode, 1);
+               if (atari_input_keyboard_interrupt_hook)
+                       atari_input_keyboard_interrupt_hook(rep_scancode, 1);
+       }
+
+       atari_enable_irq(IRQ_MFP_ACIA);
+}
+
+
+/* ++roman: If a keyboard overrun happened, we can't tell in general how much
+ * bytes have been lost and in which state of the packet structure we are now.
+ * This usually causes keyboards bytes to be interpreted as mouse movements
+ * and vice versa, which is very annoying. It seems better to throw away some
+ * bytes (that are usually mouse bytes) than to misinterpret them. Therefor I
+ * introduced the RESYNC state for IKBD data. In this state, the bytes up to
+ * one that really looks like a key event (0x04..0xf2) or the start of a mouse
+ * packet (0xf8..0xfb) are thrown away, but at most 2 bytes. This at least
+ * speeds up the resynchronization of the event structure, even if maybe a
+ * mouse movement is lost. However, nothing is perfect. For bytes 0x01..0x03,
+ * it's really hard to decide whether they're mouse or keyboard bytes. Since
+ * overruns usually occur when moving the Atari mouse rapidly, they're seen as
+ * mouse bytes here. If this is wrong, only a make code of the keyboard gets
+ * lost, which isn't too bad. Loosing a break code would be disastrous,
+ * because then the keyboard repeat strikes...
+ */
+
+static irqreturn_t atari_keyboard_interrupt(int irq, void *dummy)
+{
+       u_char acia_stat;
+       int scancode;
+       int break_flag;
+
+repeat:
+       if (acia.mid_ctrl & ACIA_IRQ)
+               if (atari_MIDI_interrupt_hook)
+                       atari_MIDI_interrupt_hook();
+       acia_stat = acia.key_ctrl;
+       /* check out if the interrupt came from this ACIA */
+       if (!((acia_stat | acia.mid_ctrl) & ACIA_IRQ))
+               return IRQ_HANDLED;
+
+       if (acia_stat & ACIA_OVRN) {
+               /* a very fast typist or a slow system, give a warning */
+               /* ...happens often if interrupts were disabled for too long */
+               printk(KERN_DEBUG "Keyboard overrun\n");
+               scancode = acia.key_data;
+               /* Turn off autorepeating in case a break code has been lost */
+               del_timer(&atakeyb_rep_timer);
+               rep_scancode = 0;
+               if (ikbd_self_test)
+                       /* During self test, don't do resyncing, just process the code */
+                       goto interpret_scancode;
+               else if (IS_SYNC_CODE(scancode)) {
+                       /* This code seem already to be the start of a new packet or a
+                        * single scancode */
+                       kb_state.state = KEYBOARD;
+                       goto interpret_scancode;
+               } else {
+                       /* Go to RESYNC state and skip this byte */
+                       kb_state.state = RESYNC;
+                       kb_state.len = 1;       /* skip max. 1 another byte */
+                       goto repeat;
+               }
+       }
+
+       if (acia_stat & ACIA_RDRF) {
+               /* received a character */
+               scancode = acia.key_data;       /* get it or reset the ACIA, I'll get it! */
+               tasklet_schedule(&keyboard_tasklet);
+       interpret_scancode:
+               switch (kb_state.state) {
+               case KEYBOARD:
+                       switch (scancode) {
+                       case 0xF7:
+                               kb_state.state = AMOUSE;
+                               kb_state.len = 0;
+                               break;
+
+                       case 0xF8:
+                       case 0xF9:
+                       case 0xFA:
+                       case 0xFB:
+                               kb_state.state = RMOUSE;
+                               kb_state.len = 1;
+                               kb_state.buf[0] = scancode;
+                               break;
+
+                       case 0xFC:
+                               kb_state.state = CLOCK;
+                               kb_state.len = 0;
+                               break;
+
+                       case 0xFE:
+                       case 0xFF:
+                               kb_state.state = JOYSTICK;
+                               kb_state.len = 1;
+                               kb_state.buf[0] = scancode;
+                               break;
+
+                       case 0xF1:
+                               /* during self-test, note that 0xf1 received */
+                               if (ikbd_self_test) {
+                                       ++ikbd_self_test;
+                                       self_test_last_rcv = jiffies;
+                                       break;
+                               }
+                               /* FALL THROUGH */
+
+                       default:
+                               break_flag = scancode & BREAK_MASK;
+                               scancode &= ~BREAK_MASK;
+                               if (ikbd_self_test) {
+                                       /* Scancodes sent during the self-test stand for broken
+                                        * keys (keys being down). The code *should* be a break
+                                        * code, but nevertheless some AT keyboard interfaces send
+                                        * make codes instead. Therefore, simply ignore
+                                        * break_flag...
+                                        */
+                                       int keyval = plain_map[scancode], keytyp;
+
+                                       set_bit(scancode, broken_keys);
+                                       self_test_last_rcv = jiffies;
+                                       keyval = plain_map[scancode];
+                                       keytyp = KTYP(keyval) - 0xf0;
+                                       keyval = KVAL(keyval);
+
+                                       printk(KERN_WARNING "Key with scancode %d ", scancode);
+                                       if (keytyp == KT_LATIN || keytyp == KT_LETTER) {
+                                               if (keyval < ' ')
+                                                       printk("('^%c') ", keyval + '@');
+                                               else
+                                                       printk("('%c') ", keyval);
+                                       }
+                                       printk("is broken -- will be ignored.\n");
+                                       break;
+                               } else if (test_bit(scancode, broken_keys))
+                                       break;
+
+#if 0  // FIXME; hangs at boot
+                               if (break_flag) {
+                                       del_timer(&atakeyb_rep_timer);
+                                       rep_scancode = 0;
+                               } else {
+                                       del_timer(&atakeyb_rep_timer);
+                                       rep_scancode = scancode;
+                                       atakeyb_rep_timer.expires = jiffies + key_repeat_delay;
+                                       add_timer(&atakeyb_rep_timer);
+                               }
+#endif
+
+                               // handle_scancode(scancode, !break_flag);
+                               if (atari_input_keyboard_interrupt_hook)
+                                       atari_input_keyboard_interrupt_hook((unsigned char)scancode, !break_flag);
+                               break;
+                       }
+                       break;
+
+               case AMOUSE:
+                       kb_state.buf[kb_state.len++] = scancode;
+                       if (kb_state.len == 5) {
+                               kb_state.state = KEYBOARD;
+                               /* not yet used */
+                               /* wake up someone waiting for this */
+                       }
+                       break;
+
+               case RMOUSE:
+                       kb_state.buf[kb_state.len++] = scancode;
+                       if (kb_state.len == 3) {
+                               kb_state.state = KEYBOARD;
+                               if (atari_mouse_interrupt_hook)
+                                       atari_mouse_interrupt_hook(kb_state.buf);
+                       }
+                       break;
+
+               case JOYSTICK:
+                       kb_state.buf[1] = scancode;
+                       kb_state.state = KEYBOARD;
+#ifdef FIXED_ATARI_JOYSTICK
+                       atari_joystick_interrupt(kb_state.buf);
+#endif
+                       break;
+
+               case CLOCK:
+                       kb_state.buf[kb_state.len++] = scancode;
+                       if (kb_state.len == 6) {
+                               kb_state.state = KEYBOARD;
+                               /* wake up someone waiting for this.
+                                  But will this ever be used, as Linux keeps its own time.
+                                  Perhaps for synchronization purposes? */
+                               /* wake_up_interruptible(&clock_wait); */
+                       }
+                       break;
+
+               case RESYNC:
+                       if (kb_state.len <= 0 || IS_SYNC_CODE(scancode)) {
+                               kb_state.state = KEYBOARD;
+                               goto interpret_scancode;
+                       }
+                       kb_state.len--;
+                       break;
+               }
+       }
+
+#if 0
+       if (acia_stat & ACIA_CTS)
+               /* cannot happen */;
+#endif
+
+       if (acia_stat & (ACIA_FE | ACIA_PE)) {
+               printk("Error in keyboard communication\n");
+       }
+
+       /* handle_scancode() can take a lot of time, so check again if
+        * some character arrived
+        */
+       goto repeat;
+}
+
+/*
+ * I write to the keyboard without using interrupts, I poll instead.