aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CREDITS5
-rw-r--r--Documentation/block/biodoc.txt14
-rw-r--r--Documentation/pnp.txt3
-rw-r--r--Documentation/robust-futex-ABI.txt182
-rw-r--r--Documentation/robust-futexes.txt218
-rw-r--r--Documentation/rpc-cache.txt121
-rw-r--r--MAINTAINERS6
-rw-r--r--arch/alpha/kernel/setup.c14
-rw-r--r--arch/alpha/mm/numa.c4
-rw-r--r--arch/arm/Kconfig3
-rw-r--r--arch/arm/common/rtctime.c108
-rw-r--r--arch/arm/mach-integrator/time.c16
-rw-r--r--arch/arm/mach-omap1/board-netstar.c2
-rw-r--r--arch/arm/mach-omap1/board-voiceblue.c2
-rw-r--r--arch/arm/mach-pxa/generic.c6
-rw-r--r--arch/arm/mach-sa1100/generic.c6
-rw-r--r--arch/arm26/mm/init.c7
-rw-r--r--arch/cris/kernel/setup.c5
-rw-r--r--arch/i386/Kconfig9
-rw-r--r--arch/i386/boot/video.S2
-rw-r--r--arch/i386/kernel/cpu/common.c10
-rw-r--r--arch/i386/kernel/cpu/intel_cacheinfo.c77
-rw-r--r--arch/i386/kernel/setup.c1
-rw-r--r--arch/i386/kernel/smpboot.c24
-rw-r--r--arch/i386/kernel/syscall_table.S2
-rw-r--r--arch/i386/kernel/timers/timer_pm.c104
-rw-r--r--arch/i386/kernel/traps.c17
-rw-r--r--arch/i386/mm/discontig.c12
-rw-r--r--arch/i386/mm/pgtable.c2
-rw-r--r--arch/ia64/kernel/traps.c6
-rw-r--r--arch/ia64/mm/discontig.c33
-rw-r--r--arch/ia64/mm/init.c2
-rw-r--r--arch/m32r/kernel/setup.c1
-rw-r--r--arch/m32r/mm/discontig.c7
-rw-r--r--arch/m32r/mm/init.c3
-rw-r--r--arch/mips/ddb5xxx/common/rtc_ds1386.c4
-rw-r--r--arch/mips/dec/time.c4
-rw-r--r--arch/mips/ite-boards/generic/time.c4
-rw-r--r--arch/mips/ite-boards/ivr/init.c3
-rw-r--r--arch/mips/ite-boards/qed-4n-s01b/init.c3
-rw-r--r--arch/mips/jmr3927/common/rtc_ds1742.c4
-rw-r--r--arch/mips/kernel/setup.c9
-rw-r--r--arch/mips/kernel/time.c22
-rw-r--r--arch/mips/lasat/setup.c7
-rw-r--r--arch/mips/mips-boards/atlas/atlas_setup.c2
-rw-r--r--arch/mips/mips-boards/generic/memory.c7
-rw-r--r--arch/mips/mips-boards/malta/malta_setup.c2
-rw-r--r--arch/mips/mips-boards/sim/sim_mem.c7
-rw-r--r--arch/mips/mm/init.c4
-rw-r--r--arch/mips/momentum/jaguar_atx/setup.c4
-rw-r--r--arch/mips/momentum/ocelot_3/setup.c4
-rw-r--r--arch/mips/momentum/ocelot_c/setup.c4
-rw-r--r--arch/mips/pmc-sierra/yosemite/setup.c4
-rw-r--r--arch/mips/sgi-ip22/ip22-reset.c2
-rw-r--r--arch/mips/sgi-ip22/ip22-time.c4
-rw-r--r--arch/mips/sgi-ip27/ip27-memory.c3
-rw-r--r--arch/mips/sgi-ip32/ip32-reset.c2
-rw-r--r--arch/mips/sgi-ip32/ip32-setup.c4
-rw-r--r--arch/mips/sibyte/swarm/setup.c8
-rw-r--r--arch/mips/sni/setup.c4
-rw-r--r--arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c4
-rw-r--r--arch/mips/tx4938/common/rtc_rx5c348.c4
-rw-r--r--arch/parisc/kernel/pdc_chassis.c3
-rw-r--r--arch/powerpc/kernel/setup_64.c3
-rw-r--r--arch/powerpc/kernel/traps.c16
-rw-r--r--arch/powerpc/mm/mem.c4
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c10
-rw-r--r--arch/ppc/platforms/prep_setup.c2
-rw-r--r--arch/s390/kernel/process.c11
-rw-r--r--arch/sh/kernel/setup.c5
-rw-r--r--arch/sh64/kernel/setup.c1
-rw-r--r--arch/sparc64/defconfig39
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c10
-rw-r--r--arch/sparc64/kernel/traps.c17
-rw-r--r--arch/um/drivers/mconsole_kern.c3
-rw-r--r--arch/um/drivers/ubd_kern.c76
-rw-r--r--arch/um/include/irq_user.h15
-rw-r--r--arch/um/include/kern.h2
-rw-r--r--arch/um/include/misc_constants.h6
-rw-r--r--arch/um/include/os.h36
-rw-r--r--arch/um/include/sigio.h3
-rw-r--r--arch/um/include/skas/mode-skas.h1
-rw-r--r--arch/um/include/skas/skas.h1
-rw-r--r--arch/um/include/user_util.h1
-rw-r--r--arch/um/kernel/Makefile9
-rw-r--r--arch/um/kernel/exec_kern.c2
-rw-r--r--arch/um/kernel/irq.c294
-rw-r--r--arch/um/kernel/irq_user.c412
-rw-r--r--arch/um/kernel/physmem.c3
-rw-r--r--arch/um/kernel/sigio_kern.c10
-rw-r--r--arch/um/kernel/smp.c14
-rw-r--r--arch/um/kernel/um_arch.c12
-rw-r--r--arch/um/os-Linux/Makefile13
-rw-r--r--arch/um/os-Linux/irq.c162
-rw-r--r--arch/um/os-Linux/sigio.c (renamed from arch/um/kernel/sigio_user.c)233
-rw-r--r--arch/um/os-Linux/start_up.c128
-rw-r--r--arch/um/os-Linux/tt.c10
-rw-r--r--arch/um/os-Linux/tty_log.c (renamed from arch/um/kernel/tty_log.c)18
-rw-r--r--arch/um/os-Linux/umid.c33
-rw-r--r--arch/um/sys-i386/ptrace.c15
-rw-r--r--arch/um/sys-i386/signal.c59
-rw-r--r--arch/um/sys-i386/user-offsets.c10
-rw-r--r--arch/um/sys-x86_64/ptrace.c22
-rw-r--r--arch/um/sys-x86_64/signal.c56
-rw-r--r--arch/um/sys-x86_64/user-offsets.c6
-rw-r--r--arch/x86_64/Kconfig13
-rw-r--r--arch/x86_64/ia32/ia32entry.S2
-rw-r--r--arch/x86_64/kernel/process.c17
-rw-r--r--arch/x86_64/kernel/setup.c3
-rw-r--r--arch/x86_64/kernel/smpboot.c24
-rw-r--r--arch/x86_64/kernel/traps.c18
-rw-r--r--arch/x86_64/mm/init.c2
-rw-r--r--arch/x86_64/mm/numa.c15
-rw-r--r--arch/xtensa/platform-iss/setup.c2
-rw-r--r--block/Kconfig1
-rw-r--r--block/genhd.c6
-rw-r--r--block/ll_rw_blk.c16
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/base/memory.c8
-rw-r--r--drivers/block/DAC960.c7
-rw-r--r--drivers/block/cciss.c12
-rw-r--r--drivers/block/cciss_scsi.c3
-rw-r--r--drivers/block/paride/bpck6.c3
-rw-r--r--drivers/char/Kconfig2
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c4
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c7
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c6
-rw-r--r--drivers/cpufreq/cpufreq.c61
-rw-r--r--drivers/firmware/dcdbas.c19
-rw-r--r--drivers/i2c/chips/Kconfig18
-rw-r--r--drivers/i2c/chips/Makefile2
-rw-r--r--drivers/i2c/chips/rtc8564.c385
-rw-r--r--drivers/i2c/chips/rtc8564.h78
-rw-r--r--drivers/ide/ide-cd.c1
-rw-r--r--drivers/macintosh/adb.c11
-rw-r--r--drivers/macintosh/adbhid.c3
-rw-r--r--drivers/macintosh/via-pmu.c2
-rw-r--r--drivers/macintosh/via-pmu68k.c7
-rw-r--r--drivers/macintosh/windfarm_core.c8
-rw-r--r--drivers/md/Kconfig26
-rw-r--r--drivers/md/dm-crypt.c11
-rw-r--r--drivers/md/dm-ioctl.c100
-rw-r--r--drivers/md/dm-linear.c8
-rw-r--r--drivers/md/dm-raid1.c29
-rw-r--r--drivers/md/dm-snap.c409
-rw-r--r--drivers/md/dm-stripe.c13
-rw-r--r--drivers/md/dm-table.c53
-rw-r--r--drivers/md/dm.c88
-rw-r--r--drivers/md/dm.h23
-rw-r--r--drivers/md/kcopyd.c28
-rw-r--r--drivers/md/md.c235
-rw-r--r--drivers/md/raid1.c27
-rw-r--r--drivers/md/raid5.c719
-rw-r--r--drivers/md/raid6main.c14
-rw-r--r--drivers/misc/ibmasm/heartbeat.c5
-rw-r--r--drivers/net/bonding/bond_main.c2
-rw-r--r--drivers/net/irda/nsc-ircc.c2
-rw-r--r--drivers/parisc/led.c14
-rw-r--r--drivers/parisc/power.c6
-rw-r--r--drivers/parport/parport_pc.c31
-rw-r--r--drivers/pnp/card.c16
-rw-r--r--drivers/pnp/driver.c19
-rw-r--r--drivers/rtc/Kconfig165
-rw-r--r--drivers/rtc/Makefile21
-rw-r--r--drivers/rtc/class.c145
-rw-r--r--drivers/rtc/hctosys.c69
-rw-r--r--drivers/rtc/interface.c277
-rw-r--r--drivers/rtc/rtc-dev.c382
-rw-r--r--drivers/rtc/rtc-ds1672.c233
-rw-r--r--drivers/rtc/rtc-ep93xx.c162
-rw-r--r--drivers/rtc/rtc-lib.c101
-rw-r--r--drivers/rtc/rtc-m48t86.c209
-rw-r--r--drivers/rtc/rtc-pcf8563.c353
-rw-r--r--drivers/rtc/rtc-proc.c162
-rw-r--r--drivers/rtc/rtc-rs5c372.c294
-rw-r--r--drivers/rtc/rtc-sa1100.c388
-rw-r--r--drivers/rtc/rtc-sysfs.c124
-rw-r--r--drivers/rtc/rtc-test.c204
-rw-r--r--drivers/rtc/rtc-x1205.c (renamed from drivers/i2c/chips/x1205.c)453
-rw-r--r--drivers/scsi/gdth.c9
-rw-r--r--drivers/usb/core/notify.c65
-rw-r--r--drivers/video/Kconfig27
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/acornfb.c8
-rw-r--r--drivers/video/asiliantfb.c14
-rw-r--r--drivers/video/aty/aty128fb.c4
-rw-r--r--drivers/video/aty/atyfb_base.c16
-rw-r--r--drivers/video/aty/mach64_gx.c3
-rw-r--r--drivers/video/aty/radeon_base.c6
-rw-r--r--drivers/video/au1200fb.c3844
-rw-r--r--drivers/video/au1200fb.h572
-rw-r--r--drivers/video/chipsfb.c14
-rw-r--r--drivers/video/console/Kconfig24
-rw-r--r--drivers/video/console/fonts.c2
-rw-r--r--drivers/video/console/newport_con.c4
-rw-r--r--drivers/video/console/vgacon.c271
-rw-r--r--drivers/video/fbcmap.c4
-rw-r--r--drivers/video/fbmem.c31
-rw-r--r--drivers/video/fbmon.c6
-rw-r--r--drivers/video/fbsysfs.c4
-rw-r--r--drivers/video/geode/Kconfig17
-rw-r--r--drivers/video/geode/Makefile4
-rw-r--r--drivers/video/geode/display_gx.c156
-rw-r--r--drivers/video/geode/display_gx.h96
-rw-r--r--drivers/video/geode/gxfb_core.c423
-rw-r--r--drivers/video/geode/video_gx.c262
-rw-r--r--drivers/video/geode/video_gx.h47
-rw-r--r--drivers/video/i810/i810-i2c.c3
-rw-r--r--drivers/video/imsttfb.c32
-rw-r--r--drivers/video/macmodes.c2
-rw-r--r--drivers/video/matrox/matroxfb_g450.c2
-rw-r--r--drivers/video/matrox/matroxfb_maven.c78
-rw-r--r--drivers/video/modedb.c6
-rw-r--r--drivers/video/neofb.c8
-rw-r--r--drivers/video/nvidia/nv_accel.c12
-rw-r--r--drivers/video/nvidia/nv_i2c.c3
-rw-r--r--drivers/video/nvidia/nv_type.h1
-rw-r--r--drivers/video/nvidia/nvidia.c119
-rw-r--r--drivers/video/pmagb-b-fb.c2
-rw-r--r--drivers/video/radeonfb.c2
-rw-r--r--drivers/video/riva/fbdev.c2
-rw-r--r--drivers/video/savage/savagefb-i2c.c3
-rw-r--r--drivers/video/sis/init301.c11
-rw-r--r--drivers/video/sstfb.c11
-rw-r--r--drivers/video/virgefb.c3
-rw-r--r--fs/autofs/dirhash.c2
-rw-r--r--fs/autofs4/autofs_i.h47
-rw-r--r--fs/autofs4/expire.c292
-rw-r--r--fs/autofs4/inode.c104
-rw-r--r--fs/autofs4/root.c324
-rw-r--r--fs/autofs4/waitq.c111
-rw-r--r--fs/block_dev.c297
-rw-r--r--fs/buffer.c2
-rw-r--r--fs/hostfs/hostfs_user.c1
-rw-r--r--fs/namei.c39
-rw-r--r--fs/namespace.c8
-rw-r--r--fs/nfsd/export.c368
-rw-r--r--fs/nfsd/nfs4idmap.c146
-rw-r--r--fs/nfsd/nfsfh.c2
-rw-r--r--fs/partitions/check.c27
-rw-r--r--include/asm-alpha/mmzone.h19
-rw-r--r--include/asm-alpha/page.h4
-rw-r--r--include/asm-arm/memory.h15
-rw-r--r--include/asm-arm/rtc.h3
-rw-r--r--include/asm-arm26/memory.h4
-rw-r--r--include/asm-cris/page.h4
-rw-r--r--include/asm-frv/futex.h6
-rw-r--r--include/asm-frv/page.h7
-rw-r--r--include/asm-generic/futex.h6
-rw-r--r--include/asm-generic/memory_model.h77
-rw-r--r--include/asm-h8300/page.h4
-rw-r--r--include/asm-i386/futex.h27
-rw-r--r--include/asm-i386/kdebug.h10
-rw-r--r--include/asm-i386/mmzone.h17
-rw-r--r--include/asm-i386/page.h3
-rw-r--r--include/asm-i386/processor.h5
-rw-r--r--include/asm-i386/setup.h4
-rw-r--r--include/asm-i386/topology.h2
-rw-r--r--include/asm-i386/unistd.h4
-rw-r--r--include/asm-ia64/compat.h6
-rw-r--r--include/asm-ia64/kdebug.h4
-rw-r--r--include/asm-ia64/page.h18
-rw-r--r--include/asm-m32r/mmzone.h14
-rw-r--r--include/asm-m32r/page.h5
-rw-r--r--include/asm-m32r/setup.h4
-rw-r--r--include/asm-mips/compat.h5
-rw-r--r--include/asm-mips/futex.h6
-rw-r--r--include/asm-mips/mmzone.h14
-rw-r--r--include/asm-mips/page.h3
-rw-r--r--include/asm-mips/time.h12
-rw-r--r--include/asm-parisc/compat.h5
-rw-r--r--include/asm-parisc/mmzone.h17
-rw-r--r--include/asm-parisc/page.h3
-rw-r--r--include/asm-powerpc/futex.h6
-rw-r--r--include/asm-powerpc/kdebug.h12
-rw-r--r--include/asm-powerpc/page.h3
-rw-r--r--include/asm-ppc/page.h4
-rw-r--r--include/asm-s390/compat.h5
-rw-r--r--include/asm-s390/page.h3
-rw-r--r--include/asm-sh/page.h5
-rw-r--r--include/asm-sh64/page.h5
-rw-r--r--include/asm-sh64/platform.h5
-rw-r--r--include/asm-sparc/page.h4
-rw-r--r--include/asm-sparc64/futex.h6
-rw-r--r--include/asm-sparc64/kdebug.h11
-rw-r--r--include/asm-sparc64/page.h2
-rw-r--r--include/asm-um/page.h4
-rw-r--r--include/asm-um/uaccess.h31
-rw-r--r--include/asm-v850/page.h4
-rw-r--r--include/asm-x86_64/futex.h27
-rw-r--r--include/asm-x86_64/kdebug.h23
-rw-r--r--include/asm-x86_64/mmzone.h4
-rw-r--r--include/asm-x86_64/page.h3
-rw-r--r--include/asm-x86_64/processor.h4
-rw-r--r--include/asm-x86_64/smp.h1
-rw-r--r--include/asm-x86_64/topology.h2
-rw-r--r--include/asm-x86_64/unistd.h6
-rw-r--r--include/asm-xtensa/page.h6
-rw-r--r--include/linux/adb.h2
-rw-r--r--include/linux/auto_fs4.h51
-rw-r--r--include/linux/bootmem.h1
-rw-r--r--include/linux/compat.h18
-rw-r--r--include/linux/compat_ioctl.h2
-rw-r--r--include/linux/device-mapper.h1
-rw-r--r--include/linux/dm-ioctl.h17
-rw-r--r--include/linux/fs.h10
-rw-r--r--include/linux/futex.h89
-rw-r--r--include/linux/genhd.h15
-rw-r--r--include/linux/i2c-id.h4
-rw-r--r--include/linux/kernel.h2
-rw-r--r--include/linux/m48t86.h16
-rw-r--r--include/linux/memory.h1
-rw-r--r--include/linux/mmzone.h91
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack.h17
-rw-r--r--include/linux/nfsd/export.h29
-rw-r--r--include/linux/nodemask.h4
-rw-r--r--include/linux/notifier.h96
-rw-r--r--include/linux/pci_ids.h1
-rw-r--r--include/linux/pfn.h9
-rw-r--r--include/linux/raid/md.h3
-rw-r--r--include/linux/raid/md_k.h21
-rw-r--r--include/linux/raid/md_p.h32
-rw-r--r--include/linux/raid/raid5.h25
-rw-r--r--include/linux/rtc.h92
-rw-r--r--include/linux/sched.h6
-rw-r--r--include/linux/sunrpc/cache.h145
-rw-r--r--include/linux/sunrpc/svcauth.h12
-rw-r--r--include/linux/threads.h3
-rw-r--r--include/linux/topology.h9
-rw-r--r--include/linux/x1205.h31
-rw-r--r--include/net/netfilter/nf_conntrack.h17
-rw-r--r--kernel/Makefile3
-rw-r--r--kernel/compat.c23
-rw-r--r--kernel/cpu.c29
-rw-r--r--kernel/exit.c8
-rw-r--r--kernel/fork.c5
-rw-r--r--kernel/futex.c170
-rw-r--r--kernel/futex_compat.c141
-rw-r--r--kernel/module.c20
-rw-r--r--kernel/panic.c4
-rw-r--r--kernel/profile.c53
-rw-r--r--kernel/sched.c146
-rw-r--r--kernel/softlockup.c2
-rw-r--r--kernel/sys.c327
-rw-r--r--kernel/sys_ni.c4
-rw-r--r--lib/Kconfig.debug2
-rw-r--r--mm/Makefile2
-rw-r--r--mm/bootmem.c39
-rw-r--r--mm/mmzone.c50
-rw-r--r--mm/page_alloc.c56
-rw-r--r--mm/vmscan.c6
-rw-r--r--net/bluetooth/hci_core.c8
-rw-r--r--net/core/dev.c42
-rw-r--r--net/decnet/dn_dev.c10
-rw-r--r--net/ipv4/devinet.c16
-rw-r--r--net/ipv4/netfilter/ip_conntrack_core.c6
-rw-r--r--net/ipv6/addrconf.c10
-rw-r--r--net/netfilter/nf_conntrack_core.c6
-rw-r--r--net/netlink/af_netlink.c9
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c182
-rw-r--r--net/sunrpc/cache.c163
-rw-r--r--net/sunrpc/sunrpc_syms.c6
-rw-r--r--net/sunrpc/svcauth.c122
-rw-r--r--net/sunrpc/svcauth_unix.c229
-rw-r--r--sound/drivers/mpu401/mpu401.c16
-rw-r--r--sound/isa/ad1816a/ad1816a.c12
-rw-r--r--sound/isa/als100.c14
-rw-r--r--sound/isa/azt2320.c12
-rw-r--r--sound/isa/cmi8330.c15
-rw-r--r--sound/isa/cs423x/cs4236.c25
-rw-r--r--sound/isa/dt019x.c12
-rw-r--r--sound/isa/es18xx.c13
-rw-r--r--sound/isa/gus/interwave.c12
-rw-r--r--sound/isa/opl3sa2.c17
-rw-r--r--sound/isa/sb/es968.c12
-rw-r--r--sound/isa/sb/sb16.c14
-rw-r--r--sound/isa/sscape.c4
-rw-r--r--sound/isa/wavefront/wavefront.c10
-rw-r--r--sound/oss/cs4232.c15
-rw-r--r--sound/oss/sb_card.c29
381 files changed, 16467 insertions, 4405 deletions
diff --git a/CREDITS b/CREDITS
index c6d69bf10e15..35850d882c34 100644
--- a/CREDITS
+++ b/CREDITS
@@ -3741,10 +3741,11 @@ D: Mylex DAC960 PCI RAID driver
3741D: Miscellaneous kernel fixes 3741D: Miscellaneous kernel fixes
3742 3742
3743N: Alessandro Zummo 3743N: Alessandro Zummo
3744E: azummo@ita.flashnet.it 3744E: a.zummo@towertech.it
3745W: http://freepage.logicom.it/azummo/
3746D: CMI8330 support is sb_card.c 3745D: CMI8330 support is sb_card.c
3747D: ISAPnP fixes in sb_card.c 3746D: ISAPnP fixes in sb_card.c
3747D: ZyXEL omni.net lcd plus driver
3748D: RTC subsystem
3748S: Italy 3749S: Italy
3749 3750
3750N: Marc Zyngier 3751N: Marc Zyngier
diff --git a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt
index 8e63831971d5..f989a9e839b4 100644
--- a/Documentation/block/biodoc.txt
+++ b/Documentation/block/biodoc.txt
@@ -132,8 +132,18 @@ Some new queue property settings:
132 limit. No highmem default. 132 limit. No highmem default.
133 133
134 blk_queue_max_sectors(q, max_sectors) 134 blk_queue_max_sectors(q, max_sectors)
135 Maximum size request you can handle in units of 512 byte 135 Sets two variables that limit the size of the request.
136 sectors. 255 default. 136
137 - The request queue's max_sectors, which is a soft size in
138 in units of 512 byte sectors, and could be dynamically varied
139 by the core kernel.
140
141 - The request queue's max_hw_sectors, which is a hard limit
142 and reflects the maximum size request a driver can handle
143 in units of 512 byte sectors.
144
145 The default for both max_sectors and max_hw_sectors is
146 255. The upper limit of max_sectors is 1024.
137 147
138 blk_queue_max_phys_segments(q, max_segments) 148 blk_queue_max_phys_segments(q, max_segments)
139 Maximum physical segments you can handle in a request. 128 149 Maximum physical segments you can handle in a request. 128
diff --git a/Documentation/pnp.txt b/Documentation/pnp.txt
index af0f6eabfa1c..9529c9c9fd59 100644
--- a/Documentation/pnp.txt
+++ b/Documentation/pnp.txt
@@ -115,6 +115,9 @@ pnp_unregister_protocol
115pnp_register_driver 115pnp_register_driver
116- adds a PnP driver to the Plug and Play Layer 116- adds a PnP driver to the Plug and Play Layer
117- this includes driver model integration 117- this includes driver model integration
118- returns zero for success or a negative error number for failure; count
119 calls to the .add() method if you need to know how many devices bind to
120 the driver
118 121
119pnp_unregister_driver 122pnp_unregister_driver
120- removes a PnP driver from the Plug and Play Layer 123- removes a PnP driver from the Plug and Play Layer
diff --git a/Documentation/robust-futex-ABI.txt b/Documentation/robust-futex-ABI.txt
new file mode 100644
index 000000000000..8529a17ffaa1
--- /dev/null
+++ b/Documentation/robust-futex-ABI.txt
@@ -0,0 +1,182 @@
1Started by Paul Jackson <pj@sgi.com>
2
3The robust futex ABI
4--------------------
5
6Robust_futexes provide a mechanism that is used in addition to normal
7futexes, for kernel assist of cleanup of held locks on task exit.
8
9The interesting data as to what futexes a thread is holding is kept on a
10linked list in user space, where it can be updated efficiently as locks
11are taken and dropped, without kernel intervention. The only additional
12kernel intervention required for robust_futexes above and beyond what is
13required for futexes is:
14
15 1) a one time call, per thread, to tell the kernel where its list of
16 held robust_futexes begins, and
17 2) internal kernel code at exit, to handle any listed locks held
18 by the exiting thread.
19
20The existing normal futexes already provide a "Fast Userspace Locking"
21mechanism, which handles uncontested locking without needing a system
22call, and handles contested locking by maintaining a list of waiting
23threads in the kernel. Options on the sys_futex(2) system call support
24waiting on a particular futex, and waking up the next waiter on a
25particular futex.
26
27For robust_futexes to work, the user code (typically in a library such
28as glibc linked with the application) has to manage and place the
29necessary list elements exactly as the kernel expects them. If it fails
30to do so, then improperly listed locks will not be cleaned up on exit,
31probably causing deadlock or other such failure of the other threads
32waiting on the same locks.
33
34A thread that anticipates possibly using robust_futexes should first
35issue the system call:
36
37 asmlinkage long
38 sys_set_robust_list(struct robust_list_head __user *head, size_t len);
39
40The pointer 'head' points to a structure in the threads address space
41consisting of three words. Each word is 32 bits on 32 bit arch's, or 64
42bits on 64 bit arch's, and local byte order. Each thread should have
43its own thread private 'head'.
44
45If a thread is running in 32 bit compatibility mode on a 64 native arch
46kernel, then it can actually have two such structures - one using 32 bit
47words for 32 bit compatibility mode, and one using 64 bit words for 64
48bit native mode. The kernel, if it is a 64 bit kernel supporting 32 bit
49compatibility mode, will attempt to process both lists on each task
50exit, if the corresponding sys_set_robust_list() call has been made to
51setup that list.
52
53 The first word in the memory structure at 'head' contains a
54 pointer to a single linked list of 'lock entries', one per lock,
55 as described below. If the list is empty, the pointer will point
56 to itself, 'head'. The last 'lock entry' points back to the 'head'.
57
58 The second word, called 'offset', specifies the offset from the
59 address of the associated 'lock entry', plus or minus, of what will
60 be called the 'lock word', from that 'lock entry'. The 'lock word'
61 is always a 32 bit word, unlike the other words above. The 'lock
62 word' holds 3 flag bits in the upper 3 bits, and the thread id (TID)
63 of the thread holding the lock in the bottom 29 bits. See further
64 below for a description of the flag bits.
65
66 The third word, called 'list_op_pending', contains transient copy of
67 the address of the 'lock entry', during list insertion and removal,
68 and is needed to correctly resolve races should a thread exit while
69 in the middle of a locking or unlocking operation.
70
71Each 'lock entry' on the single linked list starting at 'head' consists
72of just a single word, pointing to the next 'lock entry', or back to
73'head' if there are no more entries. In addition, nearby to each 'lock
74entry', at an offset from the 'lock entry' specified by the 'offset'
75word, is one 'lock word'.
76
77The 'lock word' is always 32 bits, and is intended to be the same 32 bit
78lock variable used by the futex mechanism, in conjunction with
79robust_futexes. The kernel will only be able to wakeup the next thread
80waiting for a lock on a threads exit if that next thread used the futex
81mechanism to register the address of that 'lock word' with the kernel.
82
83For each futex lock currently held by a thread, if it wants this
84robust_futex support for exit cleanup of that lock, it should have one
85'lock entry' on this list, with its associated 'lock word' at the
86specified 'offset'. Should a thread die while holding any such locks,
87the kernel will walk this list, mark any such locks with a bit
88indicating their holder died, and wakeup the next thread waiting for
89that lock using the futex mechanism.
90
91When a thread has invoked the above system call to indicate it
92anticipates using robust_futexes, the kernel stores the passed in 'head'
93pointer for that task. The task may retrieve that value later on by
94using the system call:
95
96 asmlinkage long
97 sys_get_robust_list(int pid, struct robust_list_head __user **head_ptr,
98 size_t __user *len_ptr);
99
100It is anticipated that threads will use robust_futexes embedded in
101larger, user level locking structures, one per lock. The kernel
102robust_futex mechanism doesn't care what else is in that structure, so
103long as the 'offset' to the 'lock word' is the same for all
104robust_futexes used by that thread. The thread should link those locks
105it currently holds using the 'lock entry' pointers. It may also have
106other links between the locks, such as the reverse side of a double
107linked list, but that doesn't matter to the kernel.
108
109By keeping its locks linked this way, on a list starting with a 'head'
110pointer known to the kernel, the kernel can provide to a thread the
111essential service available for robust_futexes, which is to help clean
112up locks held at the time of (a perhaps unexpectedly) exit.
113
114Actual locking and unlocking, during normal operations, is handled
115entirely by user level code in the contending threads, and by the
116existing futex mechanism to wait for, and wakeup, locks. The kernels
117only essential involvement in robust_futexes is to remember where the
118list 'head' is, and to walk the list on thread exit, handling locks
119still held by the departing thread, as described below.
120
121There may exist thousands of futex lock structures in a threads shared
122memory, on various data structures, at a given point in time. Only those
123lock structures for locks currently held by that thread should be on
124that thread's robust_futex linked lock list a given time.
125
126A given futex lock structure in a user shared memory region may be held
127at different times by any of the threads with access to that region. The
128thread currently holding such a lock, if any, is marked with the threads
129TID in the lower 29 bits of the 'lock word'.
130
131When adding or removing a lock from its list of held locks, in order for
132the kernel to correctly handle lock cleanup regardless of when the task
133exits (perhaps it gets an unexpected signal 9 in the middle of
134manipulating this list), the user code must observe the following
135protocol on 'lock entry' insertion and removal:
136
137On insertion:
138 1) set the 'list_op_pending' word to the address of the 'lock word'
139 to be inserted,
140 2) acquire the futex lock,
141 3) add the lock entry, with its thread id (TID) in the bottom 29 bits
142 of the 'lock word', to the linked list starting at 'head', and
143 4) clear the 'list_op_pending' word.
144
145On removal:
146 1) set the 'list_op_pending' word to the address of the 'lock word'
147 to be removed,
148 2) remove the lock entry for this lock from the 'head' list,
149 2) release the futex lock, and
150 2) clear the 'lock_op_pending' word.
151
152On exit, the kernel will consider the address stored in
153'list_op_pending' and the address of each 'lock word' found by walking
154the list starting at 'head'. For each such address, if the bottom 29
155bits of the 'lock word' at offset 'offset' from that address equals the
156exiting threads TID, then the kernel will do two things:
157
158 1) if bit 31 (0x80000000) is set in that word, then attempt a futex
159 wakeup on that address, which will waken the next thread that has
160 used to the futex mechanism to wait on that address, and
161 2) atomically set bit 30 (0x40000000) in the 'lock word'.
162
163In the above, bit 31 was set by futex waiters on that lock to indicate
164they were waiting, and bit 30 is set by the kernel to indicate that the
165lock owner died holding the lock.
166
167The kernel exit code will silently stop scanning the list further if at
168any point:
169
170 1) the 'head' pointer or an subsequent linked list pointer
171 is not a valid address of a user space word
172 2) the calculated location of the 'lock word' (address plus
173 'offset') is not the valud address of a 32 bit user space
174 word
175 3) if the list contains more than 1 million (subject to
176 future kernel configuration changes) elements.
177
178When the kernel sees a list entry whose 'lock word' doesn't have the
179current threads TID in the lower 29 bits, it does nothing with that
180entry, and goes on to the next entry.
181
182Bit 29 (0x20000000) of the 'lock word' is reserved for future use.
diff --git a/Documentation/robust-futexes.txt b/Documentation/robust-futexes.txt
new file mode 100644
index 000000000000..df82d75245a0
--- /dev/null
+++ b/Documentation/robust-futexes.txt
@@ -0,0 +1,218 @@
1Started by: Ingo Molnar <mingo@redhat.com>
2
3Background
4----------
5
6what are robust futexes? To answer that, we first need to understand
7what futexes are: normal futexes are special types of locks that in the
8noncontended case can be acquired/released from userspace without having
9to enter the kernel.
10
11A futex is in essence a user-space address, e.g. a 32-bit lock variable
12field. If userspace notices contention (the lock is already owned and
13someone else wants to grab it too) then the lock is marked with a value
14that says "there's a waiter pending", and the sys_futex(FUTEX_WAIT)
15syscall is used to wait for the other guy to release it. The kernel
16creates a 'futex queue' internally, so that it can later on match up the
17waiter with the waker - without them having to know about each other.
18When the owner thread releases the futex, it notices (via the variable
19value) that there were waiter(s) pending, and does the
20sys_futex(FUTEX_WAKE) syscall to wake them up. Once all waiters have
21taken and released the lock, the futex is again back to 'uncontended'
22state, and there's no in-kernel state associated with it. The kernel
23completely forgets that there ever was a futex at that address. This
24method makes futexes very lightweight and scalable.
25
26"Robustness" is about dealing with crashes while holding a lock: if a
27process exits prematurely while holding a pthread_mutex_t lock that is
28also shared with some other process (e.g. yum segfaults while holding a
29pthread_mutex_t, or yum is kill -9-ed), then waiters for that lock need
30to be notified that the last owner of the lock exited in some irregular
31way.
32
33To solve such types of problems, "robust mutex" userspace APIs were
34created: pthread_mutex_lock() returns an error value if the owner exits
35prematurely - and the new owner can decide whether the data protected by
36the lock can be recovered safely.
37
38There is a big conceptual problem with futex based mutexes though: it is
39the kernel that destroys the owner task (e.g. due to a SEGFAULT), but
40the kernel cannot help with the cleanup: if there is no 'futex queue'
41(and in most cases there is none, futexes being fast lightweight locks)
42then the kernel has no information to clean up after the held lock!
43Userspace has no chance to clean up after the lock either - userspace is
44the one that crashes, so it has no opportunity to clean up. Catch-22.
45
46In practice, when e.g. yum is kill -9-ed (or segfaults), a system reboot
47is needed to release that futex based lock. This is one of the leading
48bugreports against yum.
49
50To solve this problem, the traditional approach was to extend the vma
51(virtual memory area descriptor) concept to have a notion of 'pending
52robust futexes attached to this area'. This approach requires 3 new
53syscall variants to sys_futex(): FUTEX_REGISTER, FUTEX_DEREGISTER and
54FUTEX_RECOVER. At do_exit() time, all vmas are searched to see whether
55they have a robust_head set. This approach has two fundamental problems
56left:
57
58 - it has quite complex locking and race scenarios. The vma-based
59 approach had been pending for years, but they are still not completely
60 reliable.
61
62 - they have to scan _every_ vma at sys_exit() time, per thread!
63
64The second disadvantage is a real killer: pthread_exit() takes around 1
65microsecond on Linux, but with thousands (or tens of thousands) of vmas
66every pthread_exit() takes a millisecond or more, also totally
67destroying the CPU's L1 and L2 caches!
68
69This is very much noticeable even for normal process sys_exit_group()
70calls: the kernel has to do the vma scanning unconditionally! (this is
71because the kernel has no knowledge about how many robust futexes there
72are to be cleaned up, because a robust futex might have been registered
73in another task, and the futex variable might have been simply mmap()-ed
74into this process's address space).
75
76This huge overhead forced the creation of CONFIG_FUTEX_ROBUST so that
77normal kernels can turn it off, but worse than that: the overhead makes
78robust futexes impractical for any type of generic Linux distribution.
79
80So something had to be done.
81
82New approach to robust futexes
83------------------------------
84
85At the heart of this new approach there is a per-thread private list of
86robust locks that userspace is holding (maintained by glibc) - which
87userspace list is registered with the kernel via a new syscall [this
88registration happens at most once per thread lifetime]. At do_exit()
89time, the kernel checks this user-space list: are there any robust futex
90locks to be cleaned up?
91
92In the common case, at do_exit() time, there is no list registered, so
93the cost of robust futexes is just a simple current->robust_list != NULL
94comparison. If the thread has registered a list, then normally the list
95is empty. If the thread/process crashed or terminated in some incorrect
96way then the list might be non-empty: in this case the kernel carefully
97walks the list [not trusting it], and marks all locks that are owned by
98this thread with the FUTEX_OWNER_DEAD bit, and wakes up one waiter (if
99any).
100
101The list is guaranteed to be private and per-thread at do_exit() time,
102so it can be accessed by the kernel in a lockless way.
103
104There is one race possible though: since adding to and removing from the
105list is done after the futex is acquired by glibc, there is a few
106instructions window for the thread (or process) to die there, leaving
107the futex hung. To protect against this possibility, userspace (glibc)
108also maintains a simple per-thread 'list_op_pending' field, to allow the
109kernel to clean up if the thread dies after acquiring the lock, but just
110before it could have added itself to the list. Glibc sets this
111list_op_pending field before it tries to acquire the futex, and clears
112it after the list-add (or list-remove) has finished.
113
114That's all that is needed - all the rest of robust-futex cleanup is done
115in userspace [just like with the previous patches].
116
117Ulrich Drepper has implemented the necessary glibc support for this new
118mechanism, which fully enables robust mutexes.
119
120Key differences of this userspace-list based approach, compared to the
121vma based method:
122
123 - it's much, much faster: at thread exit time, there's no need to loop
124 over every vma (!), which the VM-based method has to do. Only a very
125 simple 'is the list empty' op is done.
126
127 - no VM changes are needed - 'struct address_space' is left alone.
128
129 - no registration of individual locks is needed: robust mutexes dont
130 need any extra per-lock syscalls. Robust mutexes thus become a very
131 lightweight primitive - so they dont force the application designer
132 to do a hard choice between performance and robustness - robust
133 mutexes are just as fast.
134
135 - no per-lock kernel allocation happens.
136
137 - no resource limits are needed.
138
139 - no kernel-space recovery call (FUTEX_RECOVER) is needed.
140
141 - the implementation and the locking is "obvious", and there are no
142 interactions with the VM.
143
144Performance
145-----------
146
147I have benchmarked the time needed for the kernel to process a list of 1
148million (!) held locks, using the new method [on a 2GHz CPU]:
149
150 - with FUTEX_WAIT set [contended mutex]: 130 msecs
151 - without FUTEX_WAIT set [uncontended mutex]: 30 msecs
152
153I have also measured an approach where glibc does the lock notification
154[which it currently does for !pshared robust mutexes], and that took 256
155msecs - clearly slower, due to the 1 million FUTEX_WAKE syscalls
156userspace had to do.
157
158(1 million held locks are unheard of - we expect at most a handful of
159locks to be held at a time. Nevertheless it's nice to know that this
160approach scales nicely.)
161
162Implementation details
163----------------------
164
165The patch adds two new syscalls: one to register the userspace list, and
166one to query the registered list pointer:
167
168 asmlinkage long
169 sys_set_robust_list(struct robust_list_head __user *head,
170 size_t len);
171
172 asmlinkage long
173 sys_get_robust_list(int pid, struct robust_list_head __user **head_ptr,
174 size_t __user *len_ptr);
175
176List registration is very fast: the pointer is simply stored in
177current->robust_list. [Note that in the future, if robust futexes become
178widespread, we could extend sys_clone() to register a robust-list head
179for new threads, without the need of another syscall.]
180
181So there is virtually zero overhead for tasks not using robust futexes,
182and even for robust futex users, there is only one extra syscall per
183thread lifetime, and the cleanup operation, if it happens, is fast and
184straightforward. The kernel doesnt have any internal distinction between
185robust and normal futexes.
186
187If a futex is found to be held at exit time, the kernel sets the
188following bit of the futex word:
189
190 #define FUTEX_OWNER_DIED 0x40000000
191
192and wakes up the next futex waiter (if any). User-space does the rest of
193the cleanup.
194
195Otherwise, robust futexes are acquired by glibc by putting the TID into
196the futex field atomically. Waiters set the FUTEX_WAITERS bit:
197
198 #define FUTEX_WAITERS 0x80000000
199
200and the remaining bits are for the TID.
201
202Testing, architecture support
203-----------------------------
204
205i've tested the new syscalls on x86 and x86_64, and have made sure the
206parsing of the userspace list is robust [ ;-) ] even if the list is
207deliberately corrupted.
208
209i386 and x86_64 syscalls are wired up at the moment, and Ulrich has
210tested the new glibc code (on x86_64 and i386), and it works for his
211robust-mutex testcases.
212
213All other architectures should build just fine too - but they wont have
214the new syscalls yet.
215
216Architectures need to implement the new futex_atomic_cmpxchg_inatomic()
217inline function before writing up the syscalls (that function returns
218-ENOSYS right now).
diff --git a/Documentation/rpc-cache.txt b/Documentation/rpc-cache.txt
index 2b5d4434fa5a..5f757c8cf979 100644
--- a/Documentation/rpc-cache.txt
+++ b/Documentation/rpc-cache.txt
@@ -1,4 +1,4 @@
1This document gives a brief introduction to the caching 1 This document gives a brief introduction to the caching
2mechanisms in the sunrpc layer that is used, in particular, 2mechanisms in the sunrpc layer that is used, in particular,
3for NFS authentication. 3for NFS authentication.
4 4
@@ -25,25 +25,17 @@ The common code handles such things as:
25 - supporting 'NEGATIVE' as well as positive entries 25 - supporting 'NEGATIVE' as well as positive entries
26 - allowing an EXPIRED time on cache items, and removing 26 - allowing an EXPIRED time on cache items, and removing
27 items after they expire, and are no longe in-use. 27 items after they expire, and are no longe in-use.
28
29 Future code extensions are expect to handle
30 - making requests to user-space to fill in cache entries 28 - making requests to user-space to fill in cache entries
31 - allowing user-space to directly set entries in the cache 29 - allowing user-space to directly set entries in the cache
32 - delaying RPC requests that depend on as-yet incomplete 30 - delaying RPC requests that depend on as-yet incomplete
33 cache entries, and replaying those requests when the cache entry 31 cache entries, and replaying those requests when the cache entry
34 is complete. 32 is complete.
35 - maintaining last-access times on cache entries 33 - clean out old entries as they expire.
36 - clean out old entries when the caches become full
37
38The code for performing a cache lookup is also common, but in the form
39of a template. i.e. a #define.
40Each cache defines a lookup function by using the DefineCacheLookup
41macro, or the simpler DefineSimpleCacheLookup macro
42 34
43Creating a Cache 35Creating a Cache
44---------------- 36----------------
45 37
461/ A cache needs a datum to cache. This is in the form of a 381/ A cache needs a datum to store. This is in the form of a
47 structure definition that must contain a 39 structure definition that must contain a
48 struct cache_head 40 struct cache_head
49 as an element, usually the first. 41 as an element, usually the first.
@@ -51,35 +43,69 @@ Creating a Cache
51 Each cache element is reference counted and contains 43 Each cache element is reference counted and contains
52 expiry and update times for use in cache management. 44 expiry and update times for use in cache management.
532/ A cache needs a "cache_detail" structure that 452/ A cache needs a "cache_detail" structure that
54 describes the cache. This stores the hash table, and some 46 describes the cache. This stores the hash table, some
55 parameters for cache management. 47 parameters for cache management, and some operations detailing how
563/ A cache needs a lookup function. This is created using 48 to work with particular cache items.
57 the DefineCacheLookup macro. This lookup function is used both 49 The operations requires are:
58 to find entries and to update entries. The normal mode for 50 struct cache_head *alloc(void)
59 updating an entry is to replace the old entry with a new 51 This simply allocates appropriate memory and returns
60 entry. However it is possible to allow update-in-place 52 a pointer to the cache_detail embedded within the
61 for those caches where it makes sense (no atomicity issues 53 structure
62 or indirect reference counting issue) 54 void cache_put(struct kref *)
634/ A cache needs to be registered using cache_register(). This 55 This is called when the last reference to an item is
64 includes in on a list of caches that will be regularly 56 is dropped. The pointer passed is to the 'ref' field
65 cleaned to discard old data. For this to work, some 57 in the cache_head. cache_put should release any
66 thread must periodically call cache_clean 58 references create by 'cache_init' and, if CACHE_VALID
67 59 is set, any references created by cache_update.
60 It should then release the memory allocated by
61 'alloc'.
62 int match(struct cache_head *orig, struct cache_head *new)
63 test if the keys in the two structures match. Return
64 1 if they do, 0 if they don't.
65 void init(struct cache_head *orig, struct cache_head *new)
66 Set the 'key' fields in 'new' from 'orig'. This may
67 include taking references to shared objects.
68 void update(struct cache_head *orig, struct cache_head *new)
69 Set the 'content' fileds in 'new' from 'orig'.
70 int cache_show(struct seq_file *m, struct cache_detail *cd,
71 struct cache_head *h)
72 Optional. Used to provide a /proc file that lists the
73 contents of a cache. This should show one item,
74 usually on just one line.
75 int cache_request(struct cache_detail *cd, struct cache_head *h,
76 char **bpp, int *blen)
77 Format a request to be send to user-space for an item
78 to be instantiated. *bpp is a buffer of size *blen.
79 bpp should be moved forward over the encoded message,
80 and *blen should be reduced to show how much free
81 space remains. Return 0 on success or <0 if not
82 enough room or other problem.
83 int cache_parse(struct cache_detail *cd, char *buf, int len)
84 A message from user space has arrived to fill out a
85 cache entry. It is in 'buf' of length 'len'.
86 cache_parse should parse this, find the item in the
87 cache with sunrpc_cache_lookup, and update the item
88 with sunrpc_cache_update.
89
90
913/ A cache needs to be registered using cache_register(). This
92 includes it on a list of caches that will be regularly
93 cleaned to discard old data.
94
68Using a cache 95Using a cache
69------------- 96-------------
70 97
71To find a value in a cache, call the lookup function passing it a the 98To find a value in a cache, call sunrpc_cache_lookup passing a pointer
72datum which contains key, and possibly content, and a flag saying 99to the cache_head in a sample item with the 'key' fields filled in.
73whether to update the cache with new data from the datum. Depending 100This will be passed to ->match to identify the target entry. If no
74on how the cache lookup function was defined, it may take an extra 101entry is found, a new entry will be create, added to the cache, and
75argument to identify the particular cache in question. 102marked as not containing valid data.
76 103
77Except in cases of kmalloc failure, the lookup function 104The item returned is typically passed to cache_check which will check
78will return a new datum which will store the key and 105if the data is valid, and may initiate an up-call to get fresh data.
79may contain valid content, or may not. 106cache_check will return -ENOENT in the entry is negative or if an up
80This datum is typically passed to cache_check which determines the 107call is needed but not possible, -EAGAIN if an upcall is pending,
81validity of the datum and may later initiate an upcall to fill 108or 0 if the data is valid;
82in the data.
83 109
84cache_check can be passed a "struct cache_req *". This structure is 110cache_check can be passed a "struct cache_req *". This structure is
85typically embedded in the actual request and can be used to create a 111typically embedded in the actual request and can be used to create a
@@ -90,6 +116,13 @@ item does become valid, the deferred copy of the request will be
90revisited (->revisit). It is expected that this method will 116revisited (->revisit). It is expected that this method will
91reschedule the request for processing. 117reschedule the request for processing.
92 118
119The value returned by sunrpc_cache_lookup can also be passed to
120sunrpc_cache_update to set the content for the item. A second item is
121passed which should hold the content. If the item found by _lookup
122has valid data, then it is discarded and a new item is created. This
123saves any user of an item from worrying about content changing while
124it is being inspected. If the item found by _lookup does not contain
125valid data, then the content is copied across and CACHE_VALID is set.
93 126
94Populating a cache 127Populating a cache
95------------------ 128------------------
@@ -114,8 +147,8 @@ should be create or updated to have the given content, and the
114expiry time should be set on that item. 147expiry time should be set on that item.
115 148
116Reading from a channel is a bit more interesting. When a cache 149Reading from a channel is a bit more interesting. When a cache
117lookup fail, or when it suceeds but finds an entry that may soon 150lookup fails, or when it succeeds but finds an entry that may soon
118expiry, a request is lodged for that cache item to be updated by 151expire, a request is lodged for that cache item to be updated by
119user-space. These requests appear in the channel file. 152user-space. These requests appear in the channel file.
120 153
121Successive reads will return successive requests. 154Successive reads will return successive requests.
@@ -130,7 +163,7 @@ Thus a user-space helper is likely to:
130 write a response 163 write a response
131 loop. 164 loop.
132 165
133If it dies and needs to be restarted, any requests that have not be 166If it dies and needs to be restarted, any requests that have not been
134answered will still appear in the file and will be read by the new 167answered will still appear in the file and will be read by the new
135instance of the helper. 168instance of the helper.
136 169
@@ -142,10 +175,9 @@ Each cache should also define a "cache_request" method which
142takes a cache item and encodes a request into the buffer 175takes a cache item and encodes a request into the buffer
143provided. 176provided.
144 177
145
146Note: If a cache has no active readers on the channel, and has had not 178Note: If a cache has no active readers on the channel, and has had not
147active readers for more than 60 seconds, further requests will not be 179active readers for more than 60 seconds, further requests will not be
148added to the channel but instead all looks that do not find a valid 180added to the channel but instead all lookups that do not find a valid
149entry will fail. This is partly for backward compatibility: The 181entry will fail. This is partly for backward compatibility: The
150previous nfs exports table was deemed to be authoritative and a 182previous nfs exports table was deemed to be authoritative and a
151failed lookup meant a definite 'no'. 183failed lookup meant a definite 'no'.
@@ -154,18 +186,17 @@ request/response format
154----------------------- 186-----------------------
155 187
156While each cache is free to use it's own format for requests 188While each cache is free to use it's own format for requests
157and responses over channel, the following is recommended are 189and responses over channel, the following is recommended as
158appropriate and support routines are available to help: 190appropriate and support routines are available to help:
159Each request or response record should be printable ASCII 191Each request or response record should be printable ASCII
160with precisely one newline character which should be at the end. 192with precisely one newline character which should be at the end.
161Fields within the record should be separated by spaces, normally one. 193Fields within the record should be separated by spaces, normally one.
162If spaces, newlines, or nul characters are needed in a field they 194If spaces, newlines, or nul characters are needed in a field they
163much be quotes. two mechanisms are available: 195much be quoted. two mechanisms are available:
1641/ If a field begins '\x' then it must contain an even number of 1961/ If a field begins '\x' then it must contain an even number of
165 hex digits, and pairs of these digits provide the bytes in the 197 hex digits, and pairs of these digits provide the bytes in the
166 field. 198 field.
1672/ otherwise a \ in the field must be followed by 3 octal digits 1992/ otherwise a \ in the field must be followed by 3 octal digits
168 which give the code for a byte. Other characters are treated 200 which give the code for a byte. Other characters are treated
169 as them selves. At the very least, space, newlines nul, and 201 as them selves. At the very least, space, newline, nul, and
170 '\' must be quoted in this way. 202 '\' must be quoted in this way.
171
diff --git a/MAINTAINERS b/MAINTAINERS
index f27846734b06..e5b051f0e27e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2233,6 +2233,12 @@ M: p_gortmaker@yahoo.com
2233L: linux-kernel@vger.kernel.org 2233L: linux-kernel@vger.kernel.org
2234S: Maintained 2234S: Maintained
2235 2235
2236REAL TIME CLOCK (RTC) SUBSYSTEM
2237P: Alessandro Zummo
2238M: a.zummo@towertech.it
2239L: linux-kernel@vger.kernel.org
2240S: Maintained
2241
2236REISERFS FILE SYSTEM 2242REISERFS FILE SYSTEM
2237P: Hans Reiser 2243P: Hans Reiser
2238M: reiserfs-dev@namesys.com 2244M: reiserfs-dev@namesys.com
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index b4e5f8ff2b25..dd8769670596 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -34,6 +34,7 @@
34#include <linux/root_dev.h> 34#include <linux/root_dev.h>
35#include <linux/initrd.h> 35#include <linux/initrd.h>
36#include <linux/eisa.h> 36#include <linux/eisa.h>
37#include <linux/pfn.h>
37#ifdef CONFIG_MAGIC_SYSRQ 38#ifdef CONFIG_MAGIC_SYSRQ
38#include <linux/sysrq.h> 39#include <linux/sysrq.h>
39#include <linux/reboot.h> 40#include <linux/reboot.h>
@@ -42,7 +43,7 @@
42#include <asm/setup.h> 43#include <asm/setup.h>
43#include <asm/io.h> 44#include <asm/io.h>
44 45
45extern struct notifier_block *panic_notifier_list; 46extern struct atomic_notifier_head panic_notifier_list;
46static int alpha_panic_event(struct notifier_block *, unsigned long, void *); 47static int alpha_panic_event(struct notifier_block *, unsigned long, void *);
47static struct notifier_block alpha_panic_block = { 48static struct notifier_block alpha_panic_block = {
48 alpha_panic_event, 49 alpha_panic_event,
@@ -241,9 +242,6 @@ reserve_std_resources(void)
241 request_resource(io, standard_io_resources+i); 242 request_resource(io, standard_io_resources+i);
242} 243}
243 244
244#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
245#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
246#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
247#define PFN_MAX PFN_DOWN(0x80000000) 245#define PFN_MAX PFN_DOWN(0x80000000)
248#define for_each_mem_cluster(memdesc, cluster, i) \ 246#define for_each_mem_cluster(memdesc, cluster, i) \
249 for ((cluster) = (memdesc)->cluster, (i) = 0; \ 247 for ((cluster) = (memdesc)->cluster, (i) = 0; \
@@ -472,11 +470,6 @@ page_is_ram(unsigned long pfn)
472 return 0; 470 return 0;
473} 471}
474 472
475#undef PFN_UP
476#undef PFN_DOWN
477#undef PFN_PHYS
478#undef PFN_MAX
479
480void __init 473void __init
481setup_arch(char **cmdline_p) 474setup_arch(char **cmdline_p)
482{ 475{
@@ -507,7 +500,8 @@ setup_arch(char **cmdline_p)
507 } 500 }
508 501
509 /* Register a call for panic conditions. */ 502 /* Register a call for panic conditions. */
510 notifier_chain_register(&panic_notifier_list, &alpha_panic_block); 503 atomic_notifier_chain_register(&panic_notifier_list,
504 &alpha_panic_block);
511 505
512#ifdef CONFIG_ALPHA_GENERIC 506#ifdef CONFIG_ALPHA_GENERIC
513 /* Assume that we've booted from SRM if we haven't booted from MILO. 507 /* Assume that we've booted from SRM if we haven't booted from MILO.
diff --git a/arch/alpha/mm/numa.c b/arch/alpha/mm/numa.c
index 6d5251254f68..bf6b65c81bef 100644
--- a/arch/alpha/mm/numa.c
+++ b/arch/alpha/mm/numa.c
@@ -13,6 +13,7 @@
13#include <linux/bootmem.h> 13#include <linux/bootmem.h>
14#include <linux/swap.h> 14#include <linux/swap.h>
15#include <linux/initrd.h> 15#include <linux/initrd.h>
16#include <linux/pfn.h>
16 17
17#include <asm/hwrpb.h> 18#include <asm/hwrpb.h>
18#include <asm/pgalloc.h> 19#include <asm/pgalloc.h>
@@ -27,9 +28,6 @@ bootmem_data_t node_bdata[MAX_NUMNODES];
27#define DBGDCONT(args...) 28#define DBGDCONT(args...)
28#endif 29#endif
29 30
30#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
31#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
32#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
33#define for_each_mem_cluster(memdesc, cluster, i) \ 31#define for_each_mem_cluster(memdesc, cluster, i) \
34 for ((cluster) = (memdesc)->cluster, (i) = 0; \ 32 for ((cluster) = (memdesc)->cluster, (i) = 0; \
35 (i) < (memdesc)->numclusters; (i)++, (cluster)++) 33 (i) < (memdesc)->numclusters; (i)++, (cluster)++)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index bf2e72698d02..9731b3f826ab 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -8,6 +8,7 @@ mainmenu "Linux Kernel Configuration"
8config ARM 8config ARM
9 bool 9 bool
10 default y 10 default y
11 select RTC_LIB
11 help 12 help
12 The ARM series is a line of low-power-consumption RISC chip designs 13 The ARM series is a line of low-power-consumption RISC chip designs
13 licensed by ARM Ltd and targeted at embedded applications and 14 licensed by ARM Ltd and targeted at embedded applications and
@@ -839,6 +840,8 @@ source "drivers/usb/Kconfig"
839 840
840source "drivers/mmc/Kconfig" 841source "drivers/mmc/Kconfig"
841 842
843source "drivers/rtc/Kconfig"
844
842endmenu 845endmenu
843 846
844source "fs/Kconfig" 847source "fs/Kconfig"
diff --git a/arch/arm/common/rtctime.c b/arch/arm/common/rtctime.c
index e851d86c212c..35c9a64ac14c 100644
--- a/arch/arm/common/rtctime.c
+++ b/arch/arm/common/rtctime.c
@@ -20,6 +20,7 @@
20#include <linux/capability.h> 20#include <linux/capability.h>
21#include <linux/device.h> 21#include <linux/device.h>
22#include <linux/mutex.h> 22#include <linux/mutex.h>
23#include <linux/rtc.h>
23 24
24#include <asm/rtc.h> 25#include <asm/rtc.h>
25#include <asm/semaphore.h> 26#include <asm/semaphore.h>
@@ -42,89 +43,6 @@ static struct rtc_ops *rtc_ops;
42 43
43#define rtc_epoch 1900UL 44#define rtc_epoch 1900UL
44 45
45static const unsigned char days_in_month[] = {
46 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
47};
48
49#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400)
50#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400))
51
52static int month_days(unsigned int month, unsigned int year)
53{
54 return days_in_month[month] + (LEAP_YEAR(year) && month == 1);
55}
56
57/*
58 * Convert seconds since 01-01-1970 00:00:00 to Gregorian date.
59 */
60void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
61{
62 int days, month, year;
63
64 days = time / 86400;
65 time -= days * 86400;
66
67 tm->tm_wday = (days + 4) % 7;
68
69 year = 1970 + days / 365;
70 days -= (year - 1970) * 365
71 + LEAPS_THRU_END_OF(year - 1)
72 - LEAPS_THRU_END_OF(1970 - 1);
73 if (days < 0) {
74 year -= 1;
75 days += 365 + LEAP_YEAR(year);
76 }
77 tm->tm_year = year - 1900;
78 tm->tm_yday = days + 1;
79
80 for (month = 0; month < 11; month++) {
81 int newdays;
82
83 newdays = days - month_days(month, year);
84 if (newdays < 0)
85 break;
86 days = newdays;
87 }
88 tm->tm_mon = month;
89 tm->tm_mday = days + 1;
90
91 tm->tm_hour = time / 3600;
92 time -= tm->tm_hour * 3600;
93 tm->tm_min = time / 60;
94 tm->tm_sec = time - tm->tm_min * 60;
95}
96EXPORT_SYMBOL(rtc_time_to_tm);
97
98/*
99 * Does the rtc_time represent a valid date/time?
100 */
101int rtc_valid_tm(struct rtc_time *tm)
102{
103 if (tm->tm_year < 70 ||
104 tm->tm_mon >= 12 ||
105 tm->tm_mday < 1 ||
106 tm->tm_mday > month_days(tm->tm_mon, tm->tm_year + 1900) ||
107 tm->tm_hour >= 24 ||
108 tm->tm_min >= 60 ||
109 tm->tm_sec >= 60)
110 return -EINVAL;
111
112 return 0;
113}
114EXPORT_SYMBOL(rtc_valid_tm);
115
116/*
117 * Convert Gregorian date to seconds since 01-01-1970 00:00:00.
118 */
119int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time)
120{
121 *time = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
122 tm->tm_hour, tm->tm_min, tm->tm_sec);
123
124 return 0;
125}
126EXPORT_SYMBOL(rtc_tm_to_time);
127
128/* 46/*
129 * Calculate the next alarm time given the requested alarm time mask 47 * Calculate the next alarm time given the requested alarm time mask
130 * and the current time. 48 * and the current time.
@@ -151,13 +69,13 @@ void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc
151 } 69 }
152} 70}
153 71
154static inline int rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm) 72static inline int rtc_arm_read_time(struct rtc_ops *ops, struct rtc_time *tm)
155{ 73{
156 memset(tm, 0, sizeof(struct rtc_time)); 74 memset(tm, 0, sizeof(struct rtc_time));
157 return ops->read_time(tm); 75 return ops->read_time(tm);
158} 76}
159 77
160static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm) 78static inline int rtc_arm_set_time(struct rtc_ops *ops, struct rtc_time *tm)
161{ 79{
162 int ret; 80 int ret;
163 81
@@ -168,7 +86,7 @@ static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm)
168 return ret; 86 return ret;
169} 87}
170 88
171static inline int rtc_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) 89static inline int rtc_arm_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
172{ 90{
173 int ret = -EINVAL; 91 int ret = -EINVAL;
174 if (ops->read_alarm) { 92 if (ops->read_alarm) {
@@ -178,7 +96,7 @@ static inline int rtc_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
178 return ret; 96 return ret;
179} 97}
180 98
181static inline int rtc_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) 99static inline int rtc_arm_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
182{ 100{
183 int ret = -EINVAL; 101 int ret = -EINVAL;
184 if (ops->set_alarm) 102 if (ops->set_alarm)
@@ -266,7 +184,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
266 184
267 switch (cmd) { 185 switch (cmd) {
268 case RTC_ALM_READ: 186 case RTC_ALM_READ:
269 ret = rtc_read_alarm(ops, &alrm); 187 ret = rtc_arm_read_alarm(ops, &alrm);
270 if (ret) 188 if (ret)
271 break; 189 break;
272 ret = copy_to_user(uarg, &alrm.time, sizeof(tm)); 190 ret = copy_to_user(uarg, &alrm.time, sizeof(tm));
@@ -288,11 +206,11 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
288 alrm.time.tm_wday = -1; 206 alrm.time.tm_wday = -1;
289 alrm.time.tm_yday = -1; 207 alrm.time.tm_yday = -1;
290 alrm.time.tm_isdst = -1; 208 alrm.time.tm_isdst = -1;
291 ret = rtc_set_alarm(ops, &alrm); 209 ret = rtc_arm_set_alarm(ops, &alrm);
292 break; 210 break;
293 211
294 case RTC_RD_TIME: 212 case RTC_RD_TIME:
295 ret = rtc_read_time(ops, &tm); 213 ret = rtc_arm_read_time(ops, &tm);
296 if (ret) 214 if (ret)
297 break; 215 break;
298 ret = copy_to_user(uarg, &tm, sizeof(tm)); 216 ret = copy_to_user(uarg, &tm, sizeof(tm));
@@ -310,7 +228,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
310 ret = -EFAULT; 228 ret = -EFAULT;
311 break; 229 break;
312 } 230 }
313 ret = rtc_set_time(ops, &tm); 231 ret = rtc_arm_set_time(ops, &tm);
314 break; 232 break;
315 233
316 case RTC_EPOCH_SET: 234 case RTC_EPOCH_SET:
@@ -341,11 +259,11 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
341 ret = -EFAULT; 259 ret = -EFAULT;
342 break; 260 break;
343 } 261 }
344 ret = rtc_set_alarm(ops, &alrm); 262 ret = rtc_arm_set_alarm(ops, &alrm);
345 break; 263 break;
346 264
347 case RTC_WKALM_RD: 265 case RTC_WKALM_RD:
348 ret = rtc_read_alarm(ops, &alrm); 266 ret = rtc_arm_read_alarm(ops, &alrm);
349 if (ret) 267 if (ret)
350 break; 268 break;
351 ret = copy_to_user(uarg, &alrm, sizeof(alrm)); 269 ret = copy_to_user(uarg, &alrm, sizeof(alrm));
@@ -435,7 +353,7 @@ static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eo
435 struct rtc_time tm; 353 struct rtc_time tm;
436 char *p = page; 354 char *p = page;
437 355
438 if (rtc_read_time(ops, &tm) == 0) { 356 if (rtc_arm_read_time(ops, &tm) == 0) {
439 p += sprintf(p, 357 p += sprintf(p,
440 "rtc_time\t: %02d:%02d:%02d\n" 358 "rtc_time\t: %02d:%02d:%02d\n"
441 "rtc_date\t: %04d-%02d-%02d\n" 359 "rtc_date\t: %04d-%02d-%02d\n"
@@ -445,7 +363,7 @@ static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eo
445 rtc_epoch); 363 rtc_epoch);
446 } 364 }
447 365
448 if (rtc_read_alarm(ops, &alrm) == 0) { 366 if (rtc_arm_read_alarm(ops, &alrm) == 0) {
449 p += sprintf(p, "alrm_time\t: "); 367 p += sprintf(p, "alrm_time\t: ");
450 if ((unsigned int)alrm.time.tm_hour <= 24) 368 if ((unsigned int)alrm.time.tm_hour <= 24)
451 p += sprintf(p, "%02d:", alrm.time.tm_hour); 369 p += sprintf(p, "%02d:", alrm.time.tm_hour);
diff --git a/arch/arm/mach-integrator/time.c b/arch/arm/mach-integrator/time.c
index 3c22c16b38bf..bc07f52a6fd7 100644
--- a/arch/arm/mach-integrator/time.c
+++ b/arch/arm/mach-integrator/time.c
@@ -40,13 +40,13 @@ static int integrator_set_rtc(void)
40 return 1; 40 return 1;
41} 41}
42 42
43static int rtc_read_alarm(struct rtc_wkalrm *alrm) 43static int integrator_rtc_read_alarm(struct rtc_wkalrm *alrm)
44{ 44{
45 rtc_time_to_tm(readl(rtc_base + RTC_MR), &alrm->time); 45 rtc_time_to_tm(readl(rtc_base + RTC_MR), &alrm->time);
46 return 0; 46 return 0;
47} 47}
48 48
49static inline int rtc_set_alarm(struct rtc_wkalrm *alrm) 49static inline int integrator_rtc_set_alarm(struct rtc_wkalrm *alrm)
50{ 50{
51 unsigned long time; 51 unsigned long time;
52 int ret; 52 int ret;
@@ -62,7 +62,7 @@ static inline int rtc_set_alarm(struct rtc_wkalrm *alrm)
62 return ret; 62 return ret;
63} 63}
64 64
65static int rtc_read_time(struct rtc_time *tm) 65static int integrator_rtc_read_time(struct rtc_time *tm)
66{ 66{
67 rtc_time_to_tm(readl(rtc_base + RTC_DR), tm); 67 rtc_time_to_tm(readl(rtc_base + RTC_DR), tm);
68 return 0; 68 return 0;
@@ -76,7 +76,7 @@ static int rtc_read_time(struct rtc_time *tm)
76 * edge of the 1Hz clock, we must write the time one second 76 * edge of the 1Hz clock, we must write the time one second
77 * in advance. 77 * in advance.
78 */ 78 */
79static inline int rtc_set_time(struct rtc_time *tm) 79static inline int integrator_rtc_set_time(struct rtc_time *tm)
80{ 80{
81 unsigned long time; 81 unsigned long time;
82 int ret; 82 int ret;
@@ -90,10 +90,10 @@ static inline int rtc_set_time(struct rtc_time *tm)
90 90
91static struct rtc_ops rtc_ops = { 91static struct rtc_ops rtc_ops = {
92 .owner = THIS_MODULE, 92 .owner = THIS_MODULE,
93 .read_time = rtc_read_time, 93 .read_time = integrator_rtc_read_time,
94 .set_time = rtc_set_time, 94 .set_time = integrator_rtc_set_time,
95 .read_alarm = rtc_read_alarm, 95 .read_alarm = integrator_rtc_read_alarm,
96 .set_alarm = rtc_set_alarm, 96 .set_alarm = integrator_rtc_set_alarm,
97}; 97};
98 98
99static irqreturn_t arm_rtc_interrupt(int irq, void *dev_id, 99static irqreturn_t arm_rtc_interrupt(int irq, void *dev_id,
diff --git a/arch/arm/mach-omap1/board-netstar.c b/arch/arm/mach-omap1/board-netstar.c
index 60d5f8a3339c..7520e602d7a2 100644
--- a/arch/arm/mach-omap1/board-netstar.c
+++ b/arch/arm/mach-omap1/board-netstar.c
@@ -141,7 +141,7 @@ static int __init netstar_late_init(void)
141 /* TODO: Setup front panel switch here */ 141 /* TODO: Setup front panel switch here */
142 142
143 /* Setup panic notifier */ 143 /* Setup panic notifier */
144 notifier_chain_register(&panic_notifier_list, &panic_block); 144 atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
145 145
146 return 0; 146 return 0;
147} 147}
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index bfd5fdd1a875..52e4a9d69642 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -235,7 +235,7 @@ static struct notifier_block panic_block = {
235static int __init voiceblue_setup(void) 235static int __init voiceblue_setup(void)
236{ 236{
237 /* Setup panic notifier */ 237 /* Setup panic notifier */
238 notifier_chain_register(&panic_notifier_list, &panic_block); 238 atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
239 239
240 return 0; 240 return 0;
241} 241}
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 9b48a90aefce..5efa84749f37 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -319,6 +319,11 @@ void __init pxa_set_ficp_info(struct pxaficp_platform_data *info)
319 pxaficp_device.dev.platform_data = info; 319 pxaficp_device.dev.platform_data = info;
320} 320}
321 321
322static struct platform_device pxartc_device = {
323 .name = "sa1100-rtc",
324 .id = -1,
325};
326
322static struct platform_device *devices[] __initdata = { 327static struct platform_device *devices[] __initdata = {
323 &pxamci_device, 328 &pxamci_device,
324 &udc_device, 329 &udc_device,
@@ -329,6 +334,7 @@ static struct platform_device *devices[] __initdata = {
329 &pxaficp_device, 334 &pxaficp_device,
330 &i2c_device, 335 &i2c_device,
331 &i2s_device, 336 &i2s_device,
337 &pxartc_device,
332}; 338};
333 339
334static int __init pxa_init(void) 340static int __init pxa_init(void)
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 2abdc419e984..9ea71551fc04 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -324,6 +324,11 @@ void sa11x0_set_irda_data(struct irda_platform_data *irda)
324 sa11x0ir_device.dev.platform_data = irda; 324 sa11x0ir_device.dev.platform_data = irda;
325} 325}
326 326
327static struct platform_device sa11x0rtc_device = {
328 .name = "sa1100-rtc",
329 .id = -1,
330};
331
327static struct platform_device *sa11x0_devices[] __initdata = { 332static struct platform_device *sa11x0_devices[] __initdata = {
328 &sa11x0udc_device, 333 &sa11x0udc_device,
329 &sa11x0uart1_device, 334 &sa11x0uart1_device,
@@ -333,6 +338,7 @@ static struct platform_device *sa11x0_devices[] __initdata = {
333 &sa11x0pcmcia_device, 338 &sa11x0pcmcia_device,
334 &sa11x0fb_device, 339 &sa11x0fb_device,
335 &sa11x0mtd_device, 340 &sa11x0mtd_device,
341 &sa11x0rtc_device,
336}; 342};
337 343
338static int __init sa1100_init(void) 344static int __init sa1100_init(void)
diff --git a/arch/arm26/mm/init.c b/arch/arm26/mm/init.c
index e3ecaa453747..7da8a5205678 100644
--- a/arch/arm26/mm/init.c
+++ b/arch/arm26/mm/init.c
@@ -23,6 +23,7 @@
23#include <linux/initrd.h> 23#include <linux/initrd.h>
24#include <linux/bootmem.h> 24#include <linux/bootmem.h>
25#include <linux/blkdev.h> 25#include <linux/blkdev.h>
26#include <linux/pfn.h>
26 27
27#include <asm/segment.h> 28#include <asm/segment.h>
28#include <asm/mach-types.h> 29#include <asm/mach-types.h>
@@ -101,12 +102,6 @@ struct node_info {
101 int bootmap_pages; 102 int bootmap_pages;
102}; 103};
103 104
104#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
105#define PFN_UP(x) (PAGE_ALIGN(x) >> PAGE_SHIFT)
106#define PFN_SIZE(x) ((x) >> PAGE_SHIFT)
107#define PFN_RANGE(s,e) PFN_SIZE(PAGE_ALIGN((unsigned long)(e)) - \
108 (((unsigned long)(s)) & PAGE_MASK))
109
110/* 105/*
111 * FIXME: We really want to avoid allocating the bootmap bitmap 106 * FIXME: We really want to avoid allocating the bootmap bitmap
112 * over the top of the initrd. Hopefully, this is located towards 107 * over the top of the initrd. Hopefully, this is located towards
diff --git a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c
index 1ba57efff60d..619a6eefd893 100644
--- a/arch/cris/kernel/setup.c
+++ b/arch/cris/kernel/setup.c
@@ -18,6 +18,7 @@
18#include <linux/seq_file.h> 18#include <linux/seq_file.h>
19#include <linux/tty.h> 19#include <linux/tty.h>
20#include <linux/utsname.h> 20#include <linux/utsname.h>
21#include <linux/pfn.h>
21 22
22#include <asm/setup.h> 23#include <asm/setup.h>
23 24
@@ -88,10 +89,6 @@ setup_arch(char **cmdline_p)
88 init_mm.end_data = (unsigned long) &_edata; 89 init_mm.end_data = (unsigned long) &_edata;
89 init_mm.brk = (unsigned long) &_end; 90 init_mm.brk = (unsigned long) &_end;
90 91
91#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
92#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
93#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
94
95 /* min_low_pfn points to the start of DRAM, start_pfn points 92 /* min_low_pfn points to the start of DRAM, start_pfn points
96 * to the first DRAM pages after the kernel, and max_low_pfn 93 * to the first DRAM pages after the kernel, and max_low_pfn
97 * to the end of DRAM. 94 * to the end of DRAM.
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index f7db71d0b913..f17bd1d2707e 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -231,6 +231,15 @@ config SCHED_SMT
231 cost of slightly increased overhead in some places. If unsure say 231 cost of slightly increased overhead in some places. If unsure say
232 N here. 232 N here.
233 233
234config SCHED_MC
235 bool "Multi-core scheduler support"
236 depends on SMP
237 default y
238 help
239 Multi-core scheduler support improves the CPU scheduler's decision
240 making when dealing with multi-core CPU chips at a cost of slightly
241 increased overhead in some places. If unsure say N here.
242
234source "kernel/Kconfig.preempt" 243source "kernel/Kconfig.preempt"
235 244
236config X86_UP_APIC 245config X86_UP_APIC
diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S
index 2ac40c8244c4..0000a2674537 100644
--- a/arch/i386/boot/video.S
+++ b/arch/i386/boot/video.S
@@ -1924,6 +1924,7 @@ skip10: movb %ah, %al
1924 ret 1924 ret
1925 1925
1926store_edid: 1926store_edid:
1927#ifdef CONFIG_FB_FIRMWARE_EDID
1927 pushw %es # just save all registers 1928 pushw %es # just save all registers
1928 pushw %ax 1929 pushw %ax
1929 pushw %bx 1930 pushw %bx
@@ -1954,6 +1955,7 @@ store_edid:
1954 popw %bx 1955 popw %bx
1955 popw %ax 1956 popw %ax
1956 popw %es 1957 popw %es
1958#endif
1957 ret 1959 ret
1958 1960
1959# VIDEO_SELECT-only variables 1961# VIDEO_SELECT-only variables
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 7e3d6b6a4e96..a06a49075f10 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -266,7 +266,7 @@ static void __init early_cpu_detect(void)
266void __cpuinit generic_identify(struct cpuinfo_x86 * c) 266void __cpuinit generic_identify(struct cpuinfo_x86 * c)
267{ 267{
268 u32 tfms, xlvl; 268 u32 tfms, xlvl;
269 int junk; 269 int ebx;
270 270
271 if (have_cpuid_p()) { 271 if (have_cpuid_p()) {
272 /* Get vendor name */ 272 /* Get vendor name */
@@ -282,7 +282,7 @@ void __cpuinit generic_identify(struct cpuinfo_x86 * c)
282 /* Intel-defined flags: level 0x00000001 */ 282 /* Intel-defined flags: level 0x00000001 */
283 if ( c->cpuid_level >= 0x00000001 ) { 283 if ( c->cpuid_level >= 0x00000001 ) {
284 u32 capability, excap; 284 u32 capability, excap;
285 cpuid(0x00000001, &tfms, &junk, &excap, &capability); 285 cpuid(0x00000001, &tfms, &ebx, &excap, &capability);
286 c->x86_capability[0] = capability; 286 c->x86_capability[0] = capability;
287 c->x86_capability[4] = excap; 287 c->x86_capability[4] = excap;
288 c->x86 = (tfms >> 8) & 15; 288 c->x86 = (tfms >> 8) & 15;
@@ -292,6 +292,11 @@ void __cpuinit generic_identify(struct cpuinfo_x86 * c)
292 if (c->x86 >= 0x6) 292 if (c->x86 >= 0x6)
293 c->x86_model += ((tfms >> 16) & 0xF) << 4; 293 c->x86_model += ((tfms >> 16) & 0xF) << 4;
294 c->x86_mask = tfms & 15; 294 c->x86_mask = tfms & 15;
295#ifdef CONFIG_SMP
296 c->apicid = phys_pkg_id((ebx >> 24) & 0xFF, 0);
297#else
298 c->apicid = (ebx >> 24) & 0xFF;
299#endif
295 } else { 300 } else {
296 /* Have CPUID level 0 only - unheard of */ 301 /* Have CPUID level 0 only - unheard of */
297 c->x86 = 4; 302 c->x86 = 4;
@@ -474,7 +479,6 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c)
474 479
475 cpuid(1, &eax, &ebx, &ecx, &edx); 480 cpuid(1, &eax, &ebx, &ecx, &edx);
476 481
477 c->apicid = phys_pkg_id((ebx >> 24) & 0xFF, 0);
478 482
479 if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY)) 483 if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY))
480 return; 484 return;
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c
index ce61921369e5..9df87b03612c 100644
--- a/arch/i386/kernel/cpu/intel_cacheinfo.c
+++ b/arch/i386/kernel/cpu/intel_cacheinfo.c
@@ -173,6 +173,10 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
173 unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */ 173 unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
174 unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ 174 unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
175 unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */ 175 unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
176 unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
177#ifdef CONFIG_SMP
178 unsigned int cpu = (c == &boot_cpu_data) ? 0 : (c - cpu_data);
179#endif
176 180
177 if (c->cpuid_level > 3) { 181 if (c->cpuid_level > 3) {
178 static int is_initialized; 182 static int is_initialized;
@@ -205,9 +209,15 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
205 break; 209 break;
206 case 2: 210 case 2:
207 new_l2 = this_leaf.size/1024; 211 new_l2 = this_leaf.size/1024;
212 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
213 index_msb = get_count_order(num_threads_sharing);
214 l2_id = c->apicid >> index_msb;
208 break; 215 break;
209 case 3: 216 case 3:
210 new_l3 = this_leaf.size/1024; 217 new_l3 = this_leaf.size/1024;
218 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
219 index_msb = get_count_order(num_threads_sharing);
220 l3_id = c->apicid >> index_msb;
211 break; 221 break;
212 default: 222 default:
213 break; 223 break;
@@ -215,11 +225,19 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
215 } 225 }
216 } 226 }
217 } 227 }
218 if (c->cpuid_level > 1) { 228 /*
229 * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for
230 * trace cache
231 */
232 if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
219 /* supports eax=2 call */ 233 /* supports eax=2 call */
220 int i, j, n; 234 int i, j, n;
221 int regs[4]; 235 int regs[4];
222 unsigned char *dp = (unsigned char *)regs; 236 unsigned char *dp = (unsigned char *)regs;
237 int only_trace = 0;
238
239 if (num_cache_leaves != 0 && c->x86 == 15)
240 only_trace = 1;
223 241
224 /* Number of times to iterate */ 242 /* Number of times to iterate */
225 n = cpuid_eax(2) & 0xFF; 243 n = cpuid_eax(2) & 0xFF;
@@ -241,6 +259,8 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
241 while (cache_table[k].descriptor != 0) 259 while (cache_table[k].descriptor != 0)
242 { 260 {
243 if (cache_table[k].descriptor == des) { 261 if (cache_table[k].descriptor == des) {
262 if (only_trace && cache_table[k].cache_type != LVL_TRACE)
263 break;
244 switch (cache_table[k].cache_type) { 264 switch (cache_table[k].cache_type) {
245 case LVL_1_INST: 265 case LVL_1_INST:
246 l1i += cache_table[k].size; 266 l1i += cache_table[k].size;
@@ -266,34 +286,45 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
266 } 286 }
267 } 287 }
268 } 288 }
289 }
269 290
270 if (new_l1d) 291 if (new_l1d)
271 l1d = new_l1d; 292 l1d = new_l1d;
272 293
273 if (new_l1i) 294 if (new_l1i)
274 l1i = new_l1i; 295 l1i = new_l1i;
275 296
276 if (new_l2) 297 if (new_l2) {
277 l2 = new_l2; 298 l2 = new_l2;
299#ifdef CONFIG_SMP
300 cpu_llc_id[cpu] = l2_id;
301#endif
302 }
278 303
279 if (new_l3) 304 if (new_l3) {
280 l3 = new_l3; 305 l3 = new_l3;
306#ifdef CONFIG_SMP
307 cpu_llc_id[cpu] = l3_id;
308#endif
309 }
281 310
282 if ( trace ) 311 if (trace)
283 printk (KERN_INFO "CPU: Trace cache: %dK uops", trace); 312 printk (KERN_INFO "CPU: Trace cache: %dK uops", trace);
284 else if ( l1i ) 313 else if ( l1i )
285 printk (KERN_INFO "CPU: L1 I cache: %dK", l1i); 314 printk (KERN_INFO "CPU: L1 I cache: %dK", l1i);
286 if ( l1d )
287 printk(", L1 D cache: %dK\n", l1d);
288 else
289 printk("\n");
290 if ( l2 )
291 printk(KERN_INFO "CPU: L2 cache: %dK\n", l2);
292 if ( l3 )
293 printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
294 315
295 c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d)); 316 if (l1d)
296 } 317 printk(", L1 D cache: %dK\n", l1d);
318 else
319 printk("\n");
320
321 if (l2)
322 printk(KERN_INFO "CPU: L2 cache: %dK\n", l2);
323
324 if (l3)
325 printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
326
327 c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
297 328
298 return l2; 329 return l2;
299} 330}
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 6917daa159ab..8c08660b4e5d 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -46,6 +46,7 @@
46#include <linux/kexec.h> 46#include <linux/kexec.h>
47#include <linux/crash_dump.h> 47#include <linux/crash_dump.h>
48#include <linux/dmi.h> 48#include <linux/dmi.h>
49#include <linux/pfn.h>
49 50
50#include <video/edid.h> 51#include <video/edid.h>
51 52
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 82371d83bfa9..a6969903f2d6 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -72,6 +72,9 @@ int phys_proc_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
72/* Core ID of each logical CPU */ 72/* Core ID of each logical CPU */
73int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID}; 73int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
74 74
75/* Last level cache ID of each logical CPU */
76int cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID};
77
75/* representing HT siblings of each logical CPU */ 78/* representing HT siblings of each logical CPU */
76cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly; 79cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
77EXPORT_SYMBOL(cpu_sibling_map); 80EXPORT_SYMBOL(cpu_sibling_map);
@@ -440,6 +443,18 @@ static void __devinit smp_callin(void)
440 443
441static int cpucount; 444static int cpucount;
442 445
446/* maps the cpu to the sched domain representing multi-core */
447cpumask_t cpu_coregroup_map(int cpu)
448{
449 struct cpuinfo_x86 *c = cpu_data + cpu;
450 /*
451 * For perf, we return last level cache shared map.
452 * TBD: when power saving sched policy is added, we will return
453 * cpu_core_map when power saving policy is enabled
454 */
455 return c->llc_shared_map;
456}
457
443/* representing cpus for which sibling maps can be computed */ 458/* representing cpus for which sibling maps can be computed */
444static cpumask_t cpu_sibling_setup_map; 459static cpumask_t cpu_sibling_setup_map;
445 460
@@ -459,12 +474,16 @@ set_cpu_sibling_map(int cpu)
459 cpu_set(cpu, cpu_sibling_map[i]); 474 cpu_set(cpu, cpu_sibling_map[i]);
460 cpu_set(i, cpu_core_map[cpu]); 475 cpu_set(i, cpu_core_map[cpu]);
461 cpu_set(cpu, cpu_core_map[i]); 476 cpu_set(cpu, cpu_core_map[i]);
477 cpu_set(i, c[cpu].llc_shared_map);
478 cpu_set(cpu, c[i].llc_shared_map);
462 } 479 }
463 } 480 }
464 } else { 481 } else {
465 cpu_set(cpu, cpu_sibling_map[cpu]); 482 cpu_set(cpu, cpu_sibling_map[cpu]);
466 } 483 }
467 484
485 cpu_set(cpu, c[cpu].llc_shared_map);
486
468 if (current_cpu_data.x86_max_cores == 1) { 487 if (current_cpu_data.x86_max_cores == 1) {
469 cpu_core_map[cpu] = cpu_sibling_map[cpu]; 488 cpu_core_map[cpu] = cpu_sibling_map[cpu];
470 c[cpu].booted_cores = 1; 489 c[cpu].booted_cores = 1;
@@ -472,6 +491,11 @@ set_cpu_sibling_map(int cpu)
472 } 491 }
473 492
474 for_each_cpu_mask(i, cpu_sibling_setup_map) { 493 for_each_cpu_mask(i, cpu_sibling_setup_map) {
494 if (cpu_llc_id[cpu] != BAD_APICID &&
495 cpu_llc_id[cpu] == cpu_llc_id[i]) {
496 cpu_set(i, c[cpu].llc_shared_map);
497 cpu_set(cpu, c[i].llc_shared_map);
498 }
475 if (phys_proc_id[cpu] == phys_proc_id[i]) { 499 if (phys_proc_id[cpu] == phys_proc_id[i]) {
476 cpu_set(i, cpu_core_map[cpu]); 500 cpu_set(i, cpu_core_map[cpu]);
477 cpu_set(cpu, cpu_core_map[i]); 501 cpu_set(cpu, cpu_core_map[i]);
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S
index ac687d00a1ce..326595f3fa4d 100644
--- a/arch/i386/kernel/syscall_table.S
+++ b/arch/i386/kernel/syscall_table.S
@@ -310,3 +310,5 @@ ENTRY(sys_call_table)
310 .long sys_pselect6 310 .long sys_pselect6
311 .long sys_ppoll 311 .long sys_ppoll
312 .long sys_unshare /* 310 */ 312 .long sys_unshare /* 310 */
313 .long sys_set_robust_list
314 .long sys_get_robust_list
diff --git a/arch/i386/kernel/timers/timer_pm.c b/arch/i386/kernel/timers/timer_pm.c
index 264edaaac315..144e94a04933 100644
--- a/arch/i386/kernel/timers/timer_pm.c
+++ b/arch/i386/kernel/timers/timer_pm.c
@@ -15,6 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/pci.h>
18#include <asm/types.h> 19#include <asm/types.h>
19#include <asm/timer.h> 20#include <asm/timer.h>
20#include <asm/smp.h> 21#include <asm/smp.h>
@@ -45,24 +46,31 @@ static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED;
45 46
46#define ACPI_PM_MASK 0xFFFFFF /* limit it to 24 bits */ 47#define ACPI_PM_MASK 0xFFFFFF /* limit it to 24 bits */
47 48
49static int pmtmr_need_workaround __read_mostly = 1;
50
48/*helper function to safely read acpi pm timesource*/ 51/*helper function to safely read acpi pm timesource*/
49static inline u32 read_pmtmr(void) 52static inline u32 read_pmtmr(void)
50{ 53{
51 u32 v1=0,v2=0,v3=0; 54 if (pmtmr_need_workaround) {
52 /* It has been reported that because of various broken 55 u32 v1, v2, v3;
53 * chipsets (ICH4, PIIX4 and PIIX4E) where the ACPI PM time 56
54 * source is not latched, so you must read it multiple 57 /* It has been reported that because of various broken
55 * times to insure a safe value is read. 58 * chipsets (ICH4, PIIX4 and PIIX4E) where the ACPI PM time
56 */ 59 * source is not latched, so you must read it multiple
57 do { 60 * times to insure a safe value is read.
58 v1 = inl(pmtmr_ioport); 61 */
59 v2 = inl(pmtmr_ioport); 62 do {
60 v3 = inl(pmtmr_ioport); 63 v1 = inl(pmtmr_ioport);
61 } while ((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1) 64 v2 = inl(pmtmr_ioport);
62 || (v3 > v1 && v3 < v2)); 65 v3 = inl(pmtmr_ioport);
63 66 } while ((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
64 /* mask the output to 24 bits */ 67 || (v3 > v1 && v3 < v2));
65 return v2 & ACPI_PM_MASK; 68
69 /* mask the output to 24 bits */
70 return v2 & ACPI_PM_MASK;
71 }
72
73 return inl(pmtmr_ioport) & ACPI_PM_MASK;
66} 74}
67 75
68 76
@@ -263,6 +271,72 @@ struct init_timer_opts __initdata timer_pmtmr_init = {
263 .opts = &timer_pmtmr, 271 .opts = &timer_pmtmr,
264}; 272};
265 273
274#ifdef CONFIG_PCI
275/*
276 * PIIX4 Errata:
277 *
278 * The power management timer may return improper results when read.
279 * Although the timer value settles properly after incrementing,
280 * while incrementing there is a 3 ns window every 69.8 ns where the
281 * timer value is indeterminate (a 4.2% chance that the data will be
282 * incorrect when read). As a result, the ACPI free running count up
283 * timer specification is violated due to erroneous reads.
284 */
285static int __init pmtmr_bug_check(void)
286{
287 static struct pci_device_id gray_list[] __initdata = {
288 /* these chipsets may have bug. */
289 { PCI_DEVICE(PCI_VENDOR_ID_INTEL,
290 PCI_DEVICE_ID_INTEL_82801DB_0) },
291 { },
292 };
293 struct pci_dev *dev;
294 int pmtmr_has_bug = 0;
295 u8 rev;
296
297 if (cur_timer != &timer_pmtmr || !pmtmr_need_workaround)
298 return 0;
299
300 dev = pci_get_device(PCI_VENDOR_ID_INTEL,
301 PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
302 if (dev) {
303 pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
304 /* the bug has been fixed in PIIX4M */
305 if (rev < 3) {
306 printk(KERN_WARNING "* Found PM-Timer Bug on this "
307 "chipset. Due to workarounds for a bug,\n"
308 "* this time source is slow. Consider trying "
309 "other time sources (clock=)\n");
310 pmtmr_has_bug = 1;
311 }
312 pci_dev_put(dev);
313 }
314
315 if (pci_dev_present(gray_list)) {
316 printk(KERN_WARNING "* This chipset may have PM-Timer Bug. Due"
317 " to workarounds for a bug,\n"
318 "* this time source is slow. If you are sure your timer"
319 " does not have\n"
320 "* this bug, please use \"pmtmr_good\" to disable the "
321 "workaround\n");
322 pmtmr_has_bug = 1;
323 }
324
325 if (!pmtmr_has_bug)
326 pmtmr_need_workaround = 0;
327
328 return 0;
329}
330device_initcall(pmtmr_bug_check);
331#endif
332
333static int __init pmtr_good_setup(char *__str)
334{
335 pmtmr_need_workaround = 0;
336 return 1;
337}
338__setup("pmtmr_good", pmtr_good_setup);
339
266MODULE_LICENSE("GPL"); 340MODULE_LICENSE("GPL");
267MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>"); 341MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
268MODULE_DESCRIPTION("Power Management Timer (PMTMR) as primary timing source for x86"); 342MODULE_DESCRIPTION("Power Management Timer (PMTMR) as primary timing source for x86");
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 4624f8ca2459..6b63a5aa1e46 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -92,22 +92,21 @@ asmlinkage void spurious_interrupt_bug(void);
92asmlinkage void machine_check(void); 92asmlinkage void machine_check(void);
93 93
94static int kstack_depth_to_print = 24; 94static int kstack_depth_to_print = 24;
95struct notifier_block *i386die_chain; 95ATOMIC_NOTIFIER_HEAD(i386die_chain);
96static DEFINE_SPINLOCK(die_notifier_lock);
97 96
98int register_die_notifier(struct notifier_block *nb) 97int register_die_notifier(struct notifier_block *nb)
99{ 98{
100 int err = 0;
101 unsigned long flags;
102
103 vmalloc_sync_all(); 99 vmalloc_sync_all();
104 spin_lock_irqsave(&die_notifier_lock, flags); 100 return atomic_notifier_chain_register(&i386die_chain, nb);
105 err = notifier_chain_register(&i386die_chain, nb);
106 spin_unlock_irqrestore(&die_notifier_lock, flags);
107 return err;
108} 101}
109EXPORT_SYMBOL(register_die_notifier); 102EXPORT_SYMBOL(register_die_notifier);
110 103
104int unregister_die_notifier(struct notifier_block *nb)
105{
106 return atomic_notifier_chain_unregister(&i386die_chain, nb);
107}
108EXPORT_SYMBOL(unregister_die_notifier);
109
111static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) 110static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
112{ 111{
113 return p > (void *)tinfo && 112 return p > (void *)tinfo &&
diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c
index c4af9638dbfa..fe6eb901326e 100644
--- a/arch/i386/mm/discontig.c
+++ b/arch/i386/mm/discontig.c
@@ -31,6 +31,7 @@
31#include <linux/nodemask.h> 31#include <linux/nodemask.h>
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/kexec.h> 33#include <linux/kexec.h>
34#include <linux/pfn.h>
34 35
35#include <asm/e820.h> 36#include <asm/e820.h>
36#include <asm/setup.h> 37#include <asm/setup.h>
@@ -352,17 +353,6 @@ void __init zone_sizes_init(void)
352{ 353{
353 int nid; 354 int nid;
354 355
355 /*
356 * Insert nodes into pgdat_list backward so they appear in order.
357 * Clobber node 0's links and NULL out pgdat_list before starting.
358 */
359 pgdat_list = NULL;
360 for (nid = MAX_NUMNODES - 1; nid >= 0; nid--) {
361 if (!node_online(nid))
362 continue;
363 NODE_DATA(nid)->pgdat_next = pgdat_list;
364 pgdat_list = NODE_DATA(nid);
365 }
366 356
367 for_each_online_node(nid) { 357 for_each_online_node(nid) {
368 unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; 358 unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c
index 9db3242103be..2889567e21a1 100644
--- a/arch/i386/mm/pgtable.c
+++ b/arch/i386/mm/pgtable.c
@@ -36,7 +36,7 @@ void show_mem(void)
36 printk(KERN_INFO "Mem-info:\n"); 36 printk(KERN_INFO "Mem-info:\n");
37 show_free_areas(); 37 show_free_areas();
38 printk(KERN_INFO "Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); 38 printk(KERN_INFO "Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
39 for_each_pgdat(pgdat) { 39 for_each_online_pgdat(pgdat) {
40 pgdat_resize_lock(pgdat, &flags); 40 pgdat_resize_lock(pgdat, &flags);
41 for (i = 0; i < pgdat->node_spanned_pages; ++i) { 41 for (i = 0; i < pgdat->node_spanned_pages; ++i) {
42 page = pgdat_page_nr(pgdat, i); 42 page = pgdat_page_nr(pgdat, i);
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index dabd6c32641e..7c1ddc8ac443 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -30,19 +30,19 @@ extern spinlock_t timerlist_lock;
30fpswa_interface_t *fpswa_interface; 30fpswa_interface_t *fpswa_interface;
31EXPORT_SYMBOL(fpswa_interface); 31EXPORT_SYMBOL(fpswa_interface);
32 32
33struct notifier_block *ia64die_chain; 33ATOMIC_NOTIFIER_HEAD(ia64die_chain);
34 34
35int 35int
36register_die_notifier(struct notifier_block *nb) 36register_die_notifier(struct notifier_block *nb)
37{ 37{
38 return notifier_chain_register(&ia64die_chain, nb); 38 return atomic_notifier_chain_register(&ia64die_chain, nb);
39} 39}
40EXPORT_SYMBOL_GPL(register_die_notifier); 40EXPORT_SYMBOL_GPL(register_die_notifier);
41 41
42int 42int
43unregister_die_notifier(struct notifier_block *nb) 43unregister_die_notifier(struct notifier_block *nb)
44{ 44{
45 return notifier_chain_unregister(&ia64die_chain, nb); 45 return atomic_notifier_chain_unregister(&ia64die_chain, nb);
46} 46}
47EXPORT_SYMBOL_GPL(unregister_die_notifier); 47EXPORT_SYMBOL_GPL(unregister_die_notifier);
48 48
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index 2f5e44862e91..ec9eeb89975d 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -379,31 +379,6 @@ static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize)
379} 379}
380 380
381/** 381/**
382 * pgdat_insert - insert the pgdat into global pgdat_list
383 * @pgdat: the pgdat for a node.
384 */
385static void __init pgdat_insert(pg_data_t *pgdat)
386{
387 pg_data_t *prev = NULL, *next;
388
389 for_each_pgdat(next)
390 if (pgdat->node_id < next->node_id)
391 break;
392 else
393 prev = next;
394
395 if (prev) {
396 prev->pgdat_next = pgdat;
397 pgdat->pgdat_next = next;
398 } else {
399 pgdat->pgdat_next = pgdat_list;
400 pgdat_list = pgdat;
401 }
402
403 return;
404}
405
406/**
407 * memory_less_nodes - allocate and initialize CPU only nodes pernode 382 * memory_less_nodes - allocate and initialize CPU only nodes pernode
408 * information. 383 * information.
409 */ 384 */
@@ -560,7 +535,7 @@ void show_mem(void)
560 printk("Mem-info:\n"); 535 printk("Mem-info:\n");
561 show_free_areas(); 536 show_free_areas();
562 printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); 537 printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
563 for_each_pgdat(pgdat) { 538 for_each_online_pgdat(pgdat) {
564 unsigned long present; 539 unsigned long present;
565 unsigned long flags; 540 unsigned long flags;
566 int shared = 0, cached = 0, reserved = 0; 541 int shared = 0, cached = 0, reserved = 0;
@@ -745,11 +720,5 @@ void __init paging_init(void)
745 pfn_offset, zholes_size); 720 pfn_offset, zholes_size);
746 } 721 }
747 722
748 /*
749 * Make memory less nodes become a member of the known nodes.
750 */
751 for_each_node_mask(node, memory_less_mask)
752 pgdat_insert(mem_data[node].pgdat);
753
754 zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page)); 723 zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page));
755} 724}
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index ff4f31fcd330..2ef1151cde90 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -600,7 +600,7 @@ mem_init (void)
600 kclist_add(&kcore_vmem, (void *)VMALLOC_START, VMALLOC_END-VMALLOC_START); 600 kclist_add(&kcore_vmem, (void *)VMALLOC_START, VMALLOC_END-VMALLOC_START);
601 kclist_add(&kcore_kernel, _stext, _end - _stext); 601 kclist_add(&kcore_kernel, _stext, _end - _stext);
602 602
603 for_each_pgdat(pgdat) 603 for_each_online_pgdat(pgdat)
604 if (pgdat->bdata->node_bootmem_map) 604 if (pgdat->bdata->node_bootmem_map)
605 totalram_pages += free_all_bootmem_node(pgdat); 605 totalram_pages += free_all_bootmem_node(pgdat);
606 606
diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c
index d742037a7ccb..0d78942b4c76 100644
--- a/arch/m32r/kernel/setup.c
+++ b/arch/m32r/kernel/setup.c
@@ -24,6 +24,7 @@
24#include <linux/tty.h> 24#include <linux/tty.h>
25#include <linux/cpu.h> 25#include <linux/cpu.h>
26#include <linux/nodemask.h> 26#include <linux/nodemask.h>
27#include <linux/pfn.h>
27 28
28#include <asm/processor.h> 29#include <asm/processor.h>
29#include <asm/pgtable.h> 30#include <asm/pgtable.h>
diff --git a/arch/m32r/mm/discontig.c b/arch/m32r/mm/discontig.c
index 08e727955555..cf610a7c5ff0 100644
--- a/arch/m32r/mm/discontig.c
+++ b/arch/m32r/mm/discontig.c
@@ -13,6 +13,7 @@
13#include <linux/initrd.h> 13#include <linux/initrd.h>
14#include <linux/nodemask.h> 14#include <linux/nodemask.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/pfn.h>
16 17
17#include <asm/setup.h> 18#include <asm/setup.h>
18 19
@@ -137,12 +138,6 @@ unsigned long __init zone_sizes_init(void)
137 int nid, i; 138 int nid, i;
138 mem_prof_t *mp; 139 mem_prof_t *mp;
139 140
140 pgdat_list = NULL;
141 for (nid = num_online_nodes() - 1 ; nid >= 0 ; nid--) {
142 NODE_DATA(nid)->pgdat_next = pgdat_list;
143 pgdat_list = NODE_DATA(nid);
144 }
145
146 for_each_online_node(nid) { 141 for_each_online_node(nid) {
147 mp = &mem_prof[nid]; 142 mp = &mem_prof[nid];
148 for (i = 0 ; i < MAX_NR_ZONES ; i++) { 143 for (i = 0 ; i < MAX_NR_ZONES ; i++) {
diff --git a/arch/m32r/mm/init.c b/arch/m32r/mm/init.c
index c9e7dad860b7..b71348fec1f4 100644
--- a/arch/m32r/mm/init.c
+++ b/arch/m32r/mm/init.c
@@ -18,6 +18,7 @@
18#include <linux/highmem.h> 18#include <linux/highmem.h>
19#include <linux/bitops.h> 19#include <linux/bitops.h>
20#include <linux/nodemask.h> 20#include <linux/nodemask.h>
21#include <linux/pfn.h>
21#include <asm/types.h> 22#include <asm/types.h>
22#include <asm/processor.h> 23#include <asm/processor.h>
23#include <asm/page.h> 24#include <asm/page.h>
@@ -47,7 +48,7 @@ void show_mem(void)
47 printk("Mem-info:\n"); 48 printk("Mem-info:\n");
48 show_free_areas(); 49 show_free_areas();
49 printk("Free swap: %6ldkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); 50 printk("Free swap: %6ldkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
50 for_each_pgdat(pgdat) { 51 for_each_online_pgdat(pgdat) {
51 unsigned long flags; 52 unsigned long flags;
52 pgdat_resize_lock(pgdat, &flags); 53 pgdat_resize_lock(pgdat, &flags);
53 for (i = 0; i < pgdat->node_spanned_pages; ++i) { 54 for (i = 0; i < pgdat->node_spanned_pages; ++i) {
diff --git a/arch/mips/ddb5xxx/common/rtc_ds1386.c b/arch/mips/ddb5xxx/common/rtc_ds1386.c
index 995896ac0e39..5dc34daa7150 100644
--- a/arch/mips/ddb5xxx/common/rtc_ds1386.c
+++ b/arch/mips/ddb5xxx/common/rtc_ds1386.c
@@ -165,6 +165,6 @@ rtc_ds1386_init(unsigned long base)
165 WRITE_RTC(0xB, byte); 165 WRITE_RTC(0xB, byte);
166 166
167 /* set the function pointers */ 167 /* set the function pointers */
168 rtc_get_time = rtc_ds1386_get_time; 168 rtc_mips_get_time = rtc_ds1386_get_time;
169 rtc_set_time = rtc_ds1386_set_time; 169 rtc_mips_set_time = rtc_ds1386_set_time;
170} 170}
diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c
index 174822344131..f17d3378e9a6 100644
--- a/arch/mips/dec/time.c
+++ b/arch/mips/dec/time.c
@@ -193,8 +193,8 @@ static void dec_ioasic_hpt_init(unsigned int count)
193 193
194void __init dec_time_init(void) 194void __init dec_time_init(void)
195{ 195{
196 rtc_get_time = dec_rtc_get_time; 196 rtc_mips_get_time = dec_rtc_get_time;
197 rtc_set_mmss = dec_rtc_set_mmss; 197 rtc_mips_set_mmss = dec_rtc_set_mmss;
198 198
199 mips_timer_state = dec_timer_state; 199 mips_timer_state = dec_timer_state;
200 mips_timer_ack = dec_timer_ack; 200 mips_timer_ack = dec_timer_ack;
diff --git a/arch/mips/ite-boards/generic/time.c b/arch/mips/ite-boards/generic/time.c
index f5d67ee21ac6..b79817bb6cce 100644
--- a/arch/mips/ite-boards/generic/time.c
+++ b/arch/mips/ite-boards/generic/time.c
@@ -227,8 +227,8 @@ void __init it8172_time_init(void)
227 227
228 local_irq_restore(flags); 228 local_irq_restore(flags);
229 229
230 rtc_get_time = it8172_rtc_get_time; 230 rtc_mips_get_time = it8172_rtc_get_time;
231 rtc_set_time = it8172_rtc_set_time; 231 rtc_mips_set_time = it8172_rtc_set_time;
232} 232}
233 233
234#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) 234#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
diff --git a/arch/mips/ite-boards/ivr/init.c b/arch/mips/ite-boards/ivr/init.c
index ea4e1935fec5..b774db035b31 100644
--- a/arch/mips/ite-boards/ivr/init.c
+++ b/arch/mips/ite-boards/ivr/init.c
@@ -45,9 +45,6 @@ extern void __init prom_init_cmdline(void);
45extern unsigned long __init prom_get_memsize(void); 45extern unsigned long __init prom_get_memsize(void);
46extern void __init it8172_init_ram_resource(unsigned long memsize); 46extern void __init it8172_init_ram_resource(unsigned long memsize);
47 47
48#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
49#define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
50
51const char *get_system_type(void) 48const char *get_system_type(void)
52{ 49{
53 return "Globespan IVR"; 50 return "Globespan IVR";
diff --git a/arch/mips/ite-boards/qed-4n-s01b/init.c b/arch/mips/ite-boards/qed-4n-s01b/init.c
index 56dca7e0c21d..e8ec8be66a80 100644
--- a/arch/mips/ite-boards/qed-4n-s01b/init.c
+++ b/arch/mips/ite-boards/qed-4n-s01b/init.c
@@ -45,9 +45,6 @@ extern void __init prom_init_cmdline(void);
45extern unsigned long __init prom_get_memsize(void); 45extern unsigned long __init prom_get_memsize(void);
46extern void __init it8172_init_ram_resource(unsigned long memsize); 46extern void __init it8172_init_ram_resource(unsigned long memsize);
47 47
48#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
49#define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
50
51const char *get_system_type(void) 48const char *get_system_type(void)
52{ 49{
53 return "ITE QED-4N-S01B"; 50 return "ITE QED-4N-S01B";
diff --git a/arch/mips/jmr3927/common/rtc_ds1742.c b/arch/mips/jmr3927/common/rtc_ds1742.c
index 9a8bff153d80..a6bd3f4d3049 100644
--- a/arch/mips/jmr3927/common/rtc_ds1742.c
+++ b/arch/mips/jmr3927/common/rtc_ds1742.c
@@ -159,8 +159,8 @@ rtc_ds1742_init(unsigned long base)
159 db_assert((rtc_base & 0xe0000000) == KSEG1); 159 db_assert((rtc_base & 0xe0000000) == KSEG1);
160 160
161 /* set the function pointers */ 161 /* set the function pointers */
162 rtc_get_time = rtc_ds1742_get_time; 162 rtc_mips_get_time = rtc_ds1742_get_time;
163 rtc_set_time = rtc_ds1742_set_time; 163 rtc_mips_set_time = rtc_ds1742_set_time;
164 164
165 /* clear oscillator stop bit */ 165 /* clear oscillator stop bit */
166 CMOS_WRITE(RTC_READ, RTC_CONTROL); 166 CMOS_WRITE(RTC_READ, RTC_CONTROL);
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 0cb3b6097e0e..dcbfd27071f0 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -34,6 +34,7 @@
34#include <linux/highmem.h> 34#include <linux/highmem.h>
35#include <linux/console.h> 35#include <linux/console.h>
36#include <linux/mmzone.h> 36#include <linux/mmzone.h>
37#include <linux/pfn.h>
37 38
38#include <asm/addrspace.h> 39#include <asm/addrspace.h>
39#include <asm/bootinfo.h> 40#include <asm/bootinfo.h>
@@ -257,10 +258,6 @@ static inline int parse_rd_cmdline(unsigned long* rd_start, unsigned long* rd_en
257 return 0; 258 return 0;
258} 259}
259 260
260#define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT)
261#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
262#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
263
264#define MAXMEM HIGHMEM_START 261#define MAXMEM HIGHMEM_START
265#define MAXMEM_PFN PFN_DOWN(MAXMEM) 262#define MAXMEM_PFN PFN_DOWN(MAXMEM)
266 263
@@ -493,10 +490,6 @@ static inline void resource_init(void)
493 } 490 }
494} 491}
495 492
496#undef PFN_UP
497#undef PFN_DOWN
498#undef PFN_PHYS
499
500#undef MAXMEM 493#undef MAXMEM
501#undef MAXMEM_PFN 494#undef MAXMEM_PFN
502 495
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index 51273b7297a7..5e51a2d8f3f0 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -65,9 +65,9 @@ static int null_rtc_set_time(unsigned long sec)
65 return 0; 65 return 0;
66} 66}
67 67
68unsigned long (*rtc_get_time)(void) = null_rtc_get_time; 68unsigned long (*rtc_mips_get_time)(void) = null_rtc_get_time;
69int (*rtc_set_time)(unsigned long) = null_rtc_set_time; 69int (*rtc_mips_set_time)(unsigned long) = null_rtc_set_time;
70int (*rtc_set_mmss)(unsigned long); 70int (*rtc_mips_set_mmss)(unsigned long);
71 71
72 72
73/* usecs per counter cycle, shifted to left by 32 bits */ 73/* usecs per counter cycle, shifted to left by 32 bits */
@@ -440,14 +440,14 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
440 440
441 /* 441 /*
442 * If we have an externally synchronized Linux clock, then update 442 * If we have an externally synchronized Linux clock, then update
443 * CMOS clock accordingly every ~11 minutes. rtc_set_time() has to be 443 * CMOS clock accordingly every ~11 minutes. rtc_mips_set_time() has to be
444 * called as close as possible to 500 ms before the new second starts. 444 * called as close as possible to 500 ms before the new second starts.
445 */ 445 */
446 if (ntp_synced() && 446 if (ntp_synced() &&
447 xtime.tv_sec > last_rtc_update + 660 && 447 xtime.tv_sec > last_rtc_update + 660 &&
448 (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && 448 (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
449 (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { 449 (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
450 if (rtc_set_mmss(xtime.tv_sec) == 0) { 450 if (rtc_mips_set_mmss(xtime.tv_sec) == 0) {
451 last_rtc_update = xtime.tv_sec; 451 last_rtc_update = xtime.tv_sec;
452 } else { 452 } else {
453 /* do it again in 60 s */ 453 /* do it again in 60 s */
@@ -565,7 +565,7 @@ asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs)
565 * b) (optional) calibrate and set the mips_hpt_frequency 565 * b) (optional) calibrate and set the mips_hpt_frequency
566 * (only needed if you intended to use fixed_rate_gettimeoffset 566 * (only needed if you intended to use fixed_rate_gettimeoffset
567 * or use cpu counter as timer interrupt source) 567 * or use cpu counter as timer interrupt source)
568 * 2) setup xtime based on rtc_get_time(). 568 * 2) setup xtime based on rtc_mips_get_time().
569 * 3) choose a appropriate gettimeoffset routine. 569 * 3) choose a appropriate gettimeoffset routine.
570 * 4) calculate a couple of cached variables for later usage 570 * 4) calculate a couple of cached variables for later usage
571 * 5) board_timer_setup() - 571 * 5) board_timer_setup() -
@@ -633,10 +633,10 @@ void __init time_init(void)
633 if (board_time_init) 633 if (board_time_init)
634 board_time_init(); 634 board_time_init();
635 635
636 if (!rtc_set_mmss) 636 if (!rtc_mips_set_mmss)
637 rtc_set_mmss = rtc_set_time; 637 rtc_mips_set_mmss = rtc_mips_set_time;
638 638
639 xtime.tv_sec = rtc_get_time(); 639 xtime.tv_sec = rtc_mips_get_time();
640 xtime.tv_nsec = 0; 640 xtime.tv_nsec = 0;
641 641
642 set_normalized_timespec(&wall_to_monotonic, 642 set_normalized_timespec(&wall_to_monotonic,
@@ -772,8 +772,8 @@ void to_tm(unsigned long tim, struct rtc_time *tm)
772 772
773EXPORT_SYMBOL(rtc_lock); 773EXPORT_SYMBOL(rtc_lock);
774EXPORT_SYMBOL(to_tm); 774EXPORT_SYMBOL(to_tm);
775EXPORT_SYMBOL(rtc_set_time); 775EXPORT_SYMBOL(rtc_mips_set_time);
776EXPORT_SYMBOL(rtc_get_time); 776EXPORT_SYMBOL(rtc_mips_get_time);
777 777
778unsigned long long sched_clock(void) 778unsigned long long sched_clock(void)
779{ 779{
diff --git a/arch/mips/lasat/setup.c b/arch/mips/lasat/setup.c
index 83eb08b7a072..bb70a8240e61 100644
--- a/arch/mips/lasat/setup.c
+++ b/arch/mips/lasat/setup.c
@@ -165,7 +165,8 @@ void __init plat_setup(void)
165 165
166 /* Set up panic notifier */ 166 /* Set up panic notifier */
167 for (i = 0; i < sizeof(lasat_panic_block) / sizeof(struct notifier_block); i++) 167 for (i = 0; i < sizeof(lasat_panic_block) / sizeof(struct notifier_block); i++)
168 notifier_chain_register(&panic_notifier_list, &lasat_panic_block[i]); 168 atomic_notifier_chain_register(&panic_notifier_list,
169 &lasat_panic_block[i]);
169 170
170 lasat_reboot_setup(); 171 lasat_reboot_setup();
171 172
@@ -174,8 +175,8 @@ void __init plat_setup(void)
174 175
175#ifdef CONFIG_DS1603 176#ifdef CONFIG_DS1603
176 ds1603 = &ds_defs[mips_machtype]; 177 ds1603 = &ds_defs[mips_machtype];
177 rtc_get_time = ds1603_read; 178 rtc_mips_get_time = ds1603_read;
178 rtc_set_time = ds1603_set; 179 rtc_mips_set_time = ds1603_set;
179#endif 180#endif
180 181
181#ifdef DYNAMIC_SERIAL_INIT 182#ifdef DYNAMIC_SERIAL_INIT
diff --git a/arch/mips/mips-boards/atlas/atlas_setup.c b/arch/mips/mips-boards/atlas/atlas_setup.c
index 873cf3141a31..c20d401ecf80 100644
--- a/arch/mips/mips-boards/atlas/atlas_setup.c
+++ b/arch/mips/mips-boards/atlas/atlas_setup.c
@@ -65,7 +65,7 @@ void __init plat_setup(void)
65 65
66 board_time_init = mips_time_init; 66 board_time_init = mips_time_init;
67 board_timer_setup = mips_timer_setup; 67 board_timer_setup = mips_timer_setup;
68 rtc_get_time = mips_rtc_get_time; 68 rtc_mips_get_time = mips_rtc_get_time;
69} 69}
70 70
71static void __init serial_init(void) 71static void __init serial_init(void)
diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c
index ee5e70c95cf3..32c9210373ac 100644
--- a/arch/mips/mips-boards/generic/memory.c
+++ b/arch/mips/mips-boards/generic/memory.c
@@ -49,9 +49,6 @@ static char *mtypes[3] = {
49/* References to section boundaries */ 49/* References to section boundaries */
50extern char _end; 50extern char _end;
51 51
52#define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
53
54
55struct prom_pmemblock * __init prom_getmdesc(void) 52struct prom_pmemblock * __init prom_getmdesc(void)
56{ 53{
57 char *memsize_str; 54 char *memsize_str;
@@ -109,10 +106,10 @@ struct prom_pmemblock * __init prom_getmdesc(void)
109 106
110 mdesc[3].type = yamon_dontuse; 107 mdesc[3].type = yamon_dontuse;
111 mdesc[3].base = 0x00100000; 108 mdesc[3].base = 0x00100000;
112 mdesc[3].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[3].base; 109 mdesc[3].size = CPHYSADDR(PAGE_ALIGN(&_end)) - mdesc[3].base;
113 110
114 mdesc[4].type = yamon_free; 111 mdesc[4].type = yamon_free;
115 mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end)); 112 mdesc[4].base = CPHYSADDR(PAGE_ALIGN(&_end));
116 mdesc[4].size = memsize - mdesc[4].base; 113 mdesc[4].size = memsize - mdesc[4].base;
117 114
118 return &mdesc[0]; 115 return &mdesc[0];
diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c
index 2209e8a9de34..b8488aab6df1 100644
--- a/arch/mips/mips-boards/malta/malta_setup.c
+++ b/arch/mips/mips-boards/malta/malta_setup.c
@@ -225,5 +225,5 @@ void __init plat_setup(void)
225 225
226 board_time_init = mips_time_init; 226 board_time_init = mips_time_init;
227 board_timer_setup = mips_timer_setup; 227 board_timer_setup = mips_timer_setup;
228 rtc_get_time = mips_rtc_get_time; 228 rtc_mips_get_time = mips_rtc_get_time;
229} 229}
diff --git a/arch/mips/mips-boards/sim/sim_mem.c b/arch/mips/mips-boards/sim/sim_mem.c
index 1ec4e75656bd..e57f737bab10 100644
--- a/arch/mips/mips-boards/sim/sim_mem.c
+++ b/arch/mips/mips-boards/sim/sim_mem.c
@@ -42,9 +42,6 @@ static char *mtypes[3] = {
42/* References to section boundaries */ 42/* References to section boundaries */
43extern char _end; 43extern char _end;
44 44
45#define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
46
47
48struct prom_pmemblock * __init prom_getmdesc(void) 45struct prom_pmemblock * __init prom_getmdesc(void)
49{ 46{
50 unsigned int memsize; 47 unsigned int memsize;
@@ -64,10 +61,10 @@ struct prom_pmemblock * __init prom_getmdesc(void)
64 61
65 mdesc[2].type = simmem_reserved; 62 mdesc[2].type = simmem_reserved;
66 mdesc[2].base = 0x00100000; 63 mdesc[2].base = 0x00100000;
67 mdesc[2].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[2].base; 64 mdesc[2].size = CPHYSADDR(PAGE_ALIGN(&_end)) - mdesc[2].base;
68 65
69 mdesc[3].type = simmem_free; 66 mdesc[3].type = simmem_free;
70 mdesc[3].base = CPHYSADDR(PFN_ALIGN(&_end)); 67 mdesc[3].base = CPHYSADDR(PAGE_ALIGN(&_end));
71 mdesc[3].size = memsize - mdesc[3].base; 68 mdesc[3].size = memsize - mdesc[3].base;
72 69
73 return &mdesc[0]; 70 return &mdesc[0];
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 52f7d59fe612..ad89c442f299 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -25,6 +25,7 @@
25#include <linux/highmem.h> 25#include <linux/highmem.h>
26#include <linux/swap.h> 26#include <linux/swap.h>
27#include <linux/proc_fs.h> 27#include <linux/proc_fs.h>
28#include <linux/pfn.h>
28 29
29#include <asm/bootinfo.h> 30#include <asm/bootinfo.h>
30#include <asm/cachectl.h> 31#include <asm/cachectl.h>
@@ -177,9 +178,6 @@ void __init paging_init(void)
177 free_area_init(zones_size); 178 free_area_init(zones_size);
178} 179}
179 180
180#define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT)
181#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
182
183static inline int page_is_ram(unsigned long pagenr) 181static inline int page_is_ram(unsigned long pagenr)
184{ 182{
185 int i; 183 int i;
diff --git a/arch/mips/momentum/jaguar_atx/setup.c b/arch/mips/momentum/jaguar_atx/setup.c
index 3784c898db1a..91d9637143d7 100644
--- a/arch/mips/momentum/jaguar_atx/setup.c
+++ b/arch/mips/momentum/jaguar_atx/setup.c
@@ -229,8 +229,8 @@ void momenco_time_init(void)
229 mips_hpt_frequency = cpu_clock / 2; 229 mips_hpt_frequency = cpu_clock / 2;
230 board_timer_setup = momenco_timer_setup; 230 board_timer_setup = momenco_timer_setup;
231 231
232 rtc_get_time = m48t37y_get_time; 232 rtc_mips_get_time = m48t37y_get_time;
233 rtc_set_time = m48t37y_set_time; 233 rtc_mips_set_time = m48t37y_set_time;
234} 234}
235 235
236static struct resource mv_pci_io_mem0_resource = { 236static struct resource mv_pci_io_mem0_resource = {
diff --git a/arch/mips/momentum/ocelot_3/setup.c b/arch/mips/momentum/ocelot_3/setup.c
index f95677f4f06f..969612eab8a6 100644
--- a/arch/mips/momentum/ocelot_3/setup.c
+++ b/arch/mips/momentum/ocelot_3/setup.c
@@ -215,8 +215,8 @@ void momenco_time_init(void)
215 mips_hpt_frequency = cpu_clock / 2; 215 mips_hpt_frequency = cpu_clock / 2;
216 board_timer_setup = momenco_timer_setup; 216 board_timer_setup = momenco_timer_setup;
217 217
218 rtc_get_time = m48t37y_get_time; 218 rtc_mips_get_time = m48t37y_get_time;
219 rtc_set_time = m48t37y_set_time; 219 rtc_mips_set_time = m48t37y_set_time;
220} 220}
221 221
222/* 222/*
diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c
index bd02e60d037a..a3e6f5575592 100644
--- a/arch/mips/momentum/ocelot_c/setup.c
+++ b/arch/mips/momentum/ocelot_c/setup.c
@@ -227,8 +227,8 @@ void momenco_time_init(void)
227 printk("momenco_time_init cpu_clock=%d\n", cpu_clock); 227 printk("momenco_time_init cpu_clock=%d\n", cpu_clock);
228 board_timer_setup = momenco_timer_setup; 228 board_timer_setup = momenco_timer_setup;
229 229
230 rtc_get_time = m48t37y_get_time; 230 rtc_mips_get_time = m48t37y_get_time;
231 rtc_set_time = m48t37y_set_time; 231 rtc_mips_set_time = m48t37y_set_time;
232} 232}
233 233
234void __init plat_setup(void) 234void __init plat_setup(void)
diff --git a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c
index 8bce711575de..3f724d661bdb 100644
--- a/arch/mips/pmc-sierra/yosemite/setup.c
+++ b/arch/mips/pmc-sierra/yosemite/setup.c
@@ -198,8 +198,8 @@ static void __init py_rtc_setup(void)
198 if (!m48t37_base) 198 if (!m48t37_base)
199 printk(KERN_ERR "Mapping the RTC failed\n"); 199 printk(KERN_ERR "Mapping the RTC failed\n");
200 200
201 rtc_get_time = m48t37y_get_time; 201 rtc_mips_get_time = m48t37y_get_time;
202 rtc_set_time = m48t37y_set_time; 202 rtc_mips_set_time = m48t37y_set_time;
203 203
204 write_seqlock(&xtime_lock); 204 write_seqlock(&xtime_lock);
205 xtime.tv_sec = m48t37y_get_time(); 205 xtime.tv_sec = m48t37y_get_time();
diff --git a/arch/mips/sgi-ip22/ip22-reset.c b/arch/mips/sgi-ip22/ip22-reset.c
index 92a3b3c15ed3..a9c58e067b53 100644
--- a/arch/mips/sgi-ip22/ip22-reset.c
+++ b/arch/mips/sgi-ip22/ip22-reset.c
@@ -238,7 +238,7 @@ static int __init reboot_setup(void)
238 request_irq(SGI_PANEL_IRQ, panel_int, 0, "Front Panel", NULL); 238 request_irq(SGI_PANEL_IRQ, panel_int, 0, "Front Panel", NULL);
239 init_timer(&blink_timer); 239 init_timer(&blink_timer);
240 blink_timer.function = blink_timeout; 240 blink_timer.function = blink_timeout;
241 notifier_chain_register(&panic_notifier_list, &panic_block); 241 atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
242 242
243 return 0; 243 return 0;
244} 244}
diff --git a/arch/mips/sgi-ip22/ip22-time.c b/arch/mips/sgi-ip22/ip22-time.c
index b7300cc5c5ad..cca688ad64ad 100644
--- a/arch/mips/sgi-ip22/ip22-time.c
+++ b/arch/mips/sgi-ip22/ip22-time.c
@@ -212,8 +212,8 @@ static void indy_timer_setup(struct irqaction *irq)
212void __init ip22_time_init(void) 212void __init ip22_time_init(void)
213{ 213{
214 /* setup hookup functions */ 214 /* setup hookup functions */
215 rtc_get_time = indy_rtc_get_time; 215 rtc_mips_get_time = indy_rtc_get_time;
216 rtc_set_time = indy_rtc_set_time; 216 rtc_mips_set_time = indy_rtc_set_time;
217 217
218 board_time_init = indy_time_init; 218 board_time_init = indy_time_init;
219 board_timer_setup = indy_timer_setup; 219 board_timer_setup = indy_timer_setup;
diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c
index e0d095daa5ed..6c00dce9f73f 100644
--- a/arch/mips/sgi-ip27/ip27-memory.c
+++ b/arch/mips/sgi-ip27/ip27-memory.c
@@ -19,6 +19,7 @@
19#include <linux/nodemask.h> 19#include <linux/nodemask.h>
20#include <linux/swap.h> 20#include <linux/swap.h>
21#include <linux/bootmem.h> 21#include <linux/bootmem.h>
22#include <linux/pfn.h>
22#include <asm/page.h> 23#include <asm/page.h>
23#include <asm/sections.h> 24#include <asm/sections.h>
24 25
@@ -28,8 +29,6 @@
28#include <asm/sn/sn_private.h> 29#include <asm/sn/sn_private.h>
29 30
30 31
31#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
32
33#define SLOT_PFNSHIFT (SLOT_SHIFT - PAGE_SHIFT) 32#define SLOT_PFNSHIFT (SLOT_SHIFT - PAGE_SHIFT)
34#define PFN_NASIDSHFT (NASID_SHFT - PAGE_SHIFT) 33#define PFN_NASIDSHFT (NASID_SHFT - PAGE_SHIFT)
35 34
diff --git a/arch/mips/sgi-ip32/ip32-reset.c b/arch/mips/sgi-ip32/ip32-reset.c
index 0c948008b023..ab9d9cef089e 100644
--- a/arch/mips/sgi-ip32/ip32-reset.c
+++ b/arch/mips/sgi-ip32/ip32-reset.c
@@ -193,7 +193,7 @@ static __init int ip32_reboot_setup(void)
193 193
194 init_timer(&blink_timer); 194 init_timer(&blink_timer);
195 blink_timer.function = blink_timeout; 195 blink_timer.function = blink_timeout;
196 notifier_chain_register(&panic_notifier_list, &panic_block); 196 atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
197 197
198 request_irq(MACEISA_RTC_IRQ, ip32_rtc_int, 0, "rtc", NULL); 198 request_irq(MACEISA_RTC_IRQ, ip32_rtc_int, 0, "rtc", NULL);
199 199
diff --git a/arch/mips/sgi-ip32/ip32-setup.c b/arch/mips/sgi-ip32/ip32-setup.c
index 2f50c79b7887..a2dd8ae1ea8f 100644
--- a/arch/mips/sgi-ip32/ip32-setup.c
+++ b/arch/mips/sgi-ip32/ip32-setup.c
@@ -91,8 +91,8 @@ void __init plat_setup(void)
91{ 91{
92 board_be_init = ip32_be_init; 92 board_be_init = ip32_be_init;
93 93
94 rtc_get_time = mc146818_get_cmos_time; 94 rtc_mips_get_time = mc146818_get_cmos_time;
95 rtc_set_mmss = mc146818_set_rtc_mmss; 95 rtc_mips_set_mmss = mc146818_set_rtc_mmss;
96 96
97 board_time_init = ip32_time_init; 97 board_time_init = ip32_time_init;
98 board_timer_setup = ip32_timer_setup; 98 board_timer_setup = ip32_timer_setup;
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c
index b661d2425a36..4b5f74ff3edd 100644
--- a/arch/mips/sibyte/swarm/setup.c
+++ b/arch/mips/sibyte/swarm/setup.c
@@ -121,14 +121,14 @@ void __init plat_setup(void)
121 121
122 if (xicor_probe()) { 122 if (xicor_probe()) {
123 printk("swarm setup: Xicor 1241 RTC detected.\n"); 123 printk("swarm setup: Xicor 1241 RTC detected.\n");
124 rtc_get_time = xicor_get_time; 124 rtc_mips_get_time = xicor_get_time;
125 rtc_set_time = xicor_set_time; 125 rtc_mips_set_time = xicor_set_time;
126 } 126 }
127 127
128 if (m41t81_probe()) { 128 if (m41t81_probe()) {
129 printk("swarm setup: M41T81 RTC detected.\n"); 129 printk("swarm setup: M41T81 RTC detected.\n");
130 rtc_get_time = m41t81_get_time; 130 rtc_mips_get_time = m41t81_get_time;
131 rtc_set_time = m41t81_set_time; 131 rtc_mips_set_time = m41t81_set_time;
132 } 132 }
133 133
134 printk("This kernel optimized for " 134 printk("This kernel optimized for "
diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c
index 1141fcd13a59..01ba6c581e3d 100644
--- a/arch/mips/sni/setup.c
+++ b/arch/mips/sni/setup.c
@@ -164,8 +164,8 @@ static struct pci_controller sni_controller = {
164 164
165static inline void sni_pcimt_time_init(void) 165static inline void sni_pcimt_time_init(void)
166{ 166{
167 rtc_get_time = mc146818_get_cmos_time; 167 rtc_mips_get_time = mc146818_get_cmos_time;
168 rtc_set_time = mc146818_set_rtc_mmss; 168 rtc_mips_set_time = mc146818_set_rtc_mmss;
169} 169}
170 170
171void __init plat_setup(void) 171void __init plat_setup(void)
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
index 2ad6401d2af4..6dcf077f61a0 100644
--- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
@@ -1036,8 +1036,8 @@ toshiba_rbtx4927_time_init(void)
1036 1036
1037#ifdef CONFIG_RTC_DS1742 1037#ifdef CONFIG_RTC_DS1742
1038 1038
1039 rtc_get_time = rtc_ds1742_get_time; 1039 rtc_mips_get_time = rtc_ds1742_get_time;
1040 rtc_set_time = rtc_ds1742_set_time; 1040 rtc_mips_set_time = rtc_ds1742_set_time;
1041 1041
1042 TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, 1042 TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT,
1043 ":rtc_ds1742_init()-\n"); 1043 ":rtc_ds1742_init()-\n");
diff --git a/arch/mips/tx4938/common/rtc_rx5c348.c b/arch/mips/tx4938/common/rtc_rx5c348.c
index d249edbb6af4..f74295f28527 100644
--- a/arch/mips/tx4938/common/rtc_rx5c348.c
+++ b/arch/mips/tx4938/common/rtc_rx5c348.c
@@ -197,6 +197,6 @@ rtc_rx5c348_init(int chipid)
197 srtc_24h = 1; 197 srtc_24h = 1;
198 198
199 /* set the function pointers */ 199 /* set the function pointers */
200 rtc_get_time = rtc_rx5c348_get_time; 200 rtc_mips_get_time = rtc_rx5c348_get_time;
201 rtc_set_time = rtc_rx5c348_set_time; 201 rtc_mips_set_time = rtc_rx5c348_set_time;
202} 202}
diff --git a/arch/parisc/kernel/pdc_chassis.c b/arch/parisc/kernel/pdc_chassis.c
index 2a01fe1bdc98..0cea6958f427 100644
--- a/arch/parisc/kernel/pdc_chassis.c
+++ b/arch/parisc/kernel/pdc_chassis.c
@@ -150,7 +150,8 @@ void __init parisc_pdc_chassis_init(void)
150 150
151 if (handle) { 151 if (handle) {
152 /* initialize panic notifier chain */ 152 /* initialize panic notifier chain */
153 notifier_chain_register(&panic_notifier_list, &pdc_chassis_panic_block); 153 atomic_notifier_chain_register(&panic_notifier_list,
154 &pdc_chassis_panic_block);
154 155
155 /* initialize reboot notifier chain */ 156 /* initialize reboot notifier chain */
156 register_reboot_notifier(&pdc_chassis_reboot_block); 157 register_reboot_notifier(&pdc_chassis_reboot_block);
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 2f3fdad35594..e20c1fae3423 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -579,7 +579,8 @@ void __init setup_arch(char **cmdline_p)
579 panic_timeout = 180; 579 panic_timeout = 180;
580 580
581 if (ppc_md.panic) 581 if (ppc_md.panic)
582 notifier_chain_register(&panic_notifier_list, &ppc64_panic_block); 582 atomic_notifier_chain_register(&panic_notifier_list,
583 &ppc64_panic_block);
583 584
584 init_mm.start_code = PAGE_OFFSET; 585 init_mm.start_code = PAGE_OFFSET;
585 init_mm.end_code = (unsigned long) _etext; 586 init_mm.end_code = (unsigned long) _etext;
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 98660aedeeb7..9763faab6739 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -74,19 +74,19 @@ EXPORT_SYMBOL(__debugger_dabr_match);
74EXPORT_SYMBOL(__debugger_fault_handler); 74EXPORT_SYMBOL(__debugger_fault_handler);
75#endif 75#endif
76 76
77struct notifier_block *powerpc_die_chain; 77ATOMIC_NOTIFIER_HEAD(powerpc_die_chain);
78static DEFINE_SPINLOCK(die_notifier_lock);
79 78
80int register_die_notifier(struct notifier_block *nb) 79int register_die_notifier(struct notifier_block *nb)
81{ 80{
82 int err = 0; 81 return atomic_notifier_chain_register(&powerpc_die_chain, nb);
83 unsigned long flags; 82}
83EXPORT_SYMBOL(register_die_notifier);
84 84
85 spin_lock_irqsave(&die_notifier_lock, flags); 85int unregister_die_notifier(struct notifier_block *nb)
86 err = notifier_chain_register(&powerpc_die_chain, nb); 86{
87 spin_unlock_irqrestore(&die_notifier_lock, flags); 87 return atomic_notifier_chain_unregister(&powerpc_die_chain, nb);
88 return err;
89} 88}
89EXPORT_SYMBOL(unregister_die_notifier);
90 90
91/* 91/*
92 * Trap & Exception support 92 * Trap & Exception support
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index badac10d700c..5e435a9c3431 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -195,7 +195,7 @@ void show_mem(void)
195 printk("Mem-info:\n"); 195 printk("Mem-info:\n");
196 show_free_areas(); 196 show_free_areas();
197 printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); 197 printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
198 for_each_pgdat(pgdat) { 198 for_each_online_pgdat(pgdat) {
199 unsigned long flags; 199 unsigned long flags;
200 pgdat_resize_lock(pgdat, &flags); 200 pgdat_resize_lock(pgdat, &flags);
201 for (i = 0; i < pgdat->node_spanned_pages; i++) { 201 for (i = 0; i < pgdat->node_spanned_pages; i++) {
@@ -351,7 +351,7 @@ void __init mem_init(void)
351 max_mapnr = max_pfn; 351 max_mapnr = max_pfn;
352 totalram_pages += free_all_bootmem(); 352 totalram_pages += free_all_bootmem();
353#endif 353#endif
354 for_each_pgdat(pgdat) { 354 for_each_online_pgdat(pgdat) {
355 for (i = 0; i < pgdat->node_spanned_pages; i++) { 355 for (i = 0; i < pgdat->node_spanned_pages; i++) {
356 if (!pfn_valid(pgdat->node_start_pfn + i)) 356 if (!pfn_valid(pgdat->node_start_pfn + i))
357 continue; 357 continue;
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 86cfa6ecdcf3..5ad90676567a 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -94,16 +94,16 @@ static struct device_node *derive_parent(const char *path)
94 return parent; 94 return parent;
95} 95}
96 96
97static struct notifier_block *pSeries_reconfig_chain; 97static BLOCKING_NOTIFIER_HEAD(pSeries_reconfig_chain);
98 98
99int pSeries_reconfig_notifier_register(struct notifier_block *nb) 99int pSeries_reconfig_notifier_register(struct notifier_block *nb)
100{ 100{
101 return notifier_chain_register(&pSeries_reconfig_chain, nb); 101 return blocking_notifier_chain_register(&pSeries_reconfig_chain, nb);
102} 102}
103 103
104void pSeries_reconfig_notifier_unregister(struct notifier_block *nb) 104void pSeries_reconfig_notifier_unregister(struct notifier_block *nb)
105{ 105{
106 notifier_chain_unregister(&pSeries_reconfig_chain, nb); 106 blocking_notifier_chain_unregister(&pSeries_reconfig_chain, nb);
107} 107}
108 108
109static int pSeries_reconfig_add_node(const char *path, struct property *proplist) 109static int pSeries_reconfig_add_node(const char *path, struct property *proplist)
@@ -131,7 +131,7 @@ static int pSeries_reconfig_add_node(const char *path, struct property *proplist
131 goto out_err; 131 goto out_err;
132 } 132 }
133 133
134 err = notifier_call_chain(&pSeries_reconfig_chain, 134 err = blocking_notifier_call_chain(&pSeries_reconfig_chain,
135 PSERIES_RECONFIG_ADD, np); 135 PSERIES_RECONFIG_ADD, np);
136 if (err == NOTIFY_BAD) { 136 if (err == NOTIFY_BAD) {
137 printk(KERN_ERR "Failed to add device node %s\n", path); 137 printk(KERN_ERR "Failed to add device node %s\n", path);
@@ -171,7 +171,7 @@ static int pSeries_reconfig_remove_node(struct device_node *np)
171 171
172 remove_node_proc_entries(np); 172 remove_node_proc_entries(np);
173 173
174 notifier_call_chain(&pSeries_reconfig_chain, 174 blocking_notifier_call_chain(&pSeries_reconfig_chain,
175 PSERIES_RECONFIG_REMOVE, np); 175 PSERIES_RECONFIG_REMOVE, np);
176 of_detach_node(np); 176 of_detach_node(np);
177 177
diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c
index a0fc628ffb1e..d95c05d9824d 100644
--- a/arch/ppc/platforms/prep_setup.c
+++ b/arch/ppc/platforms/prep_setup.c
@@ -736,7 +736,7 @@ ibm_statusled_progress(char *s, unsigned short hex)
736 hex = 0xfff; 736 hex = 0xfff;
737 if (!notifier_installed) { 737 if (!notifier_installed) {
738 ++notifier_installed; 738 ++notifier_installed;
739 notifier_chain_register(&panic_notifier_list, 739 atomic_notifier_chain_register(&panic_notifier_list,
740 &ibm_statusled_block); 740 &ibm_statusled_block);
741 } 741 }
742 } 742 }
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 99182a415fe7..4a0f5a1551ea 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -76,17 +76,17 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
76/* 76/*
77 * Need to know about CPUs going idle? 77 * Need to know about CPUs going idle?
78 */ 78 */
79static struct notifier_block *idle_chain; 79static ATOMIC_NOTIFIER_HEAD(idle_chain);
80 80
81int register_idle_notifier(struct notifier_block *nb) 81int register_idle_notifier(struct notifier_block *nb)
82{ 82{
83 return notifier_chain_register(&idle_chain, nb); 83 return atomic_notifier_chain_register(&idle_chain, nb);
84} 84}
85EXPORT_SYMBOL(register_idle_notifier); 85EXPORT_SYMBOL(register_idle_notifier);
86 86
87int unregister_idle_notifier(struct notifier_block *nb) 87int unregister_idle_notifier(struct notifier_block *nb)
88{ 88{
89 return notifier_chain_unregister(&idle_chain, nb); 89 return atomic_notifier_chain_unregister(&idle_chain, nb);
90} 90}
91EXPORT_SYMBOL(unregister_idle_notifier); 91EXPORT_SYMBOL(unregister_idle_notifier);
92 92
@@ -95,7 +95,7 @@ void do_monitor_call(struct pt_regs *regs, long interruption_code)
95 /* disable monitor call class 0 */ 95 /* disable monitor call class 0 */
96 __ctl_clear_bit(8, 15); 96 __ctl_clear_bit(8, 15);
97 97
98 notifier_call_chain(&idle_chain, CPU_NOT_IDLE, 98 atomic_notifier_call_chain(&idle_chain, CPU_NOT_IDLE,
99 (void *)(long) smp_processor_id()); 99 (void *)(long) smp_processor_id());
100} 100}
101 101
@@ -116,7 +116,8 @@ static void default_idle(void)
116 return; 116 return;
117 } 117 }
118 118
119 rc = notifier_call_chain(&idle_chain, CPU_IDLE, (void *)(long) cpu); 119 rc = atomic_notifier_call_chain(&idle_chain,
120 CPU_IDLE, (void *)(long) cpu);
120 if (rc != NOTIFY_OK && rc != NOTIFY_DONE) 121 if (rc != NOTIFY_OK && rc != NOTIFY_DONE)
121 BUG(); 122 BUG();
122 if (rc != NOTIFY_OK) { 123 if (rc != NOTIFY_OK) {
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index c0e79843f580..7ee4ca203616 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -20,6 +20,7 @@
20#include <linux/root_dev.h> 20#include <linux/root_dev.h>
21#include <linux/utsname.h> 21#include <linux/utsname.h>
22#include <linux/cpu.h> 22#include <linux/cpu.h>
23#include <linux/pfn.h>
23#include <asm/uaccess.h> 24#include <asm/uaccess.h>
24#include <asm/io.h> 25#include <asm/io.h>
25#include <asm/sections.h> 26#include <asm/sections.h>
@@ -275,10 +276,6 @@ void __init setup_arch(char **cmdline_p)
275 276
276 sh_mv_setup(cmdline_p); 277 sh_mv_setup(cmdline_p);
277 278
278#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
279#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
280#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
281
282 /* 279 /*
283 * Find the highest page frame number we have available 280 * Find the highest page frame number we have available
284 */ 281 */
diff --git a/arch/sh64/kernel/setup.c b/arch/sh64/kernel/setup.c
index c7a7b816a30f..d2711c9c9d13 100644
--- a/arch/sh64/kernel/setup.c
+++ b/arch/sh64/kernel/setup.c
@@ -48,6 +48,7 @@
48#include <linux/root_dev.h> 48#include <linux/root_dev.h>
49#include <linux/cpu.h> 49#include <linux/cpu.h>
50#include <linux/initrd.h> 50#include <linux/initrd.h>
51#include <linux/pfn.h>
51#include <asm/processor.h> 52#include <asm/processor.h>
52#include <asm/page.h> 53#include <asm/page.h>
53#include <asm/pgtable.h> 54#include <asm/pgtable.h>
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index f819a9663a8d..900fb0b940d8 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.16 3# Linux kernel version: 2.6.16
4# Mon Mar 20 01:23:21 2006 4# Sun Mar 26 14:58:11 2006
5# 5#
6CONFIG_SPARC=y 6CONFIG_SPARC=y
7CONFIG_SPARC64=y 7CONFIG_SPARC64=y
@@ -38,6 +38,7 @@ CONFIG_POSIX_MQUEUE=y
38CONFIG_SYSCTL=y 38CONFIG_SYSCTL=y
39# CONFIG_AUDIT is not set 39# CONFIG_AUDIT is not set
40# CONFIG_IKCONFIG is not set 40# CONFIG_IKCONFIG is not set
41CONFIG_RELAY=y
41CONFIG_INITRAMFS_SOURCE="" 42CONFIG_INITRAMFS_SOURCE=""
42CONFIG_UID16=y 43CONFIG_UID16=y
43CONFIG_CC_OPTIMIZE_FOR_SIZE=y 44CONFIG_CC_OPTIMIZE_FOR_SIZE=y
@@ -53,10 +54,6 @@ CONFIG_BASE_FULL=y
53CONFIG_FUTEX=y 54CONFIG_FUTEX=y
54CONFIG_EPOLL=y 55CONFIG_EPOLL=y
55CONFIG_SHMEM=y 56CONFIG_SHMEM=y
56CONFIG_CC_ALIGN_FUNCTIONS=0
57CONFIG_CC_ALIGN_LABELS=0
58CONFIG_CC_ALIGN_LOOPS=0
59CONFIG_CC_ALIGN_JUMPS=0
60CONFIG_SLAB=y 57CONFIG_SLAB=y
61# CONFIG_TINY_SHMEM is not set 58# CONFIG_TINY_SHMEM is not set
62CONFIG_BASE_SMALL=0 59CONFIG_BASE_SMALL=0
@@ -68,7 +65,6 @@ CONFIG_BASE_SMALL=0
68CONFIG_MODULES=y 65CONFIG_MODULES=y
69CONFIG_MODULE_UNLOAD=y 66CONFIG_MODULE_UNLOAD=y
70CONFIG_MODULE_FORCE_UNLOAD=y 67CONFIG_MODULE_FORCE_UNLOAD=y
71CONFIG_OBSOLETE_MODPARM=y
72CONFIG_MODVERSIONS=y 68CONFIG_MODVERSIONS=y
73CONFIG_MODULE_SRCVERSION_ALL=y 69CONFIG_MODULE_SRCVERSION_ALL=y
74CONFIG_KMOD=y 70CONFIG_KMOD=y
@@ -76,6 +72,7 @@ CONFIG_KMOD=y
76# 72#
77# Block layer 73# Block layer
78# 74#
75CONFIG_BLK_DEV_IO_TRACE=y
79 76
80# 77#
81# IO Schedulers 78# IO Schedulers
@@ -111,6 +108,8 @@ CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
111CONFIG_US3_FREQ=m 108CONFIG_US3_FREQ=m
112CONFIG_US2E_FREQ=m 109CONFIG_US2E_FREQ=m
113CONFIG_RWSEM_XCHGADD_ALGORITHM=y 110CONFIG_RWSEM_XCHGADD_ALGORITHM=y
111CONFIG_GENERIC_FIND_NEXT_BIT=y
112CONFIG_GENERIC_HWEIGHT=y
114CONFIG_GENERIC_CALIBRATE_DELAY=y 113CONFIG_GENERIC_CALIBRATE_DELAY=y
115CONFIG_HUGETLB_PAGE_SIZE_4MB=y 114CONFIG_HUGETLB_PAGE_SIZE_4MB=y
116# CONFIG_HUGETLB_PAGE_SIZE_512K is not set 115# CONFIG_HUGETLB_PAGE_SIZE_512K is not set
@@ -128,7 +127,6 @@ CONFIG_HAVE_MEMORY_PRESENT=y
128CONFIG_SPARSEMEM_EXTREME=y 127CONFIG_SPARSEMEM_EXTREME=y
129CONFIG_MEMORY_HOTPLUG=y 128CONFIG_MEMORY_HOTPLUG=y
130CONFIG_SPLIT_PTLOCK_CPUS=4 129CONFIG_SPLIT_PTLOCK_CPUS=4
131CONFIG_MIGRATION=y
132CONFIG_GENERIC_ISA_DMA=y 130CONFIG_GENERIC_ISA_DMA=y
133CONFIG_SBUS=y 131CONFIG_SBUS=y
134CONFIG_SBUSCHAR=y 132CONFIG_SBUSCHAR=y
@@ -136,7 +134,6 @@ CONFIG_SUN_AUXIO=y
136CONFIG_SUN_IO=y 134CONFIG_SUN_IO=y
137CONFIG_PCI=y 135CONFIG_PCI=y
138CONFIG_PCI_DOMAINS=y 136CONFIG_PCI_DOMAINS=y
139# CONFIG_PCI_LEGACY_PROC is not set
140# CONFIG_PCI_DEBUG is not set 137# CONFIG_PCI_DEBUG is not set
141CONFIG_SUN_OPENPROMFS=m 138CONFIG_SUN_OPENPROMFS=m
142CONFIG_SPARC32_COMPAT=y 139CONFIG_SPARC32_COMPAT=y
@@ -201,6 +198,8 @@ CONFIG_TCP_CONG_VEGAS=m
201CONFIG_TCP_CONG_SCALABLE=m 198CONFIG_TCP_CONG_SCALABLE=m
202CONFIG_IPV6=m 199CONFIG_IPV6=m
203CONFIG_IPV6_PRIVACY=y 200CONFIG_IPV6_PRIVACY=y
201CONFIG_IPV6_ROUTER_PREF=y
202CONFIG_IPV6_ROUTE_INFO=y
204CONFIG_INET6_AH=m 203CONFIG_INET6_AH=m
205CONFIG_INET6_ESP=m 204CONFIG_INET6_ESP=m
206CONFIG_INET6_IPCOMP=m 205CONFIG_INET6_IPCOMP=m
@@ -213,10 +212,12 @@ CONFIG_IPV6_TUNNEL=m
213# 212#
214CONFIG_IP_DCCP=m 213CONFIG_IP_DCCP=m
215CONFIG_INET_DCCP_DIAG=m 214CONFIG_INET_DCCP_DIAG=m
215CONFIG_IP_DCCP_ACKVEC=y
216 216
217# 217#
218# DCCP CCIDs Configuration (EXPERIMENTAL) 218# DCCP CCIDs Configuration (EXPERIMENTAL)
219# 219#
220CONFIG_IP_DCCP_CCID2=m
220CONFIG_IP_DCCP_CCID3=m 221CONFIG_IP_DCCP_CCID3=m
221CONFIG_IP_DCCP_TFRC_LIB=m 222CONFIG_IP_DCCP_TFRC_LIB=m
222 223
@@ -224,7 +225,6 @@ CONFIG_IP_DCCP_TFRC_LIB=m
224# DCCP Kernel Hacking 225# DCCP Kernel Hacking
225# 226#
226# CONFIG_IP_DCCP_DEBUG is not set 227# CONFIG_IP_DCCP_DEBUG is not set
227# CONFIG_IP_DCCP_UNLOAD_HACK is not set
228 228
229# 229#
230# SCTP Configuration (EXPERIMENTAL) 230# SCTP Configuration (EXPERIMENTAL)
@@ -309,6 +309,7 @@ CONFIG_BLK_DEV_NBD=m
309CONFIG_BLK_DEV_UB=m 309CONFIG_BLK_DEV_UB=m
310# CONFIG_BLK_DEV_RAM is not set 310# CONFIG_BLK_DEV_RAM is not set
311CONFIG_BLK_DEV_RAM_COUNT=16 311CONFIG_BLK_DEV_RAM_COUNT=16
312# CONFIG_BLK_DEV_INITRD is not set
312CONFIG_CDROM_PKTCDVD=m 313CONFIG_CDROM_PKTCDVD=m
313CONFIG_CDROM_PKTCDVD_BUFFERS=8 314CONFIG_CDROM_PKTCDVD_BUFFERS=8
314CONFIG_CDROM_PKTCDVD_WCACHE=y 315CONFIG_CDROM_PKTCDVD_WCACHE=y
@@ -722,7 +723,6 @@ CONFIG_I2C_ALGOBIT=y
722# CONFIG_I2C_PARPORT_LIGHT is not set 723# CONFIG_I2C_PARPORT_LIGHT is not set
723# CONFIG_I2C_PROSAVAGE is not set 724# CONFIG_I2C_PROSAVAGE is not set
724# CONFIG_I2C_SAVAGE4 is not set 725# CONFIG_I2C_SAVAGE4 is not set
725# CONFIG_SCx200_ACB is not set
726# CONFIG_I2C_SIS5595 is not set 726# CONFIG_I2C_SIS5595 is not set
727# CONFIG_I2C_SIS630 is not set 727# CONFIG_I2C_SIS630 is not set
728# CONFIG_I2C_SIS96X is not set 728# CONFIG_I2C_SIS96X is not set
@@ -808,10 +808,6 @@ CONFIG_HWMON=y
808# 808#
809 809
810# 810#
811# Multimedia Capabilities Port drivers
812#
813
814#
815# Multimedia devices 811# Multimedia devices
816# 812#
817# CONFIG_VIDEO_DEV is not set 813# CONFIG_VIDEO_DEV is not set
@@ -820,6 +816,7 @@ CONFIG_HWMON=y
820# Digital Video Broadcasting Devices 816# Digital Video Broadcasting Devices
821# 817#
822# CONFIG_DVB is not set 818# CONFIG_DVB is not set
819# CONFIG_USB_DABUSB is not set
823 820
824# 821#
825# Graphics support 822# Graphics support
@@ -901,10 +898,12 @@ CONFIG_SND_SEQ_DUMMY=m
901CONFIG_SND_OSSEMUL=y 898CONFIG_SND_OSSEMUL=y
902CONFIG_SND_MIXER_OSS=m 899CONFIG_SND_MIXER_OSS=m
903CONFIG_SND_PCM_OSS=m 900CONFIG_SND_PCM_OSS=m
901CONFIG_SND_PCM_OSS_PLUGINS=y
904CONFIG_SND_SEQUENCER_OSS=y 902CONFIG_SND_SEQUENCER_OSS=y
905# CONFIG_SND_RTCTIMER is not set 903# CONFIG_SND_RTCTIMER is not set
906# CONFIG_SND_DYNAMIC_MINORS is not set 904# CONFIG_SND_DYNAMIC_MINORS is not set
907CONFIG_SND_SUPPORT_OLD_API=y 905CONFIG_SND_SUPPORT_OLD_API=y
906CONFIG_SND_VERBOSE_PROCFS=y
908# CONFIG_SND_VERBOSE_PRINTK is not set 907# CONFIG_SND_VERBOSE_PRINTK is not set
909# CONFIG_SND_DEBUG is not set 908# CONFIG_SND_DEBUG is not set
910 909
@@ -987,6 +986,7 @@ CONFIG_SND_SUN_CS4231=m
987# 986#
988CONFIG_USB_ARCH_HAS_HCD=y 987CONFIG_USB_ARCH_HAS_HCD=y
989CONFIG_USB_ARCH_HAS_OHCI=y 988CONFIG_USB_ARCH_HAS_OHCI=y
989CONFIG_USB_ARCH_HAS_EHCI=y
990CONFIG_USB=y 990CONFIG_USB=y
991# CONFIG_USB_DEBUG is not set 991# CONFIG_USB_DEBUG is not set
992 992
@@ -1014,7 +1014,6 @@ CONFIG_USB_UHCI_HCD=m
1014# 1014#
1015# USB Device Class drivers 1015# USB Device Class drivers
1016# 1016#
1017# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
1018# CONFIG_USB_ACM is not set 1017# CONFIG_USB_ACM is not set
1019# CONFIG_USB_PRINTER is not set 1018# CONFIG_USB_PRINTER is not set
1020 1019
@@ -1058,15 +1057,6 @@ CONFIG_USB_HIDDEV=y
1058# CONFIG_USB_MICROTEK is not set 1057# CONFIG_USB_MICROTEK is not set
1059 1058
1060# 1059#
1061# USB Multimedia devices
1062#
1063# CONFIG_USB_DABUSB is not set
1064
1065#
1066# Video4Linux support is needed for USB Multimedia device support
1067#
1068
1069#
1070# USB Network Adapters 1060# USB Network Adapters
1071# 1061#
1072# CONFIG_USB_CATC is not set 1062# CONFIG_USB_CATC is not set
@@ -1194,7 +1184,6 @@ CONFIG_TMPFS=y
1194CONFIG_HUGETLBFS=y 1184CONFIG_HUGETLBFS=y
1195CONFIG_HUGETLB_PAGE=y 1185CONFIG_HUGETLB_PAGE=y
1196CONFIG_RAMFS=y 1186CONFIG_RAMFS=y
1197CONFIG_RELAYFS_FS=m
1198# CONFIG_CONFIGFS_FS is not set 1187# CONFIG_CONFIGFS_FS is not set
1199 1188
1200# 1189#
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index c7fbbcfce824..f5e8db1de76b 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -274,18 +274,9 @@ EXPORT_SYMBOL(__prom_getsibling);
274 274
275/* sparc library symbols */ 275/* sparc library symbols */
276EXPORT_SYMBOL(strlen); 276EXPORT_SYMBOL(strlen);
277EXPORT_SYMBOL(strnlen);
278EXPORT_SYMBOL(__strlen_user); 277EXPORT_SYMBOL(__strlen_user);
279EXPORT_SYMBOL(__strnlen_user); 278EXPORT_SYMBOL(__strnlen_user);
280EXPORT_SYMBOL(strcpy);
281EXPORT_SYMBOL(strncpy);
282EXPORT_SYMBOL(strcat);
283EXPORT_SYMBOL(strncat);
284EXPORT_SYMBOL(strcmp);
285EXPORT_SYMBOL(strchr);
286EXPORT_SYMBOL(strrchr);
287EXPORT_SYMBOL(strpbrk); 279EXPORT_SYMBOL(strpbrk);
288EXPORT_SYMBOL(strstr);
289 280
290#ifdef CONFIG_SOLARIS_EMUL_MODULE 281#ifdef CONFIG_SOLARIS_EMUL_MODULE
291EXPORT_SYMBOL(linux_sparc_syscall); 282EXPORT_SYMBOL(linux_sparc_syscall);
@@ -319,7 +310,6 @@ EXPORT_SYMBOL(__memscan_zero);
319EXPORT_SYMBOL(__memscan_generic); 310EXPORT_SYMBOL(__memscan_generic);
320EXPORT_SYMBOL(__memcmp); 311EXPORT_SYMBOL(__memcmp);
321EXPORT_SYMBOL(__memset); 312EXPORT_SYMBOL(__memset);
322EXPORT_SYMBOL(memchr);
323 313
324EXPORT_SYMBOL(csum_partial); 314EXPORT_SYMBOL(csum_partial);
325EXPORT_SYMBOL(csum_partial_copy_nocheck); 315EXPORT_SYMBOL(csum_partial_copy_nocheck);
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index df612e4f75f9..ff090bb9734b 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -43,18 +43,19 @@
43#include <linux/kmod.h> 43#include <linux/kmod.h>
44#endif 44#endif
45 45
46struct notifier_block *sparc64die_chain; 46ATOMIC_NOTIFIER_HEAD(sparc64die_chain);
47static DEFINE_SPINLOCK(die_notifier_lock);
48 47
49int register_die_notifier(struct notifier_block *nb) 48int register_die_notifier(struct notifier_block *nb)
50{ 49{
51 int err = 0; 50 return atomic_notifier_chain_register(&sparc64die_chain, nb);
52 unsigned long flags;
53 spin_lock_irqsave(&die_notifier_lock, flags);
54 err = notifier_chain_register(&sparc64die_chain, nb);
55 spin_unlock_irqrestore(&die_notifier_lock, flags);
56 return err;
57} 51}
52EXPORT_SYMBOL(register_die_notifier);
53
54int unregister_die_notifier(struct notifier_block *nb)
55{
56 return atomic_notifier_chain_unregister(&sparc64die_chain, nb);
57}
58EXPORT_SYMBOL(unregister_die_notifier);
58 59
59/* When an irrecoverable trap occurs at tl > 0, the trap entry 60/* When an irrecoverable trap occurs at tl > 0, the trap entry
60 * code logs the trap state registers at every level in the trap 61 * code logs the trap state registers at every level in the trap
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 54388d10bcf9..1488816588ea 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -762,7 +762,8 @@ static struct notifier_block panic_exit_notifier = {
762 762
763static int add_notifier(void) 763static int add_notifier(void)
764{ 764{
765 notifier_chain_register(&panic_notifier_list, &panic_exit_notifier); 765 atomic_notifier_chain_register(&panic_notifier_list,
766 &panic_exit_notifier);
766 return(0); 767 return(0);
767} 768}
768 769
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index fa617e0719ab..0336575d2448 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -71,7 +71,7 @@ struct io_thread_req {
71 int error; 71 int error;
72}; 72};
73 73
74extern int open_ubd_file(char *file, struct openflags *openflags, 74extern int open_ubd_file(char *file, struct openflags *openflags, int shared,
75 char **backing_file_out, int *bitmap_offset_out, 75 char **backing_file_out, int *bitmap_offset_out,
76 unsigned long *bitmap_len_out, int *data_offset_out, 76 unsigned long *bitmap_len_out, int *data_offset_out,
77 int *create_cow_out); 77 int *create_cow_out);
@@ -137,7 +137,7 @@ static int fake_major = MAJOR_NR;
137 137
138static struct gendisk *ubd_gendisk[MAX_DEV]; 138static struct gendisk *ubd_gendisk[MAX_DEV];
139static struct gendisk *fake_gendisk[MAX_DEV]; 139static struct gendisk *fake_gendisk[MAX_DEV];
140 140
141#ifdef CONFIG_BLK_DEV_UBD_SYNC 141#ifdef CONFIG_BLK_DEV_UBD_SYNC
142#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \ 142#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \
143 .cl = 1 }) 143 .cl = 1 })
@@ -168,6 +168,7 @@ struct ubd {
168 __u64 size; 168 __u64 size;
169 struct openflags boot_openflags; 169 struct openflags boot_openflags;
170 struct openflags openflags; 170 struct openflags openflags;
171 int shared;
171 int no_cow; 172 int no_cow;
172 struct cow cow; 173 struct cow cow;
173 struct platform_device pdev; 174 struct platform_device pdev;
@@ -189,6 +190,7 @@ struct ubd {
189 .boot_openflags = OPEN_FLAGS, \ 190 .boot_openflags = OPEN_FLAGS, \
190 .openflags = OPEN_FLAGS, \ 191 .openflags = OPEN_FLAGS, \
191 .no_cow = 0, \ 192 .no_cow = 0, \
193 .shared = 0, \
192 .cow = DEFAULT_COW, \ 194 .cow = DEFAULT_COW, \
193} 195}
194 196
@@ -305,7 +307,7 @@ static int ubd_setup_common(char *str, int *index_out)
305 } 307 }
306 major = simple_strtoul(str, &end, 0); 308 major = simple_strtoul(str, &end, 0);
307 if((*end != '\0') || (end == str)){ 309 if((*end != '\0') || (end == str)){
308 printk(KERN_ERR 310 printk(KERN_ERR
309 "ubd_setup : didn't parse major number\n"); 311 "ubd_setup : didn't parse major number\n");
310 return(1); 312 return(1);
311 } 313 }
@@ -316,7 +318,7 @@ static int ubd_setup_common(char *str, int *index_out)
316 printk(KERN_ERR "Can't assign a fake major twice\n"); 318 printk(KERN_ERR "Can't assign a fake major twice\n");
317 goto out1; 319 goto out1;
318 } 320 }
319 321
320 fake_major = major; 322 fake_major = major;
321 323
322 printk(KERN_INFO "Setting extra ubd major number to %d\n", 324 printk(KERN_INFO "Setting extra ubd major number to %d\n",
@@ -351,7 +353,7 @@ static int ubd_setup_common(char *str, int *index_out)
351 if (index_out) 353 if (index_out)
352 *index_out = n; 354 *index_out = n;
353 355
354 for (i = 0; i < 4; i++) { 356 for (i = 0; i < sizeof("rscd="); i++) {
355 switch (*str) { 357 switch (*str) {
356 case 'r': 358 case 'r':
357 flags.w = 0; 359 flags.w = 0;
@@ -362,11 +364,14 @@ static int ubd_setup_common(char *str, int *index_out)
362 case 'd': 364 case 'd':
363 dev->no_cow = 1; 365 dev->no_cow = 1;
364 break; 366 break;
367 case 'c':
368 dev->shared = 1;
369 break;
365 case '=': 370 case '=':
366 str++; 371 str++;
367 goto break_loop; 372 goto break_loop;
368 default: 373 default:
369 printk(KERN_ERR "ubd_setup : Expected '=' or flag letter (r,s or d)\n"); 374 printk(KERN_ERR "ubd_setup : Expected '=' or flag letter (r, s, c, or d)\n");
370 goto out; 375 goto out;
371 } 376 }
372 str++; 377 str++;
@@ -515,7 +520,7 @@ static void ubd_handler(void)
515 spin_unlock(&ubd_io_lock); 520 spin_unlock(&ubd_io_lock);
516 return; 521 return;
517 } 522 }
518 523
519 ubd_finish(rq, req.error); 524 ubd_finish(rq, req.error);
520 reactivate_fd(thread_fd, UBD_IRQ); 525 reactivate_fd(thread_fd, UBD_IRQ);
521 do_ubd_request(ubd_queue); 526 do_ubd_request(ubd_queue);
@@ -532,7 +537,7 @@ static int io_pid = -1;
532 537
533void kill_io_thread(void) 538void kill_io_thread(void)
534{ 539{
535 if(io_pid != -1) 540 if(io_pid != -1)
536 os_kill_process(io_pid, 1); 541 os_kill_process(io_pid, 1);
537} 542}
538 543
@@ -567,14 +572,15 @@ static int ubd_open_dev(struct ubd *dev)
567 create_cow = 0; 572 create_cow = 0;
568 create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL; 573 create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
569 back_ptr = dev->no_cow ? NULL : &dev->cow.file; 574 back_ptr = dev->no_cow ? NULL : &dev->cow.file;
570 dev->fd = open_ubd_file(dev->file, &dev->openflags, back_ptr, 575 dev->fd = open_ubd_file(dev->file, &dev->openflags, dev->shared,
571 &dev->cow.bitmap_offset, &dev->cow.bitmap_len, 576 back_ptr, &dev->cow.bitmap_offset,
572 &dev->cow.data_offset, create_ptr); 577 &dev->cow.bitmap_len, &dev->cow.data_offset,
578 create_ptr);
573 579
574 if((dev->fd == -ENOENT) && create_cow){ 580 if((dev->fd == -ENOENT) && create_cow){
575 dev->fd = create_cow_file(dev->file, dev->cow.file, 581 dev->fd = create_cow_file(dev->file, dev->cow.file,
576 dev->openflags, 1 << 9, PAGE_SIZE, 582 dev->openflags, 1 << 9, PAGE_SIZE,
577 &dev->cow.bitmap_offset, 583 &dev->cow.bitmap_offset,
578 &dev->cow.bitmap_len, 584 &dev->cow.bitmap_len,
579 &dev->cow.data_offset); 585 &dev->cow.data_offset);
580 if(dev->fd >= 0){ 586 if(dev->fd >= 0){
@@ -598,16 +604,16 @@ static int ubd_open_dev(struct ubd *dev)
598 } 604 }
599 flush_tlb_kernel_vm(); 605 flush_tlb_kernel_vm();
600 606
601 err = read_cow_bitmap(dev->fd, dev->cow.bitmap, 607 err = read_cow_bitmap(dev->fd, dev->cow.bitmap,
602 dev->cow.bitmap_offset, 608 dev->cow.bitmap_offset,
603 dev->cow.bitmap_len); 609 dev->cow.bitmap_len);
604 if(err < 0) 610 if(err < 0)
605 goto error; 611 goto error;
606 612
607 flags = dev->openflags; 613 flags = dev->openflags;
608 flags.w = 0; 614 flags.w = 0;
609 err = open_ubd_file(dev->cow.file, &flags, NULL, NULL, NULL, 615 err = open_ubd_file(dev->cow.file, &flags, dev->shared, NULL,
610 NULL, NULL); 616 NULL, NULL, NULL, NULL);
611 if(err < 0) goto error; 617 if(err < 0) goto error;
612 dev->cow.fd = err; 618 dev->cow.fd = err;
613 } 619 }
@@ -685,11 +691,11 @@ static int ubd_add(int n)
685 dev->size = ROUND_BLOCK(dev->size); 691 dev->size = ROUND_BLOCK(dev->size);
686 692
687 err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]); 693 err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]);
688 if(err) 694 if(err)
689 goto out_close; 695 goto out_close;
690 696
691 if(fake_major != MAJOR_NR) 697 if(fake_major != MAJOR_NR)
692 ubd_new_disk(fake_major, dev->size, n, 698 ubd_new_disk(fake_major, dev->size, n,
693 &fake_gendisk[n]); 699 &fake_gendisk[n]);
694 700
695 /* perhaps this should also be under the "if (fake_major)" above */ 701 /* perhaps this should also be under the "if (fake_major)" above */
@@ -854,7 +860,7 @@ int ubd_init(void)
854 return -1; 860 return -1;
855 } 861 }
856 platform_driver_register(&ubd_driver); 862 platform_driver_register(&ubd_driver);
857 for (i = 0; i < MAX_DEV; i++) 863 for (i = 0; i < MAX_DEV; i++)
858 ubd_add(i); 864 ubd_add(i);
859 return 0; 865 return 0;
860} 866}
@@ -872,16 +878,16 @@ int ubd_driver_init(void){
872 * enough. So use anyway the io thread. */ 878 * enough. So use anyway the io thread. */
873 } 879 }
874 stack = alloc_stack(0, 0); 880 stack = alloc_stack(0, 0);
875 io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *), 881 io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
876 &thread_fd); 882 &thread_fd);
877 if(io_pid < 0){ 883 if(io_pid < 0){
878 printk(KERN_ERR 884 printk(KERN_ERR
879 "ubd : Failed to start I/O thread (errno = %d) - " 885 "ubd : Failed to start I/O thread (errno = %d) - "
880 "falling back to synchronous I/O\n", -io_pid); 886 "falling back to synchronous I/O\n", -io_pid);
881 io_pid = -1; 887 io_pid = -1;
882 return(0); 888 return(0);
883 } 889 }
884 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, 890 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
885 SA_INTERRUPT, "ubd", ubd_dev); 891 SA_INTERRUPT, "ubd", ubd_dev);
886 if(err != 0) 892 if(err != 0)
887 printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err); 893 printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
@@ -978,7 +984,7 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
978 if(req->op == UBD_READ) { 984 if(req->op == UBD_READ) {
979 for(i = 0; i < req->length >> 9; i++){ 985 for(i = 0; i < req->length >> 9; i++){
980 if(ubd_test_bit(sector + i, (unsigned char *) bitmap)) 986 if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
981 ubd_set_bit(i, (unsigned char *) 987 ubd_set_bit(i, (unsigned char *)
982 &req->sector_mask); 988 &req->sector_mask);
983 } 989 }
984 } 990 }
@@ -999,7 +1005,7 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
999 1005
1000 /* This should be impossible now */ 1006 /* This should be impossible now */
1001 if((rq_data_dir(req) == WRITE) && !dev->openflags.w){ 1007 if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
1002 printk("Write attempted on readonly ubd device %s\n", 1008 printk("Write attempted on readonly ubd device %s\n",
1003 disk->disk_name); 1009 disk->disk_name);
1004 end_request(req, 0); 1010 end_request(req, 0);
1005 return(1); 1011 return(1);
@@ -1182,7 +1188,7 @@ int read_cow_bitmap(int fd, void *buf, int offset, int len)
1182 return(0); 1188 return(0);
1183} 1189}
1184 1190
1185int open_ubd_file(char *file, struct openflags *openflags, 1191int open_ubd_file(char *file, struct openflags *openflags, int shared,
1186 char **backing_file_out, int *bitmap_offset_out, 1192 char **backing_file_out, int *bitmap_offset_out,
1187 unsigned long *bitmap_len_out, int *data_offset_out, 1193 unsigned long *bitmap_len_out, int *data_offset_out,
1188 int *create_cow_out) 1194 int *create_cow_out)
@@ -1206,10 +1212,14 @@ int open_ubd_file(char *file, struct openflags *openflags,
1206 return fd; 1212 return fd;
1207 } 1213 }
1208 1214
1209 err = os_lock_file(fd, openflags->w); 1215 if(shared)
1210 if(err < 0){ 1216 printk("Not locking \"%s\" on the host\n", file);
1211 printk("Failed to lock '%s', err = %d\n", file, -err); 1217 else {
1212 goto out_close; 1218 err = os_lock_file(fd, openflags->w);
1219 if(err < 0){
1220 printk("Failed to lock '%s', err = %d\n", file, -err);
1221 goto out_close;
1222 }
1213 } 1223 }
1214 1224
1215 /* Succesful return case! */ 1225 /* Succesful return case! */
@@ -1260,7 +1270,7 @@ int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
1260 int err, fd; 1270 int err, fd;
1261 1271
1262 flags.c = 1; 1272 flags.c = 1;
1263 fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL); 1273 fd = open_ubd_file(cow_file, &flags, 0, NULL, NULL, NULL, NULL, NULL);
1264 if(fd < 0){ 1274 if(fd < 0){
1265 err = fd; 1275 err = fd;
1266 printk("Open of COW file '%s' failed, errno = %d\n", cow_file, 1276 printk("Open of COW file '%s' failed, errno = %d\n", cow_file,
diff --git a/arch/um/include/irq_user.h b/arch/um/include/irq_user.h
index b61deb8b362a..69a93c804f0e 100644
--- a/arch/um/include/irq_user.h
+++ b/arch/um/include/irq_user.h
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -6,6 +6,17 @@
6#ifndef __IRQ_USER_H__ 6#ifndef __IRQ_USER_H__
7#define __IRQ_USER_H__ 7#define __IRQ_USER_H__
8 8
9struct irq_fd {
10 struct irq_fd *next;
11 void *id;
12 int fd;
13 int type;
14 int irq;
15 int pid;
16 int events;
17 int current_events;
18};
19
9enum { IRQ_READ, IRQ_WRITE }; 20enum { IRQ_READ, IRQ_WRITE };
10 21
11extern void sigio_handler(int sig, union uml_pt_regs *regs); 22extern void sigio_handler(int sig, union uml_pt_regs *regs);
@@ -16,8 +27,6 @@ extern void reactivate_fd(int fd, int irqnum);
16extern void deactivate_fd(int fd, int irqnum); 27extern void deactivate_fd(int fd, int irqnum);
17extern int deactivate_all_fds(void); 28extern int deactivate_all_fds(void);
18extern void forward_interrupts(int pid); 29extern void forward_interrupts(int pid);
19extern void init_irq_signals(int on_sigstack);
20extern void forward_ipi(int fd, int pid);
21extern int activate_ipi(int fd, int pid); 30extern int activate_ipi(int fd, int pid);
22extern unsigned long irq_lock(void); 31extern unsigned long irq_lock(void);
23extern void irq_unlock(unsigned long flags); 32extern void irq_unlock(unsigned long flags);
diff --git a/arch/um/include/kern.h b/arch/um/include/kern.h
index 7d223beccbc0..4ce3fc650e57 100644
--- a/arch/um/include/kern.h
+++ b/arch/um/include/kern.h
@@ -29,7 +29,7 @@ extern int getuid(void);
29extern int getgid(void); 29extern int getgid(void);
30extern int pause(void); 30extern int pause(void);
31extern int write(int, const void *, int); 31extern int write(int, const void *, int);
32extern int exit(int); 32extern void exit(int);
33extern int close(int); 33extern int close(int);
34extern int read(unsigned int, char *, int); 34extern int read(unsigned int, char *, int);
35extern int pipe(int *); 35extern int pipe(int *);
diff --git a/arch/um/include/misc_constants.h b/arch/um/include/misc_constants.h
new file mode 100644
index 000000000000..989bc08de36e
--- /dev/null
+++ b/arch/um/include/misc_constants.h
@@ -0,0 +1,6 @@
1#ifndef __MISC_CONSTANT_H_
2#define __MISC_CONSTANT_H_
3
4#include <user_constants.h>
5
6#endif
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 2a1c64d8d0bf..d3d1bc6074ef 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -12,6 +12,7 @@
12#include "sysdep/ptrace.h" 12#include "sysdep/ptrace.h"
13#include "kern_util.h" 13#include "kern_util.h"
14#include "skas/mm_id.h" 14#include "skas/mm_id.h"
15#include "irq_user.h"
15 16
16#define OS_TYPE_FILE 1 17#define OS_TYPE_FILE 1
17#define OS_TYPE_DIR 2 18#define OS_TYPE_DIR 2
@@ -121,6 +122,7 @@ static inline struct openflags of_cloexec(struct openflags flags)
121 return(flags); 122 return(flags);
122} 123}
123 124
125/* file.c */
124extern int os_stat_file(const char *file_name, struct uml_stat *buf); 126extern int os_stat_file(const char *file_name, struct uml_stat *buf);
125extern int os_stat_fd(const int fd, struct uml_stat *buf); 127extern int os_stat_fd(const int fd, struct uml_stat *buf);
126extern int os_access(const char *file, int mode); 128extern int os_access(const char *file, int mode);
@@ -156,10 +158,20 @@ extern int os_connect_socket(char *name);
156extern int os_file_type(char *file); 158extern int os_file_type(char *file);
157extern int os_file_mode(char *file, struct openflags *mode_out); 159extern int os_file_mode(char *file, struct openflags *mode_out);
158extern int os_lock_file(int fd, int excl); 160extern int os_lock_file(int fd, int excl);
161extern void os_flush_stdout(void);
162extern int os_stat_filesystem(char *path, long *bsize_out,
163 long long *blocks_out, long long *bfree_out,
164 long long *bavail_out, long long *files_out,
165 long long *ffree_out, void *fsid_out,
166 int fsid_size, long *namelen_out,
167 long *spare_out);
168extern int os_change_dir(char *dir);
169extern int os_fchange_dir(int fd);
159 170
160/* start_up.c */ 171/* start_up.c */
161extern void os_early_checks(void); 172extern void os_early_checks(void);
162extern int can_do_skas(void); 173extern int can_do_skas(void);
174extern void os_check_bugs(void);
163 175
164/* Make sure they are clear when running in TT mode. Required by 176/* Make sure they are clear when running in TT mode. Required by
165 * SEGV_MAYBE_FIXABLE */ 177 * SEGV_MAYBE_FIXABLE */
@@ -198,6 +210,8 @@ extern void os_flush_stdout(void);
198/* tt.c 210/* tt.c
199 * for tt mode only (will be deleted in future...) 211 * for tt mode only (will be deleted in future...)
200 */ 212 */
213extern void forward_ipi(int fd, int pid);
214extern void kill_child_dead(int pid);
201extern void stop(void); 215extern void stop(void);
202extern int wait_for_stop(int pid, int sig, int cont_type, void *relay); 216extern int wait_for_stop(int pid, int sig, int cont_type, void *relay);
203extern int protect_memory(unsigned long addr, unsigned long len, 217extern int protect_memory(unsigned long addr, unsigned long len,
@@ -294,4 +308,26 @@ extern void initial_thread_cb_skas(void (*proc)(void *),
294extern void halt_skas(void); 308extern void halt_skas(void);
295extern void reboot_skas(void); 309extern void reboot_skas(void);
296 310
311/* irq.c */
312extern int os_waiting_for_events(struct irq_fd *active_fds);
313extern int os_isatty(int fd);
314extern int os_create_pollfd(int fd, int events, void *tmp_pfd, int size_tmpfds);
315extern void os_free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg,
316 struct irq_fd *active_fds, struct irq_fd ***last_irq_ptr2);
317extern void os_free_irq_later(struct irq_fd *active_fds,
318 int irq, void *dev_id);
319extern int os_get_pollfd(int i);
320extern void os_set_pollfd(int i, int fd);
321extern void os_set_ioignore(void);
322extern void init_irq_signals(int on_sigstack);
323
324/* sigio.c */
325extern void write_sigio_workaround(void);
326extern int add_sigio_fd(int fd, int read);
327extern int ignore_sigio_fd(int fd);
328
329/* skas/trap */
330extern void sig_handler_common_skas(int sig, void *sc_ptr);
331extern void user_signal(int sig, union uml_pt_regs *regs, int pid);
332
297#endif 333#endif
diff --git a/arch/um/include/sigio.h b/arch/um/include/sigio.h
index 37d76e29a147..fe99ea163c2e 100644
--- a/arch/um/include/sigio.h
+++ b/arch/um/include/sigio.h
@@ -8,9 +8,6 @@
8 8
9extern int write_sigio_irq(int fd); 9extern int write_sigio_irq(int fd);
10extern int register_sigio_fd(int fd); 10extern int register_sigio_fd(int fd);
11extern int read_sigio_fd(int fd);
12extern int add_sigio_fd(int fd, int read);
13extern int ignore_sigio_fd(int fd);
14extern void sigio_lock(void); 11extern void sigio_lock(void);
15extern void sigio_unlock(void); 12extern void sigio_unlock(void);
16 13
diff --git a/arch/um/include/skas/mode-skas.h b/arch/um/include/skas/mode-skas.h
index 260065cfeef1..8bc6916bbbb1 100644
--- a/arch/um/include/skas/mode-skas.h
+++ b/arch/um/include/skas/mode-skas.h
@@ -13,7 +13,6 @@ extern unsigned long exec_fp_regs[];
13extern unsigned long exec_fpx_regs[]; 13extern unsigned long exec_fpx_regs[];
14extern int have_fpx_regs; 14extern int have_fpx_regs;
15 15
16extern void sig_handler_common_skas(int sig, void *sc_ptr);
17extern void kill_off_processes_skas(void); 16extern void kill_off_processes_skas(void);
18 17
19#endif 18#endif
diff --git a/arch/um/include/skas/skas.h b/arch/um/include/skas/skas.h
index 86357282d681..853b26f148c5 100644
--- a/arch/um/include/skas/skas.h
+++ b/arch/um/include/skas/skas.h
@@ -17,7 +17,6 @@ extern int user_thread(unsigned long stack, int flags);
17extern void new_thread_proc(void *stack, void (*handler)(int sig)); 17extern void new_thread_proc(void *stack, void (*handler)(int sig));
18extern void new_thread_handler(int sig); 18extern void new_thread_handler(int sig);
19extern void handle_syscall(union uml_pt_regs *regs); 19extern void handle_syscall(union uml_pt_regs *regs);
20extern void user_signal(int sig, union uml_pt_regs *regs, int pid);
21extern int new_mm(unsigned long stack); 20extern int new_mm(unsigned long stack);
22extern void get_skas_faultinfo(int pid, struct faultinfo * fi); 21extern void get_skas_faultinfo(int pid, struct faultinfo * fi);
23extern long execute_syscall_skas(void *r); 22extern long execute_syscall_skas(void *r);
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h
index a6f1f176cf84..992a7e1e0fca 100644
--- a/arch/um/include/user_util.h
+++ b/arch/um/include/user_util.h
@@ -58,7 +58,6 @@ extern int attach(int pid);
58extern void kill_child_dead(int pid); 58extern void kill_child_dead(int pid);
59extern int cont(int pid); 59extern int cont(int pid);
60extern void check_sigio(void); 60extern void check_sigio(void);
61extern void write_sigio_workaround(void);
62extern void arch_check_bugs(void); 61extern void arch_check_bugs(void);
63extern int cpu_feature(char *what, char *buf, int len); 62extern int cpu_feature(char *what, char *buf, int len);
64extern int arch_handle_signal(int sig, union uml_pt_regs *regs); 63extern int arch_handle_signal(int sig, union uml_pt_regs *regs);
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index 693018ba80f1..fe08971b64cf 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -7,23 +7,20 @@ extra-y := vmlinux.lds
7clean-files := 7clean-files :=
8 8
9obj-y = config.o exec_kern.o exitcode.o \ 9obj-y = config.o exec_kern.o exitcode.o \
10 init_task.o irq.o irq_user.o ksyms.o mem.o physmem.o \ 10 init_task.o irq.o ksyms.o mem.o physmem.o \
11 process_kern.o ptrace.o reboot.o resource.o sigio_user.o sigio_kern.o \ 11 process_kern.o ptrace.o reboot.o resource.o sigio_kern.o \
12 signal_kern.o smp.o syscall_kern.o sysrq.o \ 12 signal_kern.o smp.o syscall_kern.o sysrq.o \
13 time_kern.o tlb.o trap_kern.o uaccess.o um_arch.o umid.o 13 time_kern.o tlb.o trap_kern.o uaccess.o um_arch.o umid.o
14 14
15obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o 15obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
16obj-$(CONFIG_GPROF) += gprof_syms.o 16obj-$(CONFIG_GPROF) += gprof_syms.o
17obj-$(CONFIG_GCOV) += gmon_syms.o 17obj-$(CONFIG_GCOV) += gmon_syms.o
18obj-$(CONFIG_TTY_LOG) += tty_log.o
19obj-$(CONFIG_SYSCALL_DEBUG) += syscall.o 18obj-$(CONFIG_SYSCALL_DEBUG) += syscall.o
20 19
21obj-$(CONFIG_MODE_TT) += tt/ 20obj-$(CONFIG_MODE_TT) += tt/
22obj-$(CONFIG_MODE_SKAS) += skas/ 21obj-$(CONFIG_MODE_SKAS) += skas/
23 22
24user-objs-$(CONFIG_TTY_LOG) += tty_log.o 23USER_OBJS := config.o
25
26USER_OBJS := $(user-objs-y) config.o tty_log.o
27 24
28include arch/um/scripts/Makefile.rules 25include arch/um/scripts/Makefile.rules
29 26
diff --git a/arch/um/kernel/exec_kern.c b/arch/um/kernel/exec_kern.c
index c264e1c05ab3..1ca84319317d 100644
--- a/arch/um/kernel/exec_kern.c
+++ b/arch/um/kernel/exec_kern.c
@@ -30,8 +30,6 @@ void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
30 CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp); 30 CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
31} 31}
32 32
33extern void log_exec(char **argv, void *tty);
34
35static long execve1(char *file, char __user * __user *argv, 33static long execve1(char *file, char __user * __user *argv,
36 char __user *__user *env) 34 char __user *__user *env)
37{ 35{
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index bbf94bf2921e..c39ea3abeda4 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -31,6 +31,8 @@
31#include "irq_user.h" 31#include "irq_user.h"
32#include "irq_kern.h" 32#include "irq_kern.h"
33#include "os.h" 33#include "os.h"
34#include "sigio.h"
35#include "misc_constants.h"
34 36
35/* 37/*
36 * Generic, controller-independent functions: 38 * Generic, controller-independent functions:
@@ -77,6 +79,298 @@ skip:
77 return 0; 79 return 0;
78} 80}
79 81
82struct irq_fd *active_fds = NULL;
83static struct irq_fd **last_irq_ptr = &active_fds;
84
85extern void free_irqs(void);
86
87void sigio_handler(int sig, union uml_pt_regs *regs)
88{
89 struct irq_fd *irq_fd;
90 int n;
91
92 if(smp_sigio_handler()) return;
93 while(1){
94 n = os_waiting_for_events(active_fds);
95 if (n <= 0) {
96 if(n == -EINTR) continue;
97 else break;
98 }
99
100 for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
101 if(irq_fd->current_events != 0){
102 irq_fd->current_events = 0;
103 do_IRQ(irq_fd->irq, regs);
104 }
105 }
106 }
107
108 free_irqs();
109}
110
111static void maybe_sigio_broken(int fd, int type)
112{
113 if(os_isatty(fd)){
114 if((type == IRQ_WRITE) && !pty_output_sigio){
115 write_sigio_workaround();
116 add_sigio_fd(fd, 0);
117 }
118 else if((type == IRQ_READ) && !pty_close_sigio){
119 write_sigio_workaround();
120 add_sigio_fd(fd, 1);
121 }
122 }
123}
124
125
126int activate_fd(int irq, int fd, int type, void *dev_id)
127{
128 struct pollfd *tmp_pfd;
129 struct irq_fd *new_fd, *irq_fd;
130 unsigned long flags;
131 int pid, events, err, n;
132
133 pid = os_getpid();
134 err = os_set_fd_async(fd, pid);
135 if(err < 0)
136 goto out;
137
138 new_fd = um_kmalloc(sizeof(*new_fd));
139 err = -ENOMEM;
140 if(new_fd == NULL)
141 goto out;
142
143 if(type == IRQ_READ) events = UM_POLLIN | UM_POLLPRI;
144 else events = UM_POLLOUT;
145 *new_fd = ((struct irq_fd) { .next = NULL,
146 .id = dev_id,
147 .fd = fd,
148 .type = type,
149 .irq = irq,
150 .pid = pid,
151 .events = events,
152 .current_events = 0 } );
153
154 /* Critical section - locked by a spinlock because this stuff can
155 * be changed from interrupt handlers. The stuff above is done
156 * outside the lock because it allocates memory.
157 */
158
159 /* Actually, it only looks like it can be called from interrupt
160 * context. The culprit is reactivate_fd, which calls
161 * maybe_sigio_broken, which calls write_sigio_workaround,
162 * which calls activate_fd. However, write_sigio_workaround should
163 * only be called once, at boot time. That would make it clear that
164 * this is called only from process context, and can be locked with
165 * a semaphore.
166 */
167 flags = irq_lock();
168 for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
169 if((irq_fd->fd == fd) && (irq_fd->type == type)){
170 printk("Registering fd %d twice\n", fd);
171 printk("Irqs : %d, %d\n", irq_fd->irq, irq);
172 printk("Ids : 0x%p, 0x%p\n", irq_fd->id, dev_id);
173 goto out_unlock;
174 }
175 }
176
177 /*-------------*/
178 if(type == IRQ_WRITE)
179 fd = -1;
180
181 tmp_pfd = NULL;
182 n = 0;
183
184 while(1){
185 n = os_create_pollfd(fd, events, tmp_pfd, n);
186 if (n == 0)
187 break;
188
189 /* n > 0
190 * It means we couldn't put new pollfd to current pollfds
191 * and tmp_fds is NULL or too small for new pollfds array.
192 * Needed size is equal to n as minimum.
193 *
194 * Here we have to drop the lock in order to call
195 * kmalloc, which might sleep.
196 * If something else came in and changed the pollfds array
197 * so we will not be able to put new pollfd struct to pollfds
198 * then we free the buffer tmp_fds and try again.
199 */
200 irq_unlock(flags);
201 if (tmp_pfd != NULL) {
202 kfree(tmp_pfd);
203 tmp_pfd = NULL;
204 }
205
206 tmp_pfd = um_kmalloc(n);
207 if (tmp_pfd == NULL)
208 goto out_kfree;
209
210 flags = irq_lock();
211 }
212 /*-------------*/
213
214 *last_irq_ptr = new_fd;
215 last_irq_ptr = &new_fd->next;
216
217 irq_unlock(flags);
218
219 /* This calls activate_fd, so it has to be outside the critical
220 * section.
221 */
222 maybe_sigio_broken(fd, type);
223
224 return(0);
225
226 out_unlock:
227 irq_unlock(flags);
228 out_kfree:
229 kfree(new_fd);
230 out:
231 return(err);
232}
233
234static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
235{
236 unsigned long flags;
237
238 flags = irq_lock();
239 os_free_irq_by_cb(test, arg, active_fds, &last_irq_ptr);
240 irq_unlock(flags);
241}
242
243struct irq_and_dev {
244 int irq;
245 void *dev;
246};
247
248static int same_irq_and_dev(struct irq_fd *irq, void *d)
249{
250 struct irq_and_dev *data = d;
251
252 return((irq->irq == data->irq) && (irq->id == data->dev));
253}
254
255void free_irq_by_irq_and_dev(unsigned int irq, void *dev)
256{
257 struct irq_and_dev data = ((struct irq_and_dev) { .irq = irq,
258 .dev = dev });
259
260 free_irq_by_cb(same_irq_and_dev, &data);
261}
262
263static int same_fd(struct irq_fd *irq, void *fd)
264{
265 return(irq->fd == *((int *) fd));
266}
267
268void free_irq_by_fd(int fd)
269{
270 free_irq_by_cb(same_fd, &fd);
271}
272
273static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
274{
275 struct irq_fd *irq;
276 int i = 0;
277 int fdi;
278
279 for(irq=active_fds; irq != NULL; irq = irq->next){
280 if((irq->fd == fd) && (irq->irq == irqnum)) break;
281 i++;
282 }
283 if(irq == NULL){
284 printk("find_irq_by_fd doesn't have descriptor %d\n", fd);
285 goto out;
286 }
287 fdi = os_get_pollfd(i);
288 if((fdi != -1) && (fdi != fd)){
289 printk("find_irq_by_fd - mismatch between active_fds and "
290 "pollfds, fd %d vs %d, need %d\n", irq->fd,
291 fdi, fd);
292 irq = NULL;
293 goto out;
294 }
295 *index_out = i;
296 out:
297 return(irq);
298}
299
300void reactivate_fd(int fd, int irqnum)
301{
302 struct irq_fd *irq;
303 unsigned long flags;
304 int i;
305
306 flags = irq_lock();
307 irq = find_irq_by_fd(fd, irqnum, &i);
308 if(irq == NULL){
309 irq_unlock(flags);
310 return;
311 }
312 os_set_pollfd(i, irq->fd);
313 irq_unlock(flags);
314
315 /* This calls activate_fd, so it has to be outside the critical
316 * section.
317 */
318 maybe_sigio_broken(fd, irq->type);
319}
320
321void deactivate_fd(int fd, int irqnum)
322{
323 struct irq_fd *irq;
324 unsigned long flags;
325 int i;
326
327 flags = irq_lock();
328 irq = find_irq_by_fd(fd, irqnum, &i);
329 if(irq == NULL)
330 goto out;
331 os_set_pollfd(i, -1);
332 out:
333 irq_unlock(flags);
334}
335
336int deactivate_all_fds(void)
337{
338 struct irq_fd *irq;
339 int err;
340
341 for(irq=active_fds;irq != NULL;irq = irq->next){
342 err = os_clear_fd_async(irq->fd);
343 if(err)
344 return(err);
345 }
346 /* If there is a signal already queued, after unblocking ignore it */
347 os_set_ioignore();
348
349 return(0);
350}
351
352void forward_interrupts(int pid)
353{
354 struct irq_fd *irq;
355 unsigned long flags;
356 int err;
357
358 flags = irq_lock();
359 for(irq=active_fds;irq != NULL;irq = irq->next){
360 err = os_set_owner(irq->fd, pid);
361 if(err < 0){
362 /* XXX Just remove the irq rather than
363 * print out an infinite stream of these
364 */
365 printk("Failed to forward %d to pid %d, err = %d\n",
366 irq->fd, pid, -err);
367 }
368
369 irq->pid = pid;
370 }
371 irq_unlock(flags);
372}
373
80/* 374/*
81 * do_IRQ handles all normal device IRQ's (the special 375 * do_IRQ handles all normal device IRQ's (the special
82 * SMP cross-CPU interrupts have their own specific 376 * SMP cross-CPU interrupts have their own specific
diff --git a/arch/um/kernel/irq_user.c b/arch/um/kernel/irq_user.c
deleted file mode 100644
index 0e32f5f4a887..000000000000
--- a/arch/um/kernel/irq_user.c
+++ /dev/null
@@ -1,412 +0,0 @@
1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <stdlib.h>
7#include <unistd.h>
8#include <errno.h>
9#include <signal.h>
10#include <string.h>
11#include <sys/poll.h>
12#include <sys/types.h>
13#include <sys/time.h>
14#include "user_util.h"
15#include "kern_util.h"
16#include "user.h"
17#include "process.h"
18#include "sigio.h"
19#include "irq_user.h"
20#include "os.h"
21
22struct irq_fd {
23 struct irq_fd *next;
24 void *id;
25 int fd;
26 int type;
27 int irq;
28 int pid;
29 int events;
30 int current_events;
31};
32
33static struct irq_fd *active_fds = NULL;
34static struct irq_fd **last_irq_ptr = &active_fds;
35
36static struct pollfd *pollfds = NULL;
37static int pollfds_num = 0;
38static int pollfds_size = 0;
39
40extern int io_count, intr_count;
41
42extern void free_irqs(void);
43
44void sigio_handler(int sig, union uml_pt_regs *regs)
45{
46 struct irq_fd *irq_fd;
47 int i, n;
48
49 if(smp_sigio_handler()) return;
50 while(1){
51 n = poll(pollfds, pollfds_num, 0);
52 if(n < 0){
53 if(errno == EINTR) continue;
54 printk("sigio_handler : poll returned %d, "
55 "errno = %d\n", n, errno);
56 break;
57 }
58 if(n == 0) break;
59
60 irq_fd = active_fds;
61 for(i = 0; i < pollfds_num; i++){
62 if(pollfds[i].revents != 0){
63 irq_fd->current_events = pollfds[i].revents;
64 pollfds[i].fd = -1;
65 }
66 irq_fd = irq_fd->next;
67 }
68
69 for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
70 if(irq_fd->current_events != 0){
71 irq_fd->current_events = 0;
72 do_IRQ(irq_fd->irq, regs);
73 }
74 }
75 }
76
77 free_irqs();
78}
79
80int activate_ipi(int fd, int pid)
81{
82 return(os_set_fd_async(fd, pid));
83}
84
85static void maybe_sigio_broken(int fd, int type)
86{
87 if(isatty(fd)){
88 if((type == IRQ_WRITE) && !pty_output_sigio){
89 write_sigio_workaround();
90 add_sigio_fd(fd, 0);
91 }
92 else if((type == IRQ_READ) && !pty_close_sigio){
93 write_sigio_workaround();
94 add_sigio_fd(fd, 1);
95 }
96 }
97}
98
99int activate_fd(int irq, int fd, int type, void *dev_id)
100{
101 struct pollfd *tmp_pfd;
102 struct irq_fd *new_fd, *irq_fd;
103 unsigned long flags;
104 int pid, events, err, n, size;
105
106 pid = os_getpid();
107 err = os_set_fd_async(fd, pid);
108 if(err < 0)
109 goto out;
110
111 new_fd = um_kmalloc(sizeof(*new_fd));
112 err = -ENOMEM;
113 if(new_fd == NULL)
114 goto out;
115
116 if(type == IRQ_READ) events = POLLIN | POLLPRI;
117 else events = POLLOUT;
118 *new_fd = ((struct irq_fd) { .next = NULL,
119 .id = dev_id,
120 .fd = fd,
121 .type = type,
122 .irq = irq,
123 .pid = pid,
124 .events = events,
125 .current_events = 0 } );
126
127 /* Critical section - locked by a spinlock because this stuff can
128 * be changed from interrupt handlers. The stuff above is done
129 * outside the lock because it allocates memory.
130 */
131
132 /* Actually, it only looks like it can be called from interrupt
133 * context. The culprit is reactivate_fd, which calls
134 * maybe_sigio_broken, which calls write_sigio_workaround,
135 * which calls activate_fd. However, write_sigio_workaround should
136 * only be called once, at boot time. That would make it clear that
137 * this is called only from process context, and can be locked with
138 * a semaphore.
139 */
140 flags = irq_lock();
141 for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
142 if((irq_fd->fd == fd) && (irq_fd->type == type)){
143 printk("Registering fd %d twice\n", fd);
144 printk("Irqs : %d, %d\n", irq_fd->irq, irq);
145 printk("Ids : 0x%x, 0x%x\n", irq_fd->id, dev_id);
146 goto out_unlock;
147 }
148 }
149
150 n = pollfds_num;
151 if(n == pollfds_size){
152 while(1){
153 /* Here we have to drop the lock in order to call
154 * kmalloc, which might sleep. If something else
155 * came in and changed the pollfds array, we free
156 * the buffer and try again.
157 */
158 irq_unlock(flags);
159 size = (pollfds_num + 1) * sizeof(pollfds[0]);
160 tmp_pfd = um_kmalloc(size);
161 flags = irq_lock();
162 if(tmp_pfd == NULL)
163 goto out_unlock;
164 if(n == pollfds_size)
165 break;
166 kfree(tmp_pfd);
167 }
168 if(pollfds != NULL){
169 memcpy(tmp_pfd, pollfds,
170 sizeof(pollfds[0]) * pollfds_size);
171 kfree(pollfds);
172 }
173 pollfds = tmp_pfd;
174 pollfds_size++;
175 }
176
177 if(type == IRQ_WRITE)
178 fd = -1;
179
180 pollfds[pollfds_num] = ((struct pollfd) { .fd = fd,
181 .events = events,
182 .revents = 0 });
183 pollfds_num++;
184
185 *last_irq_ptr = new_fd;
186 last_irq_ptr = &new_fd->next;
187
188 irq_unlock(flags);
189
190 /* This calls activate_fd, so it has to be outside the critical
191 * section.
192 */
193 maybe_sigio_broken(fd, type);
194
195 return(0);
196
197 out_unlock:
198 irq_unlock(flags);
199 kfree(new_fd);
200 out:
201 return(err);
202}
203
204static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
205{
206 struct irq_fd **prev;
207 unsigned long flags;
208 int i = 0;
209
210 flags = irq_lock();
211 prev = &active_fds;
212 while(*prev != NULL){
213 if((*test)(*prev, arg)){
214 struct irq_fd *old_fd = *prev;
215 if((pollfds[i].fd != -1) &&
216 (pollfds[i].fd != (*prev)->fd)){
217 printk("free_irq_by_cb - mismatch between "
218 "active_fds and pollfds, fd %d vs %d\n",
219 (*prev)->fd, pollfds[i].fd);
220 goto out;
221 }
222
223 pollfds_num--;
224
225 /* This moves the *whole* array after pollfds[i] (though
226 * it doesn't spot as such)! */
227
228 memmove(&pollfds[i], &pollfds[i + 1],
229 (pollfds_num - i) * sizeof(pollfds[0]));
230
231 if(last_irq_ptr == &old_fd->next)
232 last_irq_ptr = prev;
233 *prev = (*prev)->next;
234 if(old_fd->type == IRQ_WRITE)
235 ignore_sigio_fd(old_fd->fd);
236 kfree(old_fd);
237 continue;
238 }
239 prev = &(*prev)->next;
240 i++;
241 }
242 out:
243 irq_unlock(flags);
244}
245
246struct irq_and_dev {
247 int irq;
248 void *dev;
249};
250
251static int same_irq_and_dev(struct irq_fd *irq, void *d)
252{
253 struct irq_and_dev *data = d;
254
255 return((irq->irq == data->irq) && (irq->id == data->dev));
256}
257
258void free_irq_by_irq_and_dev(unsigned int irq, void *dev)
259{
260 struct irq_and_dev data = ((struct irq_and_dev) { .irq = irq,
261 .dev = dev });
262
263 free_irq_by_cb(same_irq_and_dev, &data);
264}
265
266static int same_fd(struct irq_fd *irq, void *fd)
267{
268 return(irq->fd == *((int *) fd));
269}
270
271void free_irq_by_fd(int fd)
272{
273 free_irq_by_cb(same_fd, &fd);
274}
275
276static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
277{
278 struct irq_fd *irq;
279 int i = 0;
280
281 for(irq=active_fds; irq != NULL; irq = irq->next){
282 if((irq->fd == fd) && (irq->irq == irqnum)) break;
283 i++;
284 }
285 if(irq == NULL){
286 printk("find_irq_by_fd doesn't have descriptor %d\n", fd);
287 goto out;
288 }
289 if((pollfds[i].fd != -1) && (pollfds[i].fd != fd)){
290 printk("find_irq_by_fd - mismatch between active_fds and "
291 "pollfds, fd %d vs %d, need %d\n", irq->fd,
292 pollfds[i].fd, fd);
293 irq = NULL;
294 goto out;
295 }
296 *index_out = i;
297 out:
298 return(irq);
299}
300
301void reactivate_fd(int fd, int irqnum)
302{
303 struct irq_fd *irq;
304 unsigned long flags;
305 int i;
306
307 flags = irq_lock();
308 irq = find_irq_by_fd(fd, irqnum, &i);
309 if(irq == NULL){
310 irq_unlock(flags);
311 return;
312 }
313
314 pollfds[i].fd = irq->fd;
315
316 irq_unlock(flags);
317
318 /* This calls activate_fd, so it has to be outside the critical
319 * section.
320 */
321 maybe_sigio_broken(fd, irq->type);
322}
323
324void deactivate_fd(int fd, int irqnum)
325{
326 struct irq_fd *irq;
327 unsigned long flags;
328 int i;
329
330 flags = irq_lock();
331 irq = find_irq_by_fd(fd, irqnum, &i);
332 if(irq == NULL)
333 goto out;
334 pollfds[i].fd = -1;
335 out:
336 irq_unlock(flags);
337}
338
339int deactivate_all_fds(void)
340{
341 struct irq_fd *irq;
342 int err;
343
344 for(irq=active_fds;irq != NULL;irq = irq->next){
345 err = os_clear_fd_async(irq->fd);
346 if(err)
347 return(err);
348 }
349 /* If there is a signal already queued, after unblocking ignore it */
350 set_handler(SIGIO, SIG_IGN, 0, -1);
351
352 return(0);
353}
354
355void forward_ipi(int fd, int pid)
356{
357 int err;
358
359 err = os_set_owner(fd, pid);
360 if(err < 0)
361 printk("forward_ipi: set_owner failed, fd = %d, me = %d, "
362 "target = %d, err = %d\n", fd, os_getpid(), pid, -err);
363}
364
365void forward_interrupts(int pid)
366{
367 struct irq_fd *irq;
368 unsigned long flags;
369 int err;
370
371 flags = irq_lock();
372 for(irq=active_fds;irq != NULL;irq = irq->next){
373 err = os_set_owner(irq->fd, pid);
374 if(err < 0){
375 /* XXX Just remove the irq rather than
376 * print out an infinite stream of these
377 */
378 printk("Failed to forward %d to pid %d, err = %d\n",
379 irq->fd, pid, -err);
380 }
381
382 irq->pid = pid;
383 }
384 irq_unlock(flags);
385}
386
387void init_irq_signals(int on_sigstack)
388{
389 __sighandler_t h;
390 int flags;
391
392 flags = on_sigstack ? SA_ONSTACK : 0;
393 if(timer_irq_inited) h = (__sighandler_t) alarm_handler;
394 else h = boot_timer_handler;
395
396 set_handler(SIGVTALRM, h, flags | SA_RESTART,
397 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
398 set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART,
399 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
400 signal(SIGWINCH, SIG_IGN);
401}
402
403/*
404 * Overrides for Emacs so that we follow Linus's tabbing style.
405 * Emacs will notice this stuff at the end of the file and automatically
406 * adjust the settings for this buffer only. This must remain at the end
407 * of the file.
408 * ---------------------------------------------------------------------------
409 * Local variables:
410 * c-file-style: "linux"
411 * End:
412 */
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index 0e65340eee33..0500800df1c1 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -9,6 +9,7 @@
9#include "linux/vmalloc.h" 9#include "linux/vmalloc.h"
10#include "linux/bootmem.h" 10#include "linux/bootmem.h"
11#include "linux/module.h" 11#include "linux/module.h"
12#include "linux/pfn.h"
12#include "asm/types.h" 13#include "asm/types.h"
13#include "asm/pgtable.h" 14#include "asm/pgtable.h"
14#include "kern_util.h" 15#include "kern_util.h"
@@ -316,8 +317,6 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
316 } 317 }
317} 318}
318 319
319#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
320
321extern int __syscall_stub_start, __binary_start; 320extern int __syscall_stub_start, __binary_start;
322 321
323void setup_physmem(unsigned long start, unsigned long reserve_end, 322void setup_physmem(unsigned long start, unsigned long reserve_end,
diff --git a/arch/um/kernel/sigio_kern.c b/arch/um/kernel/sigio_kern.c
index 229988463c4c..1c1300fb1e95 100644
--- a/arch/um/kernel/sigio_kern.c
+++ b/arch/um/kernel/sigio_kern.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -12,13 +12,16 @@
12#include "sigio.h" 12#include "sigio.h"
13#include "irq_user.h" 13#include "irq_user.h"
14#include "irq_kern.h" 14#include "irq_kern.h"
15#include "os.h"
15 16
16/* Protected by sigio_lock() called from write_sigio_workaround */ 17/* Protected by sigio_lock() called from write_sigio_workaround */
17static int sigio_irq_fd = -1; 18static int sigio_irq_fd = -1;
18 19
19static irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused) 20static irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused)
20{ 21{
21 read_sigio_fd(sigio_irq_fd); 22 char c;
23
24 os_read_file(sigio_irq_fd, &c, sizeof(c));
22 reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ); 25 reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
23 return(IRQ_HANDLED); 26 return(IRQ_HANDLED);
24} 27}
@@ -51,6 +54,9 @@ void sigio_unlock(void)
51 spin_unlock(&sigio_spinlock); 54 spin_unlock(&sigio_spinlock);
52} 55}
53 56
57extern void sigio_cleanup(void);
58__uml_exitcall(sigio_cleanup);
59
54/* 60/*
55 * Overrides for Emacs so that we follow Linus's tabbing style. 61 * Overrides for Emacs so that we follow Linus's tabbing style.
56 * Emacs will notice this stuff at the end of the file and automatically 62 * Emacs will notice this stuff at the end of the file and automatically
diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
index 72113b0a96e7..c8d8d0ac1a7f 100644
--- a/arch/um/kernel/smp.c
+++ b/arch/um/kernel/smp.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -77,9 +77,9 @@ static int idle_proc(void *cpup)
77 if(err < 0) 77 if(err < 0)
78 panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err); 78 panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err);
79 79
80 activate_ipi(cpu_data[cpu].ipi_pipe[0], 80 os_set_fd_async(cpu_data[cpu].ipi_pipe[0],
81 current->thread.mode.tt.extern_pid); 81 current->thread.mode.tt.extern_pid);
82 82
83 wmb(); 83 wmb();
84 if (cpu_test_and_set(cpu, cpu_callin_map)) { 84 if (cpu_test_and_set(cpu, cpu_callin_map)) {
85 printk("huh, CPU#%d already present??\n", cpu); 85 printk("huh, CPU#%d already present??\n", cpu);
@@ -106,7 +106,7 @@ static struct task_struct *idle_thread(int cpu)
106 panic("copy_process failed in idle_thread, error = %ld", 106 panic("copy_process failed in idle_thread, error = %ld",
107 PTR_ERR(new_task)); 107 PTR_ERR(new_task));
108 108
109 cpu_tasks[cpu] = ((struct cpu_task) 109 cpu_tasks[cpu] = ((struct cpu_task)
110 { .pid = new_task->thread.mode.tt.extern_pid, 110 { .pid = new_task->thread.mode.tt.extern_pid,
111 .task = new_task } ); 111 .task = new_task } );
112 idle_threads[cpu] = new_task; 112 idle_threads[cpu] = new_task;
@@ -134,12 +134,12 @@ void smp_prepare_cpus(unsigned int maxcpus)
134 if(err < 0) 134 if(err < 0)
135 panic("CPU#0 failed to create IPI pipe, errno = %d", -err); 135 panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
136 136
137 activate_ipi(cpu_data[me].ipi_pipe[0], 137 os_set_fd_async(cpu_data[me].ipi_pipe[0],
138 current->thread.mode.tt.extern_pid); 138 current->thread.mode.tt.extern_pid);
139 139
140 for(cpu = 1; cpu < ncpus; cpu++){ 140 for(cpu = 1; cpu < ncpus; cpu++){
141 printk("Booting processor %d...\n", cpu); 141 printk("Booting processor %d...\n", cpu);
142 142
143 idle = idle_thread(cpu); 143 idle = idle_thread(cpu);
144 144
145 init_idle(idle, cpu); 145 init_idle(idle, cpu);
@@ -223,7 +223,7 @@ void smp_call_function_slave(int cpu)
223 atomic_inc(&scf_finished); 223 atomic_inc(&scf_finished);
224} 224}
225 225
226int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic, 226int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic,
227 int wait) 227 int wait)
228{ 228{
229 int cpus = num_online_cpus() - 1; 229 int cpus = num_online_cpus() - 1;
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 80c9c18aae94..7d51dd7201c3 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -421,7 +421,7 @@ int linux_main(int argc, char **argv)
421#ifndef CONFIG_HIGHMEM 421#ifndef CONFIG_HIGHMEM
422 highmem = 0; 422 highmem = 0;
423 printf("CONFIG_HIGHMEM not enabled - physical memory shrunk " 423 printf("CONFIG_HIGHMEM not enabled - physical memory shrunk "
424 "to %lu bytes\n", physmem_size); 424 "to %Lu bytes\n", physmem_size);
425#endif 425#endif
426 } 426 }
427 427
@@ -433,8 +433,8 @@ int linux_main(int argc, char **argv)
433 433
434 setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem); 434 setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem);
435 if(init_maps(physmem_size, iomem_size, highmem)){ 435 if(init_maps(physmem_size, iomem_size, highmem)){
436 printf("Failed to allocate mem_map for %lu bytes of physical " 436 printf("Failed to allocate mem_map for %Lu bytes of physical "
437 "memory and %lu bytes of highmem\n", physmem_size, 437 "memory and %Lu bytes of highmem\n", physmem_size,
438 highmem); 438 highmem);
439 exit(1); 439 exit(1);
440 } 440 }
@@ -477,7 +477,8 @@ static struct notifier_block panic_exit_notifier = {
477 477
478void __init setup_arch(char **cmdline_p) 478void __init setup_arch(char **cmdline_p)
479{ 479{
480 notifier_chain_register(&panic_notifier_list, &panic_exit_notifier); 480 atomic_notifier_chain_register(&panic_notifier_list,
481 &panic_exit_notifier);
481 paging_init(); 482 paging_init();
482 strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE); 483 strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
483 *cmdline_p = command_line; 484 *cmdline_p = command_line;
@@ -487,8 +488,7 @@ void __init setup_arch(char **cmdline_p)
487void __init check_bugs(void) 488void __init check_bugs(void)
488{ 489{
489 arch_check_bugs(); 490 arch_check_bugs();
490 check_sigio(); 491 os_check_bugs();
491 check_devanon();
492} 492}
493 493
494void apply_alternatives(struct alt_instr *start, struct alt_instr *end) 494void apply_alternatives(struct alt_instr *start, struct alt_instr *end)
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index 08a4e628b24c..1659386b42bb 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -3,14 +3,17 @@
3# Licensed under the GPL 3# Licensed under the GPL
4# 4#
5 5
6obj-y = aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \ 6obj-y = aio.o elf_aux.o file.o helper.o irq.o main.o mem.o process.o sigio.o \
7 start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o user_syms.o \ 7 signal.o start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o \
8 util.o drivers/ sys-$(SUBARCH)/ 8 user_syms.o util.o drivers/ sys-$(SUBARCH)/
9 9
10obj-$(CONFIG_MODE_SKAS) += skas/ 10obj-$(CONFIG_MODE_SKAS) += skas/
11obj-$(CONFIG_TTY_LOG) += tty_log.o
12user-objs-$(CONFIG_TTY_LOG) += tty_log.o
11 13
12USER_OBJS := aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \ 14USER_OBJS := $(user-objs-y) aio.o elf_aux.o file.o helper.o irq.o main.o mem.o \
13 start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o util.o 15 process.o sigio.o signal.o start_up.o time.o trap.o tt.o tty.o \
16 uaccess.o umid.o util.o
14 17
15elf_aux.o: $(ARCH_DIR)/kernel-offsets.h 18elf_aux.o: $(ARCH_DIR)/kernel-offsets.h
16CFLAGS_elf_aux.o += -I$(objtree)/arch/um 19CFLAGS_elf_aux.o += -I$(objtree)/arch/um
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c
new file mode 100644
index 000000000000..e599be423da1
--- /dev/null
+++ b/arch/um/os-Linux/irq.c
@@ -0,0 +1,162 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <stdlib.h>
7#include <unistd.h>
8#include <errno.h>
9#include <signal.h>
10#include <string.h>
11#include <sys/poll.h>
12#include <sys/types.h>
13#include <sys/time.h>
14#include "user_util.h"
15#include "kern_util.h"
16#include "user.h"
17#include "process.h"
18#include "sigio.h"
19#include "irq_user.h"
20#include "os.h"
21
22static struct pollfd *pollfds = NULL;
23static int pollfds_num = 0;
24static int pollfds_size = 0;
25
26int os_waiting_for_events(struct irq_fd *active_fds)
27{
28 struct irq_fd *irq_fd;
29 int i, n, err;
30
31 n = poll(pollfds, pollfds_num, 0);
32 if(n < 0){
33 err = -errno;
34 if(errno != EINTR)
35 printk("sigio_handler: os_waiting_for_events:"
36 " poll returned %d, errno = %d\n", n, errno);
37 return err;
38 }
39
40 if(n == 0)
41 return 0;
42
43 irq_fd = active_fds;
44
45 for(i = 0; i < pollfds_num; i++){
46 if(pollfds[i].revents != 0){
47 irq_fd->current_events = pollfds[i].revents;
48 pollfds[i].fd = -1;
49 }
50 irq_fd = irq_fd->next;
51 }
52 return n;
53}
54
55int os_isatty(int fd)
56{
57 return(isatty(fd));
58}
59
60int os_create_pollfd(int fd, int events, void *tmp_pfd, int size_tmpfds)
61{
62 if (pollfds_num == pollfds_size) {
63 if (size_tmpfds <= pollfds_size * sizeof(pollfds[0])) {
64 /* return min size needed for new pollfds area */
65 return((pollfds_size + 1) * sizeof(pollfds[0]));
66 }
67
68 if(pollfds != NULL){
69 memcpy(tmp_pfd, pollfds,
70 sizeof(pollfds[0]) * pollfds_size);
71 /* remove old pollfds */
72 kfree(pollfds);
73 }
74 pollfds = tmp_pfd;
75 pollfds_size++;
76 } else {
77 /* remove not used tmp_pfd */
78 if (tmp_pfd != NULL)
79 kfree(tmp_pfd);
80 }
81
82 pollfds[pollfds_num] = ((struct pollfd) { .fd = fd,
83 .events = events,
84 .revents = 0 });
85 pollfds_num++;
86
87 return(0);
88}
89
90void os_free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg,
91 struct irq_fd *active_fds, struct irq_fd ***last_irq_ptr2)
92{
93 struct irq_fd **prev;
94 int i = 0;
95
96 prev = &active_fds;
97 while(*prev != NULL){
98 if((*test)(*prev, arg)){
99 struct irq_fd *old_fd = *prev;
100 if((pollfds[i].fd != -1) &&
101 (pollfds[i].fd != (*prev)->fd)){
102 printk("os_free_irq_by_cb - mismatch between "
103 "active_fds and pollfds, fd %d vs %d\n",
104 (*prev)->fd, pollfds[i].fd);
105 goto out;
106 }
107
108 pollfds_num--;
109
110 /* This moves the *whole* array after pollfds[i]
111 * (though it doesn't spot as such)!
112 */
113
114 memmove(&pollfds[i], &pollfds[i + 1],
115 (pollfds_num - i) * sizeof(pollfds[0]));
116 if(*last_irq_ptr2 == &old_fd->next)
117 *last_irq_ptr2 = prev;
118
119 *prev = (*prev)->next;
120 if(old_fd->type == IRQ_WRITE)
121 ignore_sigio_fd(old_fd->fd);
122 kfree(old_fd);
123 continue;
124 }
125 prev = &(*prev)->next;
126 i++;
127 }
128 out:
129 return;
130}
131
132
133int os_get_pollfd(int i)
134{
135 return(pollfds[i].fd);
136}
137
138void os_set_pollfd(int i, int fd)
139{
140 pollfds[i].fd = fd;
141}
142
143void os_set_ioignore(void)
144{
145 set_handler(SIGIO, SIG_IGN, 0, -1);
146}
147
148void init_irq_signals(int on_sigstack)
149{
150 __sighandler_t h;
151 int flags;
152
153 flags = on_sigstack ? SA_ONSTACK : 0;
154 if(timer_irq_inited) h = (__sighandler_t) alarm_handler;
155 else h = boot_timer_handler;
156
157 set_handler(SIGVTALRM, h, flags | SA_RESTART,
158 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
159 set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART,
160 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
161 signal(SIGWINCH, SIG_IGN);
162}
diff --git a/arch/um/kernel/sigio_user.c b/arch/um/os-Linux/sigio.c
index f7b18e157d35..9ba942947146 100644
--- a/arch/um/kernel/sigio_user.c
+++ b/arch/um/os-Linux/sigio.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -20,128 +20,7 @@
20#include "sigio.h" 20#include "sigio.h"
21#include "os.h" 21#include "os.h"
22 22
23/* Changed during early boot */ 23/* Protected by sigio_lock(), also used by sigio_cleanup, which is an
24int pty_output_sigio = 0;
25int pty_close_sigio = 0;
26
27/* Used as a flag during SIGIO testing early in boot */
28static volatile int got_sigio = 0;
29
30void __init handler(int sig)
31{
32 got_sigio = 1;
33}
34
35struct openpty_arg {
36 int master;
37 int slave;
38 int err;
39};
40
41static void openpty_cb(void *arg)
42{
43 struct openpty_arg *info = arg;
44
45 info->err = 0;
46 if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
47 info->err = -errno;
48}
49
50void __init check_one_sigio(void (*proc)(int, int))
51{
52 struct sigaction old, new;
53 struct openpty_arg pty = { .master = -1, .slave = -1 };
54 int master, slave, err;
55
56 initial_thread_cb(openpty_cb, &pty);
57 if(pty.err){
58 printk("openpty failed, errno = %d\n", -pty.err);
59 return;
60 }
61
62 master = pty.master;
63 slave = pty.slave;
64
65 if((master == -1) || (slave == -1)){
66 printk("openpty failed to allocate a pty\n");
67 return;
68 }
69
70 /* Not now, but complain so we now where we failed. */
71 err = raw(master);
72 if (err < 0)
73 panic("check_sigio : __raw failed, errno = %d\n", -err);
74
75 err = os_sigio_async(master, slave);
76 if(err < 0)
77 panic("tty_fds : sigio_async failed, err = %d\n", -err);
78
79 if(sigaction(SIGIO, NULL, &old) < 0)
80 panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
81 new = old;
82 new.sa_handler = handler;
83 if(sigaction(SIGIO, &new, NULL) < 0)
84 panic("check_sigio : sigaction 2 failed, errno = %d\n", errno);
85
86 got_sigio = 0;
87 (*proc)(master, slave);
88
89 os_close_file(master);
90 os_close_file(slave);
91
92 if(sigaction(SIGIO, &old, NULL) < 0)
93 panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
94}
95
96static void tty_output(int master, int slave)
97{
98 int n;
99 char buf[512];
100
101 printk("Checking that host ptys support output SIGIO...");
102
103 memset(buf, 0, sizeof(buf));
104
105 while(os_write_file(master, buf, sizeof(buf)) > 0) ;
106 if(errno != EAGAIN)
107 panic("check_sigio : write failed, errno = %d\n", errno);
108 while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
109
110 if (got_sigio) {
111 printk("Yes\n");
112 pty_output_sigio = 1;
113 } else if (n == -EAGAIN) {
114 printk("No, enabling workaround\n");
115 } else {
116 panic("check_sigio : read failed, err = %d\n", n);
117 }
118}
119
120static void tty_close(int master, int slave)
121{
122 printk("Checking that host ptys support SIGIO on close...");
123
124 os_close_file(slave);
125 if(got_sigio){
126 printk("Yes\n");
127 pty_close_sigio = 1;
128 }
129 else printk("No, enabling workaround\n");
130}
131
132void __init check_sigio(void)
133{
134 if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) &&
135 (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){
136 printk("No pseudo-terminals available - skipping pty SIGIO "
137 "check\n");
138 return;
139 }
140 check_one_sigio(tty_output);
141 check_one_sigio(tty_close);
142}
143
144/* Protected by sigio_lock(), also used by sigio_cleanup, which is an
145 * exitcall. 24 * exitcall.
146 */ 25 */
147static int write_sigio_pid = -1; 26static int write_sigio_pid = -1;
@@ -150,8 +29,10 @@ static int write_sigio_pid = -1;
150 * the descriptors closed after it is killed. So, it can't see them change. 29 * the descriptors closed after it is killed. So, it can't see them change.
151 * On the UML side, they are changed under the sigio_lock. 30 * On the UML side, they are changed under the sigio_lock.
152 */ 31 */
153static int write_sigio_fds[2] = { -1, -1 }; 32#define SIGIO_FDS_INIT {-1, -1}
154static int sigio_private[2] = { -1, -1 }; 33
34static int write_sigio_fds[2] = SIGIO_FDS_INIT;
35static int sigio_private[2] = SIGIO_FDS_INIT;
155 36
156struct pollfds { 37struct pollfds {
157 struct pollfd *poll; 38 struct pollfd *poll;
@@ -264,13 +145,13 @@ static void update_thread(void)
264 return; 145 return;
265 fail: 146 fail:
266 /* Critical section start */ 147 /* Critical section start */
267 if(write_sigio_pid != -1) 148 if(write_sigio_pid != -1)
268 os_kill_process(write_sigio_pid, 1); 149 os_kill_process(write_sigio_pid, 1);
269 write_sigio_pid = -1; 150 write_sigio_pid = -1;
270 os_close_file(sigio_private[0]); 151 close(sigio_private[0]);
271 os_close_file(sigio_private[1]); 152 close(sigio_private[1]);
272 os_close_file(write_sigio_fds[0]); 153 close(write_sigio_fds[0]);
273 os_close_file(write_sigio_fds[1]); 154 close(write_sigio_fds[1]);
274 /* Critical section end */ 155 /* Critical section end */
275 set_signals(flags); 156 set_signals(flags);
276} 157}
@@ -281,13 +162,13 @@ int add_sigio_fd(int fd, int read)
281 162
282 sigio_lock(); 163 sigio_lock();
283 for(i = 0; i < current_poll.used; i++){ 164 for(i = 0; i < current_poll.used; i++){
284 if(current_poll.poll[i].fd == fd) 165 if(current_poll.poll[i].fd == fd)
285 goto out; 166 goto out;
286 } 167 }
287 168
288 n = current_poll.used + 1; 169 n = current_poll.used + 1;
289 err = need_poll(n); 170 err = need_poll(n);
290 if(err) 171 if(err)
291 goto out; 172 goto out;
292 173
293 for(i = 0; i < current_poll.used; i++) 174 for(i = 0; i < current_poll.used; i++)
@@ -316,7 +197,7 @@ int ignore_sigio_fd(int fd)
316 } 197 }
317 if(i == current_poll.used) 198 if(i == current_poll.used)
318 goto out; 199 goto out;
319 200
320 err = need_poll(current_poll.used - 1); 201 err = need_poll(current_poll.used - 1);
321 if(err) 202 if(err)
322 goto out; 203 goto out;
@@ -337,7 +218,7 @@ int ignore_sigio_fd(int fd)
337 return(err); 218 return(err);
338} 219}
339 220
340static struct pollfd* setup_initial_poll(int fd) 221static struct pollfd *setup_initial_poll(int fd)
341{ 222{
342 struct pollfd *p; 223 struct pollfd *p;
343 224
@@ -377,7 +258,7 @@ void write_sigio_workaround(void)
377 } 258 }
378 err = os_pipe(l_sigio_private, 1, 1); 259 err = os_pipe(l_sigio_private, 1, 1);
379 if(err < 0){ 260 if(err < 0){
380 printk("write_sigio_workaround - os_pipe 1 failed, " 261 printk("write_sigio_workaround - os_pipe 2 failed, "
381 "err = %d\n", -err); 262 "err = %d\n", -err);
382 goto out_close1; 263 goto out_close1;
383 } 264 }
@@ -391,76 +272,52 @@ void write_sigio_workaround(void)
391 /* Did we race? Don't try to optimize this, please, it's not so likely 272 /* Did we race? Don't try to optimize this, please, it's not so likely
392 * to happen, and no more than once at the boot. */ 273 * to happen, and no more than once at the boot. */
393 if(write_sigio_pid != -1) 274 if(write_sigio_pid != -1)
394 goto out_unlock; 275 goto out_free;
395 276
396 write_sigio_pid = run_helper_thread(write_sigio_thread, NULL, 277 current_poll = ((struct pollfds) { .poll = p,
397 CLONE_FILES | CLONE_VM, &stack, 0); 278 .used = 1,
398 279 .size = 1 });
399 if (write_sigio_pid < 0)
400 goto out_clear;
401 280
402 if (write_sigio_irq(l_write_sigio_fds[0])) 281 if (write_sigio_irq(l_write_sigio_fds[0]))
403 goto out_kill; 282 goto out_clear_poll;
404 283
405 /* Success, finally. */
406 memcpy(write_sigio_fds, l_write_sigio_fds, sizeof(l_write_sigio_fds)); 284 memcpy(write_sigio_fds, l_write_sigio_fds, sizeof(l_write_sigio_fds));
407 memcpy(sigio_private, l_sigio_private, sizeof(l_sigio_private)); 285 memcpy(sigio_private, l_sigio_private, sizeof(l_sigio_private));
408 286
409 current_poll = ((struct pollfds) { .poll = p, 287 write_sigio_pid = run_helper_thread(write_sigio_thread, NULL,
410 .used = 1, 288 CLONE_FILES | CLONE_VM, &stack, 0);
411 .size = 1 });
412 289
413 sigio_unlock(); 290 if (write_sigio_pid < 0)
414 return; 291 goto out_clear;
415 292
416 out_kill:
417 l_write_sigio_pid = write_sigio_pid;
418 write_sigio_pid = -1;
419 sigio_unlock(); 293 sigio_unlock();
420 /* Going to call waitpid, avoid holding the lock. */ 294 return;
421 os_kill_process(l_write_sigio_pid, 1);
422 goto out_free;
423 295
424 out_clear: 296out_clear:
425 write_sigio_pid = -1; 297 write_sigio_pid = -1;
426 out_unlock: 298 write_sigio_fds[0] = -1;
427 sigio_unlock(); 299 write_sigio_fds[1] = -1;
428 out_free: 300 sigio_private[0] = -1;
301 sigio_private[1] = -1;
302out_clear_poll:
303 current_poll = ((struct pollfds) { .poll = NULL,
304 .size = 0,
305 .used = 0 });
306out_free:
429 kfree(p); 307 kfree(p);
430 out_close2: 308 sigio_unlock();
431 os_close_file(l_sigio_private[0]); 309out_close2:
432 os_close_file(l_sigio_private[1]); 310 close(l_sigio_private[0]);
433 out_close1: 311 close(l_sigio_private[1]);
434 os_close_file(l_write_sigio_fds[0]); 312out_close1:
435 os_close_file(l_write_sigio_fds[1]); 313 close(l_write_sigio_fds[0]);
436 return; 314 close(l_write_sigio_fds[1]);
437}
438
439int read_sigio_fd(int fd)
440{
441 int n;
442 char c;
443
444 n = os_read_file(fd, &c, sizeof(c));
445 if(n != sizeof(c)){
446 if(n < 0) {
447 printk("read_sigio_fd - read failed, err = %d\n", -n);
448 return(n);
449 }
450 else {
451 printk("read_sigio_fd - short read, bytes = %d\n", n);
452 return(-EIO);
453 }
454 }
455 return(n);
456} 315}
457 316
458static void sigio_cleanup(void) 317void sigio_cleanup(void)
459{ 318{
460 if (write_sigio_pid != -1) { 319 if(write_sigio_pid != -1){
461 os_kill_process(write_sigio_pid, 1); 320 os_kill_process(write_sigio_pid, 1);
462 write_sigio_pid = -1; 321 write_sigio_pid = -1;
463 } 322 }
464} 323}
465
466__uml_exitcall(sigio_cleanup);
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 829d6b0d8b02..32753131f8d8 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -3,6 +3,7 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <pty.h>
6#include <stdio.h> 7#include <stdio.h>
7#include <stddef.h> 8#include <stddef.h>
8#include <stdarg.h> 9#include <stdarg.h>
@@ -539,3 +540,130 @@ int __init parse_iomem(char *str, int *add)
539 return(1); 540 return(1);
540} 541}
541 542
543
544/* Changed during early boot */
545int pty_output_sigio = 0;
546int pty_close_sigio = 0;
547
548/* Used as a flag during SIGIO testing early in boot */
549static volatile int got_sigio = 0;
550
551static void __init handler(int sig)
552{
553 got_sigio = 1;
554}
555
556struct openpty_arg {
557 int master;
558 int slave;
559 int err;
560};
561
562static void openpty_cb(void *arg)
563{
564 struct openpty_arg *info = arg;
565
566 info->err = 0;
567 if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
568 info->err = -errno;
569}
570
571static void __init check_one_sigio(void (*proc)(int, int))
572{
573 struct sigaction old, new;
574 struct openpty_arg pty = { .master = -1, .slave = -1 };
575 int master, slave, err;
576
577 initial_thread_cb(openpty_cb, &pty);
578 if(pty.err){
579 printk("openpty failed, errno = %d\n", -pty.err);
580 return;
581 }
582
583 master = pty.master;
584 slave = pty.slave;
585
586 if((master == -1) || (slave == -1)){
587 printk("openpty failed to allocate a pty\n");
588 return;
589 }
590
591 /* Not now, but complain so we now where we failed. */
592 err = raw(master);
593 if (err < 0)
594 panic("check_sigio : __raw failed, errno = %d\n", -err);
595
596 err = os_sigio_async(master, slave);
597 if(err < 0)
598 panic("tty_fds : sigio_async failed, err = %d\n", -err);
599
600 if(sigaction(SIGIO, NULL, &old) < 0)
601 panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
602 new = old;
603 new.sa_handler = handler;
604 if(sigaction(SIGIO, &new, NULL) < 0)
605 panic("check_sigio : sigaction 2 failed, errno = %d\n", errno);
606
607 got_sigio = 0;
608 (*proc)(master, slave);
609
610 close(master);
611 close(slave);
612
613 if(sigaction(SIGIO, &old, NULL) < 0)
614 panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
615}
616
617static void tty_output(int master, int slave)
618{
619 int n;
620 char buf[512];
621
622 printk("Checking that host ptys support output SIGIO...");
623
624 memset(buf, 0, sizeof(buf));
625
626 while(os_write_file(master, buf, sizeof(buf)) > 0) ;
627 if(errno != EAGAIN)
628 panic("check_sigio : write failed, errno = %d\n", errno);
629 while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
630
631 if(got_sigio){
632 printk("Yes\n");
633 pty_output_sigio = 1;
634 }
635 else if(n == -EAGAIN) printk("No, enabling workaround\n");
636 else panic("check_sigio : read failed, err = %d\n", n);
637}
638
639static void tty_close(int master, int slave)
640{
641 printk("Checking that host ptys support SIGIO on close...");
642
643 close(slave);
644 if(got_sigio){
645 printk("Yes\n");
646 pty_close_sigio = 1;
647 }
648 else printk("No, enabling workaround\n");
649}
650
651void __init check_sigio(void)
652{
653 if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) &&
654 (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){
655 printk("No pseudo-terminals available - skipping pty SIGIO "
656 "check\n");
657 return;
658 }
659 check_one_sigio(tty_output);
660 check_one_sigio(tty_close);
661}
662
663void os_check_bugs(void)
664{
665 check_ptrace();
666 check_sigio();
667 check_devanon();
668}
669
diff --git a/arch/um/os-Linux/tt.c b/arch/um/os-Linux/tt.c
index 919d19f11537..5461a065bbb9 100644
--- a/arch/um/os-Linux/tt.c
+++ b/arch/um/os-Linux/tt.c
@@ -110,6 +110,16 @@ int wait_for_stop(int pid, int sig, int cont_type, void *relay)
110 } 110 }
111} 111}
112 112
113void forward_ipi(int fd, int pid)
114{
115 int err;
116
117 err = os_set_owner(fd, pid);
118 if(err < 0)
119 printk("forward_ipi: set_owner failed, fd = %d, me = %d, "
120 "target = %d, err = %d\n", fd, os_getpid(), pid, -err);
121}
122
113/* 123/*
114 *------------------------- 124 *-------------------------
115 * only for tt mode (will be deleted in future...) 125 * only for tt mode (will be deleted in future...)
diff --git a/arch/um/kernel/tty_log.c b/arch/um/os-Linux/tty_log.c
index 9ada656f68ce..c6ba56c1560f 100644
--- a/arch/um/kernel/tty_log.c
+++ b/arch/um/os-Linux/tty_log.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) and 2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) and
3 * geoffrey hing <ghing@net.ohio-state.edu> 3 * geoffrey hing <ghing@net.ohio-state.edu>
4 * Licensed under the GPL 4 * Licensed under the GPL
5 */ 5 */
@@ -58,7 +58,7 @@ int open_tty_log(void *tty, void *current_tty)
58 return(tty_log_fd); 58 return(tty_log_fd);
59 } 59 }
60 60
61 sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec, 61 sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec,
62 (unsigned int) tv.tv_usec); 62 (unsigned int) tv.tv_usec);
63 63
64 fd = os_open_file(buf, of_append(of_create(of_rdwr(OPENFLAGS()))), 64 fd = os_open_file(buf, of_append(of_create(of_rdwr(OPENFLAGS()))),
@@ -216,15 +216,3 @@ __uml_setup("tty_log_fd=", set_tty_log_fd,
216" tty data will be written. Preconfigure the descriptor with something\n" 216" tty data will be written. Preconfigure the descriptor with something\n"
217" like '10>tty_log tty_log_fd=10'.\n\n" 217" like '10>tty_log tty_log_fd=10'.\n\n"
218); 218);
219
220
221/*
222 * Overrides for Emacs so that we follow Linus's tabbing style.
223 * Emacs will notice this stuff at the end of the file and automatically
224 * adjust the settings for this buffer only. This must remain at the end
225 * of the file.
226 * ---------------------------------------------------------------------------
227 * Local variables:
228 * c-file-style: "linux"
229 * End:
230 */
diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c
index ecf107ae5ac8..198e59163288 100644
--- a/arch/um/os-Linux/umid.c
+++ b/arch/um/os-Linux/umid.c
@@ -143,8 +143,10 @@ static int not_dead_yet(char *dir)
143 goto out_close; 143 goto out_close;
144 } 144 }
145 145
146 if((kill(p, 0) == 0) || (errno != ESRCH)) 146 if((kill(p, 0) == 0) || (errno != ESRCH)){
147 printk("umid \"%s\" is already in use by pid %d\n", umid, p);
147 return 1; 148 return 1;
149 }
148 150
149 err = actually_do_remove(dir); 151 err = actually_do_remove(dir);
150 if(err) 152 if(err)
@@ -234,33 +236,44 @@ int __init make_umid(void)
234 err = mkdir(tmp, 0777); 236 err = mkdir(tmp, 0777);
235 if(err < 0){ 237 if(err < 0){
236 err = -errno; 238 err = -errno;
237 if(errno != EEXIST) 239 if(err != -EEXIST)
238 goto err; 240 goto err;
239 241
240 if(not_dead_yet(tmp) < 0) 242 /* 1 -> this umid is already in use
243 * < 0 -> we couldn't remove the umid directory
244 * In either case, we can't use this umid, so return -EEXIST.
245 */
246 if(not_dead_yet(tmp) != 0)
241 goto err; 247 goto err;
242 248
243 err = mkdir(tmp, 0777); 249 err = mkdir(tmp, 0777);
244 } 250 }
245 if(err < 0){ 251 if(err){
246 printk("Failed to create '%s' - err = %d\n", umid, err); 252 err = -errno;
247 goto err_rmdir; 253 printk("Failed to create '%s' - err = %d\n", umid, -errno);
254 goto err;
248 } 255 }
249 256
250 umid_setup = 1; 257 umid_setup = 1;
251 258
252 create_pid_file(); 259 create_pid_file();
253 260
254 return 0; 261 err = 0;
255
256 err_rmdir:
257 rmdir(tmp);
258 err: 262 err:
259 return err; 263 return err;
260} 264}
261 265
262static int __init make_umid_init(void) 266static int __init make_umid_init(void)
263{ 267{
268 if(!make_umid())
269 return 0;
270
271 /* If initializing with the given umid failed, then try again with
272 * a random one.
273 */
274 printk("Failed to initialize umid \"%s\", trying with a random umid\n",
275 umid);
276 *umid = '\0';
264 make_umid(); 277 make_umid();
265 278
266 return 0; 279 return 0;
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c
index e839ce65ad28..8032a105949a 100644
--- a/arch/um/sys-i386/ptrace.c
+++ b/arch/um/sys-i386/ptrace.c
@@ -6,6 +6,7 @@
6#include <linux/config.h> 6#include <linux/config.h>
7#include <linux/compiler.h> 7#include <linux/compiler.h>
8#include "linux/sched.h" 8#include "linux/sched.h"
9#include "linux/mm.h"
9#include "asm/elf.h" 10#include "asm/elf.h"
10#include "asm/ptrace.h" 11#include "asm/ptrace.h"
11#include "asm/uaccess.h" 12#include "asm/uaccess.h"
@@ -26,9 +27,17 @@ int is_syscall(unsigned long addr)
26 27
27 n = copy_from_user(&instr, (void __user *) addr, sizeof(instr)); 28 n = copy_from_user(&instr, (void __user *) addr, sizeof(instr));
28 if(n){ 29 if(n){
29 printk("is_syscall : failed to read instruction from 0x%lx\n", 30 /* access_process_vm() grants access to vsyscall and stub,
30 addr); 31 * while copy_from_user doesn't. Maybe access_process_vm is
31 return(0); 32 * slow, but that doesn't matter, since it will be called only
33 * in case of singlestepping, if copy_from_user failed.
34 */
35 n = access_process_vm(current, addr, &instr, sizeof(instr), 0);
36 if(n != sizeof(instr)) {
37 printk("is_syscall : failed to read instruction from "
38 "0x%lx\n", addr);
39 return(1);
40 }
32 } 41 }
33 /* int 0x80 or sysenter */ 42 /* int 0x80 or sysenter */
34 return((instr == 0x80cd) || (instr == 0x340f)); 43 return((instr == 0x80cd) || (instr == 0x340f));
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
index 7cd1a82dc8c2..33a40f5ef0d2 100644
--- a/arch/um/sys-i386/signal.c
+++ b/arch/um/sys-i386/signal.c
@@ -58,7 +58,7 @@ static int copy_sc_from_user_skas(struct pt_regs *regs,
58} 58}
59 59
60int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, 60int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
61 struct pt_regs *regs) 61 struct pt_regs *regs, unsigned long sp)
62{ 62{
63 struct sigcontext sc; 63 struct sigcontext sc;
64 unsigned long fpregs[HOST_FP_SIZE]; 64 unsigned long fpregs[HOST_FP_SIZE];
@@ -72,7 +72,7 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
72 sc.edi = REGS_EDI(regs->regs.skas.regs); 72 sc.edi = REGS_EDI(regs->regs.skas.regs);
73 sc.esi = REGS_ESI(regs->regs.skas.regs); 73 sc.esi = REGS_ESI(regs->regs.skas.regs);
74 sc.ebp = REGS_EBP(regs->regs.skas.regs); 74 sc.ebp = REGS_EBP(regs->regs.skas.regs);
75 sc.esp = REGS_SP(regs->regs.skas.regs); 75 sc.esp = sp;
76 sc.ebx = REGS_EBX(regs->regs.skas.regs); 76 sc.ebx = REGS_EBX(regs->regs.skas.regs);
77 sc.edx = REGS_EDX(regs->regs.skas.regs); 77 sc.edx = REGS_EDX(regs->regs.skas.regs);
78 sc.ecx = REGS_ECX(regs->regs.skas.regs); 78 sc.ecx = REGS_ECX(regs->regs.skas.regs);
@@ -132,7 +132,7 @@ int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from,
132} 132}
133 133
134int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp, 134int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp,
135 struct sigcontext *from, int fpsize) 135 struct sigcontext *from, int fpsize, unsigned long sp)
136{ 136{
137 struct _fpstate *to_fp, *from_fp; 137 struct _fpstate *to_fp, *from_fp;
138 int err; 138 int err;
@@ -140,11 +140,18 @@ int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp,
140 to_fp = (fp ? fp : (struct _fpstate *) (to + 1)); 140 to_fp = (fp ? fp : (struct _fpstate *) (to + 1));
141 from_fp = from->fpstate; 141 from_fp = from->fpstate;
142 err = copy_to_user(to, from, sizeof(*to)); 142 err = copy_to_user(to, from, sizeof(*to));
143
144 /* The SP in the sigcontext is the updated one for the signal
145 * delivery. The sp passed in is the original, and this needs
146 * to be restored, so we stick it in separately.
147 */
148 err |= copy_to_user(&SC_SP(to), sp, sizeof(sp));
149
143 if(from_fp != NULL){ 150 if(from_fp != NULL){
144 err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate)); 151 err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate));
145 err |= copy_to_user(to_fp, from_fp, fpsize); 152 err |= copy_to_user(to_fp, from_fp, fpsize);
146 } 153 }
147 return(err); 154 return err;
148} 155}
149#endif 156#endif
150 157
@@ -159,11 +166,11 @@ static int copy_sc_from_user(struct pt_regs *to, void __user *from)
159} 166}
160 167
161static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp, 168static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp,
162 struct pt_regs *from) 169 struct pt_regs *from, unsigned long sp)
163{ 170{
164 return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), 171 return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
165 sizeof(*fp)), 172 sizeof(*fp), sp),
166 copy_sc_to_user_skas(to, fp, from))); 173 copy_sc_to_user_skas(to, fp, from, sp)));
167} 174}
168 175
169static int copy_ucontext_to_user(struct ucontext *uc, struct _fpstate *fp, 176static int copy_ucontext_to_user(struct ucontext *uc, struct _fpstate *fp,
@@ -174,7 +181,7 @@ static int copy_ucontext_to_user(struct ucontext *uc, struct _fpstate *fp,
174 err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp); 181 err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp);
175 err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags); 182 err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags);
176 err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size); 183 err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size);
177 err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs); 184 err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs, sp);
178 err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set)); 185 err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
179 return(err); 186 return(err);
180} 187}
@@ -207,6 +214,7 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
207{ 214{
208 struct sigframe __user *frame; 215 struct sigframe __user *frame;
209 void *restorer; 216 void *restorer;
217 unsigned long save_sp = PT_REGS_SP(regs);
210 int err = 0; 218 int err = 0;
211 219
212 stack_top &= -8UL; 220 stack_top &= -8UL;
@@ -218,9 +226,19 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
218 if(ka->sa.sa_flags & SA_RESTORER) 226 if(ka->sa.sa_flags & SA_RESTORER)
219 restorer = ka->sa.sa_restorer; 227 restorer = ka->sa.sa_restorer;
220 228
229 /* Update SP now because the page fault handler refuses to extend
230 * the stack if the faulting address is too far below the current
231 * SP, which frame now certainly is. If there's an error, the original
232 * value is restored on the way out.
233 * When writing the sigcontext to the stack, we have to write the
234 * original value, so that's passed to copy_sc_to_user, which does
235 * the right thing with it.
236 */
237 PT_REGS_SP(regs) = (unsigned long) frame;
238
221 err |= __put_user(restorer, &frame->pretcode); 239 err |= __put_user(restorer, &frame->pretcode);
222 err |= __put_user(sig, &frame->sig); 240 err |= __put_user(sig, &frame->sig);
223 err |= copy_sc_to_user(&frame->sc, NULL, regs); 241 err |= copy_sc_to_user(&frame->sc, NULL, regs, save_sp);
224 err |= __put_user(mask->sig[0], &frame->sc.oldmask); 242 err |= __put_user(mask->sig[0], &frame->sc.oldmask);
225 if (_NSIG_WORDS > 1) 243 if (_NSIG_WORDS > 1)
226 err |= __copy_to_user(&frame->extramask, &mask->sig[1], 244 err |= __copy_to_user(&frame->extramask, &mask->sig[1],
@@ -238,7 +256,7 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
238 err |= __put_user(0x80cd, (short __user *)(frame->retcode+6)); 256 err |= __put_user(0x80cd, (short __user *)(frame->retcode+6));
239 257
240 if(err) 258 if(err)
241 return(err); 259 goto err;
242 260
243 PT_REGS_SP(regs) = (unsigned long) frame; 261 PT_REGS_SP(regs) = (unsigned long) frame;
244 PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; 262 PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
@@ -248,7 +266,11 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
248 266
249 if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) 267 if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
250 ptrace_notify(SIGTRAP); 268 ptrace_notify(SIGTRAP);
251 return(0); 269 return 0;
270
271err:
272 PT_REGS_SP(regs) = save_sp;
273 return err;
252} 274}
253 275
254int setup_signal_stack_si(unsigned long stack_top, int sig, 276int setup_signal_stack_si(unsigned long stack_top, int sig,
@@ -257,6 +279,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
257{ 279{
258 struct rt_sigframe __user *frame; 280 struct rt_sigframe __user *frame;
259 void *restorer; 281 void *restorer;
282 unsigned long save_sp = PT_REGS_SP(regs);
260 int err = 0; 283 int err = 0;
261 284
262 stack_top &= -8UL; 285 stack_top &= -8UL;
@@ -268,13 +291,16 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
268 if(ka->sa.sa_flags & SA_RESTORER) 291 if(ka->sa.sa_flags & SA_RESTORER)
269 restorer = ka->sa.sa_restorer; 292 restorer = ka->sa.sa_restorer;
270 293
294 /* See comment above about why this is here */
295 PT_REGS_SP(regs) = (unsigned long) frame;
296
271 err |= __put_user(restorer, &frame->pretcode); 297 err |= __put_user(restorer, &frame->pretcode);
272 err |= __put_user(sig, &frame->sig); 298 err |= __put_user(sig, &frame->sig);
273 err |= __put_user(&frame->info, &frame->pinfo); 299 err |= __put_user(&frame->info, &frame->pinfo);
274 err |= __put_user(&frame->uc, &frame->puc); 300 err |= __put_user(&frame->uc, &frame->puc);
275 err |= copy_siginfo_to_user(&frame->info, info); 301 err |= copy_siginfo_to_user(&frame->info, info);
276 err |= copy_ucontext_to_user(&frame->uc, &frame->fpstate, mask, 302 err |= copy_ucontext_to_user(&frame->uc, &frame->fpstate, mask,
277 PT_REGS_SP(regs)); 303 save_sp);
278 304
279 /* 305 /*
280 * This is movl $,%eax ; int $0x80 306 * This is movl $,%eax ; int $0x80
@@ -288,9 +314,8 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
288 err |= __put_user(0x80cd, (short __user *)(frame->retcode+5)); 314 err |= __put_user(0x80cd, (short __user *)(frame->retcode+5));
289 315
290 if(err) 316 if(err)
291 return(err); 317 goto err;
292 318
293 PT_REGS_SP(regs) = (unsigned long) frame;
294 PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; 319 PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
295 PT_REGS_EAX(regs) = (unsigned long) sig; 320 PT_REGS_EAX(regs) = (unsigned long) sig;
296 PT_REGS_EDX(regs) = (unsigned long) &frame->info; 321 PT_REGS_EDX(regs) = (unsigned long) &frame->info;
@@ -298,7 +323,11 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
298 323
299 if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) 324 if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
300 ptrace_notify(SIGTRAP); 325 ptrace_notify(SIGTRAP);
301 return(0); 326 return 0;
327
328err:
329 PT_REGS_SP(regs) = save_sp;
330 return err;
302} 331}
303 332
304long sys_sigreturn(struct pt_regs regs) 333long sys_sigreturn(struct pt_regs regs)
diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c
index 26b68675053d..6f4ef2b7fa4a 100644
--- a/arch/um/sys-i386/user-offsets.c
+++ b/arch/um/sys-i386/user-offsets.c
@@ -3,12 +3,13 @@
3#include <asm/ptrace.h> 3#include <asm/ptrace.h>
4#include <asm/user.h> 4#include <asm/user.h>
5#include <linux/stddef.h> 5#include <linux/stddef.h>
6#include <sys/poll.h>
6 7
7#define DEFINE(sym, val) \ 8#define DEFINE(sym, val) \
8 asm volatile("\n->" #sym " %0 " #val : : "i" (val)) 9 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
9 10
10#define DEFINE_LONGS(sym, val) \ 11#define DEFINE_LONGS(sym, val) \
11 asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long))) 12 asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long)))
12 13
13#define OFFSET(sym, str, mem) \ 14#define OFFSET(sym, str, mem) \
14 DEFINE(sym, offsetof(struct str, mem)); 15 DEFINE(sym, offsetof(struct str, mem));
@@ -67,4 +68,9 @@ void foo(void)
67 DEFINE(HOST_ES, ES); 68 DEFINE(HOST_ES, ES);
68 DEFINE(HOST_GS, GS); 69 DEFINE(HOST_GS, GS);
69 DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct)); 70 DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct));
71
72 /* XXX Duplicated between i386 and x86_64 */
73 DEFINE(UM_POLLIN, POLLIN);
74 DEFINE(UM_POLLPRI, POLLPRI);
75 DEFINE(UM_POLLOUT, POLLOUT);
70} 76}
diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c
index 74eee5c7c6dd..147bbf05cbc2 100644
--- a/arch/um/sys-x86_64/ptrace.c
+++ b/arch/um/sys-x86_64/ptrace.c
@@ -8,6 +8,7 @@
8#include <asm/ptrace.h> 8#include <asm/ptrace.h>
9#include <linux/sched.h> 9#include <linux/sched.h>
10#include <linux/errno.h> 10#include <linux/errno.h>
11#include <linux/mm.h>
11#include <asm/uaccess.h> 12#include <asm/uaccess.h>
12#include <asm/elf.h> 13#include <asm/elf.h>
13 14
@@ -136,9 +137,28 @@ void arch_switch(void)
136*/ 137*/
137} 138}
138 139
140/* XXX Mostly copied from sys-i386 */
139int is_syscall(unsigned long addr) 141int is_syscall(unsigned long addr)
140{ 142{
141 panic("is_syscall"); 143 unsigned short instr;
144 int n;
145
146 n = copy_from_user(&instr, (void __user *) addr, sizeof(instr));
147 if(n){
148 /* access_process_vm() grants access to vsyscall and stub,
149 * while copy_from_user doesn't. Maybe access_process_vm is
150 * slow, but that doesn't matter, since it will be called only
151 * in case of singlestepping, if copy_from_user failed.
152 */
153 n = access_process_vm(current, addr, &instr, sizeof(instr), 0);
154 if(n != sizeof(instr)) {
155 printk("is_syscall : failed to read instruction from "
156 "0x%lx\n", addr);
157 return(1);
158 }
159 }
160 /* sysenter */
161 return(instr == 0x050f);
142} 162}
143 163
144int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu ) 164int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu )
diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c
index fe1d065332b1..e75c4e1838b0 100644
--- a/arch/um/sys-x86_64/signal.c
+++ b/arch/um/sys-x86_64/signal.c
@@ -55,7 +55,8 @@ static int copy_sc_from_user_skas(struct pt_regs *regs,
55} 55}
56 56
57int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, 57int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
58 struct pt_regs *regs, unsigned long mask) 58 struct pt_regs *regs, unsigned long mask,
59 unsigned long sp)
59{ 60{
60 struct faultinfo * fi = &current->thread.arch.faultinfo; 61 struct faultinfo * fi = &current->thread.arch.faultinfo;
61 int err = 0; 62 int err = 0;
@@ -70,7 +71,11 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
70 err |= PUTREG(regs, RDI, to, rdi); 71 err |= PUTREG(regs, RDI, to, rdi);
71 err |= PUTREG(regs, RSI, to, rsi); 72 err |= PUTREG(regs, RSI, to, rsi);
72 err |= PUTREG(regs, RBP, to, rbp); 73 err |= PUTREG(regs, RBP, to, rbp);
73 err |= PUTREG(regs, RSP, to, rsp); 74 /* Must use orignal RSP, which is passed in, rather than what's in
75 * the pt_regs, because that's already been updated to point at the
76 * signal frame.
77 */
78 err |= __put_user(sp, &to->rsp);
74 err |= PUTREG(regs, RBX, to, rbx); 79 err |= PUTREG(regs, RBX, to, rbx);
75 err |= PUTREG(regs, RDX, to, rdx); 80 err |= PUTREG(regs, RDX, to, rdx);
76 err |= PUTREG(regs, RCX, to, rcx); 81 err |= PUTREG(regs, RCX, to, rcx);
@@ -102,7 +107,7 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
102 107
103#ifdef CONFIG_MODE_TT 108#ifdef CONFIG_MODE_TT
104int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from, 109int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from,
105 int fpsize) 110 int fpsize)
106{ 111{
107 struct _fpstate *to_fp, *from_fp; 112 struct _fpstate *to_fp, *from_fp;
108 unsigned long sigs; 113 unsigned long sigs;
@@ -120,7 +125,7 @@ int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from,
120} 125}
121 126
122int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp, 127int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp,
123 struct sigcontext *from, int fpsize) 128 struct sigcontext *from, int fpsize, unsigned long sp)
124{ 129{
125 struct _fpstate *to_fp, *from_fp; 130 struct _fpstate *to_fp, *from_fp;
126 int err; 131 int err;
@@ -128,11 +133,17 @@ int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp,
128 to_fp = (fp ? fp : (struct _fpstate *) (to + 1)); 133 to_fp = (fp ? fp : (struct _fpstate *) (to + 1));
129 from_fp = from->fpstate; 134 from_fp = from->fpstate;
130 err = copy_to_user(to, from, sizeof(*to)); 135 err = copy_to_user(to, from, sizeof(*to));
136 /* The SP in the sigcontext is the updated one for the signal
137 * delivery. The sp passed in is the original, and this needs
138 * to be restored, so we stick it in separately.
139 */
140 err |= copy_to_user(&SC_SP(to), sp, sizeof(sp));
141
131 if(from_fp != NULL){ 142 if(from_fp != NULL){
132 err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate)); 143 err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate));
133 err |= copy_to_user(to_fp, from_fp, fpsize); 144 err |= copy_to_user(to_fp, from_fp, fpsize);
134 } 145 }
135 return(err); 146 return err;
136} 147}
137 148
138#endif 149#endif
@@ -148,11 +159,12 @@ static int copy_sc_from_user(struct pt_regs *to, void __user *from)
148} 159}
149 160
150static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp, 161static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp,
151 struct pt_regs *from, unsigned long mask) 162 struct pt_regs *from, unsigned long mask,
163 unsigned long sp)
152{ 164{
153 return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), 165 return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
154 sizeof(*fp)), 166 sizeof(*fp), sp),
155 copy_sc_to_user_skas(to, fp, from, mask))); 167 copy_sc_to_user_skas(to, fp, from, mask, sp)));
156} 168}
157 169
158struct rt_sigframe 170struct rt_sigframe
@@ -170,6 +182,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
170{ 182{
171 struct rt_sigframe __user *frame; 183 struct rt_sigframe __user *frame;
172 struct _fpstate __user *fp = NULL; 184 struct _fpstate __user *fp = NULL;
185 unsigned long save_sp = PT_REGS_RSP(regs);
173 int err = 0; 186 int err = 0;
174 struct task_struct *me = current; 187 struct task_struct *me = current;
175 188
@@ -193,14 +206,25 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
193 goto out; 206 goto out;
194 } 207 }
195 208
209 /* Update SP now because the page fault handler refuses to extend
210 * the stack if the faulting address is too far below the current
211 * SP, which frame now certainly is. If there's an error, the original
212 * value is restored on the way out.
213 * When writing the sigcontext to the stack, we have to write the
214 * original value, so that's passed to copy_sc_to_user, which does
215 * the right thing with it.
216 */
217 PT_REGS_RSP(regs) = (unsigned long) frame;
218
196 /* Create the ucontext. */ 219 /* Create the ucontext. */
197 err |= __put_user(0, &frame->uc.uc_flags); 220 err |= __put_user(0, &frame->uc.uc_flags);
198 err |= __put_user(0, &frame->uc.uc_link); 221 err |= __put_user(0, &frame->uc.uc_link);
199 err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp); 222 err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
200 err |= __put_user(sas_ss_flags(PT_REGS_SP(regs)), 223 err |= __put_user(sas_ss_flags(save_sp),
201 &frame->uc.uc_stack.ss_flags); 224 &frame->uc.uc_stack.ss_flags);
202 err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size); 225 err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
203 err |= copy_sc_to_user(&frame->uc.uc_mcontext, fp, regs, set->sig[0]); 226 err |= copy_sc_to_user(&frame->uc.uc_mcontext, fp, regs, set->sig[0],
227 save_sp);
204 err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate); 228 err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
205 if (sizeof(*set) == 16) { 229 if (sizeof(*set) == 16) {
206 __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]); 230 __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
@@ -217,10 +241,10 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
217 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); 241 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
218 else 242 else
219 /* could use a vstub here */ 243 /* could use a vstub here */
220 goto out; 244 goto restore_sp;
221 245
222 if (err) 246 if (err)
223 goto out; 247 goto restore_sp;
224 248
225 /* Set up registers for signal handler */ 249 /* Set up registers for signal handler */
226 { 250 {
@@ -238,10 +262,12 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
238 PT_REGS_RSI(regs) = (unsigned long) &frame->info; 262 PT_REGS_RSI(regs) = (unsigned long) &frame->info;
239 PT_REGS_RDX(regs) = (unsigned long) &frame->uc; 263 PT_REGS_RDX(regs) = (unsigned long) &frame->uc;
240 PT_REGS_RIP(regs) = (unsigned long) ka->sa.sa_handler; 264 PT_REGS_RIP(regs) = (unsigned long) ka->sa.sa_handler;
241
242 PT_REGS_RSP(regs) = (unsigned long) frame;
243 out: 265 out:
244 return(err); 266 return err;
267
268restore_sp:
269 PT_REGS_RSP(regs) = save_sp;
270 return err;
245} 271}
246 272
247long sys_rt_sigreturn(struct pt_regs *regs) 273long sys_rt_sigreturn(struct pt_regs *regs)
diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c
index 7bd54a921cf7..899cebb57c3f 100644
--- a/arch/um/sys-x86_64/user-offsets.c
+++ b/arch/um/sys-x86_64/user-offsets.c
@@ -1,6 +1,7 @@
1#include <stdio.h> 1#include <stdio.h>
2#include <stddef.h> 2#include <stddef.h>
3#include <signal.h> 3#include <signal.h>
4#include <sys/poll.h>
4#define __FRAME_OFFSETS 5#define __FRAME_OFFSETS
5#include <asm/ptrace.h> 6#include <asm/ptrace.h>
6#include <asm/types.h> 7#include <asm/types.h>
@@ -88,4 +89,9 @@ void foo(void)
88 DEFINE_LONGS(HOST_IP, RIP); 89 DEFINE_LONGS(HOST_IP, RIP);
89 DEFINE_LONGS(HOST_SP, RSP); 90 DEFINE_LONGS(HOST_SP, RSP);
90 DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct)); 91 DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct));
92
93 /* XXX Duplicated between i386 and x86_64 */
94 DEFINE(UM_POLLIN, POLLIN);
95 DEFINE(UM_POLLPRI, POLLPRI);
96 DEFINE(UM_POLLOUT, POLLOUT);
91} 97}
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 45efe0ca88f8..4310b4a311a5 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -250,6 +250,15 @@ config SCHED_SMT
250 cost of slightly increased overhead in some places. If unsure say 250 cost of slightly increased overhead in some places. If unsure say
251 N here. 251 N here.
252 252
253config SCHED_MC
254 bool "Multi-core scheduler support"
255 depends on SMP
256 default y
257 help
258 Multi-core scheduler support improves the CPU scheduler's decision
259 making when dealing with multi-core CPU chips at a cost of slightly
260 increased overhead in some places. If unsure say N here.
261
253source "kernel/Kconfig.preempt" 262source "kernel/Kconfig.preempt"
254 263
255config NUMA 264config NUMA
@@ -325,6 +334,10 @@ config HAVE_ARCH_EARLY_PFN_TO_NID
325 def_bool y 334 def_bool y
326 depends on NUMA 335 depends on NUMA
327 336
337config OUT_OF_LINE_PFN_TO_PAGE
338 def_bool y
339 depends on DISCONTIGMEM
340
328config NR_CPUS 341config NR_CPUS
329 int "Maximum number of CPUs (2-256)" 342 int "Maximum number of CPUs (2-256)"
330 range 2 255 343 range 2 255
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
index 7549a4389fbf..35b2faccdc6c 100644
--- a/arch/x86_64/ia32/ia32entry.S
+++ b/arch/x86_64/ia32/ia32entry.S
@@ -688,6 +688,8 @@ ia32_sys_call_table:
688 .quad sys_ni_syscall /* pselect6 for now */ 688 .quad sys_ni_syscall /* pselect6 for now */
689 .quad sys_ni_syscall /* ppoll for now */ 689 .quad sys_ni_syscall /* ppoll for now */
690 .quad sys_unshare /* 310 */ 690 .quad sys_unshare /* 310 */
691 .quad compat_sys_set_robust_list
692 .quad compat_sys_get_robust_list
691ia32_syscall_end: 693ia32_syscall_end:
692 .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8 694 .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8
693 .quad ni_syscall 695 .quad ni_syscall
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 0370720515f1..70dd8e5c6889 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -66,24 +66,17 @@ EXPORT_SYMBOL(boot_option_idle_override);
66void (*pm_idle)(void); 66void (*pm_idle)(void);
67static DEFINE_PER_CPU(unsigned int, cpu_idle_state); 67static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
68 68
69static struct notifier_block *idle_notifier; 69static ATOMIC_NOTIFIER_HEAD(idle_notifier);
70static DEFINE_SPINLOCK(idle_notifier_lock);
71 70
72void idle_notifier_register(struct notifier_block *n) 71void idle_notifier_register(struct notifier_block *n)
73{ 72{
74 unsigned long flags; 73 atomic_notifier_chain_register(&idle_notifier, n);
75 spin_lock_irqsave(&idle_notifier_lock, flags);
76 notifier_chain_register(&idle_notifier, n);
77 spin_unlock_irqrestore(&idle_notifier_lock, flags);
78} 74}
79EXPORT_SYMBOL_GPL(idle_notifier_register); 75EXPORT_SYMBOL_GPL(idle_notifier_register);
80 76
81void idle_notifier_unregister(struct notifier_block *n) 77void idle_notifier_unregister(struct notifier_block *n)
82{ 78{
83 unsigned long flags; 79 atomic_notifier_chain_unregister(&idle_notifier, n);
84 spin_lock_irqsave(&idle_notifier_lock, flags);
85 notifier_chain_unregister(&idle_notifier, n);
86 spin_unlock_irqrestore(&idle_notifier_lock, flags);
87} 80}
88EXPORT_SYMBOL(idle_notifier_unregister); 81EXPORT_SYMBOL(idle_notifier_unregister);
89 82
@@ -93,13 +86,13 @@ static DEFINE_PER_CPU(enum idle_state, idle_state) = CPU_NOT_IDLE;
93void enter_idle(void) 86void enter_idle(void)
94{ 87{
95 __get_cpu_var(idle_state) = CPU_IDLE; 88 __get_cpu_var(idle_state) = CPU_IDLE;
96 notifier_call_chain(&idle_notifier, IDLE_START, NULL); 89 atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL);
97} 90}
98 91
99static void __exit_idle(void) 92static void __exit_idle(void)
100{ 93{
101 __get_cpu_var(idle_state) = CPU_NOT_IDLE; 94 __get_cpu_var(idle_state) = CPU_NOT_IDLE;
102 notifier_call_chain(&idle_notifier, IDLE_END, NULL); 95 atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL);
103} 96}
104 97
105/* Called from interrupts to signify idle end */ 98/* Called from interrupts to signify idle end */
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index a57eec8311a7..d1f3e9272c05 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -962,7 +962,6 @@ static void __cpuinit detect_ht(struct cpuinfo_x86 *c)
962 962
963 cpuid(1, &eax, &ebx, &ecx, &edx); 963 cpuid(1, &eax, &ebx, &ecx, &edx);
964 964
965 c->apicid = phys_pkg_id(0);
966 965
967 if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY)) 966 if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY))
968 return; 967 return;
@@ -1171,6 +1170,8 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
1171 c->x86_capability[2] = cpuid_edx(0x80860001); 1170 c->x86_capability[2] = cpuid_edx(0x80860001);
1172 } 1171 }
1173 1172
1173 c->apicid = phys_pkg_id(0);
1174
1174 /* 1175 /*
1175 * Vendor-specific initialization. In this section we 1176 * Vendor-specific initialization. In this section we
1176 * canonicalize the feature flags, meaning if there are 1177 * canonicalize the feature flags, meaning if there are
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 66e98659d077..ea48fa638070 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -68,6 +68,9 @@ u8 phys_proc_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID };
68/* core ID of each logical CPU */ 68/* core ID of each logical CPU */
69u8 cpu_core_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID }; 69u8 cpu_core_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID };
70 70
71/* Last level cache ID of each logical CPU */
72u8 cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID};
73
71/* Bitmask of currently online CPUs */ 74/* Bitmask of currently online CPUs */
72cpumask_t cpu_online_map __read_mostly; 75cpumask_t cpu_online_map __read_mostly;
73 76
@@ -445,6 +448,18 @@ void __cpuinit smp_callin(void)
445 cpu_set(cpuid, cpu_callin_map); 448 cpu_set(cpuid, cpu_callin_map);
446} 449}
447 450
451/* maps the cpu to the sched domain representing multi-core */
452cpumask_t cpu_coregroup_map(int cpu)
453{
454 struct cpuinfo_x86 *c = cpu_data + cpu;
455 /*
456 * For perf, we return last level cache shared map.
457 * TBD: when power saving sched policy is added, we will return
458 * cpu_core_map when power saving policy is enabled
459 */
460 return c->llc_shared_map;
461}
462
448/* representing cpus for which sibling maps can be computed */ 463/* representing cpus for which sibling maps can be computed */
449static cpumask_t cpu_sibling_setup_map; 464static cpumask_t cpu_sibling_setup_map;
450 465
@@ -463,12 +478,16 @@ static inline void set_cpu_sibling_map(int cpu)
463 cpu_set(cpu, cpu_sibling_map[i]); 478 cpu_set(cpu, cpu_sibling_map[i]);
464 cpu_set(i, cpu_core_map[cpu]); 479 cpu_set(i, cpu_core_map[cpu]);
465 cpu_set(cpu, cpu_core_map[i]); 480 cpu_set(cpu, cpu_core_map[i]);
481 cpu_set(i, c[cpu].llc_shared_map);
482 cpu_set(cpu, c[i].llc_shared_map);
466 } 483 }
467 } 484 }
468 } else { 485 } else {
469 cpu_set(cpu, cpu_sibling_map[cpu]); 486 cpu_set(cpu, cpu_sibling_map[cpu]);
470 } 487 }
471 488
489 cpu_set(cpu, c[cpu].llc_shared_map);
490
472 if (current_cpu_data.x86_max_cores == 1) { 491 if (current_cpu_data.x86_max_cores == 1) {
473 cpu_core_map[cpu] = cpu_sibling_map[cpu]; 492 cpu_core_map[cpu] = cpu_sibling_map[cpu];
474 c[cpu].booted_cores = 1; 493 c[cpu].booted_cores = 1;
@@ -476,6 +495,11 @@ static inline void set_cpu_sibling_map(int cpu)
476 } 495 }
477 496
478 for_each_cpu_mask(i, cpu_sibling_setup_map) { 497 for_each_cpu_mask(i, cpu_sibling_setup_map) {
498 if (cpu_llc_id[cpu] != BAD_APICID &&
499 cpu_llc_id[cpu] == cpu_llc_id[i]) {
500 cpu_set(i, c[cpu].llc_shared_map);
501 cpu_set(cpu, c[i].llc_shared_map);
502 }
479 if (phys_proc_id[cpu] == phys_proc_id[i]) { 503 if (phys_proc_id[cpu] == phys_proc_id[i]) {
480 cpu_set(i, cpu_core_map[cpu]); 504 cpu_set(i, cpu_core_map[cpu]);
481 cpu_set(cpu, cpu_core_map[i]); 505 cpu_set(cpu, cpu_core_map[i]);
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index 7b148309c529..edaa9fe654dc 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -69,20 +69,20 @@ asmlinkage void alignment_check(void);
69asmlinkage void machine_check(void); 69asmlinkage void machine_check(void);
70asmlinkage void spurious_interrupt_bug(void); 70asmlinkage void spurious_interrupt_bug(void);
71 71
72struct notifier_block *die_chain; 72ATOMIC_NOTIFIER_HEAD(die_chain);
73static DEFINE_SPINLOCK(die_notifier_lock);
74 73
75int register_die_notifier(struct notifier_block *nb) 74int register_die_notifier(struct notifier_block *nb)
76{ 75{
77 int err = 0;
78 unsigned long flags;
79
80 vmalloc_sync_all(); 76 vmalloc_sync_all();
81 spin_lock_irqsave(&die_notifier_lock, flags); 77 return atomic_notifier_chain_register(&die_chain, nb);
82 err = notifier_chain_register(&die_chain, nb); 78}
83 spin_unlock_irqrestore(&die_notifier_lock, flags); 79EXPORT_SYMBOL(register_die_notifier);
84 return err; 80
81int unregister_die_notifier(struct notifier_block *nb)
82{
83 return atomic_notifier_chain_unregister(&die_chain, nb);
85} 84}
85EXPORT_SYMBOL(unregister_die_notifier);
86 86
87static inline void conditional_sti(struct pt_regs *regs) 87static inline void conditional_sti(struct pt_regs *regs)
88{ 88{
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index b04415625442..e5f7f1c34462 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -72,7 +72,7 @@ void show_mem(void)
72 show_free_areas(); 72 show_free_areas();
73 printk(KERN_INFO "Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); 73 printk(KERN_INFO "Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
74 74
75 for_each_pgdat(pgdat) { 75 for_each_online_pgdat(pgdat) {
76 for (i = 0; i < pgdat->node_spanned_pages; ++i) { 76 for (i = 0; i < pgdat->node_spanned_pages; ++i) {
77 page = pfn_to_page(pgdat->node_start_pfn + i); 77 page = pfn_to_page(pgdat->node_start_pfn + i);
78 total++; 78 total++;
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c
index 63c72641b737..4be82d6e2b48 100644
--- a/arch/x86_64/mm/numa.c
+++ b/arch/x86_64/mm/numa.c
@@ -377,21 +377,6 @@ EXPORT_SYMBOL(node_data);
377 * Should do that. 377 * Should do that.
378 */ 378 */
379 379
380/* Requires pfn_valid(pfn) to be true */
381struct page *pfn_to_page(unsigned long pfn)
382{
383 int nid = phys_to_nid(((unsigned long)(pfn)) << PAGE_SHIFT);
384 return (pfn - node_start_pfn(nid)) + NODE_DATA(nid)->node_mem_map;
385}
386EXPORT_SYMBOL(pfn_to_page);
387
388unsigned long page_to_pfn(struct page *page)
389{
390 return (long)(((page) - page_zone(page)->zone_mem_map) +
391 page_zone(page)->zone_start_pfn);
392}
393EXPORT_SYMBOL(page_to_pfn);
394
395int pfn_valid(unsigned long pfn) 380int pfn_valid(unsigned long pfn)
396{ 381{
397 unsigned nid; 382 unsigned nid;
diff --git a/arch/xtensa/platform-iss/setup.c b/arch/xtensa/platform-iss/setup.c
index 2e6dcbf0cc04..23790a5610e2 100644
--- a/arch/xtensa/platform-iss/setup.c
+++ b/arch/xtensa/platform-iss/setup.c
@@ -108,5 +108,5 @@ static struct notifier_block iss_panic_block = {
108 108
109void __init platform_setup(char **p_cmdline) 109void __init platform_setup(char **p_cmdline)
110{ 110{
111 notifier_chain_register(&panic_notifier_list, &iss_panic_block); 111 atomic_notifier_chain_register(&panic_notifier_list, &iss_panic_block);
112} 112}
diff --git a/block/Kconfig b/block/Kconfig
index 43ca070dc0f8..5536839886ff 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -13,6 +13,7 @@ config LBD
13 13
14config BLK_DEV_IO_TRACE 14config BLK_DEV_IO_TRACE
15 bool "Support for tracing block io actions" 15 bool "Support for tracing block io actions"
16 depends on SYSFS
16 select RELAY 17 select RELAY
17 select DEBUG_FS 18 select DEBUG_FS
18 help 19 help
diff --git a/block/genhd.c b/block/genhd.c
index 64510fd88621..db4c60c802d6 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -454,8 +454,8 @@ static ssize_t disk_stats_read(struct gendisk * disk, char *page)
454 disk_round_stats(disk); 454 disk_round_stats(disk);
455 preempt_enable(); 455 preempt_enable();
456 return sprintf(page, 456 return sprintf(page,
457 "%8u %8u %8llu %8u " 457 "%8lu %8lu %8llu %8u "
458 "%8u %8u %8llu %8u " 458 "%8lu %8lu %8llu %8u "
459 "%8u %8u %8u" 459 "%8u %8u %8u"
460 "\n", 460 "\n",
461 disk_stat_read(disk, ios[READ]), 461 disk_stat_read(disk, ios[READ]),
@@ -649,7 +649,7 @@ static int diskstats_show(struct seq_file *s, void *v)
649 preempt_disable(); 649 preempt_disable();
650 disk_round_stats(gp); 650 disk_round_stats(gp);
651 preempt_enable(); 651 preempt_enable();
652 seq_printf(s, "%4d %4d %s %u %u %llu %u %u %u %llu %u %u %u %u\n", 652 seq_printf(s, "%4d %4d %s %lu %lu %llu %u %lu %lu %llu %u %u %u %u\n",
653 gp->major, n + gp->first_minor, disk_name(gp, n, buf), 653 gp->major, n + gp->first_minor, disk_name(gp, n, buf),
654 disk_stat_read(gp, ios[0]), disk_stat_read(gp, merges[0]), 654 disk_stat_read(gp, ios[0]), disk_stat_read(gp, merges[0]),
655 (unsigned long long)disk_stat_read(gp, sectors[0]), 655 (unsigned long long)disk_stat_read(gp, sectors[0]),
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 062067fa7ead..82469db25100 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -785,6 +785,8 @@ void blk_queue_stack_limits(request_queue_t *t, request_queue_t *b)
785 t->max_hw_segments = min(t->max_hw_segments,b->max_hw_segments); 785 t->max_hw_segments = min(t->max_hw_segments,b->max_hw_segments);
786 t->max_segment_size = min(t->max_segment_size,b->max_segment_size); 786 t->max_segment_size = min(t->max_segment_size,b->max_segment_size);
787 t->hardsect_size = max(t->hardsect_size,b->hardsect_size); 787 t->hardsect_size = max(t->hardsect_size,b->hardsect_size);
788 if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags))
789 clear_bit(QUEUE_FLAG_CLUSTER, &t->queue_flags);
788} 790}
789 791
790EXPORT_SYMBOL(blk_queue_stack_limits); 792EXPORT_SYMBOL(blk_queue_stack_limits);
@@ -906,17 +908,15 @@ init_tag_map(request_queue_t *q, struct blk_queue_tag *tags, int depth)
906 __FUNCTION__, depth); 908 __FUNCTION__, depth);
907 } 909 }
908 910
909 tag_index = kmalloc(depth * sizeof(struct request *), GFP_ATOMIC); 911 tag_index = kzalloc(depth * sizeof(struct request *), GFP_ATOMIC);
910 if (!tag_index) 912 if (!tag_index)
911 goto fail; 913 goto fail;
912 914
913 nr_ulongs = ALIGN(depth, BITS_PER_LONG) / BITS_PER_LONG; 915 nr_ulongs = ALIGN(depth, BITS_PER_LONG) / BITS_PER_LONG;
914 tag_map = kmalloc(nr_ulongs * sizeof(unsigned long), GFP_ATOMIC); 916 tag_map = kzalloc(nr_ulongs * sizeof(unsigned long), GFP_ATOMIC);
915 if (!tag_map) 917 if (!tag_map)
916 goto fail; 918 goto fail;
917 919
918 memset(tag_index, 0, depth * sizeof(struct request *));
919 memset(tag_map, 0, nr_ulongs * sizeof(unsigned long));
920 tags->real_max_depth = depth; 920 tags->real_max_depth = depth;
921 tags->max_depth = depth; 921 tags->max_depth = depth;
922 tags->tag_index = tag_index; 922 tags->tag_index = tag_index;
@@ -2479,10 +2479,12 @@ void blk_execute_rq_nowait(request_queue_t *q, struct gendisk *bd_disk,
2479 rq->rq_disk = bd_disk; 2479 rq->rq_disk = bd_disk;
2480 rq->flags |= REQ_NOMERGE; 2480 rq->flags |= REQ_NOMERGE;
2481 rq->end_io = done; 2481 rq->end_io = done;
2482 elv_add_request(q, rq, where, 1); 2482 WARN_ON(irqs_disabled());
2483 generic_unplug_device(q); 2483 spin_lock_irq(q->queue_lock);
2484 __elv_add_request(q, rq, where, 1);
2485 __generic_unplug_device(q);
2486 spin_unlock_irq(q->queue_lock);
2484} 2487}
2485
2486EXPORT_SYMBOL_GPL(blk_execute_rq_nowait); 2488EXPORT_SYMBOL_GPL(blk_execute_rq_nowait);
2487 2489
2488/** 2490/**
diff --git a/drivers/Kconfig b/drivers/Kconfig
index bddf431bbb72..9f5c0da57c90 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -70,4 +70,6 @@ source "drivers/sn/Kconfig"
70 70
71source "drivers/edac/Kconfig" 71source "drivers/edac/Kconfig"
72 72
73source "drivers/rtc/Kconfig"
74
73endmenu 75endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 5c69b86db624..424955274e60 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_USB_GADGET) += usb/gadget/
56obj-$(CONFIG_GAMEPORT) += input/gameport/ 56obj-$(CONFIG_GAMEPORT) += input/gameport/
57obj-$(CONFIG_INPUT) += input/ 57obj-$(CONFIG_INPUT) += input/
58obj-$(CONFIG_I2O) += message/ 58obj-$(CONFIG_I2O) += message/
59obj-$(CONFIG_RTC_LIB) += rtc/
59obj-$(CONFIG_I2C) += i2c/ 60obj-$(CONFIG_I2C) += i2c/
60obj-$(CONFIG_W1) += w1/ 61obj-$(CONFIG_W1) += w1/
61obj-$(CONFIG_HWMON) += hwmon/ 62obj-$(CONFIG_HWMON) += hwmon/
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 105a0d61eb1f..dd547af4681a 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -47,16 +47,16 @@ static struct kset_uevent_ops memory_uevent_ops = {
47 .uevent = memory_uevent, 47 .uevent = memory_uevent,
48}; 48};
49 49
50static struct notifier_block *memory_chain; 50static BLOCKING_NOTIFIER_HEAD(memory_chain);
51 51
52int register_memory_notifier(struct notifier_block *nb) 52int register_memory_notifier(struct notifier_block *nb)
53{ 53{
54 return notifier_chain_register(&memory_chain, nb); 54 return blocking_notifier_chain_register(&memory_chain, nb);
55} 55}
56 56
57void unregister_memory_notifier(struct notifier_block *nb) 57void unregister_memory_notifier(struct notifier_block *nb)
58{ 58{
59 notifier_chain_unregister(&memory_chain, nb); 59 blocking_notifier_chain_unregister(&memory_chain, nb);
60} 60}
61 61
62/* 62/*
@@ -140,7 +140,7 @@ static ssize_t show_mem_state(struct sys_device *dev, char *buf)
140 140
141static inline int memory_notify(unsigned long val, void *v) 141static inline int memory_notify(unsigned long val, void *v)
142{ 142{
143 return notifier_call_chain(&memory_chain, val, v); 143 return blocking_notifier_call_chain(&memory_chain, val, v);
144} 144}
145 145
146/* 146/*
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 9bdea2a5cf0e..49c7cd558ddf 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -311,11 +311,10 @@ static boolean DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
311 CommandsRemaining = CommandAllocationGroupSize; 311 CommandsRemaining = CommandAllocationGroupSize;
312 CommandGroupByteCount = 312 CommandGroupByteCount =
313 CommandsRemaining * CommandAllocationLength; 313 CommandsRemaining * CommandAllocationLength;
314 AllocationPointer = kmalloc(CommandGroupByteCount, GFP_ATOMIC); 314 AllocationPointer = kzalloc(CommandGroupByteCount, GFP_ATOMIC);
315 if (AllocationPointer == NULL) 315 if (AllocationPointer == NULL)
316 return DAC960_Failure(Controller, 316 return DAC960_Failure(Controller,
317 "AUXILIARY STRUCTURE CREATION"); 317 "AUXILIARY STRUCTURE CREATION");
318 memset(AllocationPointer, 0, CommandGroupByteCount);
319 } 318 }
320 Command = (DAC960_Command_T *) AllocationPointer; 319 Command = (DAC960_Command_T *) AllocationPointer;
321 AllocationPointer += CommandAllocationLength; 320 AllocationPointer += CommandAllocationLength;
@@ -2709,14 +2708,12 @@ DAC960_DetectController(struct pci_dev *PCI_Device,
2709 void __iomem *BaseAddress; 2708 void __iomem *BaseAddress;
2710 int i; 2709 int i;
2711 2710
2712 Controller = (DAC960_Controller_T *) 2711 Controller = kzalloc(sizeof(DAC960_Controller_T), GFP_ATOMIC);
2713 kmalloc(sizeof(DAC960_Controller_T), GFP_ATOMIC);
2714 if (Controller == NULL) { 2712 if (Controller == NULL) {
2715 DAC960_Error("Unable to allocate Controller structure for " 2713 DAC960_Error("Unable to allocate Controller structure for "
2716 "Controller at\n", NULL); 2714 "Controller at\n", NULL);
2717 return NULL; 2715 return NULL;
2718 } 2716 }
2719 memset(Controller, 0, sizeof(DAC960_Controller_T));
2720 Controller->ControllerNumber = DAC960_ControllerCount; 2717 Controller->ControllerNumber = DAC960_ControllerCount;
2721 DAC960_Controllers[DAC960_ControllerCount++] = Controller; 2718 DAC960_Controllers[DAC960_ControllerCount++] = Controller;
2722 Controller->Bus = PCI_Device->bus->number; 2719 Controller->Bus = PCI_Device->bus->number;
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 71ec9e664383..1b0fd31c57c3 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -996,13 +996,11 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
996 status = -EINVAL; 996 status = -EINVAL;
997 goto cleanup1; 997 goto cleanup1;
998 } 998 }
999 buff = (unsigned char **) kmalloc(MAXSGENTRIES * 999 buff = kzalloc(MAXSGENTRIES * sizeof(char *), GFP_KERNEL);
1000 sizeof(char *), GFP_KERNEL);
1001 if (!buff) { 1000 if (!buff) {
1002 status = -ENOMEM; 1001 status = -ENOMEM;
1003 goto cleanup1; 1002 goto cleanup1;
1004 } 1003 }
1005 memset(buff, 0, MAXSGENTRIES);
1006 buff_size = (int *) kmalloc(MAXSGENTRIES * sizeof(int), 1004 buff_size = (int *) kmalloc(MAXSGENTRIES * sizeof(int),
1007 GFP_KERNEL); 1005 GFP_KERNEL);
1008 if (!buff_size) { 1006 if (!buff_size) {
@@ -2729,9 +2727,9 @@ static void __devinit cciss_interrupt_mode(ctlr_info_t *c, struct pci_dev *pdev,
2729 return; 2727 return;
2730 } 2728 }
2731 } 2729 }
2730default_int_mode:
2732#endif /* CONFIG_PCI_MSI */ 2731#endif /* CONFIG_PCI_MSI */
2733 /* if we get here we're going to use the default interrupt mode */ 2732 /* if we get here we're going to use the default interrupt mode */
2734default_int_mode:
2735 c->intr[SIMPLE_MODE_INT] = pdev->irq; 2733 c->intr[SIMPLE_MODE_INT] = pdev->irq;
2736 return; 2734 return;
2737} 2735}
@@ -2940,13 +2938,12 @@ static void cciss_getgeometry(int cntl_num)
2940 int block_size; 2938 int block_size;
2941 int total_size; 2939 int total_size;
2942 2940
2943 ld_buff = kmalloc(sizeof(ReportLunData_struct), GFP_KERNEL); 2941 ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL);
2944 if (ld_buff == NULL) 2942 if (ld_buff == NULL)
2945 { 2943 {
2946 printk(KERN_ERR "cciss: out of memory\n"); 2944 printk(KERN_ERR "cciss: out of memory\n");
2947 return; 2945 return;
2948 } 2946 }
2949 memset(ld_buff, 0, sizeof(ReportLunData_struct));
2950 size_buff = kmalloc(sizeof( ReadCapdata_struct), GFP_KERNEL); 2947 size_buff = kmalloc(sizeof( ReadCapdata_struct), GFP_KERNEL);
2951 if (size_buff == NULL) 2948 if (size_buff == NULL)
2952 { 2949 {
@@ -3060,10 +3057,9 @@ static int alloc_cciss_hba(void)
3060 for(i=0; i< MAX_CTLR; i++) { 3057 for(i=0; i< MAX_CTLR; i++) {
3061 if (!hba[i]) { 3058 if (!hba[i]) {
3062 ctlr_info_t *p; 3059 ctlr_info_t *p;
3063 p = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL); 3060 p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL);
3064 if (!p) 3061 if (!p)
3065 goto Enomem; 3062 goto Enomem;
3066 memset(p, 0, sizeof(ctlr_info_t));
3067 for (n = 0; n < NWD; n++) 3063 for (n = 0; n < NWD; n++)
3068 p->gendisk[n] = disk[n]; 3064 p->gendisk[n] = disk[n];
3069 hba[i] = p; 3065 hba[i] = p;
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index 0e66e904bd8c..597c007fe81b 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -1027,12 +1027,11 @@ cciss_update_non_disk_devices(int cntl_num, int hostno)
1027 int i; 1027 int i;
1028 1028
1029 c = (ctlr_info_t *) hba[cntl_num]; 1029 c = (ctlr_info_t *) hba[cntl_num];
1030 ld_buff = kmalloc(reportlunsize, GFP_KERNEL); 1030 ld_buff = kzalloc(reportlunsize, GFP_KERNEL);
1031 if (ld_buff == NULL) { 1031 if (ld_buff == NULL) {
1032 printk(KERN_ERR "cciss: out of memory\n"); 1032 printk(KERN_ERR "cciss: out of memory\n");
1033 return; 1033 return;
1034 } 1034 }
1035 memset(ld_buff, 0, reportlunsize);
1036 inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL); 1035 inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
1037 if (inq_buff == NULL) { 1036 if (inq_buff == NULL) {
1038 printk(KERN_ERR "cciss: out of memory\n"); 1037 printk(KERN_ERR "cciss: out of memory\n");
diff --git a/drivers/block/paride/bpck6.c b/drivers/block/paride/bpck6.c
index 08d858ad64db..41a237c5957d 100644
--- a/drivers/block/paride/bpck6.c
+++ b/drivers/block/paride/bpck6.c
@@ -224,10 +224,9 @@ static void bpck6_log_adapter( PIA *pi, char * scratch, int verbose )
224 224
225static int bpck6_init_proto(PIA *pi) 225static int bpck6_init_proto(PIA *pi)
226{ 226{
227 Interface *p = kmalloc(sizeof(Interface), GFP_KERNEL); 227 Interface *p = kzalloc(sizeof(Interface), GFP_KERNEL);
228 228
229 if (p) { 229 if (p) {
230 memset(p, 0, sizeof(Interface));
231 pi->private = (unsigned long)p; 230 pi->private = (unsigned long)p;
232 return 0; 231 return 0;
233 } 232 }
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index facc3f1d9e37..73d30bf01582 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -696,7 +696,7 @@ config NVRAM
696 696
697config RTC 697config RTC
698 tristate "Enhanced Real Time Clock Support" 698 tristate "Enhanced Real Time Clock Support"
699 depends on !PPC && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV 699 depends on !PPC && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV && !ARM
700 ---help--- 700 ---help---
701 If you say Y here and create a character special file /dev/rtc with 701 If you say Y here and create a character special file /dev/rtc with
702 major number 10 and minor number 135 using mknod ("man mknod"), you 702 major number 10 and minor number 135 using mknod ("man mknod"), you
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index b8fb87c6c29f..40eb005b9d77 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -3744,7 +3744,7 @@ static int ipmi_init_msghandler(void)
3744 ipmi_timer.expires = jiffies + IPMI_TIMEOUT_JIFFIES; 3744 ipmi_timer.expires = jiffies + IPMI_TIMEOUT_JIFFIES;
3745 add_timer(&ipmi_timer); 3745 add_timer(&ipmi_timer);
3746 3746
3747 notifier_chain_register(&panic_notifier_list, &panic_block); 3747 atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
3748 3748
3749 initialized = 1; 3749 initialized = 1;
3750 3750
@@ -3764,7 +3764,7 @@ static __exit void cleanup_ipmi(void)
3764 if (!initialized) 3764 if (!initialized)
3765 return; 3765 return;
3766 3766
3767 notifier_chain_unregister(&panic_notifier_list, &panic_block); 3767 atomic_notifier_chain_unregister(&panic_notifier_list, &panic_block);
3768 3768
3769 /* This can't be called if any interfaces exist, so no worry about 3769 /* This can't be called if any interfaces exist, so no worry about
3770 shutting down the interfaces. */ 3770 shutting down the interfaces. */
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 12f858dc9994..35fbd4d8ed4b 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -237,10 +237,10 @@ struct smi_info
237 237
238static int try_smi_init(struct smi_info *smi); 238static int try_smi_init(struct smi_info *smi);
239 239
240static struct notifier_block *xaction_notifier_list; 240static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list);
241static int register_xaction_notifier(struct notifier_block * nb) 241static int register_xaction_notifier(struct notifier_block * nb)
242{ 242{
243 return notifier_chain_register(&xaction_notifier_list, nb); 243 return atomic_notifier_chain_register(&xaction_notifier_list, nb);
244} 244}
245 245
246static void si_restart_short_timer(struct smi_info *smi_info); 246static void si_restart_short_timer(struct smi_info *smi_info);
@@ -302,7 +302,8 @@ static enum si_sm_result start_next_msg(struct smi_info *smi_info)
302 do_gettimeofday(&t); 302 do_gettimeofday(&t);
303 printk("**Start2: %d.%9.9d\n", t.tv_sec, t.tv_usec); 303 printk("**Start2: %d.%9.9d\n", t.tv_sec, t.tv_usec);
304#endif 304#endif
305 err = notifier_call_chain(&xaction_notifier_list, 0, smi_info); 305 err = atomic_notifier_call_chain(&xaction_notifier_list,
306 0, smi_info);
306 if (err & NOTIFY_STOP_MASK) { 307 if (err & NOTIFY_STOP_MASK) {
307 rv = SI_SM_CALL_WITHOUT_DELAY; 308 rv = SI_SM_CALL_WITHOUT_DELAY;
308 goto out; 309 goto out;
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 616539310d9a..7ece9f3c8f70 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -1158,7 +1158,8 @@ static int __init ipmi_wdog_init(void)
1158 } 1158 }
1159 1159
1160 register_reboot_notifier(&wdog_reboot_notifier); 1160 register_reboot_notifier(&wdog_reboot_notifier);
1161 notifier_chain_register(&panic_notifier_list, &wdog_panic_notifier); 1161 atomic_notifier_chain_register(&panic_notifier_list,
1162 &wdog_panic_notifier);
1162 1163
1163 printk(KERN_INFO PFX "driver initialized\n"); 1164 printk(KERN_INFO PFX "driver initialized\n");
1164 1165
@@ -1176,7 +1177,8 @@ static __exit void ipmi_unregister_watchdog(void)
1176 release_nmi(&ipmi_nmi_handler); 1177 release_nmi(&ipmi_nmi_handler);
1177#endif 1178#endif
1178 1179
1179 notifier_chain_unregister(&panic_notifier_list, &wdog_panic_notifier); 1180 atomic_notifier_chain_unregister(&panic_notifier_list,
1181 &wdog_panic_notifier);
1180 unregister_reboot_notifier(&wdog_reboot_notifier); 1182 unregister_reboot_notifier(&wdog_reboot_notifier);
1181 1183
1182 if (! watchdog_user) 1184 if (! watchdog_user)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index aed80e6aec6d..9b6ae7dc8b8a 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -52,9 +52,8 @@ static void handle_update(void *data);
52 * changes to devices when the CPU clock speed changes. 52 * changes to devices when the CPU clock speed changes.
53 * The mutex locks both lists. 53 * The mutex locks both lists.
54 */ 54 */
55static struct notifier_block *cpufreq_policy_notifier_list; 55static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);
56static struct notifier_block *cpufreq_transition_notifier_list; 56static BLOCKING_NOTIFIER_HEAD(cpufreq_transition_notifier_list);
57static DECLARE_RWSEM (cpufreq_notifier_rwsem);
58 57
59 58
60static LIST_HEAD(cpufreq_governor_list); 59static LIST_HEAD(cpufreq_governor_list);
@@ -247,8 +246,6 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
247 dprintk("notification %u of frequency transition to %u kHz\n", 246 dprintk("notification %u of frequency transition to %u kHz\n",
248 state, freqs->new); 247 state, freqs->new);
249 248
250 down_read(&cpufreq_notifier_rwsem);
251
252 policy = cpufreq_cpu_data[freqs->cpu]; 249 policy = cpufreq_cpu_data[freqs->cpu];
253 switch (state) { 250 switch (state) {
254 251
@@ -266,20 +263,19 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
266 freqs->old = policy->cur; 263 freqs->old = policy->cur;
267 } 264 }
268 } 265 }
269 notifier_call_chain(&cpufreq_transition_notifier_list, 266 blocking_notifier_call_chain(&cpufreq_transition_notifier_list,
270 CPUFREQ_PRECHANGE, freqs); 267 CPUFREQ_PRECHANGE, freqs);
271 adjust_jiffies(CPUFREQ_PRECHANGE, freqs); 268 adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
272 break; 269 break;
273 270
274 case CPUFREQ_POSTCHANGE: 271 case CPUFREQ_POSTCHANGE:
275 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); 272 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
276 notifier_call_chain(&cpufreq_transition_notifier_list, 273 blocking_notifier_call_chain(&cpufreq_transition_notifier_list,
277 CPUFREQ_POSTCHANGE, freqs); 274 CPUFREQ_POSTCHANGE, freqs);
278 if (likely(policy) && likely(policy->cpu == freqs->cpu)) 275 if (likely(policy) && likely(policy->cpu == freqs->cpu))
279 policy->cur = freqs->new; 276 policy->cur = freqs->new;
280 break; 277 break;
281 } 278 }
282 up_read(&cpufreq_notifier_rwsem);
283} 279}
284EXPORT_SYMBOL_GPL(cpufreq_notify_transition); 280EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
285 281
@@ -1007,7 +1003,7 @@ static int cpufreq_suspend(struct sys_device * sysdev, pm_message_t pmsg)
1007 freqs.old = cpu_policy->cur; 1003 freqs.old = cpu_policy->cur;
1008 freqs.new = cur_freq; 1004 freqs.new = cur_freq;
1009 1005
1010 notifier_call_chain(&cpufreq_transition_notifier_list, 1006 blocking_notifier_call_chain(&cpufreq_transition_notifier_list,
1011 CPUFREQ_SUSPENDCHANGE, &freqs); 1007 CPUFREQ_SUSPENDCHANGE, &freqs);
1012 adjust_jiffies(CPUFREQ_SUSPENDCHANGE, &freqs); 1008 adjust_jiffies(CPUFREQ_SUSPENDCHANGE, &freqs);
1013 1009
@@ -1088,7 +1084,8 @@ static int cpufreq_resume(struct sys_device * sysdev)
1088 freqs.old = cpu_policy->cur; 1084 freqs.old = cpu_policy->cur;
1089 freqs.new = cur_freq; 1085 freqs.new = cur_freq;
1090 1086
1091 notifier_call_chain(&cpufreq_transition_notifier_list, 1087 blocking_notifier_call_chain(
1088 &cpufreq_transition_notifier_list,
1092 CPUFREQ_RESUMECHANGE, &freqs); 1089 CPUFREQ_RESUMECHANGE, &freqs);
1093 adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs); 1090 adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs);
1094 1091
@@ -1125,24 +1122,24 @@ static struct sysdev_driver cpufreq_sysdev_driver = {
1125 * changes in cpufreq policy. 1122 * changes in cpufreq policy.
1126 * 1123 *
1127 * This function may sleep, and has the same return conditions as 1124 * This function may sleep, and has the same return conditions as
1128 * notifier_chain_register. 1125 * blocking_notifier_chain_register.
1129 */ 1126 */
1130int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list) 1127int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1131{ 1128{
1132 int ret; 1129 int ret;
1133 1130
1134 down_write(&cpufreq_notifier_rwsem);
1135 switch (list) { 1131 switch (list) {
1136 case CPUFREQ_TRANSITION_NOTIFIER: 1132 case CPUFREQ_TRANSITION_NOTIFIER:
1137 ret = notifier_chain_register(&cpufreq_transition_notifier_list, nb); 1133 ret = blocking_notifier_chain_register(
1134 &cpufreq_transition_notifier_list, nb);
1138 break; 1135 break;
1139 case CPUFREQ_POLICY_NOTIFIER: 1136 case CPUFREQ_POLICY_NOTIFIER:
1140 ret = notifier_chain_register(&cpufreq_policy_notifier_list, nb); 1137 ret = blocking_notifier_chain_register(
1138 &cpufreq_policy_notifier_list, nb);
1141 break; 1139 break;
1142 default: 1140 default:
1143 ret = -EINVAL; 1141 ret = -EINVAL;
1144 } 1142 }
1145 up_write(&cpufreq_notifier_rwsem);
1146 1143
1147 return ret; 1144 return ret;
1148} 1145}
@@ -1157,24 +1154,24 @@ EXPORT_SYMBOL(cpufreq_register_notifier);
1157 * Remove a driver from the CPU frequency notifier list. 1154 * Remove a driver from the CPU frequency notifier list.
1158 * 1155 *
1159 * This function may sleep, and has the same return conditions as 1156 * This function may sleep, and has the same return conditions as
1160 * notifier_chain_unregister. 1157 * blocking_notifier_chain_unregister.
1161 */ 1158 */
1162int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list) 1159int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1163{ 1160{
1164 int ret; 1161 int ret;
1165 1162
1166 down_write(&cpufreq_notifier_rwsem);
1167 switch (list) { 1163 switch (list) {
1168 case CPUFREQ_TRANSITION_NOTIFIER: 1164 case CPUFREQ_TRANSITION_NOTIFIER:
1169 ret = notifier_chain_unregister(&cpufreq_transition_notifier_list, nb); 1165 ret = blocking_notifier_chain_unregister(
1166 &cpufreq_transition_notifier_list, nb);
1170 break; 1167 break;
1171 case CPUFREQ_POLICY_NOTIFIER: 1168 case CPUFREQ_POLICY_NOTIFIER:
1172 ret = notifier_chain_unregister(&cpufreq_policy_notifier_list, nb); 1169 ret = blocking_notifier_chain_unregister(
1170 &cpufreq_policy_notifier_list, nb);
1173 break; 1171 break;
1174 default: 1172 default:
1175 ret = -EINVAL; 1173 ret = -EINVAL;
1176 } 1174 }
1177 up_write(&cpufreq_notifier_rwsem);
1178 1175
1179 return ret; 1176 return ret;
1180} 1177}
@@ -1346,29 +1343,23 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli
1346 if (ret) 1343 if (ret)
1347 goto error_out; 1344 goto error_out;
1348 1345
1349 down_read(&cpufreq_notifier_rwsem);
1350
1351 /* adjust if necessary - all reasons */ 1346 /* adjust if necessary - all reasons */
1352 notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_ADJUST, 1347 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1353 policy); 1348 CPUFREQ_ADJUST, policy);
1354 1349
1355 /* adjust if necessary - hardware incompatibility*/ 1350 /* adjust if necessary - hardware incompatibility*/
1356 notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_INCOMPATIBLE, 1351 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1357 policy); 1352 CPUFREQ_INCOMPATIBLE, policy);
1358 1353
1359 /* verify the cpu speed can be set within this limit, 1354 /* verify the cpu speed can be set within this limit,
1360 which might be different to the first one */ 1355 which might be different to the first one */
1361 ret = cpufreq_driver->verify(policy); 1356 ret = cpufreq_driver->verify(policy);
1362 if (ret) { 1357 if (ret)
1363 up_read(&cpufreq_notifier_rwsem);
1364 goto error_out; 1358 goto error_out;
1365 }
1366 1359
1367 /* notification of the new policy */ 1360 /* notification of the new policy */
1368 notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_NOTIFY, 1361 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1369 policy); 1362 CPUFREQ_NOTIFY, policy);
1370
1371 up_read(&cpufreq_notifier_rwsem);
1372 1363
1373 data->min = policy->min; 1364 data->min = policy->min;
1374 data->max = policy->max; 1365 data->max = policy->max;
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c
index d6543fc4a923..339f405ff708 100644
--- a/drivers/firmware/dcdbas.c
+++ b/drivers/firmware/dcdbas.c
@@ -484,26 +484,15 @@ static void dcdbas_host_control(void)
484static int dcdbas_reboot_notify(struct notifier_block *nb, unsigned long code, 484static int dcdbas_reboot_notify(struct notifier_block *nb, unsigned long code,
485 void *unused) 485 void *unused)
486{ 486{
487 static unsigned int notify_cnt = 0;
488
489 switch (code) { 487 switch (code) {
490 case SYS_DOWN: 488 case SYS_DOWN:
491 case SYS_HALT: 489 case SYS_HALT:
492 case SYS_POWER_OFF: 490 case SYS_POWER_OFF:
493 if (host_control_on_shutdown) { 491 if (host_control_on_shutdown) {
494 /* firmware is going to perform host control action */ 492 /* firmware is going to perform host control action */
495 if (++notify_cnt == 2) { 493 printk(KERN_WARNING "Please wait for shutdown "
496 printk(KERN_WARNING 494 "action to complete...\n");
497 "Please wait for shutdown " 495 dcdbas_host_control();
498 "action to complete...\n");
499 dcdbas_host_control();
500 }
501 /*
502 * register again and initiate the host control
503 * action on the second notification to allow
504 * everyone that registered to be notified
505 */
506 register_reboot_notifier(nb);
507 } 496 }
508 break; 497 break;
509 } 498 }
@@ -514,7 +503,7 @@ static int dcdbas_reboot_notify(struct notifier_block *nb, unsigned long code,
514static struct notifier_block dcdbas_reboot_nb = { 503static struct notifier_block dcdbas_reboot_nb = {
515 .notifier_call = dcdbas_reboot_notify, 504 .notifier_call = dcdbas_reboot_notify,
516 .next = NULL, 505 .next = NULL,
517 .priority = 0 506 .priority = INT_MIN
518}; 507};
519 508
520static DCDBAS_BIN_ATTR_RW(smi_data); 509static DCDBAS_BIN_ATTR_RW(smi_data);
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
index f9fae28f5612..7aa5c38f0855 100644
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -65,15 +65,6 @@ config SENSORS_PCF8591
65 This driver can also be built as a module. If so, the module 65 This driver can also be built as a module. If so, the module
66 will be called pcf8591. 66 will be called pcf8591.
67 67
68config SENSORS_RTC8564
69 tristate "Epson 8564 RTC chip"
70 depends on I2C && EXPERIMENTAL
71 help
72 If you say yes here you get support for the Epson 8564 RTC chip.
73
74 This driver can also be built as a module. If so, the module
75 will be called i2c-rtc8564.
76
77config ISP1301_OMAP 68config ISP1301_OMAP
78 tristate "Philips ISP1301 with OMAP OTG" 69 tristate "Philips ISP1301 with OMAP OTG"
79 depends on I2C && ARCH_OMAP_OTG 70 depends on I2C && ARCH_OMAP_OTG
@@ -126,13 +117,4 @@ config SENSORS_MAX6875
126 This driver can also be built as a module. If so, the module 117 This driver can also be built as a module. If so, the module
127 will be called max6875. 118 will be called max6875.
128 119
129config RTC_X1205_I2C
130 tristate "Xicor X1205 RTC chip"
131 depends on I2C && EXPERIMENTAL
132 help
133 If you say yes here you get support for the Xicor X1205 RTC chip.
134
135 This driver can also be built as a module. If so, the module
136 will be called x1205.
137
138endmenu 120endmenu
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
index 46178b57b1f1..779868ef2e26 100644
--- a/drivers/i2c/chips/Makefile
+++ b/drivers/i2c/chips/Makefile
@@ -10,10 +10,8 @@ obj-$(CONFIG_SENSORS_M41T00) += m41t00.o
10obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o 10obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o
11obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o 11obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o
12obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o 12obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
13obj-$(CONFIG_SENSORS_RTC8564) += rtc8564.o
14obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o 13obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o
15obj-$(CONFIG_TPS65010) += tps65010.o 14obj-$(CONFIG_TPS65010) += tps65010.o
16obj-$(CONFIG_RTC_X1205_I2C) += x1205.o
17 15
18ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) 16ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
19EXTRA_CFLAGS += -DDEBUG 17EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/i2c/chips/rtc8564.c b/drivers/i2c/chips/rtc8564.c
deleted file mode 100644
index 0d8699b3f488..000000000000
--- a/drivers/i2c/chips/rtc8564.c
+++ /dev/null
@@ -1,385 +0,0 @@
1/*
2 * linux/drivers/i2c/chips/rtc8564.c
3 *
4 * Copyright (C) 2002-2004 Stefan Eletzhofer
5 *
6 * based on linux/drivers/acron/char/pcf8583.c
7 * Copyright (C) 2000 Russell King
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * Driver for system3's EPSON RTC 8564 chip
14 */
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/bcd.h>
18#include <linux/i2c.h>
19#include <linux/slab.h>
20#include <linux/string.h>
21#include <linux/rtc.h> /* get the user-level API */
22#include <linux/init.h>
23
24#include "rtc8564.h"
25
26#ifdef DEBUG
27# define _DBG(x, fmt, args...) do{ if (debug>=x) printk(KERN_DEBUG"%s: " fmt "\n", __FUNCTION__, ##args); } while(0);
28#else
29# define _DBG(x, fmt, args...) do { } while(0);
30#endif
31
32#define _DBGRTCTM(x, rtctm) if (debug>=x) printk("%s: secs=%d, mins=%d, hours=%d, mday=%d, " \
33 "mon=%d, year=%d, wday=%d VL=%d\n", __FUNCTION__, \
34 (rtctm).secs, (rtctm).mins, (rtctm).hours, (rtctm).mday, \
35 (rtctm).mon, (rtctm).year, (rtctm).wday, (rtctm).vl);
36
37struct rtc8564_data {
38 struct i2c_client client;
39 u16 ctrl;
40};
41
42static inline u8 _rtc8564_ctrl1(struct i2c_client *client)
43{
44 struct rtc8564_data *data = i2c_get_clientdata(client);
45 return data->ctrl & 0xff;
46}
47static inline u8 _rtc8564_ctrl2(struct i2c_client *client)
48{
49 struct rtc8564_data *data = i2c_get_clientdata(client);
50 return (data->ctrl & 0xff00) >> 8;
51}
52
53#define CTRL1(c) _rtc8564_ctrl1(c)
54#define CTRL2(c) _rtc8564_ctrl2(c)
55
56static int debug;
57module_param(debug, int, S_IRUGO | S_IWUSR);
58
59static struct i2c_driver rtc8564_driver;
60
61static unsigned short ignore[] = { I2C_CLIENT_END };
62static unsigned short normal_addr[] = { 0x51, I2C_CLIENT_END };
63
64static struct i2c_client_address_data addr_data = {
65 .normal_i2c = normal_addr,
66 .probe = ignore,
67 .ignore = ignore,
68};
69
70static int rtc8564_read_mem(struct i2c_client *client, struct mem *mem);
71static int rtc8564_write_mem(struct i2c_client *client, struct mem *mem);
72
73static int rtc8564_read(struct i2c_client *client, unsigned char adr,
74 unsigned char *buf, unsigned char len)
75{
76 int ret = -EIO;
77 unsigned char addr[1] = { adr };
78 struct i2c_msg msgs[2] = {
79 {client->addr, 0, 1, addr},
80 {client->addr, I2C_M_RD, len, buf}
81 };
82
83 _DBG(1, "client=%p, adr=%d, buf=%p, len=%d", client, adr, buf, len);
84
85 if (!buf) {
86 ret = -EINVAL;
87 goto done;
88 }
89
90 ret = i2c_transfer(client->adapter, msgs, 2);
91 if (ret == 2) {
92 ret = 0;
93 }
94
95done:
96 return ret;
97}
98
99static int rtc8564_write(struct i2c_client *client, unsigned char adr,
100 unsigned char *data, unsigned char len)
101{
102 int ret = 0;
103 unsigned char _data[16];
104 struct i2c_msg wr;
105 int i;
106
107 if (!data || len > 15) {
108 ret = -EINVAL;
109 goto done;
110 }
111
112 _DBG(1, "client=%p, adr=%d, buf=%p, len=%d", client, adr, data, len);
113
114 _data[0] = adr;
115 for (i = 0; i < len; i++) {
116 _data[i + 1] = data[i];
117 _DBG(5, "data[%d] = 0x%02x (%d)", i, data[i], data[i]);
118 }
119
120 wr.addr = client->addr;
121 wr.flags = 0;
122 wr.len = len + 1;
123 wr.buf = _data;
124
125 ret = i2c_transfer(client->adapter, &wr, 1);
126 if (ret == 1) {
127 ret = 0;
128 }
129
130done:
131 return ret;
132}
133
134static int rtc8564_attach(struct i2c_adapter *adap, int addr, int kind)
135{
136 int ret;
137 struct i2c_client *new_client;
138 struct rtc8564_data *d;
139 unsigned char data[10];
140 unsigned char ad[1] = { 0 };
141 struct i2c_msg ctrl_wr[1] = {
142 {addr, 0, 2, data}
143 };
144 struct i2c_msg ctrl_rd[2] = {
145 {addr, 0, 1, ad},
146 {addr, I2C_M_RD, 2, data}
147 };
148
149 d = kzalloc(sizeof(struct rtc8564_data), GFP_KERNEL);
150 if (!d) {
151 ret = -ENOMEM;
152 goto done;
153 }
154 new_client = &d->client;
155
156 strlcpy(new_client->name, "RTC8564", I2C_NAME_SIZE);
157 i2c_set_clientdata(new_client, d);
158 new_client->addr = addr;
159 new_client->adapter = adap;
160 new_client->driver = &rtc8564_driver;
161
162 _DBG(1, "client=%p", new_client);
163
164 /* init ctrl1 reg */
165 data[0] = 0;
166 data[1] = 0;
167 ret = i2c_transfer(new_client->adapter, ctrl_wr, 1);
168 if (ret != 1) {
169 printk(KERN_INFO "rtc8564: cant init ctrl1\n");
170 ret = -ENODEV;
171 goto done;
172 }
173
174 /* read back ctrl1 and ctrl2 */
175 ret = i2c_transfer(new_client->adapter, ctrl_rd, 2);
176 if (ret != 2) {
177 printk(KERN_INFO "rtc8564: cant read ctrl\n");
178 ret = -ENODEV;
179 goto done;
180 }
181
182 d->ctrl = data[0] | (data[1] << 8);
183
184 _DBG(1, "RTC8564_REG_CTRL1=%02x, RTC8564_REG_CTRL2=%02x",
185 data[0], data[1]);
186
187 ret = i2c_attach_client(new_client);
188done:
189 if (ret) {
190 kfree(d);
191 }
192 return ret;
193}
194
195static int rtc8564_probe(struct i2c_adapter *adap)
196{
197 return i2c_probe(adap, &addr_data, rtc8564_attach);
198}
199
200static int rtc8564_detach(struct i2c_client *client)
201{
202 i2c_detach_client(client);
203 kfree(i2c_get_clientdata(client));
204 return 0;
205}
206
207static int rtc8564_get_datetime(struct i2c_client *client, struct rtc_tm *dt)
208{
209 int ret = -EIO;
210 unsigned char buf[15];
211
212 _DBG(1, "client=%p, dt=%p", client, dt);
213
214 if (!dt)
215 return -EINVAL;
216
217 memset(buf, 0, sizeof(buf));
218
219 ret = rtc8564_read(client, 0, buf, 15);
220 if (ret)
221 return ret;
222
223 /* century stored in minute alarm reg */
224 dt->year = BCD2BIN(buf[RTC8564_REG_YEAR]);
225 dt->year += 100 * BCD2BIN(buf[RTC8564_REG_AL_MIN] & 0x3f);
226 dt->mday = BCD2BIN(buf[RTC8564_REG_DAY] & 0x3f);
227 dt->wday = BCD2BIN(buf[RTC8564_REG_WDAY] & 7);
228 dt->mon = BCD2BIN(buf[RTC8564_REG_MON_CENT] & 0x1f);
229
230 dt->secs = BCD2BIN(buf[RTC8564_REG_SEC] & 0x7f);
231 dt->vl = (buf[RTC8564_REG_SEC] & 0x80) == 0x80;
232 dt->mins = BCD2BIN(buf[RTC8564_REG_MIN] & 0x7f);
233 dt->hours = BCD2BIN(buf[RTC8564_REG_HR] & 0x3f);
234
235 _DBGRTCTM(2, *dt);
236
237 return 0;
238}
239
240static int
241rtc8564_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo)
242{
243 int ret, len = 5;
244 unsigned char buf[15];
245
246 _DBG(1, "client=%p, dt=%p", client, dt);
247
248 if (!dt)
249 return -EINVAL;
250
251 _DBGRTCTM(2, *dt);
252
253 buf[RTC8564_REG_CTRL1] = CTRL1(client) | RTC8564_CTRL1_STOP;
254 buf[RTC8564_REG_CTRL2] = CTRL2(client);
255 buf[RTC8564_REG_SEC] = BIN2BCD(dt->secs);
256 buf[RTC8564_REG_MIN] = BIN2BCD(dt->mins);
257 buf[RTC8564_REG_HR] = BIN2BCD(dt->hours);
258
259 if (datetoo) {
260 len += 5;
261 buf[RTC8564_REG_DAY] = BIN2BCD(dt->mday);
262 buf[RTC8564_REG_WDAY] = BIN2BCD(dt->wday);
263 buf[RTC8564_REG_MON_CENT] = BIN2BCD(dt->mon) & 0x1f;
264 /* century stored in minute alarm reg */
265 buf[RTC8564_REG_YEAR] = BIN2BCD(dt->year % 100);
266 buf[RTC8564_REG_AL_MIN] = BIN2BCD(dt->year / 100);
267 }
268
269 ret = rtc8564_write(client, 0, buf, len);
270 if (ret) {
271 _DBG(1, "error writing data! %d", ret);
272 }
273
274 buf[RTC8564_REG_CTRL1] = CTRL1(client);
275 ret = rtc8564_write(client, 0, buf, 1);
276 if (ret) {
277 _DBG(1, "error writing data! %d", ret);
278 }
279
280 return ret;
281}
282
283static int rtc8564_get_ctrl(struct i2c_client *client, unsigned int *ctrl)
284{
285 struct rtc8564_data *data = i2c_get_clientdata(client);
286
287 if (!ctrl)
288 return -1;
289
290 *ctrl = data->ctrl;
291 return 0;
292}
293
294static int rtc8564_set_ctrl(struct i2c_client *client, unsigned int *ctrl)
295{
296 struct rtc8564_data *data = i2c_get_clientdata(client);
297 unsigned char buf[2];
298
299 if (!ctrl)
300 return -1;
301
302 buf[0] = *ctrl & 0xff;
303 buf[1] = (*ctrl & 0xff00) >> 8;
304 data->ctrl = *ctrl;
305
306 return rtc8564_write(client, 0, buf, 2);
307}
308
309static int rtc8564_read_mem(struct i2c_client *client, struct mem *mem)
310{
311
312 if (!mem)
313 return -EINVAL;
314
315 return rtc8564_read(client, mem->loc, mem->data, mem->nr);
316}
317
318static int rtc8564_write_mem(struct i2c_client *client, struct mem *mem)
319{
320
321 if (!mem)
322 return -EINVAL;
323
324 return rtc8564_write(client, mem->loc, mem->data, mem->nr);
325}
326
327static int
328rtc8564_command(struct i2c_client *client, unsigned int cmd, void *arg)
329{
330
331 _DBG(1, "cmd=%d", cmd);
332
333 switch (cmd) {
334 case RTC_GETDATETIME:
335 return rtc8564_get_datetime(client, arg);
336
337 case RTC_SETTIME:
338 return rtc8564_set_datetime(client, arg, 0);
339
340 case RTC_SETDATETIME:
341 return rtc8564_set_datetime(client, arg, 1);
342
343 case RTC_GETCTRL:
344 return rtc8564_get_ctrl(client, arg);
345
346 case RTC_SETCTRL:
347 return rtc8564_set_ctrl(client, arg);
348
349 case MEM_READ:
350 return rtc8564_read_mem(client, arg);
351
352 case MEM_WRITE:
353 return rtc8564_write_mem(client, arg);
354
355 default:
356 return -EINVAL;
357 }
358}
359
360static struct i2c_driver rtc8564_driver = {
361 .driver = {
362 .name = "RTC8564",
363 },
364 .id = I2C_DRIVERID_RTC8564,
365 .attach_adapter = rtc8564_probe,
366 .detach_client = rtc8564_detach,
367 .command = rtc8564_command
368};
369
370static __init int rtc8564_init(void)
371{
372 return i2c_add_driver(&rtc8564_driver);
373}
374
375static __exit void rtc8564_exit(void)
376{
377 i2c_del_driver(&rtc8564_driver);
378}
379
380MODULE_AUTHOR("Stefan Eletzhofer <Stefan.Eletzhofer@eletztrick.de>");
381MODULE_DESCRIPTION("EPSON RTC8564 Driver");
382MODULE_LICENSE("GPL");
383
384module_init(rtc8564_init);
385module_exit(rtc8564_exit);
diff --git a/drivers/i2c/chips/rtc8564.h b/drivers/i2c/chips/rtc8564.h
deleted file mode 100644
index e5342d10b8fa..000000000000
--- a/drivers/i2c/chips/rtc8564.h
+++ /dev/null
@@ -1,78 +0,0 @@
1/*
2 * linux/drivers/i2c/chips/rtc8564.h
3 *
4 * Copyright (C) 2002-2004 Stefan Eletzhofer
5 *
6 * based on linux/drivers/acron/char/pcf8583.h
7 * Copyright (C) 2000 Russell King
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13struct rtc_tm {
14 unsigned char secs;
15 unsigned char mins;
16 unsigned char hours;
17 unsigned char mday;
18 unsigned char mon;
19 unsigned short year; /* xxxx 4 digits :) */
20 unsigned char wday;
21 unsigned char vl;
22};
23
24struct mem {
25 unsigned int loc;
26 unsigned int nr;
27 unsigned char *data;
28};
29
30#define RTC_GETDATETIME 0
31#define RTC_SETTIME 1
32#define RTC_SETDATETIME 2
33#define RTC_GETCTRL 3
34#define RTC_SETCTRL 4
35#define MEM_READ 5
36#define MEM_WRITE 6
37
38#define RTC8564_REG_CTRL1 0x0 /* T 0 S 0 | T 0 0 0 */
39#define RTC8564_REG_CTRL2 0x1 /* 0 0 0 TI/TP | AF TF AIE TIE */
40#define RTC8564_REG_SEC 0x2 /* VL 4 2 1 | 8 4 2 1 */
41#define RTC8564_REG_MIN 0x3 /* x 4 2 1 | 8 4 2 1 */
42#define RTC8564_REG_HR 0x4 /* x x 2 1 | 8 4 2 1 */
43#define RTC8564_REG_DAY 0x5 /* x x 2 1 | 8 4 2 1 */
44#define RTC8564_REG_WDAY 0x6 /* x x x x | x 4 2 1 */
45#define RTC8564_REG_MON_CENT 0x7 /* C x x 1 | 8 4 2 1 */
46#define RTC8564_REG_YEAR 0x8 /* 8 4 2 1 | 8 4 2 1 */
47#define RTC8564_REG_AL_MIN 0x9 /* AE 4 2 1 | 8 4 2 1 */
48#define RTC8564_REG_AL_HR 0xa /* AE 4 2 1 | 8 4 2 1 */
49#define RTC8564_REG_AL_DAY 0xb /* AE x 2 1 | 8 4 2 1 */
50#define RTC8564_REG_AL_WDAY 0xc /* AE x x x | x 4 2 1 */
51#define RTC8564_REG_CLKOUT 0xd /* FE x x x | x x FD1 FD0 */
52#define RTC8564_REG_TCTL 0xe /* TE x x x | x x FD1 FD0 */
53#define RTC8564_REG_TIMER 0xf /* 8 bit binary */
54
55/* Control reg */
56#define RTC8564_CTRL1_TEST1 (1<<3)
57#define RTC8564_CTRL1_STOP (1<<5)
58#define RTC8564_CTRL1_TEST2 (1<<7)
59
60#define RTC8564_CTRL2_TIE (1<<0)
61#define RTC8564_CTRL2_AIE (1<<1)
62#define RTC8564_CTRL2_TF (1<<2)
63#define RTC8564_CTRL2_AF (1<<3)
64#define RTC8564_CTRL2_TI_TP (1<<4)
65
66/* CLKOUT frequencies */
67#define RTC8564_FD_32768HZ (0x0)
68#define RTC8564_FD_1024HZ (0x1)
69#define RTC8564_FD_32 (0x2)
70#define RTC8564_FD_1HZ (0x3)
71
72/* Timer CTRL */
73#define RTC8564_TD_4096HZ (0x0)
74#define RTC8564_TD_64HZ (0x1)
75#define RTC8564_TD_1HZ (0x2)
76#define RTC8564_TD_1_60HZ (0x3)
77
78#define I2C_DRIVERID_RTC8564 0xf000
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index c7671e188017..b4a41d6d0714 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -2143,6 +2143,7 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
2143 req.cmd[0] = GPCMD_READ_CDVD_CAPACITY; 2143 req.cmd[0] = GPCMD_READ_CDVD_CAPACITY;
2144 req.data = (char *)&capbuf; 2144 req.data = (char *)&capbuf;
2145 req.data_len = sizeof(capbuf); 2145 req.data_len = sizeof(capbuf);
2146 req.flags |= REQ_QUIET;
2146 2147
2147 stat = cdrom_queue_packet_command(drive, &req); 2148 stat = cdrom_queue_packet_command(drive, &req);
2148 if (stat == 0) { 2149 if (stat == 0) {
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
index d2ead1776c16..34fcabac5fdb 100644
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -80,7 +80,7 @@ static struct adb_driver *adb_driver_list[] = {
80static struct class *adb_dev_class; 80static struct class *adb_dev_class;
81 81
82struct adb_driver *adb_controller; 82struct adb_driver *adb_controller;
83struct notifier_block *adb_client_list = NULL; 83BLOCKING_NOTIFIER_HEAD(adb_client_list);
84static int adb_got_sleep; 84static int adb_got_sleep;
85static int adb_inited; 85static int adb_inited;
86static pid_t adb_probe_task_pid; 86static pid_t adb_probe_task_pid;
@@ -354,7 +354,8 @@ adb_notify_sleep(struct pmu_sleep_notifier *self, int when)
354 /* Stop autopoll */ 354 /* Stop autopoll */
355 if (adb_controller->autopoll) 355 if (adb_controller->autopoll)
356 adb_controller->autopoll(0); 356 adb_controller->autopoll(0);
357 ret = notifier_call_chain(&adb_client_list, ADB_MSG_POWERDOWN, NULL); 357 ret = blocking_notifier_call_chain(&adb_client_list,
358 ADB_MSG_POWERDOWN, NULL);
358 if (ret & NOTIFY_STOP_MASK) { 359 if (ret & NOTIFY_STOP_MASK) {
359 up(&adb_probe_mutex); 360 up(&adb_probe_mutex);
360 return PBOOK_SLEEP_REFUSE; 361 return PBOOK_SLEEP_REFUSE;
@@ -391,7 +392,8 @@ do_adb_reset_bus(void)
391 if (adb_controller->autopoll) 392 if (adb_controller->autopoll)
392 adb_controller->autopoll(0); 393 adb_controller->autopoll(0);
393 394
394 nret = notifier_call_chain(&adb_client_list, ADB_MSG_PRE_RESET, NULL); 395 nret = blocking_notifier_call_chain(&adb_client_list,
396 ADB_MSG_PRE_RESET, NULL);
395 if (nret & NOTIFY_STOP_MASK) { 397 if (nret & NOTIFY_STOP_MASK) {
396 if (adb_controller->autopoll) 398 if (adb_controller->autopoll)
397 adb_controller->autopoll(autopoll_devs); 399 adb_controller->autopoll(autopoll_devs);
@@ -426,7 +428,8 @@ do_adb_reset_bus(void)
426 } 428 }
427 up(&adb_handler_sem); 429 up(&adb_handler_sem);
428 430
429 nret = notifier_call_chain(&adb_client_list, ADB_MSG_POST_RESET, NULL); 431 nret = blocking_notifier_call_chain(&adb_client_list,
432 ADB_MSG_POST_RESET, NULL);
430 if (nret & NOTIFY_STOP_MASK) 433 if (nret & NOTIFY_STOP_MASK)
431 return -EBUSY; 434 return -EBUSY;
432 435
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
index c0b46bceb5df..f5779a73184d 100644
--- a/drivers/macintosh/adbhid.c
+++ b/drivers/macintosh/adbhid.c
@@ -1214,7 +1214,8 @@ static int __init adbhid_init(void)
1214 1214
1215 adbhid_probe(); 1215 adbhid_probe();
1216 1216
1217 notifier_chain_register(&adb_client_list, &adbhid_adb_notifier); 1217 blocking_notifier_chain_register(&adb_client_list,
1218 &adbhid_adb_notifier);
1218 1219
1219 return 0; 1220 return 0;
1220} 1221}
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index 4f5f3abc9cb3..0b5ff553e39a 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -187,7 +187,7 @@ extern int disable_kernel_backlight;
187 187
188int __fake_sleep; 188int __fake_sleep;
189int asleep; 189int asleep;
190struct notifier_block *sleep_notifier_list; 190BLOCKING_NOTIFIER_HEAD(sleep_notifier_list);
191 191
192#ifdef CONFIG_ADB 192#ifdef CONFIG_ADB
193static int adb_dev_map = 0; 193static int adb_dev_map = 0;
diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c
index f08e52f2107b..35b70323e7e3 100644
--- a/drivers/macintosh/via-pmu68k.c
+++ b/drivers/macintosh/via-pmu68k.c
@@ -102,7 +102,7 @@ static int pmu_kind = PMU_UNKNOWN;
102static int pmu_fully_inited = 0; 102static int pmu_fully_inited = 0;
103 103
104int asleep; 104int asleep;
105struct notifier_block *sleep_notifier_list; 105BLOCKING_NOTIFIER_HEAD(sleep_notifier_list);
106 106
107static int pmu_probe(void); 107static int pmu_probe(void);
108static int pmu_init(void); 108static int pmu_init(void);
@@ -913,7 +913,8 @@ int powerbook_sleep(void)
913 struct adb_request sleep_req; 913 struct adb_request sleep_req;
914 914
915 /* Notify device drivers */ 915 /* Notify device drivers */
916 ret = notifier_call_chain(&sleep_notifier_list, PBOOK_SLEEP, NULL); 916 ret = blocking_notifier_call_chain(&sleep_notifier_list,
917 PBOOK_SLEEP, NULL);
917 if (ret & NOTIFY_STOP_MASK) 918 if (ret & NOTIFY_STOP_MASK)
918 return -EBUSY; 919 return -EBUSY;
919 920
@@ -984,7 +985,7 @@ int powerbook_sleep(void)
984 enable_irq(i); 985 enable_irq(i);
985 986
986 /* Notify drivers */ 987 /* Notify drivers */
987 notifier_call_chain(&sleep_notifier_list, PBOOK_WAKE, NULL); 988 blocking_notifier_call_chain(&sleep_notifier_list, PBOOK_WAKE, NULL);
988 989
989 /* reenable ADB autopoll */ 990 /* reenable ADB autopoll */
990 pmu_adb_autopoll(adb_dev_map); 991 pmu_adb_autopoll(adb_dev_map);
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c
index 6c0ba04bc57a..ab3faa702d58 100644
--- a/drivers/macintosh/windfarm_core.c
+++ b/drivers/macintosh/windfarm_core.c
@@ -52,7 +52,7 @@
52static LIST_HEAD(wf_controls); 52static LIST_HEAD(wf_controls);
53static LIST_HEAD(wf_sensors); 53static LIST_HEAD(wf_sensors);
54static DEFINE_MUTEX(wf_lock); 54static DEFINE_MUTEX(wf_lock);
55static struct notifier_block *wf_client_list; 55static BLOCKING_NOTIFIER_HEAD(wf_client_list);
56static int wf_client_count; 56static int wf_client_count;
57static unsigned int wf_overtemp; 57static unsigned int wf_overtemp;
58static unsigned int wf_overtemp_counter; 58static unsigned int wf_overtemp_counter;
@@ -68,7 +68,7 @@ static struct platform_device wf_platform_device = {
68 68
69static inline void wf_notify(int event, void *param) 69static inline void wf_notify(int event, void *param)
70{ 70{
71 notifier_call_chain(&wf_client_list, event, param); 71 blocking_notifier_call_chain(&wf_client_list, event, param);
72} 72}
73 73
74int wf_critical_overtemp(void) 74int wf_critical_overtemp(void)
@@ -398,7 +398,7 @@ int wf_register_client(struct notifier_block *nb)
398 struct wf_sensor *sr; 398 struct wf_sensor *sr;
399 399
400 mutex_lock(&wf_lock); 400 mutex_lock(&wf_lock);
401 rc = notifier_chain_register(&wf_client_list, nb); 401 rc = blocking_notifier_chain_register(&wf_client_list, nb);
402 if (rc != 0) 402 if (rc != 0)
403 goto bail; 403 goto bail;
404 wf_client_count++; 404 wf_client_count++;
@@ -417,7 +417,7 @@ EXPORT_SYMBOL_GPL(wf_register_client);
417int wf_unregister_client(struct notifier_block *nb) 417int wf_unregister_client(struct notifier_block *nb)
418{ 418{
419 mutex_lock(&wf_lock); 419 mutex_lock(&wf_lock);
420 notifier_chain_unregister(&wf_client_list, nb); 420 blocking_notifier_chain_unregister(&wf_client_list, nb);
421 wf_client_count++; 421 wf_client_count++;
422 if (wf_client_count == 0) 422 if (wf_client_count == 0)
423 wf_stop_thread(); 423 wf_stop_thread();
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
index ac43f98062fd..fd2aae150ccc 100644
--- a/drivers/md/Kconfig
+++ b/drivers/md/Kconfig
@@ -127,6 +127,32 @@ config MD_RAID5
127 127
128 If unsure, say Y. 128 If unsure, say Y.
129 129
130config MD_RAID5_RESHAPE
131 bool "Support adding drives to a raid-5 array (experimental)"
132 depends on MD_RAID5 && EXPERIMENTAL
133 ---help---
134 A RAID-5 set can be expanded by adding extra drives. This
135 requires "restriping" the array which means (almost) every
136 block must be written to a different place.
137
138 This option allows such restriping to be done while the array
139 is online. However it is still EXPERIMENTAL code. It should
140 work, but please be sure that you have backups.
141
142 You will need a version of mdadm newer than 2.3.1. During the
143 early stage of reshape there is a critical section where live data
144 is being over-written. A crash during this time needs extra care
145 for recovery. The newer mdadm takes a copy of the data in the
146 critical section and will restore it, if necessary, after a crash.
147
148 The mdadm usage is e.g.
149 mdadm --grow /dev/md1 --raid-disks=6
150 to grow '/dev/md1' to having 6 disks.
151
152 Note: The array can only be expanded, not contracted.
153 There should be enough spares already present to make the new
154 array workable.
155
130config MD_RAID6 156config MD_RAID6
131 tristate "RAID-6 mode" 157 tristate "RAID-6 mode"
132 depends on BLK_DEV_MD 158 depends on BLK_DEV_MD
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 259e86f26549..61a590bb6241 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -518,6 +518,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
518 char *ivopts; 518 char *ivopts;
519 unsigned int crypto_flags; 519 unsigned int crypto_flags;
520 unsigned int key_size; 520 unsigned int key_size;
521 unsigned long long tmpll;
521 522
522 if (argc != 5) { 523 if (argc != 5) {
523 ti->error = PFX "Not enough arguments"; 524 ti->error = PFX "Not enough arguments";
@@ -633,15 +634,17 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
633 goto bad5; 634 goto bad5;
634 } 635 }
635 636
636 if (sscanf(argv[2], SECTOR_FORMAT, &cc->iv_offset) != 1) { 637 if (sscanf(argv[2], "%llu", &tmpll) != 1) {
637 ti->error = PFX "Invalid iv_offset sector"; 638 ti->error = PFX "Invalid iv_offset sector";
638 goto bad5; 639 goto bad5;
639 } 640 }
641 cc->iv_offset = tmpll;
640 642
641 if (sscanf(argv[4], SECTOR_FORMAT, &cc->start) != 1) { 643 if (sscanf(argv[4], "%llu", &tmpll) != 1) {
642 ti->error = PFX "Invalid device sector"; 644 ti->error = PFX "Invalid device sector";
643 goto bad5; 645 goto bad5;
644 } 646 }
647 cc->start = tmpll;
645 648
646 if (dm_get_device(ti, argv[3], cc->start, ti->len, 649 if (dm_get_device(ti, argv[3], cc->start, ti->len,
647 dm_table_get_mode(ti->table), &cc->dev)) { 650 dm_table_get_mode(ti->table), &cc->dev)) {
@@ -885,8 +888,8 @@ static int crypt_status(struct dm_target *ti, status_type_t type,
885 result[sz++] = '-'; 888 result[sz++] = '-';
886 } 889 }
887 890
888 DMEMIT(" " SECTOR_FORMAT " %s " SECTOR_FORMAT, 891 DMEMIT(" %llu %s %llu", (unsigned long long)cc->iv_offset,
889 cc->iv_offset, cc->dev->name, cc->start); 892 cc->dev->name, (unsigned long long)cc->start);
890 break; 893 break;
891 } 894 }
892 return 0; 895 return 0;
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 442e2be6052e..8edd6435414d 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -15,6 +15,7 @@
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/devfs_fs_kernel.h> 16#include <linux/devfs_fs_kernel.h>
17#include <linux/dm-ioctl.h> 17#include <linux/dm-ioctl.h>
18#include <linux/hdreg.h>
18 19
19#include <asm/uaccess.h> 20#include <asm/uaccess.h>
20 21
@@ -244,9 +245,9 @@ static void __hash_remove(struct hash_cell *hc)
244 dm_table_put(table); 245 dm_table_put(table);
245 } 246 }
246 247
247 dm_put(hc->md);
248 if (hc->new_map) 248 if (hc->new_map)
249 dm_table_put(hc->new_map); 249 dm_table_put(hc->new_map);
250 dm_put(hc->md);
250 free_cell(hc); 251 free_cell(hc);
251} 252}
252 253
@@ -600,12 +601,22 @@ static int dev_create(struct dm_ioctl *param, size_t param_size)
600 */ 601 */
601static struct hash_cell *__find_device_hash_cell(struct dm_ioctl *param) 602static struct hash_cell *__find_device_hash_cell(struct dm_ioctl *param)
602{ 603{
604 struct mapped_device *md;
605 void *mdptr = NULL;
606
603 if (*param->uuid) 607 if (*param->uuid)
604 return __get_uuid_cell(param->uuid); 608 return __get_uuid_cell(param->uuid);
605 else if (*param->name) 609
610 if (*param->name)
606 return __get_name_cell(param->name); 611 return __get_name_cell(param->name);
607 else 612
608 return dm_get_mdptr(huge_decode_dev(param->dev)); 613 md = dm_get_md(huge_decode_dev(param->dev));
614 if (md) {
615 mdptr = dm_get_mdptr(md);
616 dm_put(md);
617 }
618
619 return mdptr;
609} 620}
610 621
611static struct mapped_device *find_device(struct dm_ioctl *param) 622static struct mapped_device *find_device(struct dm_ioctl *param)
@@ -690,6 +701,54 @@ static int dev_rename(struct dm_ioctl *param, size_t param_size)
690 return dm_hash_rename(param->name, new_name); 701 return dm_hash_rename(param->name, new_name);
691} 702}
692 703
704static int dev_set_geometry(struct dm_ioctl *param, size_t param_size)
705{
706 int r = -EINVAL, x;
707 struct mapped_device *md;
708 struct hd_geometry geometry;
709 unsigned long indata[4];
710 char *geostr = (char *) param + param->data_start;
711
712 md = find_device(param);
713 if (!md)
714 return -ENXIO;
715
716 if (geostr < (char *) (param + 1) ||
717 invalid_str(geostr, (void *) param + param_size)) {
718 DMWARN("Invalid geometry supplied.");
719 goto out;
720 }
721
722 x = sscanf(geostr, "%lu %lu %lu %lu", indata,
723 indata + 1, indata + 2, indata + 3);
724
725 if (x != 4) {
726 DMWARN("Unable to interpret geometry settings.");
727 goto out;
728 }
729
730 if (indata[0] > 65535 || indata[1] > 255 ||
731 indata[2] > 255 || indata[3] > ULONG_MAX) {
732 DMWARN("Geometry exceeds range limits.");
733 goto out;
734 }
735
736 geometry.cylinders = indata[0];
737 geometry.heads = indata[1];
738 geometry.sectors = indata[2];
739 geometry.start = indata[3];
740
741 r = dm_set_geometry(md, &geometry);
742 if (!r)
743 r = __dev_status(md, param);
744
745 param->data_size = 0;
746
747out:
748 dm_put(md);
749 return r;
750}
751
693static int do_suspend(struct dm_ioctl *param) 752static int do_suspend(struct dm_ioctl *param)
694{ 753{
695 int r = 0; 754 int r = 0;
@@ -975,33 +1034,43 @@ static int table_load(struct dm_ioctl *param, size_t param_size)
975 int r; 1034 int r;
976 struct hash_cell *hc; 1035 struct hash_cell *hc;
977 struct dm_table *t; 1036 struct dm_table *t;
1037 struct mapped_device *md;
978 1038
979 r = dm_table_create(&t, get_mode(param), param->target_count); 1039 md = find_device(param);
1040 if (!md)
1041 return -ENXIO;
1042
1043 r = dm_table_create(&t, get_mode(param), param->target_count, md);
980 if (r) 1044 if (r)
981 return r; 1045 goto out;
982 1046
983 r = populate_table(t, param, param_size); 1047 r = populate_table(t, param, param_size);
984 if (r) { 1048 if (r) {
985 dm_table_put(t); 1049 dm_table_put(t);
986 return r; 1050 goto out;
987 } 1051 }
988 1052
989 down_write(&_hash_lock); 1053 down_write(&_hash_lock);
990 hc = __find_device_hash_cell(param); 1054 hc = dm_get_mdptr(md);
991 if (!hc) { 1055 if (!hc || hc->md != md) {
992 DMWARN("device doesn't appear to be in the dev hash table."); 1056 DMWARN("device has been removed from the dev hash table.");
993 up_write(&_hash_lock);
994 dm_table_put(t); 1057 dm_table_put(t);
995 return -ENXIO; 1058 up_write(&_hash_lock);
1059 r = -ENXIO;
1060 goto out;
996 } 1061 }
997 1062
998 if (hc->new_map) 1063 if (hc->new_map)
999 dm_table_put(hc->new_map); 1064 dm_table_put(hc->new_map);
1000 hc->new_map = t; 1065 hc->new_map = t;
1066 up_write(&_hash_lock);
1067
1001 param->flags |= DM_INACTIVE_PRESENT_FLAG; 1068 param->flags |= DM_INACTIVE_PRESENT_FLAG;
1069 r = __dev_status(md, param);
1070
1071out:
1072 dm_put(md);
1002 1073
1003 r = __dev_status(hc->md, param);
1004 up_write(&_hash_lock);
1005 return r; 1074 return r;
1006} 1075}
1007 1076
@@ -1214,7 +1283,8 @@ static ioctl_fn lookup_ioctl(unsigned int cmd)
1214 1283
1215 {DM_LIST_VERSIONS_CMD, list_versions}, 1284 {DM_LIST_VERSIONS_CMD, list_versions},
1216 1285
1217 {DM_TARGET_MSG_CMD, target_message} 1286 {DM_TARGET_MSG_CMD, target_message},
1287 {DM_DEV_SET_GEOMETRY_CMD, dev_set_geometry}
1218 }; 1288 };
1219 1289
1220 return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn; 1290 return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn;
diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
index 6a2cd5dc8a63..daf586c0898d 100644
--- a/drivers/md/dm-linear.c
+++ b/drivers/md/dm-linear.c
@@ -26,6 +26,7 @@ struct linear_c {
26static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv) 26static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv)
27{ 27{
28 struct linear_c *lc; 28 struct linear_c *lc;
29 unsigned long long tmp;
29 30
30 if (argc != 2) { 31 if (argc != 2) {
31 ti->error = "dm-linear: Invalid argument count"; 32 ti->error = "dm-linear: Invalid argument count";
@@ -38,10 +39,11 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv)
38 return -ENOMEM; 39 return -ENOMEM;
39 } 40 }
40 41
41 if (sscanf(argv[1], SECTOR_FORMAT, &lc->start) != 1) { 42 if (sscanf(argv[1], "%llu", &tmp) != 1) {
42 ti->error = "dm-linear: Invalid device sector"; 43 ti->error = "dm-linear: Invalid device sector";
43 goto bad; 44 goto bad;
44 } 45 }
46 lc->start = tmp;
45 47
46 if (dm_get_device(ti, argv[0], lc->start, ti->len, 48 if (dm_get_device(ti, argv[0], lc->start, ti->len,
47 dm_table_get_mode(ti->table), &lc->dev)) { 49 dm_table_get_mode(ti->table), &lc->dev)) {
@@ -87,8 +89,8 @@ static int linear_status(struct dm_target *ti, status_type_t type,
87 break; 89 break;
88 90
89 case STATUSTYPE_TABLE: 91 case STATUSTYPE_TABLE:
90 snprintf(result, maxlen, "%s " SECTOR_FORMAT, lc->dev->name, 92 snprintf(result, maxlen, "%s %llu", lc->dev->name,
91 lc->start); 93 (unsigned long long)lc->start);
92 break; 94 break;
93 } 95 }
94 return 0; 96 return 0;
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 4e90f231fbfb..d12cf3e5e076 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -402,9 +402,21 @@ static void rh_dec(struct region_hash *rh, region_t region)
402 402
403 spin_lock_irqsave(&rh->region_lock, flags); 403 spin_lock_irqsave(&rh->region_lock, flags);
404 if (atomic_dec_and_test(&reg->pending)) { 404 if (atomic_dec_and_test(&reg->pending)) {
405 /*
406 * There is no pending I/O for this region.
407 * We can move the region to corresponding list for next action.
408 * At this point, the region is not yet connected to any list.
409 *
410 * If the state is RH_NOSYNC, the region should be kept off
411 * from clean list.
412 * The hash entry for RH_NOSYNC will remain in memory
413 * until the region is recovered or the map is reloaded.
414 */
415
416 /* do nothing for RH_NOSYNC */
405 if (reg->state == RH_RECOVERING) { 417 if (reg->state == RH_RECOVERING) {
406 list_add_tail(&reg->list, &rh->quiesced_regions); 418 list_add_tail(&reg->list, &rh->quiesced_regions);
407 } else { 419 } else if (reg->state == RH_DIRTY) {
408 reg->state = RH_CLEAN; 420 reg->state = RH_CLEAN;
409 list_add(&reg->list, &rh->clean_regions); 421 list_add(&reg->list, &rh->clean_regions);
410 } 422 }
@@ -922,9 +934,9 @@ static inline int _check_region_size(struct dm_target *ti, uint32_t size)
922static int get_mirror(struct mirror_set *ms, struct dm_target *ti, 934static int get_mirror(struct mirror_set *ms, struct dm_target *ti,
923 unsigned int mirror, char **argv) 935 unsigned int mirror, char **argv)
924{ 936{
925 sector_t offset; 937 unsigned long long offset;
926 938
927 if (sscanf(argv[1], SECTOR_FORMAT, &offset) != 1) { 939 if (sscanf(argv[1], "%llu", &offset) != 1) {
928 ti->error = "dm-mirror: Invalid offset"; 940 ti->error = "dm-mirror: Invalid offset";
929 return -EINVAL; 941 return -EINVAL;
930 } 942 }
@@ -1191,16 +1203,17 @@ static int mirror_status(struct dm_target *ti, status_type_t type,
1191 for (m = 0; m < ms->nr_mirrors; m++) 1203 for (m = 0; m < ms->nr_mirrors; m++)
1192 DMEMIT("%s ", ms->mirror[m].dev->name); 1204 DMEMIT("%s ", ms->mirror[m].dev->name);
1193 1205
1194 DMEMIT(SECTOR_FORMAT "/" SECTOR_FORMAT, 1206 DMEMIT("%llu/%llu",
1195 ms->rh.log->type->get_sync_count(ms->rh.log), 1207 (unsigned long long)ms->rh.log->type->
1196 ms->nr_regions); 1208 get_sync_count(ms->rh.log),
1209 (unsigned long long)ms->nr_regions);
1197 break; 1210 break;
1198 1211
1199 case STATUSTYPE_TABLE: 1212 case STATUSTYPE_TABLE:
1200 DMEMIT("%d ", ms->nr_mirrors); 1213 DMEMIT("%d ", ms->nr_mirrors);
1201 for (m = 0; m < ms->nr_mirrors; m++) 1214 for (m = 0; m < ms->nr_mirrors; m++)
1202 DMEMIT("%s " SECTOR_FORMAT " ", 1215 DMEMIT("%s %llu ", ms->mirror[m].dev->name,
1203 ms->mirror[m].dev->name, ms->mirror[m].offset); 1216 (unsigned long long)ms->mirror[m].offset);
1204 } 1217 }
1205 1218
1206 return 0; 1219 return 0;
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 7401540086df..08312b46463a 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -49,11 +49,26 @@ struct pending_exception {
49 struct bio_list snapshot_bios; 49 struct bio_list snapshot_bios;
50 50
51 /* 51 /*
52 * Other pending_exceptions that are processing this 52 * Short-term queue of pending exceptions prior to submission.
53 * chunk. When this list is empty, we know we can
54 * complete the origins.
55 */ 53 */
56 struct list_head siblings; 54 struct list_head list;
55
56 /*
57 * The primary pending_exception is the one that holds
58 * the sibling_count and the list of origin_bios for a
59 * group of pending_exceptions. It is always last to get freed.
60 * These fields get set up when writing to the origin.
61 */
62 struct pending_exception *primary_pe;
63
64 /*
65 * Number of pending_exceptions processing this chunk.
66 * When this drops to zero we must complete the origin bios.
67 * If incrementing or decrementing this, hold pe->snap->lock for
68 * the sibling concerned and not pe->primary_pe->snap->lock unless
69 * they are the same.
70 */
71 atomic_t sibling_count;
57 72
58 /* Pointer back to snapshot context */ 73 /* Pointer back to snapshot context */
59 struct dm_snapshot *snap; 74 struct dm_snapshot *snap;
@@ -377,6 +392,8 @@ static void read_snapshot_metadata(struct dm_snapshot *s)
377 down_write(&s->lock); 392 down_write(&s->lock);
378 s->valid = 0; 393 s->valid = 0;
379 up_write(&s->lock); 394 up_write(&s->lock);
395
396 dm_table_event(s->table);
380 } 397 }
381} 398}
382 399
@@ -542,8 +559,12 @@ static void snapshot_dtr(struct dm_target *ti)
542{ 559{
543 struct dm_snapshot *s = (struct dm_snapshot *) ti->private; 560 struct dm_snapshot *s = (struct dm_snapshot *) ti->private;
544 561
562 /* Prevent further origin writes from using this snapshot. */
563 /* After this returns there can be no new kcopyd jobs. */
545 unregister_snapshot(s); 564 unregister_snapshot(s);
546 565
566 kcopyd_client_destroy(s->kcopyd_client);
567
547 exit_exception_table(&s->pending, pending_cache); 568 exit_exception_table(&s->pending, pending_cache);
548 exit_exception_table(&s->complete, exception_cache); 569 exit_exception_table(&s->complete, exception_cache);
549 570
@@ -552,7 +573,7 @@ static void snapshot_dtr(struct dm_target *ti)
552 573
553 dm_put_device(ti, s->origin); 574 dm_put_device(ti, s->origin);
554 dm_put_device(ti, s->cow); 575 dm_put_device(ti, s->cow);
555 kcopyd_client_destroy(s->kcopyd_client); 576
556 kfree(s); 577 kfree(s);
557} 578}
558 579
@@ -586,78 +607,117 @@ static void error_bios(struct bio *bio)
586 } 607 }
587} 608}
588 609
610static inline void error_snapshot_bios(struct pending_exception *pe)
611{
612 error_bios(bio_list_get(&pe->snapshot_bios));
613}
614
589static struct bio *__flush_bios(struct pending_exception *pe) 615static struct bio *__flush_bios(struct pending_exception *pe)
590{ 616{
591 struct pending_exception *sibling; 617 /*
618 * If this pe is involved in a write to the origin and
619 * it is the last sibling to complete then release
620 * the bios for the original write to the origin.
621 */
622
623 if (pe->primary_pe &&
624 atomic_dec_and_test(&pe->primary_pe->sibling_count))
625 return bio_list_get(&pe->primary_pe->origin_bios);
626
627 return NULL;
628}
629
630static void __invalidate_snapshot(struct dm_snapshot *s,
631 struct pending_exception *pe, int err)
632{
633 if (!s->valid)
634 return;
592 635
593 if (list_empty(&pe->siblings)) 636 if (err == -EIO)
594 return bio_list_get(&pe->origin_bios); 637 DMERR("Invalidating snapshot: Error reading/writing.");
638 else if (err == -ENOMEM)
639 DMERR("Invalidating snapshot: Unable to allocate exception.");
595 640
596 sibling = list_entry(pe->siblings.next, 641 if (pe)
597 struct pending_exception, siblings); 642 remove_exception(&pe->e);
598 643
599 list_del(&pe->siblings); 644 if (s->store.drop_snapshot)
645 s->store.drop_snapshot(&s->store);
600 646
601 /* This is fine as long as kcopyd is single-threaded. If kcopyd 647 s->valid = 0;
602 * becomes multi-threaded, we'll need some locking here.
603 */
604 bio_list_merge(&sibling->origin_bios, &pe->origin_bios);
605 648
606 return NULL; 649 dm_table_event(s->table);
607} 650}
608 651
609static void pending_complete(struct pending_exception *pe, int success) 652static void pending_complete(struct pending_exception *pe, int success)
610{ 653{
611 struct exception *e; 654 struct exception *e;
655 struct pending_exception *primary_pe;
612 struct dm_snapshot *s = pe->snap; 656 struct dm_snapshot *s = pe->snap;
613 struct bio *flush = NULL; 657 struct bio *flush = NULL;
614 658
615 if (success) { 659 if (!success) {
616 e = alloc_exception(); 660 /* Read/write error - snapshot is unusable */
617 if (!e) {
618 DMWARN("Unable to allocate exception.");
619 down_write(&s->lock);
620 s->store.drop_snapshot(&s->store);
621 s->valid = 0;
622 flush = __flush_bios(pe);
623 up_write(&s->lock);
624
625 error_bios(bio_list_get(&pe->snapshot_bios));
626 goto out;
627 }
628 *e = pe->e;
629
630 /*
631 * Add a proper exception, and remove the
632 * in-flight exception from the list.
633 */
634 down_write(&s->lock); 661 down_write(&s->lock);
635 insert_exception(&s->complete, e); 662 __invalidate_snapshot(s, pe, -EIO);
636 remove_exception(&pe->e);
637 flush = __flush_bios(pe); 663 flush = __flush_bios(pe);
638
639 /* Submit any pending write bios */
640 up_write(&s->lock); 664 up_write(&s->lock);
641 665
642 flush_bios(bio_list_get(&pe->snapshot_bios)); 666 error_snapshot_bios(pe);
643 } else { 667 goto out;
644 /* Read/write error - snapshot is unusable */ 668 }
669
670 e = alloc_exception();
671 if (!e) {
645 down_write(&s->lock); 672 down_write(&s->lock);
646 if (s->valid) 673 __invalidate_snapshot(s, pe, -ENOMEM);
647 DMERR("Error reading/writing snapshot");
648 s->store.drop_snapshot(&s->store);
649 s->valid = 0;
650 remove_exception(&pe->e);
651 flush = __flush_bios(pe); 674 flush = __flush_bios(pe);
652 up_write(&s->lock); 675 up_write(&s->lock);
653 676
654 error_bios(bio_list_get(&pe->snapshot_bios)); 677 error_snapshot_bios(pe);
678 goto out;
679 }
680 *e = pe->e;
655 681
656 dm_table_event(s->table); 682 /*
683 * Add a proper exception, and remove the
684 * in-flight exception from the list.
685 */
686 down_write(&s->lock);
687 if (!s->valid) {
688 flush = __flush_bios(pe);
689 up_write(&s->lock);
690
691 free_exception(e);
692
693 error_snapshot_bios(pe);
694 goto out;
657 } 695 }
658 696
697 insert_exception(&s->complete, e);
698 remove_exception(&pe->e);
699 flush = __flush_bios(pe);
700
701 up_write(&s->lock);
702
703 /* Submit any pending write bios */
704 flush_bios(bio_list_get(&pe->snapshot_bios));
705
659 out: 706 out:
660 free_pending_exception(pe); 707 primary_pe = pe->primary_pe;
708
709 /*
710 * Free the pe if it's not linked to an origin write or if
711 * it's not itself a primary pe.
712 */
713 if (!primary_pe || primary_pe != pe)
714 free_pending_exception(pe);
715
716 /*
717 * Free the primary pe if nothing references it.
718 */
719 if (primary_pe && !atomic_read(&primary_pe->sibling_count))
720 free_pending_exception(primary_pe);
661 721
662 if (flush) 722 if (flush)
663 flush_bios(flush); 723 flush_bios(flush);
@@ -734,38 +794,45 @@ __find_pending_exception(struct dm_snapshot *s, struct bio *bio)
734 if (e) { 794 if (e) {
735 /* cast the exception to a pending exception */ 795 /* cast the exception to a pending exception */
736 pe = container_of(e, struct pending_exception, e); 796 pe = container_of(e, struct pending_exception, e);
797 goto out;
798 }
737 799
738 } else { 800 /*
739 /* 801 * Create a new pending exception, we don't want
740 * Create a new pending exception, we don't want 802 * to hold the lock while we do this.
741 * to hold the lock while we do this. 803 */
742 */ 804 up_write(&s->lock);
743 up_write(&s->lock); 805 pe = alloc_pending_exception();
744 pe = alloc_pending_exception(); 806 down_write(&s->lock);
745 down_write(&s->lock);
746 807
747 e = lookup_exception(&s->pending, chunk); 808 if (!s->valid) {
748 if (e) { 809 free_pending_exception(pe);
749 free_pending_exception(pe); 810 return NULL;
750 pe = container_of(e, struct pending_exception, e); 811 }
751 } else {
752 pe->e.old_chunk = chunk;
753 bio_list_init(&pe->origin_bios);
754 bio_list_init(&pe->snapshot_bios);
755 INIT_LIST_HEAD(&pe->siblings);
756 pe->snap = s;
757 pe->started = 0;
758
759 if (s->store.prepare_exception(&s->store, &pe->e)) {
760 free_pending_exception(pe);
761 s->valid = 0;
762 return NULL;
763 }
764 812
765 insert_exception(&s->pending, &pe->e); 813 e = lookup_exception(&s->pending, chunk);
766 } 814 if (e) {
815 free_pending_exception(pe);
816 pe = container_of(e, struct pending_exception, e);
817 goto out;
818 }
819
820 pe->e.old_chunk = chunk;
821 bio_list_init(&pe->origin_bios);
822 bio_list_init(&pe->snapshot_bios);
823 pe->primary_pe = NULL;
824 atomic_set(&pe->sibling_count, 1);
825 pe->snap = s;
826 pe->started = 0;
827
828 if (s->store.prepare_exception(&s->store, &pe->e)) {
829 free_pending_exception(pe);
830 return NULL;
767 } 831 }
768 832
833 insert_exception(&s->pending, &pe->e);
834
835 out:
769 return pe; 836 return pe;
770} 837}
771 838
@@ -782,13 +849,15 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
782{ 849{
783 struct exception *e; 850 struct exception *e;
784 struct dm_snapshot *s = (struct dm_snapshot *) ti->private; 851 struct dm_snapshot *s = (struct dm_snapshot *) ti->private;
852 int copy_needed = 0;
785 int r = 1; 853 int r = 1;
786 chunk_t chunk; 854 chunk_t chunk;
787 struct pending_exception *pe; 855 struct pending_exception *pe = NULL;
788 856
789 chunk = sector_to_chunk(s, bio->bi_sector); 857 chunk = sector_to_chunk(s, bio->bi_sector);
790 858
791 /* Full snapshots are not usable */ 859 /* Full snapshots are not usable */
860 /* To get here the table must be live so s->active is always set. */
792 if (!s->valid) 861 if (!s->valid)
793 return -EIO; 862 return -EIO;
794 863
@@ -806,36 +875,41 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
806 * to copy an exception */ 875 * to copy an exception */
807 down_write(&s->lock); 876 down_write(&s->lock);
808 877
878 if (!s->valid) {
879 r = -EIO;
880 goto out_unlock;
881 }
882
809 /* If the block is already remapped - use that, else remap it */ 883 /* If the block is already remapped - use that, else remap it */
810 e = lookup_exception(&s->complete, chunk); 884 e = lookup_exception(&s->complete, chunk);
811 if (e) { 885 if (e) {
812 remap_exception(s, e, bio); 886 remap_exception(s, e, bio);
813 up_write(&s->lock); 887 goto out_unlock;
814 888 }
815 } else { 889
816 pe = __find_pending_exception(s, bio); 890 pe = __find_pending_exception(s, bio);
817 891 if (!pe) {
818 if (!pe) { 892 __invalidate_snapshot(s, pe, -ENOMEM);
819 if (s->store.drop_snapshot) 893 r = -EIO;
820 s->store.drop_snapshot(&s->store); 894 goto out_unlock;
821 s->valid = 0; 895 }
822 r = -EIO; 896
823 up_write(&s->lock); 897 remap_exception(s, &pe->e, bio);
824 } else { 898 bio_list_add(&pe->snapshot_bios, bio);
825 remap_exception(s, &pe->e, bio); 899
826 bio_list_add(&pe->snapshot_bios, bio); 900 if (!pe->started) {
827 901 /* this is protected by snap->lock */
828 if (!pe->started) { 902 pe->started = 1;
829 /* this is protected by snap->lock */ 903 copy_needed = 1;
830 pe->started = 1;
831 up_write(&s->lock);
832 start_copy(pe);
833 } else
834 up_write(&s->lock);
835 r = 0;
836 }
837 } 904 }
838 905
906 r = 0;
907
908 out_unlock:
909 up_write(&s->lock);
910
911 if (copy_needed)
912 start_copy(pe);
839 } else { 913 } else {
840 /* 914 /*
841 * FIXME: this read path scares me because we 915 * FIXME: this read path scares me because we
@@ -847,6 +921,11 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
847 /* Do reads */ 921 /* Do reads */
848 down_read(&s->lock); 922 down_read(&s->lock);
849 923
924 if (!s->valid) {
925 up_read(&s->lock);
926 return -EIO;
927 }
928
850 /* See if it it has been remapped */ 929 /* See if it it has been remapped */
851 e = lookup_exception(&s->complete, chunk); 930 e = lookup_exception(&s->complete, chunk);
852 if (e) 931 if (e)
@@ -884,9 +963,9 @@ static int snapshot_status(struct dm_target *ti, status_type_t type,
884 snap->store.fraction_full(&snap->store, 963 snap->store.fraction_full(&snap->store,
885 &numerator, 964 &numerator,
886 &denominator); 965 &denominator);
887 snprintf(result, maxlen, 966 snprintf(result, maxlen, "%llu/%llu",
888 SECTOR_FORMAT "/" SECTOR_FORMAT, 967 (unsigned long long)numerator,
889 numerator, denominator); 968 (unsigned long long)denominator);
890 } 969 }
891 else 970 else
892 snprintf(result, maxlen, "Unknown"); 971 snprintf(result, maxlen, "Unknown");
@@ -899,9 +978,10 @@ static int snapshot_status(struct dm_target *ti, status_type_t type,
899 * to make private copies if the output is to 978 * to make private copies if the output is to
900 * make sense. 979 * make sense.
901 */ 980 */
902 snprintf(result, maxlen, "%s %s %c " SECTOR_FORMAT, 981 snprintf(result, maxlen, "%s %s %c %llu",
903 snap->origin->name, snap->cow->name, 982 snap->origin->name, snap->cow->name,
904 snap->type, snap->chunk_size); 983 snap->type,
984 (unsigned long long)snap->chunk_size);
905 break; 985 break;
906 } 986 }
907 987
@@ -911,40 +991,27 @@ static int snapshot_status(struct dm_target *ti, status_type_t type,
911/*----------------------------------------------------------------- 991/*-----------------------------------------------------------------
912 * Origin methods 992 * Origin methods
913 *---------------------------------------------------------------*/ 993 *---------------------------------------------------------------*/
914static void list_merge(struct list_head *l1, struct list_head *l2)
915{
916 struct list_head *l1_n, *l2_p;
917
918 l1_n = l1->next;
919 l2_p = l2->prev;
920
921 l1->next = l2;
922 l2->prev = l1;
923
924 l2_p->next = l1_n;
925 l1_n->prev = l2_p;
926}
927
928static int __origin_write(struct list_head *snapshots, struct bio *bio) 994static int __origin_write(struct list_head *snapshots, struct bio *bio)
929{ 995{
930 int r = 1, first = 1; 996 int r = 1, first = 0;
931 struct dm_snapshot *snap; 997 struct dm_snapshot *snap;
932 struct exception *e; 998 struct exception *e;
933 struct pending_exception *pe, *last = NULL; 999 struct pending_exception *pe, *next_pe, *primary_pe = NULL;
934 chunk_t chunk; 1000 chunk_t chunk;
1001 LIST_HEAD(pe_queue);
935 1002
936 /* Do all the snapshots on this origin */ 1003 /* Do all the snapshots on this origin */
937 list_for_each_entry (snap, snapshots, list) { 1004 list_for_each_entry (snap, snapshots, list) {
938 1005
1006 down_write(&snap->lock);
1007
939 /* Only deal with valid and active snapshots */ 1008 /* Only deal with valid and active snapshots */
940 if (!snap->valid || !snap->active) 1009 if (!snap->valid || !snap->active)
941 continue; 1010 goto next_snapshot;
942 1011
943 /* Nothing to do if writing beyond end of snapshot */ 1012 /* Nothing to do if writing beyond end of snapshot */
944 if (bio->bi_sector >= dm_table_get_size(snap->table)) 1013 if (bio->bi_sector >= dm_table_get_size(snap->table))
945 continue; 1014 goto next_snapshot;
946
947 down_write(&snap->lock);
948 1015
949 /* 1016 /*
950 * Remember, different snapshots can have 1017 * Remember, different snapshots can have
@@ -956,49 +1023,75 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
956 * Check exception table to see if block 1023 * Check exception table to see if block
957 * is already remapped in this snapshot 1024 * is already remapped in this snapshot
958 * and trigger an exception if not. 1025 * and trigger an exception if not.
1026 *
1027 * sibling_count is initialised to 1 so pending_complete()
1028 * won't destroy the primary_pe while we're inside this loop.
959 */ 1029 */
960 e = lookup_exception(&snap->complete, chunk); 1030 e = lookup_exception(&snap->complete, chunk);
961 if (!e) { 1031 if (e)
962 pe = __find_pending_exception(snap, bio); 1032 goto next_snapshot;
963 if (!pe) { 1033
964 snap->store.drop_snapshot(&snap->store); 1034 pe = __find_pending_exception(snap, bio);
965 snap->valid = 0; 1035 if (!pe) {
966 1036 __invalidate_snapshot(snap, pe, ENOMEM);
967 } else { 1037 goto next_snapshot;
968 if (last) 1038 }
969 list_merge(&pe->siblings, 1039
970 &last->siblings); 1040 if (!primary_pe) {
971 1041 /*
972 last = pe; 1042 * Either every pe here has same
973 r = 0; 1043 * primary_pe or none has one yet.
1044 */
1045 if (pe->primary_pe)
1046 primary_pe = pe->primary_pe;
1047 else {
1048 primary_pe = pe;
1049 first = 1;
974 } 1050 }
1051
1052 bio_list_add(&primary_pe->origin_bios, bio);
1053
1054 r = 0;
1055 }
1056
1057 if (!pe->primary_pe) {
1058 atomic_inc(&primary_pe->sibling_count);
1059 pe->primary_pe = primary_pe;
1060 }
1061
1062 if (!pe->started) {
1063 pe->started = 1;
1064 list_add_tail(&pe->list, &pe_queue);
975 } 1065 }
976 1066
1067 next_snapshot:
977 up_write(&snap->lock); 1068 up_write(&snap->lock);
978 } 1069 }
979 1070
1071 if (!primary_pe)
1072 goto out;
1073
980 /* 1074 /*
981 * Now that we have a complete pe list we can start the copying. 1075 * If this is the first time we're processing this chunk and
1076 * sibling_count is now 1 it means all the pending exceptions
1077 * got completed while we were in the loop above, so it falls to
1078 * us here to remove the primary_pe and submit any origin_bios.
982 */ 1079 */
983 if (last) { 1080
984 pe = last; 1081 if (first && atomic_dec_and_test(&primary_pe->sibling_count)) {
985 do { 1082 flush_bios(bio_list_get(&primary_pe->origin_bios));
986 down_write(&pe->snap->lock); 1083 free_pending_exception(primary_pe);
987 if (first) 1084 /* If we got here, pe_queue is necessarily empty. */
988 bio_list_add(&pe->origin_bios, bio); 1085 goto out;
989 if (!pe->started) {
990 pe->started = 1;
991 up_write(&pe->snap->lock);
992 start_copy(pe);
993 } else
994 up_write(&pe->snap->lock);
995 first = 0;
996 pe = list_entry(pe->siblings.next,
997 struct pending_exception, siblings);
998
999 } while (pe != last);
1000 } 1086 }
1001 1087
1088 /*
1089 * Now that we have a complete pe list we can start the copying.
1090 */
1091 list_for_each_entry_safe(pe, next_pe, &pe_queue, list)
1092 start_copy(pe);
1093
1094 out:
1002 return r; 1095 return r;
1003} 1096}
1004 1097
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
index 697aacafb02a..08328a8f5a3c 100644
--- a/drivers/md/dm-stripe.c
+++ b/drivers/md/dm-stripe.c
@@ -49,9 +49,9 @@ static inline struct stripe_c *alloc_context(unsigned int stripes)
49static int get_stripe(struct dm_target *ti, struct stripe_c *sc, 49static int get_stripe(struct dm_target *ti, struct stripe_c *sc,
50 unsigned int stripe, char **argv) 50 unsigned int stripe, char **argv)
51{ 51{
52 sector_t start; 52 unsigned long long start;
53 53
54 if (sscanf(argv[1], SECTOR_FORMAT, &start) != 1) 54 if (sscanf(argv[1], "%llu", &start) != 1)
55 return -EINVAL; 55 return -EINVAL;
56 56
57 if (dm_get_device(ti, argv[0], start, sc->stripe_width, 57 if (dm_get_device(ti, argv[0], start, sc->stripe_width,
@@ -103,7 +103,7 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
103 return -EINVAL; 103 return -EINVAL;
104 } 104 }
105 105
106 if (((uint32_t)ti->len) & (chunk_size - 1)) { 106 if (ti->len & (chunk_size - 1)) {
107 ti->error = "dm-stripe: Target length not divisible by " 107 ti->error = "dm-stripe: Target length not divisible by "
108 "chunk size"; 108 "chunk size";
109 return -EINVAL; 109 return -EINVAL;
@@ -201,10 +201,11 @@ static int stripe_status(struct dm_target *ti,
201 break; 201 break;
202 202
203 case STATUSTYPE_TABLE: 203 case STATUSTYPE_TABLE:
204 DMEMIT("%d " SECTOR_FORMAT, sc->stripes, sc->chunk_mask + 1); 204 DMEMIT("%d %llu", sc->stripes,
205 (unsigned long long)sc->chunk_mask + 1);
205 for (i = 0; i < sc->stripes; i++) 206 for (i = 0; i < sc->stripes; i++)
206 DMEMIT(" %s " SECTOR_FORMAT, sc->stripe[i].dev->name, 207 DMEMIT(" %s %llu", sc->stripe[i].dev->name,
207 sc->stripe[i].physical_start); 208 (unsigned long long)sc->stripe[i].physical_start);
208 break; 209 break;
209 } 210 }
210 return 0; 211 return 0;
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 907b08ddb783..8f56a54cf0ce 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -14,6 +14,7 @@
14#include <linux/ctype.h> 14#include <linux/ctype.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/mutex.h>
17#include <asm/atomic.h> 18#include <asm/atomic.h>
18 19
19#define MAX_DEPTH 16 20#define MAX_DEPTH 16
@@ -22,6 +23,7 @@
22#define CHILDREN_PER_NODE (KEYS_PER_NODE + 1) 23#define CHILDREN_PER_NODE (KEYS_PER_NODE + 1)
23 24
24struct dm_table { 25struct dm_table {
26 struct mapped_device *md;
25 atomic_t holders; 27 atomic_t holders;
26 28
27 /* btree table */ 29 /* btree table */
@@ -97,6 +99,8 @@ static void combine_restrictions_low(struct io_restrictions *lhs,
97 99
98 lhs->seg_boundary_mask = 100 lhs->seg_boundary_mask =
99 min_not_zero(lhs->seg_boundary_mask, rhs->seg_boundary_mask); 101 min_not_zero(lhs->seg_boundary_mask, rhs->seg_boundary_mask);
102
103 lhs->no_cluster |= rhs->no_cluster;
100} 104}
101 105
102/* 106/*
@@ -204,7 +208,8 @@ static int alloc_targets(struct dm_table *t, unsigned int num)
204 return 0; 208 return 0;
205} 209}
206 210
207int dm_table_create(struct dm_table **result, int mode, unsigned num_targets) 211int dm_table_create(struct dm_table **result, int mode,
212 unsigned num_targets, struct mapped_device *md)
208{ 213{
209 struct dm_table *t = kmalloc(sizeof(*t), GFP_KERNEL); 214 struct dm_table *t = kmalloc(sizeof(*t), GFP_KERNEL);
210 215
@@ -227,6 +232,7 @@ int dm_table_create(struct dm_table **result, int mode, unsigned num_targets)
227 } 232 }
228 233
229 t->mode = mode; 234 t->mode = mode;
235 t->md = md;
230 *result = t; 236 *result = t;
231 return 0; 237 return 0;
232} 238}
@@ -345,7 +351,7 @@ static struct dm_dev *find_device(struct list_head *l, dev_t dev)
345/* 351/*
346 * Open a device so we can use it as a map destination. 352 * Open a device so we can use it as a map destination.
347 */ 353 */
348static int open_dev(struct dm_dev *d, dev_t dev) 354static int open_dev(struct dm_dev *d, dev_t dev, struct mapped_device *md)
349{ 355{
350 static char *_claim_ptr = "I belong to device-mapper"; 356 static char *_claim_ptr = "I belong to device-mapper";
351 struct block_device *bdev; 357 struct block_device *bdev;
@@ -357,7 +363,7 @@ static int open_dev(struct dm_dev *d, dev_t dev)
357 bdev = open_by_devnum(dev, d->mode); 363 bdev = open_by_devnum(dev, d->mode);
358 if (IS_ERR(bdev)) 364 if (IS_ERR(bdev))
359 return PTR_ERR(bdev); 365 return PTR_ERR(bdev);
360 r = bd_claim(bdev, _claim_ptr); 366 r = bd_claim_by_disk(bdev, _claim_ptr, dm_disk(md));
361 if (r) 367 if (r)
362 blkdev_put(bdev); 368 blkdev_put(bdev);
363 else 369 else
@@ -368,12 +374,12 @@ static int open_dev(struct dm_dev *d, dev_t dev)
368/* 374/*
369 * Close a device that we've been using. 375 * Close a device that we've been using.
370 */ 376 */
371static void close_dev(struct dm_dev *d) 377static void close_dev(struct dm_dev *d, struct mapped_device *md)
372{ 378{
373 if (!d->bdev) 379 if (!d->bdev)
374 return; 380 return;
375 381
376 bd_release(d->bdev); 382 bd_release_from_disk(d->bdev, dm_disk(md));
377 blkdev_put(d->bdev); 383 blkdev_put(d->bdev);
378 d->bdev = NULL; 384 d->bdev = NULL;
379} 385}
@@ -394,7 +400,7 @@ static int check_device_area(struct dm_dev *dd, sector_t start, sector_t len)
394 * careful to leave things as they were if we fail to reopen the 400 * careful to leave things as they were if we fail to reopen the
395 * device. 401 * device.
396 */ 402 */
397static int upgrade_mode(struct dm_dev *dd, int new_mode) 403static int upgrade_mode(struct dm_dev *dd, int new_mode, struct mapped_device *md)
398{ 404{
399 int r; 405 int r;
400 struct dm_dev dd_copy; 406 struct dm_dev dd_copy;
@@ -404,9 +410,9 @@ static int upgrade_mode(struct dm_dev *dd, int new_mode)
404 410
405 dd->mode |= new_mode; 411 dd->mode |= new_mode;
406 dd->bdev = NULL; 412 dd->bdev = NULL;
407 r = open_dev(dd, dev); 413 r = open_dev(dd, dev, md);
408 if (!r) 414 if (!r)
409 close_dev(&dd_copy); 415 close_dev(&dd_copy, md);
410 else 416 else
411 *dd = dd_copy; 417 *dd = dd_copy;
412 418
@@ -448,7 +454,7 @@ static int __table_get_device(struct dm_table *t, struct dm_target *ti,
448 dd->mode = mode; 454 dd->mode = mode;
449 dd->bdev = NULL; 455 dd->bdev = NULL;
450 456
451 if ((r = open_dev(dd, dev))) { 457 if ((r = open_dev(dd, dev, t->md))) {
452 kfree(dd); 458 kfree(dd);
453 return r; 459 return r;
454 } 460 }
@@ -459,7 +465,7 @@ static int __table_get_device(struct dm_table *t, struct dm_target *ti,
459 list_add(&dd->list, &t->devices); 465 list_add(&dd->list, &t->devices);
460 466
461 } else if (dd->mode != (mode | dd->mode)) { 467 } else if (dd->mode != (mode | dd->mode)) {
462 r = upgrade_mode(dd, mode); 468 r = upgrade_mode(dd, mode, t->md);
463 if (r) 469 if (r)
464 return r; 470 return r;
465 } 471 }
@@ -523,6 +529,8 @@ int dm_get_device(struct dm_target *ti, const char *path, sector_t start,
523 rs->seg_boundary_mask = 529 rs->seg_boundary_mask =
524 min_not_zero(rs->seg_boundary_mask, 530 min_not_zero(rs->seg_boundary_mask,
525 q->seg_boundary_mask); 531 q->seg_boundary_mask);
532
533 rs->no_cluster |= !test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
526 } 534 }
527 535
528 return r; 536 return r;
@@ -534,7 +542,7 @@ int dm_get_device(struct dm_target *ti, const char *path, sector_t start,
534void dm_put_device(struct dm_target *ti, struct dm_dev *dd) 542void dm_put_device(struct dm_target *ti, struct dm_dev *dd)
535{ 543{
536 if (atomic_dec_and_test(&dd->count)) { 544 if (atomic_dec_and_test(&dd->count)) {
537 close_dev(dd); 545 close_dev(dd, ti->table->md);
538 list_del(&dd->list); 546 list_del(&dd->list);
539 kfree(dd); 547 kfree(dd);
540 } 548 }
@@ -763,14 +771,14 @@ int dm_table_complete(struct dm_table *t)
763 return r; 771 return r;
764} 772}
765 773
766static DECLARE_MUTEX(_event_lock); 774static DEFINE_MUTEX(_event_lock);
767void dm_table_event_callback(struct dm_table *t, 775void dm_table_event_callback(struct dm_table *t,
768 void (*fn)(void *), void *context) 776 void (*fn)(void *), void *context)
769{ 777{
770 down(&_event_lock); 778 mutex_lock(&_event_lock);
771 t->event_fn = fn; 779 t->event_fn = fn;
772 t->event_context = context; 780 t->event_context = context;
773 up(&_event_lock); 781 mutex_unlock(&_event_lock);
774} 782}
775 783
776void dm_table_event(struct dm_table *t) 784void dm_table_event(struct dm_table *t)
@@ -781,10 +789,10 @@ void dm_table_event(struct dm_table *t)
781 */ 789 */
782 BUG_ON(in_interrupt()); 790 BUG_ON(in_interrupt());
783 791
784 down(&_event_lock); 792 mutex_lock(&_event_lock);
785 if (t->event_fn) 793 if (t->event_fn)
786 t->event_fn(t->event_context); 794 t->event_fn(t->event_context);
787 up(&_event_lock); 795 mutex_unlock(&_event_lock);
788} 796}
789 797
790sector_t dm_table_get_size(struct dm_table *t) 798sector_t dm_table_get_size(struct dm_table *t)
@@ -832,6 +840,11 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q)
832 q->hardsect_size = t->limits.hardsect_size; 840 q->hardsect_size = t->limits.hardsect_size;
833 q->max_segment_size = t->limits.max_segment_size; 841 q->max_segment_size = t->limits.max_segment_size;
834 q->seg_boundary_mask = t->limits.seg_boundary_mask; 842 q->seg_boundary_mask = t->limits.seg_boundary_mask;
843 if (t->limits.no_cluster)
844 q->queue_flags &= ~(1 << QUEUE_FLAG_CLUSTER);
845 else
846 q->queue_flags |= (1 << QUEUE_FLAG_CLUSTER);
847
835} 848}
836 849
837unsigned int dm_table_get_num_targets(struct dm_table *t) 850unsigned int dm_table_get_num_targets(struct dm_table *t)
@@ -943,12 +956,20 @@ int dm_table_flush_all(struct dm_table *t)
943 return ret; 956 return ret;
944} 957}
945 958
959struct mapped_device *dm_table_get_md(struct dm_table *t)
960{
961 dm_get(t->md);
962
963 return t->md;
964}
965
946EXPORT_SYMBOL(dm_vcalloc); 966EXPORT_SYMBOL(dm_vcalloc);
947EXPORT_SYMBOL(dm_get_device); 967EXPORT_SYMBOL(dm_get_device);
948EXPORT_SYMBOL(dm_put_device); 968EXPORT_SYMBOL(dm_put_device);
949EXPORT_SYMBOL(dm_table_event); 969EXPORT_SYMBOL(dm_table_event);
950EXPORT_SYMBOL(dm_table_get_size); 970EXPORT_SYMBOL(dm_table_get_size);
951EXPORT_SYMBOL(dm_table_get_mode); 971EXPORT_SYMBOL(dm_table_get_mode);
972EXPORT_SYMBOL(dm_table_get_md);
952EXPORT_SYMBOL(dm_table_put); 973EXPORT_SYMBOL(dm_table_put);
953EXPORT_SYMBOL(dm_table_get); 974EXPORT_SYMBOL(dm_table_get);
954EXPORT_SYMBOL(dm_table_unplug_all); 975EXPORT_SYMBOL(dm_table_unplug_all);
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index a64798ef481e..4d710b7a133b 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -10,6 +10,7 @@
10 10
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/mutex.h>
13#include <linux/moduleparam.h> 14#include <linux/moduleparam.h>
14#include <linux/blkpg.h> 15#include <linux/blkpg.h>
15#include <linux/bio.h> 16#include <linux/bio.h>
@@ -17,6 +18,7 @@
17#include <linux/mempool.h> 18#include <linux/mempool.h>
18#include <linux/slab.h> 19#include <linux/slab.h>
19#include <linux/idr.h> 20#include <linux/idr.h>
21#include <linux/hdreg.h>
20#include <linux/blktrace_api.h> 22#include <linux/blktrace_api.h>
21 23
22static const char *_name = DM_NAME; 24static const char *_name = DM_NAME;
@@ -69,6 +71,7 @@ struct mapped_device {
69 71
70 request_queue_t *queue; 72 request_queue_t *queue;
71 struct gendisk *disk; 73 struct gendisk *disk;
74 char name[16];
72 75
73 void *interface_ptr; 76 void *interface_ptr;
74 77
@@ -101,6 +104,9 @@ struct mapped_device {
101 */ 104 */
102 struct super_block *frozen_sb; 105 struct super_block *frozen_sb;
103 struct block_device *suspended_bdev; 106 struct block_device *suspended_bdev;
107
108 /* forced geometry settings */
109 struct hd_geometry geometry;
104}; 110};
105 111
106#define MIN_IOS 256 112#define MIN_IOS 256
@@ -226,6 +232,13 @@ static int dm_blk_close(struct inode *inode, struct file *file)
226 return 0; 232 return 0;
227} 233}
228 234
235static int dm_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
236{
237 struct mapped_device *md = bdev->bd_disk->private_data;
238
239 return dm_get_geometry(md, geo);
240}
241
229static inline struct dm_io *alloc_io(struct mapped_device *md) 242static inline struct dm_io *alloc_io(struct mapped_device *md)
230{ 243{
231 return mempool_alloc(md->io_pool, GFP_NOIO); 244 return mempool_alloc(md->io_pool, GFP_NOIO);
@@ -312,6 +325,33 @@ struct dm_table *dm_get_table(struct mapped_device *md)
312 return t; 325 return t;
313} 326}
314 327
328/*
329 * Get the geometry associated with a dm device
330 */
331int dm_get_geometry(struct mapped_device *md, struct hd_geometry *geo)
332{
333 *geo = md->geometry;
334
335 return 0;
336}
337
338/*
339 * Set the geometry of a device.
340 */
341int dm_set_geometry(struct mapped_device *md, struct hd_geometry *geo)
342{
343 sector_t sz = (sector_t)geo->cylinders * geo->heads * geo->sectors;
344
345 if (geo->start > sz) {
346 DMWARN("Start sector is beyond the geometry limits.");
347 return -EINVAL;
348 }
349
350 md->geometry = *geo;
351
352 return 0;
353}
354
315/*----------------------------------------------------------------- 355/*-----------------------------------------------------------------
316 * CRUD START: 356 * CRUD START:
317 * A more elegant soln is in the works that uses the queue 357 * A more elegant soln is in the works that uses the queue
@@ -704,14 +744,14 @@ static int dm_any_congested(void *congested_data, int bdi_bits)
704/*----------------------------------------------------------------- 744/*-----------------------------------------------------------------
705 * An IDR is used to keep track of allocated minor numbers. 745 * An IDR is used to keep track of allocated minor numbers.
706 *---------------------------------------------------------------*/ 746 *---------------------------------------------------------------*/
707static DECLARE_MUTEX(_minor_lock); 747static DEFINE_MUTEX(_minor_lock);
708static DEFINE_IDR(_minor_idr); 748static DEFINE_IDR(_minor_idr);
709 749
710static void free_minor(unsigned int minor) 750static void free_minor(unsigned int minor)
711{ 751{
712 down(&_minor_lock); 752 mutex_lock(&_minor_lock);
713 idr_remove(&_minor_idr, minor); 753 idr_remove(&_minor_idr, minor);
714 up(&_minor_lock); 754 mutex_unlock(&_minor_lock);
715} 755}
716 756
717/* 757/*
@@ -724,7 +764,7 @@ static int specific_minor(struct mapped_device *md, unsigned int minor)
724 if (minor >= (1 << MINORBITS)) 764 if (minor >= (1 << MINORBITS))
725 return -EINVAL; 765 return -EINVAL;
726 766
727 down(&_minor_lock); 767 mutex_lock(&_minor_lock);
728 768
729 if (idr_find(&_minor_idr, minor)) { 769 if (idr_find(&_minor_idr, minor)) {
730 r = -EBUSY; 770 r = -EBUSY;
@@ -749,7 +789,7 @@ static int specific_minor(struct mapped_device *md, unsigned int minor)
749 } 789 }
750 790
751out: 791out:
752 up(&_minor_lock); 792 mutex_unlock(&_minor_lock);
753 return r; 793 return r;
754} 794}
755 795
@@ -758,7 +798,7 @@ static int next_free_minor(struct mapped_device *md, unsigned int *minor)
758 int r; 798 int r;
759 unsigned int m; 799 unsigned int m;
760 800
761 down(&_minor_lock); 801 mutex_lock(&_minor_lock);
762 802
763 r = idr_pre_get(&_minor_idr, GFP_KERNEL); 803 r = idr_pre_get(&_minor_idr, GFP_KERNEL);
764 if (!r) { 804 if (!r) {
@@ -780,7 +820,7 @@ static int next_free_minor(struct mapped_device *md, unsigned int *minor)
780 *minor = m; 820 *minor = m;
781 821
782out: 822out:
783 up(&_minor_lock); 823 mutex_unlock(&_minor_lock);
784 return r; 824 return r;
785} 825}
786 826
@@ -842,6 +882,7 @@ static struct mapped_device *alloc_dev(unsigned int minor, int persistent)
842 md->disk->private_data = md; 882 md->disk->private_data = md;
843 sprintf(md->disk->disk_name, "dm-%d", minor); 883 sprintf(md->disk->disk_name, "dm-%d", minor);
844 add_disk(md->disk); 884 add_disk(md->disk);
885 format_dev_t(md->name, MKDEV(_major, minor));
845 886
846 atomic_set(&md->pending, 0); 887 atomic_set(&md->pending, 0);
847 init_waitqueue_head(&md->wait); 888 init_waitqueue_head(&md->wait);
@@ -904,6 +945,13 @@ static int __bind(struct mapped_device *md, struct dm_table *t)
904 sector_t size; 945 sector_t size;
905 946
906 size = dm_table_get_size(t); 947 size = dm_table_get_size(t);
948
949 /*
950 * Wipe any geometry if the size of the table changed.
951 */
952 if (size != get_capacity(md->disk))
953 memset(&md->geometry, 0, sizeof(md->geometry));
954
907 __set_size(md, size); 955 __set_size(md, size);
908 if (size == 0) 956 if (size == 0)
909 return 0; 957 return 0;
@@ -967,13 +1015,13 @@ static struct mapped_device *dm_find_md(dev_t dev)
967 if (MAJOR(dev) != _major || minor >= (1 << MINORBITS)) 1015 if (MAJOR(dev) != _major || minor >= (1 << MINORBITS))
968 return NULL; 1016 return NULL;
969 1017
970 down(&_minor_lock); 1018 mutex_lock(&_minor_lock);
971 1019
972 md = idr_find(&_minor_idr, minor); 1020 md = idr_find(&_minor_idr, minor);
973 if (!md || (dm_disk(md)->first_minor != minor)) 1021 if (!md || (dm_disk(md)->first_minor != minor))
974 md = NULL; 1022 md = NULL;
975 1023
976 up(&_minor_lock); 1024 mutex_unlock(&_minor_lock);
977 1025
978 return md; 1026 return md;
979} 1027}
@@ -988,15 +1036,9 @@ struct mapped_device *dm_get_md(dev_t dev)
988 return md; 1036 return md;
989} 1037}
990 1038
991void *dm_get_mdptr(dev_t dev) 1039void *dm_get_mdptr(struct mapped_device *md)
992{ 1040{
993 struct mapped_device *md; 1041 return md->interface_ptr;
994 void *mdptr = NULL;
995
996 md = dm_find_md(dev);
997 if (md)
998 mdptr = md->interface_ptr;
999 return mdptr;
1000} 1042}
1001 1043
1002void dm_set_mdptr(struct mapped_device *md, void *ptr) 1044void dm_set_mdptr(struct mapped_device *md, void *ptr)
@@ -1011,18 +1053,18 @@ void dm_get(struct mapped_device *md)
1011 1053
1012void dm_put(struct mapped_device *md) 1054void dm_put(struct mapped_device *md)
1013{ 1055{
1014 struct dm_table *map = dm_get_table(md); 1056 struct dm_table *map;
1015 1057
1016 if (atomic_dec_and_test(&md->holders)) { 1058 if (atomic_dec_and_test(&md->holders)) {
1059 map = dm_get_table(md);
1017 if (!dm_suspended(md)) { 1060 if (!dm_suspended(md)) {
1018 dm_table_presuspend_targets(map); 1061 dm_table_presuspend_targets(map);
1019 dm_table_postsuspend_targets(map); 1062 dm_table_postsuspend_targets(map);
1020 } 1063 }
1021 __unbind(md); 1064 __unbind(md);
1065 dm_table_put(map);
1022 free_dev(md); 1066 free_dev(md);
1023 } 1067 }
1024
1025 dm_table_put(map);
1026} 1068}
1027 1069
1028/* 1070/*
@@ -1107,6 +1149,7 @@ int dm_suspend(struct mapped_device *md, int do_lockfs)
1107{ 1149{
1108 struct dm_table *map = NULL; 1150 struct dm_table *map = NULL;
1109 DECLARE_WAITQUEUE(wait, current); 1151 DECLARE_WAITQUEUE(wait, current);
1152 struct bio *def;
1110 int r = -EINVAL; 1153 int r = -EINVAL;
1111 1154
1112 down(&md->suspend_lock); 1155 down(&md->suspend_lock);
@@ -1166,9 +1209,11 @@ int dm_suspend(struct mapped_device *md, int do_lockfs)
1166 /* were we interrupted ? */ 1209 /* were we interrupted ? */
1167 r = -EINTR; 1210 r = -EINTR;
1168 if (atomic_read(&md->pending)) { 1211 if (atomic_read(&md->pending)) {
1212 clear_bit(DMF_BLOCK_IO, &md->flags);
1213 def = bio_list_get(&md->deferred);
1214 __flush_deferred_io(md, def);
1169 up_write(&md->io_lock); 1215 up_write(&md->io_lock);
1170 unlock_fs(md); 1216 unlock_fs(md);
1171 clear_bit(DMF_BLOCK_IO, &md->flags);
1172 goto out; 1217 goto out;
1173 } 1218 }
1174 up_write(&md->io_lock); 1219 up_write(&md->io_lock);
@@ -1262,6 +1307,7 @@ int dm_suspended(struct mapped_device *md)
1262static struct block_device_operations dm_blk_dops = { 1307static struct block_device_operations dm_blk_dops = {
1263 .open = dm_blk_open, 1308 .open = dm_blk_open,
1264 .release = dm_blk_close, 1309 .release = dm_blk_close,
1310 .getgeo = dm_blk_getgeo,
1265 .owner = THIS_MODULE 1311 .owner = THIS_MODULE
1266}; 1312};
1267 1313
diff --git a/drivers/md/dm.h b/drivers/md/dm.h
index 4eaf075da217..fd90bc8f9e45 100644
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -14,6 +14,7 @@
14#include <linux/device-mapper.h> 14#include <linux/device-mapper.h>
15#include <linux/list.h> 15#include <linux/list.h>
16#include <linux/blkdev.h> 16#include <linux/blkdev.h>
17#include <linux/hdreg.h>
17 18
18#define DM_NAME "device-mapper" 19#define DM_NAME "device-mapper"
19#define DMWARN(f, x...) printk(KERN_WARNING DM_NAME ": " f "\n" , ## x) 20#define DMWARN(f, x...) printk(KERN_WARNING DM_NAME ": " f "\n" , ## x)
@@ -23,16 +24,6 @@
23#define DMEMIT(x...) sz += ((sz >= maxlen) ? \ 24#define DMEMIT(x...) sz += ((sz >= maxlen) ? \
24 0 : scnprintf(result + sz, maxlen - sz, x)) 25 0 : scnprintf(result + sz, maxlen - sz, x))
25 26
26/*
27 * FIXME: I think this should be with the definition of sector_t
28 * in types.h.
29 */
30#ifdef CONFIG_LBD
31#define SECTOR_FORMAT "%llu"
32#else
33#define SECTOR_FORMAT "%lu"
34#endif
35
36#define SECTOR_SHIFT 9 27#define SECTOR_SHIFT 9
37 28
38/* 29/*
@@ -57,7 +48,7 @@ struct mapped_device;
57int dm_create(struct mapped_device **md); 48int dm_create(struct mapped_device **md);
58int dm_create_with_minor(unsigned int minor, struct mapped_device **md); 49int dm_create_with_minor(unsigned int minor, struct mapped_device **md);
59void dm_set_mdptr(struct mapped_device *md, void *ptr); 50void dm_set_mdptr(struct mapped_device *md, void *ptr);
60void *dm_get_mdptr(dev_t dev); 51void *dm_get_mdptr(struct mapped_device *md);
61struct mapped_device *dm_get_md(dev_t dev); 52struct mapped_device *dm_get_md(dev_t dev);
62 53
63/* 54/*
@@ -95,11 +86,18 @@ int dm_wait_event(struct mapped_device *md, int event_nr);
95struct gendisk *dm_disk(struct mapped_device *md); 86struct gendisk *dm_disk(struct mapped_device *md);
96int dm_suspended(struct mapped_device *md); 87int dm_suspended(struct mapped_device *md);
97 88
89/*
90 * Geometry functions.
91 */
92int dm_get_geometry(struct mapped_device *md, struct hd_geometry *geo);
93int dm_set_geometry(struct mapped_device *md, struct hd_geometry *geo);
94
98/*----------------------------------------------------------------- 95/*-----------------------------------------------------------------
99 * Functions for manipulating a table. Tables are also reference 96 * Functions for manipulating a table. Tables are also reference
100 * counted. 97 * counted.
101 *---------------------------------------------------------------*/ 98 *---------------------------------------------------------------*/
102int dm_table_create(struct dm_table **result, int mode, unsigned num_targets); 99int dm_table_create(struct dm_table **result, int mode,
100 unsigned num_targets, struct mapped_device *md);
103 101
104void dm_table_get(struct dm_table *t); 102void dm_table_get(struct dm_table *t);
105void dm_table_put(struct dm_table *t); 103void dm_table_put(struct dm_table *t);
@@ -117,6 +115,7 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q);
117unsigned int dm_table_get_num_targets(struct dm_table *t); 115unsigned int dm_table_get_num_targets(struct dm_table *t);
118struct list_head *dm_table_get_devices(struct dm_table *t); 116struct list_head *dm_table_get_devices(struct dm_table *t);
119int dm_table_get_mode(struct dm_table *t); 117int dm_table_get_mode(struct dm_table *t);
118struct mapped_device *dm_table_get_md(struct dm_table *t);
120void dm_table_presuspend_targets(struct dm_table *t); 119void dm_table_presuspend_targets(struct dm_table *t);
121void dm_table_postsuspend_targets(struct dm_table *t); 120void dm_table_postsuspend_targets(struct dm_table *t);
122void dm_table_resume_targets(struct dm_table *t); 121void dm_table_resume_targets(struct dm_table *t);
diff --git a/drivers/md/kcopyd.c b/drivers/md/kcopyd.c
index 9dcb2c8a3853..72480a48d88b 100644
--- a/drivers/md/kcopyd.c
+++ b/drivers/md/kcopyd.c
@@ -22,6 +22,7 @@
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/vmalloc.h> 23#include <linux/vmalloc.h>
24#include <linux/workqueue.h> 24#include <linux/workqueue.h>
25#include <linux/mutex.h>
25 26
26#include "kcopyd.h" 27#include "kcopyd.h"
27 28
@@ -44,6 +45,9 @@ struct kcopyd_client {
44 struct page_list *pages; 45 struct page_list *pages;
45 unsigned int nr_pages; 46 unsigned int nr_pages;
46 unsigned int nr_free_pages; 47 unsigned int nr_free_pages;
48
49 wait_queue_head_t destroyq;
50 atomic_t nr_jobs;
47}; 51};
48 52
49static struct page_list *alloc_pl(void) 53static struct page_list *alloc_pl(void)
@@ -292,10 +296,15 @@ static int run_complete_job(struct kcopyd_job *job)
292 int read_err = job->read_err; 296 int read_err = job->read_err;
293 unsigned int write_err = job->write_err; 297 unsigned int write_err = job->write_err;
294 kcopyd_notify_fn fn = job->fn; 298 kcopyd_notify_fn fn = job->fn;
299 struct kcopyd_client *kc = job->kc;
295 300
296 kcopyd_put_pages(job->kc, job->pages); 301 kcopyd_put_pages(kc, job->pages);
297 mempool_free(job, _job_pool); 302 mempool_free(job, _job_pool);
298 fn(read_err, write_err, context); 303 fn(read_err, write_err, context);
304
305 if (atomic_dec_and_test(&kc->nr_jobs))
306 wake_up(&kc->destroyq);
307
299 return 0; 308 return 0;
300} 309}
301 310
@@ -430,6 +439,7 @@ static void do_work(void *ignored)
430 */ 439 */
431static void dispatch_job(struct kcopyd_job *job) 440static void dispatch_job(struct kcopyd_job *job)
432{ 441{
442 atomic_inc(&job->kc->nr_jobs);
433 push(&_pages_jobs, job); 443 push(&_pages_jobs, job);
434 wake(); 444 wake();
435} 445}
@@ -572,21 +582,21 @@ int kcopyd_cancel(struct kcopyd_job *job, int block)
572/*----------------------------------------------------------------- 582/*-----------------------------------------------------------------
573 * Unit setup 583 * Unit setup
574 *---------------------------------------------------------------*/ 584 *---------------------------------------------------------------*/
575static DECLARE_MUTEX(_client_lock); 585static DEFINE_MUTEX(_client_lock);
576static LIST_HEAD(_clients); 586static LIST_HEAD(_clients);
577 587
578static void client_add(struct kcopyd_client *kc) 588static void client_add(struct kcopyd_client *kc)
579{ 589{
580 down(&_client_lock); 590 mutex_lock(&_client_lock);
581 list_add(&kc->list, &_clients); 591 list_add(&kc->list, &_clients);
582 up(&_client_lock); 592 mutex_unlock(&_client_lock);
583} 593}
584 594
585static void client_del(struct kcopyd_client *kc) 595static void client_del(struct kcopyd_client *kc)
586{ 596{
587 down(&_client_lock); 597 mutex_lock(&_client_lock);
588 list_del(&kc->list); 598 list_del(&kc->list);
589 up(&_client_lock); 599 mutex_unlock(&_client_lock);
590} 600}
591 601
592static DEFINE_MUTEX(kcopyd_init_lock); 602static DEFINE_MUTEX(kcopyd_init_lock);
@@ -669,6 +679,9 @@ int kcopyd_client_create(unsigned int nr_pages, struct kcopyd_client **result)
669 return r; 679 return r;
670 } 680 }
671 681
682 init_waitqueue_head(&kc->destroyq);
683 atomic_set(&kc->nr_jobs, 0);
684
672 client_add(kc); 685 client_add(kc);
673 *result = kc; 686 *result = kc;
674 return 0; 687 return 0;
@@ -676,6 +689,9 @@ int kcopyd_client_create(unsigned int nr_pages, struct kcopyd_client **result)
676 689
677void kcopyd_client_destroy(struct kcopyd_client *kc) 690void kcopyd_client_destroy(struct kcopyd_client *kc)
678{ 691{
692 /* Wait for completion of all jobs submitted by this client. */
693 wait_event(kc->destroyq, !atomic_read(&kc->nr_jobs));
694
679 dm_io_put(kc->nr_pages); 695 dm_io_put(kc->nr_pages);
680 client_free_pages(kc); 696 client_free_pages(kc);
681 client_del(kc); 697 client_del(kc);
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 5ed2228745cb..039e071c1007 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -43,6 +43,7 @@
43#include <linux/buffer_head.h> /* for invalidate_bdev */ 43#include <linux/buffer_head.h> /* for invalidate_bdev */
44#include <linux/suspend.h> 44#include <linux/suspend.h>
45#include <linux/poll.h> 45#include <linux/poll.h>
46#include <linux/mutex.h>
46 47
47#include <linux/init.h> 48#include <linux/init.h>
48 49
@@ -158,11 +159,12 @@ static int start_readonly;
158 */ 159 */
159static DECLARE_WAIT_QUEUE_HEAD(md_event_waiters); 160static DECLARE_WAIT_QUEUE_HEAD(md_event_waiters);
160static atomic_t md_event_count; 161static atomic_t md_event_count;
161static void md_new_event(mddev_t *mddev) 162void md_new_event(mddev_t *mddev)
162{ 163{
163 atomic_inc(&md_event_count); 164 atomic_inc(&md_event_count);
164 wake_up(&md_event_waiters); 165 wake_up(&md_event_waiters);
165} 166}
167EXPORT_SYMBOL_GPL(md_new_event);
166 168
167/* 169/*
168 * Enables to iterate over all existing md arrays 170 * Enables to iterate over all existing md arrays
@@ -253,7 +255,7 @@ static mddev_t * mddev_find(dev_t unit)
253 else 255 else
254 new->md_minor = MINOR(unit) >> MdpMinorShift; 256 new->md_minor = MINOR(unit) >> MdpMinorShift;
255 257
256 init_MUTEX(&new->reconfig_sem); 258 mutex_init(&new->reconfig_mutex);
257 INIT_LIST_HEAD(&new->disks); 259 INIT_LIST_HEAD(&new->disks);
258 INIT_LIST_HEAD(&new->all_mddevs); 260 INIT_LIST_HEAD(&new->all_mddevs);
259 init_timer(&new->safemode_timer); 261 init_timer(&new->safemode_timer);
@@ -266,6 +268,7 @@ static mddev_t * mddev_find(dev_t unit)
266 kfree(new); 268 kfree(new);
267 return NULL; 269 return NULL;
268 } 270 }
271 set_bit(QUEUE_FLAG_CLUSTER, &new->queue->queue_flags);
269 272
270 blk_queue_make_request(new->queue, md_fail_request); 273 blk_queue_make_request(new->queue, md_fail_request);
271 274
@@ -274,22 +277,22 @@ static mddev_t * mddev_find(dev_t unit)
274 277
275static inline int mddev_lock(mddev_t * mddev) 278static inline int mddev_lock(mddev_t * mddev)
276{ 279{
277 return down_interruptible(&mddev->reconfig_sem); 280 return mutex_lock_interruptible(&mddev->reconfig_mutex);
278} 281}
279 282
280static inline void mddev_lock_uninterruptible(mddev_t * mddev) 283static inline void mddev_lock_uninterruptible(mddev_t * mddev)
281{ 284{
282 down(&mddev->reconfig_sem); 285 mutex_lock(&mddev->reconfig_mutex);
283} 286}
284 287
285static inline int mddev_trylock(mddev_t * mddev) 288static inline int mddev_trylock(mddev_t * mddev)
286{ 289{
287 return down_trylock(&mddev->reconfig_sem); 290 return mutex_trylock(&mddev->reconfig_mutex);
288} 291}
289 292
290static inline void mddev_unlock(mddev_t * mddev) 293static inline void mddev_unlock(mddev_t * mddev)
291{ 294{
292 up(&mddev->reconfig_sem); 295 mutex_unlock(&mddev->reconfig_mutex);
293 296
294 md_wakeup_thread(mddev->thread); 297 md_wakeup_thread(mddev->thread);
295} 298}
@@ -660,7 +663,8 @@ static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version
660 } 663 }
661 664
662 if (sb->major_version != 0 || 665 if (sb->major_version != 0 ||
663 sb->minor_version != 90) { 666 sb->minor_version < 90 ||
667 sb->minor_version > 91) {
664 printk(KERN_WARNING "Bad version number %d.%d on %s\n", 668 printk(KERN_WARNING "Bad version number %d.%d on %s\n",
665 sb->major_version, sb->minor_version, 669 sb->major_version, sb->minor_version,
666 b); 670 b);
@@ -745,6 +749,20 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
745 mddev->bitmap_offset = 0; 749 mddev->bitmap_offset = 0;
746 mddev->default_bitmap_offset = MD_SB_BYTES >> 9; 750 mddev->default_bitmap_offset = MD_SB_BYTES >> 9;
747 751
752 if (mddev->minor_version >= 91) {
753 mddev->reshape_position = sb->reshape_position;
754 mddev->delta_disks = sb->delta_disks;
755 mddev->new_level = sb->new_level;
756 mddev->new_layout = sb->new_layout;
757 mddev->new_chunk = sb->new_chunk;
758 } else {
759 mddev->reshape_position = MaxSector;
760 mddev->delta_disks = 0;
761 mddev->new_level = mddev->level;
762 mddev->new_layout = mddev->layout;
763 mddev->new_chunk = mddev->chunk_size;
764 }
765
748 if (sb->state & (1<<MD_SB_CLEAN)) 766 if (sb->state & (1<<MD_SB_CLEAN))
749 mddev->recovery_cp = MaxSector; 767 mddev->recovery_cp = MaxSector;
750 else { 768 else {
@@ -764,7 +782,8 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
764 782
765 if (sb->state & (1<<MD_SB_BITMAP_PRESENT) && 783 if (sb->state & (1<<MD_SB_BITMAP_PRESENT) &&
766 mddev->bitmap_file == NULL) { 784 mddev->bitmap_file == NULL) {
767 if (mddev->level != 1 && mddev->level != 5 && mddev->level != 6 785 if (mddev->level != 1 && mddev->level != 4
786 && mddev->level != 5 && mddev->level != 6
768 && mddev->level != 10) { 787 && mddev->level != 10) {
769 /* FIXME use a better test */ 788 /* FIXME use a better test */
770 printk(KERN_WARNING "md: bitmaps not supported for this level.\n"); 789 printk(KERN_WARNING "md: bitmaps not supported for this level.\n");
@@ -838,7 +857,6 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
838 857
839 sb->md_magic = MD_SB_MAGIC; 858 sb->md_magic = MD_SB_MAGIC;
840 sb->major_version = mddev->major_version; 859 sb->major_version = mddev->major_version;
841 sb->minor_version = mddev->minor_version;
842 sb->patch_version = mddev->patch_version; 860 sb->patch_version = mddev->patch_version;
843 sb->gvalid_words = 0; /* ignored */ 861 sb->gvalid_words = 0; /* ignored */
844 memcpy(&sb->set_uuid0, mddev->uuid+0, 4); 862 memcpy(&sb->set_uuid0, mddev->uuid+0, 4);
@@ -857,6 +875,17 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
857 sb->events_hi = (mddev->events>>32); 875 sb->events_hi = (mddev->events>>32);
858 sb->events_lo = (u32)mddev->events; 876 sb->events_lo = (u32)mddev->events;
859 877
878 if (mddev->reshape_position == MaxSector)
879 sb->minor_version = 90;
880 else {
881 sb->minor_version = 91;
882 sb->reshape_position = mddev->reshape_position;
883 sb->new_level = mddev->new_level;
884 sb->delta_disks = mddev->delta_disks;
885 sb->new_layout = mddev->new_layout;
886 sb->new_chunk = mddev->new_chunk;
887 }
888 mddev->minor_version = sb->minor_version;
860 if (mddev->in_sync) 889 if (mddev->in_sync)
861 { 890 {
862 sb->recovery_cp = mddev->recovery_cp; 891 sb->recovery_cp = mddev->recovery_cp;
@@ -893,10 +922,9 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
893 d->raid_disk = rdev2->raid_disk; 922 d->raid_disk = rdev2->raid_disk;
894 else 923 else
895 d->raid_disk = rdev2->desc_nr; /* compatibility */ 924 d->raid_disk = rdev2->desc_nr; /* compatibility */
896 if (test_bit(Faulty, &rdev2->flags)) { 925 if (test_bit(Faulty, &rdev2->flags))
897 d->state = (1<<MD_DISK_FAULTY); 926 d->state = (1<<MD_DISK_FAULTY);
898 failed++; 927 else if (test_bit(In_sync, &rdev2->flags)) {
899 } else if (test_bit(In_sync, &rdev2->flags)) {
900 d->state = (1<<MD_DISK_ACTIVE); 928 d->state = (1<<MD_DISK_ACTIVE);
901 d->state |= (1<<MD_DISK_SYNC); 929 d->state |= (1<<MD_DISK_SYNC);
902 active++; 930 active++;
@@ -1102,6 +1130,20 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
1102 } 1130 }
1103 mddev->bitmap_offset = (__s32)le32_to_cpu(sb->bitmap_offset); 1131 mddev->bitmap_offset = (__s32)le32_to_cpu(sb->bitmap_offset);
1104 } 1132 }
1133 if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_RESHAPE_ACTIVE)) {
1134 mddev->reshape_position = le64_to_cpu(sb->reshape_position);
1135 mddev->delta_disks = le32_to_cpu(sb->delta_disks);
1136 mddev->new_level = le32_to_cpu(sb->new_level);
1137 mddev->new_layout = le32_to_cpu(sb->new_layout);
1138 mddev->new_chunk = le32_to_cpu(sb->new_chunk)<<9;
1139 } else {
1140 mddev->reshape_position = MaxSector;
1141 mddev->delta_disks = 0;
1142 mddev->new_level = mddev->level;
1143 mddev->new_layout = mddev->layout;
1144 mddev->new_chunk = mddev->chunk_size;
1145 }
1146
1105 } else if (mddev->pers == NULL) { 1147 } else if (mddev->pers == NULL) {
1106 /* Insist of good event counter while assembling */ 1148 /* Insist of good event counter while assembling */
1107 __u64 ev1 = le64_to_cpu(sb->events); 1149 __u64 ev1 = le64_to_cpu(sb->events);
@@ -1173,6 +1215,14 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
1173 sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset); 1215 sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset);
1174 sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); 1216 sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET);
1175 } 1217 }
1218 if (mddev->reshape_position != MaxSector) {
1219 sb->feature_map |= cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE);
1220 sb->reshape_position = cpu_to_le64(mddev->reshape_position);
1221 sb->new_layout = cpu_to_le32(mddev->new_layout);
1222 sb->delta_disks = cpu_to_le32(mddev->delta_disks);
1223 sb->new_level = cpu_to_le32(mddev->new_level);
1224 sb->new_chunk = cpu_to_le32(mddev->new_chunk>>9);
1225 }
1176 1226
1177 max_dev = 0; 1227 max_dev = 0;
1178 ITERATE_RDEV(mddev,rdev2,tmp) 1228 ITERATE_RDEV(mddev,rdev2,tmp)
@@ -1301,6 +1351,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
1301 else 1351 else
1302 ko = &rdev->bdev->bd_disk->kobj; 1352 ko = &rdev->bdev->bd_disk->kobj;
1303 sysfs_create_link(&rdev->kobj, ko, "block"); 1353 sysfs_create_link(&rdev->kobj, ko, "block");
1354 bd_claim_by_disk(rdev->bdev, rdev, mddev->gendisk);
1304 return 0; 1355 return 0;
1305} 1356}
1306 1357
@@ -1311,6 +1362,7 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev)
1311 MD_BUG(); 1362 MD_BUG();
1312 return; 1363 return;
1313 } 1364 }
1365 bd_release_from_disk(rdev->bdev, rdev->mddev->gendisk);
1314 list_del_init(&rdev->same_set); 1366 list_del_init(&rdev->same_set);
1315 printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b)); 1367 printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b));
1316 rdev->mddev = NULL; 1368 rdev->mddev = NULL;
@@ -1493,7 +1545,7 @@ static void sync_sbs(mddev_t * mddev)
1493 } 1545 }
1494} 1546}
1495 1547
1496static void md_update_sb(mddev_t * mddev) 1548void md_update_sb(mddev_t * mddev)
1497{ 1549{
1498 int err; 1550 int err;
1499 struct list_head *tmp; 1551 struct list_head *tmp;
@@ -1570,6 +1622,7 @@ repeat:
1570 wake_up(&mddev->sb_wait); 1622 wake_up(&mddev->sb_wait);
1571 1623
1572} 1624}
1625EXPORT_SYMBOL_GPL(md_update_sb);
1573 1626
1574/* words written to sysfs files may, or my not, be \n terminated. 1627/* words written to sysfs files may, or my not, be \n terminated.
1575 * We want to accept with case. For this we use cmd_match. 1628 * We want to accept with case. For this we use cmd_match.
@@ -2162,7 +2215,9 @@ action_show(mddev_t *mddev, char *page)
2162 char *type = "idle"; 2215 char *type = "idle";
2163 if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) || 2216 if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
2164 test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) { 2217 test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) {
2165 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { 2218 if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
2219 type = "reshape";
2220 else if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
2166 if (!test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) 2221 if (!test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
2167 type = "resync"; 2222 type = "resync";
2168 else if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery)) 2223 else if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery))
@@ -2193,7 +2248,14 @@ action_store(mddev_t *mddev, const char *page, size_t len)
2193 return -EBUSY; 2248 return -EBUSY;
2194 else if (cmd_match(page, "resync") || cmd_match(page, "recover")) 2249 else if (cmd_match(page, "resync") || cmd_match(page, "recover"))
2195 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 2250 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
2196 else { 2251 else if (cmd_match(page, "reshape")) {
2252 int err;
2253 if (mddev->pers->start_reshape == NULL)
2254 return -EINVAL;
2255 err = mddev->pers->start_reshape(mddev);
2256 if (err)
2257 return err;
2258 } else {
2197 if (cmd_match(page, "check")) 2259 if (cmd_match(page, "check"))
2198 set_bit(MD_RECOVERY_CHECK, &mddev->recovery); 2260 set_bit(MD_RECOVERY_CHECK, &mddev->recovery);
2199 else if (cmd_match(page, "repair")) 2261 else if (cmd_match(page, "repair"))
@@ -2304,6 +2366,63 @@ sync_completed_show(mddev_t *mddev, char *page)
2304static struct md_sysfs_entry 2366static struct md_sysfs_entry
2305md_sync_completed = __ATTR_RO(sync_completed); 2367md_sync_completed = __ATTR_RO(sync_completed);
2306 2368
2369static ssize_t
2370suspend_lo_show(mddev_t *mddev, char *page)
2371{
2372 return sprintf(page, "%llu\n", (unsigned long long)mddev->suspend_lo);
2373}
2374
2375static ssize_t
2376suspend_lo_store(mddev_t *mddev, const char *buf, size_t len)
2377{
2378 char *e;
2379 unsigned long long new = simple_strtoull(buf, &e, 10);
2380
2381 if (mddev->pers->quiesce == NULL)
2382 return -EINVAL;
2383 if (buf == e || (*e && *e != '\n'))
2384 return -EINVAL;
2385 if (new >= mddev->suspend_hi ||
2386 (new > mddev->suspend_lo && new < mddev->suspend_hi)) {
2387 mddev->suspend_lo = new;
2388 mddev->pers->quiesce(mddev, 2);
2389 return len;
2390 } else
2391 return -EINVAL;
2392}
2393static struct md_sysfs_entry md_suspend_lo =
2394__ATTR(suspend_lo, S_IRUGO|S_IWUSR, suspend_lo_show, suspend_lo_store);
2395
2396
2397static ssize_t
2398suspend_hi_show(mddev_t *mddev, char *page)
2399{
2400 return sprintf(page, "%llu\n", (unsigned long long)mddev->suspend_hi);
2401}
2402
2403static ssize_t
2404suspend_hi_store(mddev_t *mddev, const char *buf, size_t len)
2405{
2406 char *e;
2407 unsigned long long new = simple_strtoull(buf, &e, 10);
2408
2409 if (mddev->pers->quiesce == NULL)
2410 return -EINVAL;
2411 if (buf == e || (*e && *e != '\n'))
2412 return -EINVAL;
2413 if ((new <= mddev->suspend_lo && mddev->suspend_lo >= mddev->suspend_hi) ||
2414 (new > mddev->suspend_lo && new > mddev->suspend_hi)) {
2415 mddev->suspend_hi = new;
2416 mddev->pers->quiesce(mddev, 1);
2417 mddev->pers->quiesce(mddev, 0);
2418 return len;
2419 } else
2420 return -EINVAL;
2421}
2422static struct md_sysfs_entry md_suspend_hi =
2423__ATTR(suspend_hi, S_IRUGO|S_IWUSR, suspend_hi_show, suspend_hi_store);
2424
2425
2307static struct attribute *md_default_attrs[] = { 2426static struct attribute *md_default_attrs[] = {
2308 &md_level.attr, 2427 &md_level.attr,
2309 &md_raid_disks.attr, 2428 &md_raid_disks.attr,
@@ -2321,6 +2440,8 @@ static struct attribute *md_redundancy_attrs[] = {
2321 &md_sync_max.attr, 2440 &md_sync_max.attr,
2322 &md_sync_speed.attr, 2441 &md_sync_speed.attr,
2323 &md_sync_completed.attr, 2442 &md_sync_completed.attr,
2443 &md_suspend_lo.attr,
2444 &md_suspend_hi.attr,
2324 NULL, 2445 NULL,
2325}; 2446};
2326static struct attribute_group md_redundancy_group = { 2447static struct attribute_group md_redundancy_group = {
@@ -2380,7 +2501,7 @@ int mdp_major = 0;
2380 2501
2381static struct kobject *md_probe(dev_t dev, int *part, void *data) 2502static struct kobject *md_probe(dev_t dev, int *part, void *data)
2382{ 2503{
2383 static DECLARE_MUTEX(disks_sem); 2504 static DEFINE_MUTEX(disks_mutex);
2384 mddev_t *mddev = mddev_find(dev); 2505 mddev_t *mddev = mddev_find(dev);
2385 struct gendisk *disk; 2506 struct gendisk *disk;
2386 int partitioned = (MAJOR(dev) != MD_MAJOR); 2507 int partitioned = (MAJOR(dev) != MD_MAJOR);
@@ -2390,15 +2511,15 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data)
2390 if (!mddev) 2511 if (!mddev)
2391 return NULL; 2512 return NULL;
2392 2513
2393 down(&disks_sem); 2514 mutex_lock(&disks_mutex);
2394 if (mddev->gendisk) { 2515 if (mddev->gendisk) {
2395 up(&disks_sem); 2516 mutex_unlock(&disks_mutex);
2396 mddev_put(mddev); 2517 mddev_put(mddev);
2397 return NULL; 2518 return NULL;
2398 } 2519 }
2399 disk = alloc_disk(1 << shift); 2520 disk = alloc_disk(1 << shift);
2400 if (!disk) { 2521 if (!disk) {
2401 up(&disks_sem); 2522 mutex_unlock(&disks_mutex);
2402 mddev_put(mddev); 2523 mddev_put(mddev);
2403 return NULL; 2524 return NULL;
2404 } 2525 }
@@ -2416,7 +2537,7 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data)
2416 disk->queue = mddev->queue; 2537 disk->queue = mddev->queue;
2417 add_disk(disk); 2538 add_disk(disk);
2418 mddev->gendisk = disk; 2539 mddev->gendisk = disk;
2419 up(&disks_sem); 2540 mutex_unlock(&disks_mutex);
2420 mddev->kobj.parent = &disk->kobj; 2541 mddev->kobj.parent = &disk->kobj;
2421 mddev->kobj.k_name = NULL; 2542 mddev->kobj.k_name = NULL;
2422 snprintf(mddev->kobj.name, KOBJ_NAME_LEN, "%s", "md"); 2543 snprintf(mddev->kobj.name, KOBJ_NAME_LEN, "%s", "md");
@@ -2539,6 +2660,14 @@ static int do_md_run(mddev_t * mddev)
2539 mddev->level = pers->level; 2660 mddev->level = pers->level;
2540 strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel)); 2661 strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel));
2541 2662
2663 if (mddev->reshape_position != MaxSector &&
2664 pers->start_reshape == NULL) {
2665 /* This personality cannot handle reshaping... */
2666 mddev->pers = NULL;
2667 module_put(pers->owner);
2668 return -EINVAL;
2669 }
2670
2542 mddev->recovery = 0; 2671 mddev->recovery = 0;
2543 mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */ 2672 mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */
2544 mddev->barriers_work = 1; 2673 mddev->barriers_work = 1;
@@ -2772,7 +2901,6 @@ static void autorun_array(mddev_t *mddev)
2772 */ 2901 */
2773static void autorun_devices(int part) 2902static void autorun_devices(int part)
2774{ 2903{
2775 struct list_head candidates;
2776 struct list_head *tmp; 2904 struct list_head *tmp;
2777 mdk_rdev_t *rdev0, *rdev; 2905 mdk_rdev_t *rdev0, *rdev;
2778 mddev_t *mddev; 2906 mddev_t *mddev;
@@ -2781,6 +2909,7 @@ static void autorun_devices(int part)
2781 printk(KERN_INFO "md: autorun ...\n"); 2909 printk(KERN_INFO "md: autorun ...\n");
2782 while (!list_empty(&pending_raid_disks)) { 2910 while (!list_empty(&pending_raid_disks)) {
2783 dev_t dev; 2911 dev_t dev;
2912 LIST_HEAD(candidates);
2784 rdev0 = list_entry(pending_raid_disks.next, 2913 rdev0 = list_entry(pending_raid_disks.next,
2785 mdk_rdev_t, same_set); 2914 mdk_rdev_t, same_set);
2786 2915
@@ -3427,11 +3556,18 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info)
3427 mddev->default_bitmap_offset = MD_SB_BYTES >> 9; 3556 mddev->default_bitmap_offset = MD_SB_BYTES >> 9;
3428 mddev->bitmap_offset = 0; 3557 mddev->bitmap_offset = 0;
3429 3558
3559 mddev->reshape_position = MaxSector;
3560
3430 /* 3561 /*
3431 * Generate a 128 bit UUID 3562 * Generate a 128 bit UUID
3432 */ 3563 */
3433 get_random_bytes(mddev->uuid, 16); 3564 get_random_bytes(mddev->uuid, 16);
3434 3565
3566 mddev->new_level = mddev->level;
3567 mddev->new_chunk = mddev->chunk_size;
3568 mddev->new_layout = mddev->layout;
3569 mddev->delta_disks = 0;
3570
3435 return 0; 3571 return 0;
3436} 3572}
3437 3573
@@ -3440,6 +3576,7 @@ static int update_size(mddev_t *mddev, unsigned long size)
3440 mdk_rdev_t * rdev; 3576 mdk_rdev_t * rdev;
3441 int rv; 3577 int rv;
3442 struct list_head *tmp; 3578 struct list_head *tmp;
3579 int fit = (size == 0);
3443 3580
3444 if (mddev->pers->resize == NULL) 3581 if (mddev->pers->resize == NULL)
3445 return -EINVAL; 3582 return -EINVAL;
@@ -3457,7 +3594,6 @@ static int update_size(mddev_t *mddev, unsigned long size)
3457 return -EBUSY; 3594 return -EBUSY;
3458 ITERATE_RDEV(mddev,rdev,tmp) { 3595 ITERATE_RDEV(mddev,rdev,tmp) {
3459 sector_t avail; 3596 sector_t avail;
3460 int fit = (size == 0);
3461 if (rdev->sb_offset > rdev->data_offset) 3597 if (rdev->sb_offset > rdev->data_offset)
3462 avail = (rdev->sb_offset*2) - rdev->data_offset; 3598 avail = (rdev->sb_offset*2) - rdev->data_offset;
3463 else 3599 else
@@ -3487,14 +3623,16 @@ static int update_raid_disks(mddev_t *mddev, int raid_disks)
3487{ 3623{
3488 int rv; 3624 int rv;
3489 /* change the number of raid disks */ 3625 /* change the number of raid disks */
3490 if (mddev->pers->reshape == NULL) 3626 if (mddev->pers->check_reshape == NULL)
3491 return -EINVAL; 3627 return -EINVAL;
3492 if (raid_disks <= 0 || 3628 if (raid_disks <= 0 ||
3493 raid_disks >= mddev->max_disks) 3629 raid_disks >= mddev->max_disks)
3494 return -EINVAL; 3630 return -EINVAL;
3495 if (mddev->sync_thread) 3631 if (mddev->sync_thread || mddev->reshape_position != MaxSector)
3496 return -EBUSY; 3632 return -EBUSY;
3497 rv = mddev->pers->reshape(mddev, raid_disks); 3633 mddev->delta_disks = raid_disks - mddev->raid_disks;
3634
3635 rv = mddev->pers->check_reshape(mddev);
3498 return rv; 3636 return rv;
3499} 3637}
3500 3638
@@ -4041,7 +4179,10 @@ static void status_unused(struct seq_file *seq)
4041 4179
4042static void status_resync(struct seq_file *seq, mddev_t * mddev) 4180static void status_resync(struct seq_file *seq, mddev_t * mddev)
4043{ 4181{
4044 unsigned long max_blocks, resync, res, dt, db, rt; 4182 sector_t max_blocks, resync, res;
4183 unsigned long dt, db, rt;
4184 int scale;
4185 unsigned int per_milli;
4045 4186
4046 resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active))/2; 4187 resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active))/2;
4047 4188
@@ -4057,9 +4198,22 @@ static void status_resync(struct seq_file *seq, mddev_t * mddev)
4057 MD_BUG(); 4198 MD_BUG();
4058 return; 4199 return;
4059 } 4200 }
4060 res = (resync/1024)*1000/(max_blocks/1024 + 1); 4201 /* Pick 'scale' such that (resync>>scale)*1000 will fit
4202 * in a sector_t, and (max_blocks>>scale) will fit in a
4203 * u32, as those are the requirements for sector_div.
4204 * Thus 'scale' must be at least 10
4205 */
4206 scale = 10;
4207 if (sizeof(sector_t) > sizeof(unsigned long)) {
4208 while ( max_blocks/2 > (1ULL<<(scale+32)))
4209 scale++;
4210 }
4211 res = (resync>>scale)*1000;
4212 sector_div(res, (u32)((max_blocks>>scale)+1));
4213
4214 per_milli = res;
4061 { 4215 {
4062 int i, x = res/50, y = 20-x; 4216 int i, x = per_milli/50, y = 20-x;
4063 seq_printf(seq, "["); 4217 seq_printf(seq, "[");
4064 for (i = 0; i < x; i++) 4218 for (i = 0; i < x; i++)
4065 seq_printf(seq, "="); 4219 seq_printf(seq, "=");
@@ -4068,10 +4222,14 @@ static void status_resync(struct seq_file *seq, mddev_t * mddev)
4068 seq_printf(seq, "."); 4222 seq_printf(seq, ".");
4069 seq_printf(seq, "] "); 4223 seq_printf(seq, "] ");
4070 } 4224 }
4071 seq_printf(seq, " %s =%3lu.%lu%% (%lu/%lu)", 4225 seq_printf(seq, " %s =%3u.%u%% (%llu/%llu)",
4226 (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)?
4227 "reshape" :
4072 (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) ? 4228 (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) ?
4073 "resync" : "recovery"), 4229 "resync" : "recovery")),
4074 res/10, res % 10, resync, max_blocks); 4230 per_milli/10, per_milli % 10,
4231 (unsigned long long) resync,
4232 (unsigned long long) max_blocks);
4075 4233
4076 /* 4234 /*
4077 * We do not want to overflow, so the order of operands and 4235 * We do not want to overflow, so the order of operands and
@@ -4085,7 +4243,7 @@ static void status_resync(struct seq_file *seq, mddev_t * mddev)
4085 dt = ((jiffies - mddev->resync_mark) / HZ); 4243 dt = ((jiffies - mddev->resync_mark) / HZ);
4086 if (!dt) dt++; 4244 if (!dt) dt++;
4087 db = resync - (mddev->resync_mark_cnt/2); 4245 db = resync - (mddev->resync_mark_cnt/2);
4088 rt = (dt * ((max_blocks-resync) / (db/100+1)))/100; 4246 rt = (dt * ((unsigned long)(max_blocks-resync) / (db/100+1)))/100;
4089 4247
4090 seq_printf(seq, " finish=%lu.%lumin", rt / 60, (rt % 60)/6); 4248 seq_printf(seq, " finish=%lu.%lumin", rt / 60, (rt % 60)/6);
4091 4249
@@ -4442,7 +4600,7 @@ static DECLARE_WAIT_QUEUE_HEAD(resync_wait);
4442 4600
4443#define SYNC_MARKS 10 4601#define SYNC_MARKS 10
4444#define SYNC_MARK_STEP (3*HZ) 4602#define SYNC_MARK_STEP (3*HZ)
4445static void md_do_sync(mddev_t *mddev) 4603void md_do_sync(mddev_t *mddev)
4446{ 4604{
4447 mddev_t *mddev2; 4605 mddev_t *mddev2;
4448 unsigned int currspeed = 0, 4606 unsigned int currspeed = 0,
@@ -4522,7 +4680,9 @@ static void md_do_sync(mddev_t *mddev)
4522 */ 4680 */
4523 max_sectors = mddev->resync_max_sectors; 4681 max_sectors = mddev->resync_max_sectors;
4524 mddev->resync_mismatches = 0; 4682 mddev->resync_mismatches = 0;
4525 } else 4683 } else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
4684 max_sectors = mddev->size << 1;
4685 else
4526 /* recovery follows the physical size of devices */ 4686 /* recovery follows the physical size of devices */
4527 max_sectors = mddev->size << 1; 4687 max_sectors = mddev->size << 1;
4528 4688
@@ -4658,6 +4818,8 @@ static void md_do_sync(mddev_t *mddev)
4658 mddev->pers->sync_request(mddev, max_sectors, &skipped, 1); 4818 mddev->pers->sync_request(mddev, max_sectors, &skipped, 1);
4659 4819
4660 if (!test_bit(MD_RECOVERY_ERR, &mddev->recovery) && 4820 if (!test_bit(MD_RECOVERY_ERR, &mddev->recovery) &&
4821 test_bit(MD_RECOVERY_SYNC, &mddev->recovery) &&
4822 !test_bit(MD_RECOVERY_CHECK, &mddev->recovery) &&
4661 mddev->curr_resync > 2 && 4823 mddev->curr_resync > 2 &&
4662 mddev->curr_resync >= mddev->recovery_cp) { 4824 mddev->curr_resync >= mddev->recovery_cp) {
4663 if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { 4825 if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
@@ -4675,6 +4837,7 @@ static void md_do_sync(mddev_t *mddev)
4675 set_bit(MD_RECOVERY_DONE, &mddev->recovery); 4837 set_bit(MD_RECOVERY_DONE, &mddev->recovery);
4676 md_wakeup_thread(mddev->thread); 4838 md_wakeup_thread(mddev->thread);
4677} 4839}
4840EXPORT_SYMBOL_GPL(md_do_sync);
4678 4841
4679 4842
4680/* 4843/*
@@ -4730,7 +4893,7 @@ void md_check_recovery(mddev_t *mddev)
4730 )) 4893 ))
4731 return; 4894 return;
4732 4895
4733 if (mddev_trylock(mddev)==0) { 4896 if (mddev_trylock(mddev)) {
4734 int spares =0; 4897 int spares =0;
4735 4898
4736 spin_lock_irq(&mddev->write_lock); 4899 spin_lock_irq(&mddev->write_lock);
@@ -4866,7 +5029,7 @@ static int md_notify_reboot(struct notifier_block *this,
4866 printk(KERN_INFO "md: stopping all md devices.\n"); 5029 printk(KERN_INFO "md: stopping all md devices.\n");
4867 5030
4868 ITERATE_MDDEV(mddev,tmp) 5031 ITERATE_MDDEV(mddev,tmp)
4869 if (mddev_trylock(mddev)==0) 5032 if (mddev_trylock(mddev))
4870 do_md_stop (mddev, 1); 5033 do_md_stop (mddev, 1);
4871 /* 5034 /*
4872 * certain more exotic SCSI devices are known to be 5035 * certain more exotic SCSI devices are known to be
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 5d88329e3c7a..3cb0872a845d 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1402,6 +1402,9 @@ static void raid1d(mddev_t *mddev)
1402 clear_bit(R1BIO_BarrierRetry, &r1_bio->state); 1402 clear_bit(R1BIO_BarrierRetry, &r1_bio->state);
1403 clear_bit(R1BIO_Barrier, &r1_bio->state); 1403 clear_bit(R1BIO_Barrier, &r1_bio->state);
1404 for (i=0; i < conf->raid_disks; i++) 1404 for (i=0; i < conf->raid_disks; i++)
1405 if (r1_bio->bios[i])
1406 atomic_inc(&r1_bio->remaining);
1407 for (i=0; i < conf->raid_disks; i++)
1405 if (r1_bio->bios[i]) { 1408 if (r1_bio->bios[i]) {
1406 struct bio_vec *bvec; 1409 struct bio_vec *bvec;
1407 int j; 1410 int j;
@@ -1789,6 +1792,11 @@ static int run(mddev_t *mddev)
1789 mdname(mddev), mddev->level); 1792 mdname(mddev), mddev->level);
1790 goto out; 1793 goto out;
1791 } 1794 }
1795 if (mddev->reshape_position != MaxSector) {
1796 printk("raid1: %s: reshape_position set but not supported\n",
1797 mdname(mddev));
1798 goto out;
1799 }
1792 /* 1800 /*
1793 * copy the already verified devices into our private RAID1 1801 * copy the already verified devices into our private RAID1
1794 * bookkeeping area. [whatever we allocate in run(), 1802 * bookkeeping area. [whatever we allocate in run(),
@@ -1971,7 +1979,7 @@ static int raid1_resize(mddev_t *mddev, sector_t sectors)
1971 return 0; 1979 return 0;
1972} 1980}
1973 1981
1974static int raid1_reshape(mddev_t *mddev, int raid_disks) 1982static int raid1_reshape(mddev_t *mddev)
1975{ 1983{
1976 /* We need to: 1984 /* We need to:
1977 * 1/ resize the r1bio_pool 1985 * 1/ resize the r1bio_pool
@@ -1988,10 +1996,22 @@ static int raid1_reshape(mddev_t *mddev, int raid_disks)
1988 struct pool_info *newpoolinfo; 1996 struct pool_info *newpoolinfo;
1989 mirror_info_t *newmirrors; 1997 mirror_info_t *newmirrors;
1990 conf_t *conf = mddev_to_conf(mddev); 1998 conf_t *conf = mddev_to_conf(mddev);
1991 int cnt; 1999 int cnt, raid_disks;
1992 2000
1993 int d, d2; 2001 int d, d2;
1994 2002
2003 /* Cannot change chunk_size, layout, or level */
2004 if (mddev->chunk_size != mddev->new_chunk ||
2005 mddev->layout != mddev->new_layout ||
2006 mddev->level != mddev->new_level) {
2007 mddev->new_chunk = mddev->chunk_size;
2008 mddev->new_layout = mddev->layout;
2009 mddev->new_level = mddev->level;
2010 return -EINVAL;
2011 }
2012
2013 raid_disks = mddev->raid_disks + mddev->delta_disks;
2014
1995 if (raid_disks < conf->raid_disks) { 2015 if (raid_disks < conf->raid_disks) {
1996 cnt=0; 2016 cnt=0;
1997 for (d= 0; d < conf->raid_disks; d++) 2017 for (d= 0; d < conf->raid_disks; d++)
@@ -2038,6 +2058,7 @@ static int raid1_reshape(mddev_t *mddev, int raid_disks)
2038 2058
2039 mddev->degraded += (raid_disks - conf->raid_disks); 2059 mddev->degraded += (raid_disks - conf->raid_disks);
2040 conf->raid_disks = mddev->raid_disks = raid_disks; 2060 conf->raid_disks = mddev->raid_disks = raid_disks;
2061 mddev->delta_disks = 0;
2041 2062
2042 conf->last_used = 0; /* just make sure it is in-range */ 2063 conf->last_used = 0; /* just make sure it is in-range */
2043 lower_barrier(conf); 2064 lower_barrier(conf);
@@ -2079,7 +2100,7 @@ static struct mdk_personality raid1_personality =
2079 .spare_active = raid1_spare_active, 2100 .spare_active = raid1_spare_active,
2080 .sync_request = sync_request, 2101 .sync_request = sync_request,
2081 .resize = raid1_resize, 2102 .resize = raid1_resize,
2082 .reshape = raid1_reshape, 2103 .check_reshape = raid1_reshape,
2083 .quiesce = raid1_quiesce, 2104 .quiesce = raid1_quiesce,
2084}; 2105};
2085 2106
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 2dba305daf3c..dae740adaf65 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -22,6 +22,7 @@
22#include <linux/raid/raid5.h> 22#include <linux/raid/raid5.h>
23#include <linux/highmem.h> 23#include <linux/highmem.h>
24#include <linux/bitops.h> 24#include <linux/bitops.h>
25#include <linux/kthread.h>
25#include <asm/atomic.h> 26#include <asm/atomic.h>
26 27
27#include <linux/raid/bitmap.h> 28#include <linux/raid/bitmap.h>
@@ -93,11 +94,11 @@ static void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh)
93 if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD) 94 if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD)
94 md_wakeup_thread(conf->mddev->thread); 95 md_wakeup_thread(conf->mddev->thread);
95 } 96 }
96 list_add_tail(&sh->lru, &conf->inactive_list);
97 atomic_dec(&conf->active_stripes); 97 atomic_dec(&conf->active_stripes);
98 if (!conf->inactive_blocked || 98 if (!test_bit(STRIPE_EXPANDING, &sh->state)) {
99 atomic_read(&conf->active_stripes) < (conf->max_nr_stripes*3/4)) 99 list_add_tail(&sh->lru, &conf->inactive_list);
100 wake_up(&conf->wait_for_stripe); 100 wake_up(&conf->wait_for_stripe);
101 }
101 } 102 }
102 } 103 }
103} 104}
@@ -178,10 +179,10 @@ static int grow_buffers(struct stripe_head *sh, int num)
178 179
179static void raid5_build_block (struct stripe_head *sh, int i); 180static void raid5_build_block (struct stripe_head *sh, int i);
180 181
181static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx) 182static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int disks)
182{ 183{
183 raid5_conf_t *conf = sh->raid_conf; 184 raid5_conf_t *conf = sh->raid_conf;
184 int disks = conf->raid_disks, i; 185 int i;
185 186
186 if (atomic_read(&sh->count) != 0) 187 if (atomic_read(&sh->count) != 0)
187 BUG(); 188 BUG();
@@ -198,7 +199,9 @@ static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx)
198 sh->pd_idx = pd_idx; 199 sh->pd_idx = pd_idx;
199 sh->state = 0; 200 sh->state = 0;
200 201
201 for (i=disks; i--; ) { 202 sh->disks = disks;
203
204 for (i = sh->disks; i--; ) {
202 struct r5dev *dev = &sh->dev[i]; 205 struct r5dev *dev = &sh->dev[i];
203 206
204 if (dev->toread || dev->towrite || dev->written || 207 if (dev->toread || dev->towrite || dev->written ||
@@ -215,7 +218,7 @@ static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx)
215 insert_hash(conf, sh); 218 insert_hash(conf, sh);
216} 219}
217 220
218static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector) 221static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector, int disks)
219{ 222{
220 struct stripe_head *sh; 223 struct stripe_head *sh;
221 struct hlist_node *hn; 224 struct hlist_node *hn;
@@ -223,7 +226,7 @@ static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector)
223 CHECK_DEVLOCK(); 226 CHECK_DEVLOCK();
224 PRINTK("__find_stripe, sector %llu\n", (unsigned long long)sector); 227 PRINTK("__find_stripe, sector %llu\n", (unsigned long long)sector);
225 hlist_for_each_entry(sh, hn, stripe_hash(conf, sector), hash) 228 hlist_for_each_entry(sh, hn, stripe_hash(conf, sector), hash)
226 if (sh->sector == sector) 229 if (sh->sector == sector && sh->disks == disks)
227 return sh; 230 return sh;
228 PRINTK("__stripe %llu not in cache\n", (unsigned long long)sector); 231 PRINTK("__stripe %llu not in cache\n", (unsigned long long)sector);
229 return NULL; 232 return NULL;
@@ -232,8 +235,8 @@ static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector)
232static void unplug_slaves(mddev_t *mddev); 235static void unplug_slaves(mddev_t *mddev);
233static void raid5_unplug_device(request_queue_t *q); 236static void raid5_unplug_device(request_queue_t *q);
234 237
235static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector, 238static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector, int disks,
236 int pd_idx, int noblock) 239 int pd_idx, int noblock)
237{ 240{
238 struct stripe_head *sh; 241 struct stripe_head *sh;
239 242
@@ -245,7 +248,7 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector
245 wait_event_lock_irq(conf->wait_for_stripe, 248 wait_event_lock_irq(conf->wait_for_stripe,
246 conf->quiesce == 0, 249 conf->quiesce == 0,
247 conf->device_lock, /* nothing */); 250 conf->device_lock, /* nothing */);
248 sh = __find_stripe(conf, sector); 251 sh = __find_stripe(conf, sector, disks);
249 if (!sh) { 252 if (!sh) {
250 if (!conf->inactive_blocked) 253 if (!conf->inactive_blocked)
251 sh = get_free_stripe(conf); 254 sh = get_free_stripe(conf);
@@ -259,11 +262,11 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector
259 < (conf->max_nr_stripes *3/4) 262 < (conf->max_nr_stripes *3/4)
260 || !conf->inactive_blocked), 263 || !conf->inactive_blocked),
261 conf->device_lock, 264 conf->device_lock,
262 unplug_slaves(conf->mddev); 265 unplug_slaves(conf->mddev)
263 ); 266 );
264 conf->inactive_blocked = 0; 267 conf->inactive_blocked = 0;
265 } else 268 } else
266 init_stripe(sh, sector, pd_idx); 269 init_stripe(sh, sector, pd_idx, disks);
267 } else { 270 } else {
268 if (atomic_read(&sh->count)) { 271 if (atomic_read(&sh->count)) {
269 if (!list_empty(&sh->lru)) 272 if (!list_empty(&sh->lru))
@@ -271,9 +274,8 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector
271 } else { 274 } else {
272 if (!test_bit(STRIPE_HANDLE, &sh->state)) 275 if (!test_bit(STRIPE_HANDLE, &sh->state))
273 atomic_inc(&conf->active_stripes); 276 atomic_inc(&conf->active_stripes);
274 if (list_empty(&sh->lru)) 277 if (!list_empty(&sh->lru))
275 BUG(); 278 list_del_init(&sh->lru);
276 list_del_init(&sh->lru);
277 } 279 }
278 } 280 }
279 } while (sh == NULL); 281 } while (sh == NULL);
@@ -300,6 +302,7 @@ static int grow_one_stripe(raid5_conf_t *conf)
300 kmem_cache_free(conf->slab_cache, sh); 302 kmem_cache_free(conf->slab_cache, sh);
301 return 0; 303 return 0;
302 } 304 }
305 sh->disks = conf->raid_disks;
303 /* we just created an active stripe so... */ 306 /* we just created an active stripe so... */
304 atomic_set(&sh->count, 1); 307 atomic_set(&sh->count, 1);
305 atomic_inc(&conf->active_stripes); 308 atomic_inc(&conf->active_stripes);
@@ -313,14 +316,16 @@ static int grow_stripes(raid5_conf_t *conf, int num)
313 kmem_cache_t *sc; 316 kmem_cache_t *sc;
314 int devs = conf->raid_disks; 317 int devs = conf->raid_disks;
315 318
316 sprintf(conf->cache_name, "raid5/%s", mdname(conf->mddev)); 319 sprintf(conf->cache_name[0], "raid5/%s", mdname(conf->mddev));
317 320 sprintf(conf->cache_name[1], "raid5/%s-alt", mdname(conf->mddev));
318 sc = kmem_cache_create(conf->cache_name, 321 conf->active_name = 0;
322 sc = kmem_cache_create(conf->cache_name[conf->active_name],
319 sizeof(struct stripe_head)+(devs-1)*sizeof(struct r5dev), 323 sizeof(struct stripe_head)+(devs-1)*sizeof(struct r5dev),
320 0, 0, NULL, NULL); 324 0, 0, NULL, NULL);
321 if (!sc) 325 if (!sc)
322 return 1; 326 return 1;
323 conf->slab_cache = sc; 327 conf->slab_cache = sc;
328 conf->pool_size = devs;
324 while (num--) { 329 while (num--) {
325 if (!grow_one_stripe(conf)) 330 if (!grow_one_stripe(conf))
326 return 1; 331 return 1;
@@ -328,6 +333,129 @@ static int grow_stripes(raid5_conf_t *conf, int num)
328 return 0; 333 return 0;
329} 334}
330 335
336#ifdef CONFIG_MD_RAID5_RESHAPE
337static int resize_stripes(raid5_conf_t *conf, int newsize)
338{
339 /* Make all the stripes able to hold 'newsize' devices.
340 * New slots in each stripe get 'page' set to a new page.
341 *
342 * This happens in stages:
343 * 1/ create a new kmem_cache and allocate the required number of
344 * stripe_heads.
345 * 2/ gather all the old stripe_heads and tranfer the pages across
346 * to the new stripe_heads. This will have the side effect of
347 * freezing the array as once all stripe_heads have been collected,
348 * no IO will be possible. Old stripe heads are freed once their
349 * pages have been transferred over, and the old kmem_cache is
350 * freed when all stripes are done.
351 * 3/ reallocate conf->disks to be suitable bigger. If this fails,
352 * we simple return a failre status - no need to clean anything up.
353 * 4/ allocate new pages for the new slots in the new stripe_heads.
354 * If this fails, we don't bother trying the shrink the
355 * stripe_heads down again, we just leave them as they are.
356 * As each stripe_head is processed the new one is released into
357 * active service.
358 *
359 * Once step2 is started, we cannot afford to wait for a write,
360 * so we use GFP_NOIO allocations.
361 */
362 struct stripe_head *osh, *nsh;
363 LIST_HEAD(newstripes);
364 struct disk_info *ndisks;
365 int err = 0;
366 kmem_cache_t *sc;
367 int i;
368
369 if (newsize <= conf->pool_size)
370 return 0; /* never bother to shrink */
371
372 /* Step 1 */
373 sc = kmem_cache_create(conf->cache_name[1-conf->active_name],
374 sizeof(struct stripe_head)+(newsize-1)*sizeof(struct r5dev),
375 0, 0, NULL, NULL);
376 if (!sc)
377 return -ENOMEM;
378
379 for (i = conf->max_nr_stripes; i; i--) {
380 nsh = kmem_cache_alloc(sc, GFP_KERNEL);
381 if (!nsh)
382 break;
383
384 memset(nsh, 0, sizeof(*nsh) + (newsize-1)*sizeof(struct r5dev));
385
386 nsh->raid_conf = conf;
387 spin_lock_init(&nsh->lock);
388
389 list_add(&nsh->lru, &newstripes);
390 }
391 if (i) {
392 /* didn't get enough, give up */
393 while (!list_empty(&newstripes)) {
394 nsh = list_entry(newstripes.next, struct stripe_head, lru);
395 list_del(&nsh->lru);
396 kmem_cache_free(sc, nsh);
397 }
398 kmem_cache_destroy(sc);
399 return -ENOMEM;
400 }
401 /* Step 2 - Must use GFP_NOIO now.
402 * OK, we have enough stripes, start collecting inactive
403 * stripes and copying them over
404 */
405 list_for_each_entry(nsh, &newstripes, lru) {
406 spin_lock_irq(&conf->device_lock);
407 wait_event_lock_irq(conf->wait_for_stripe,
408 !list_empty(&conf->inactive_list),
409 conf->device_lock,
410 unplug_slaves(conf->mddev)
411 );
412 osh = get_free_stripe(conf);
413 spin_unlock_irq(&conf->device_lock);
414 atomic_set(&nsh->count, 1);
415 for(i=0; i<conf->pool_size; i++)
416 nsh->dev[i].page = osh->dev[i].page;
417 for( ; i<newsize; i++)
418 nsh->dev[i].page = NULL;
419 kmem_cache_free(conf->slab_cache, osh);
420 }
421 kmem_cache_destroy(conf->slab_cache);
422
423 /* Step 3.
424 * At this point, we are holding all the stripes so the array
425 * is completely stalled, so now is a good time to resize
426 * conf->disks.
427 */
428 ndisks = kzalloc(newsize * sizeof(struct disk_info), GFP_NOIO);
429 if (ndisks) {
430 for (i=0; i<conf->raid_disks; i++)
431 ndisks[i] = conf->disks[i];
432 kfree(conf->disks);
433 conf->disks = ndisks;
434 } else
435 err = -ENOMEM;
436
437 /* Step 4, return new stripes to service */
438 while(!list_empty(&newstripes)) {
439 nsh = list_entry(newstripes.next, struct stripe_head, lru);
440 list_del_init(&nsh->lru);
441 for (i=conf->raid_disks; i < newsize; i++)
442 if (nsh->dev[i].page == NULL) {
443 struct page *p = alloc_page(GFP_NOIO);
444 nsh->dev[i].page = p;
445 if (!p)
446 err = -ENOMEM;
447 }
448 release_stripe(nsh);
449 }
450 /* critical section pass, GFP_NOIO no longer needed */
451
452 conf->slab_cache = sc;
453 conf->active_name = 1-conf->active_name;
454 conf->pool_size = newsize;
455 return err;
456}
457#endif
458
331static int drop_one_stripe(raid5_conf_t *conf) 459static int drop_one_stripe(raid5_conf_t *conf)
332{ 460{
333 struct stripe_head *sh; 461 struct stripe_head *sh;
@@ -339,7 +467,7 @@ static int drop_one_stripe(raid5_conf_t *conf)
339 return 0; 467 return 0;
340 if (atomic_read(&sh->count)) 468 if (atomic_read(&sh->count))
341 BUG(); 469 BUG();
342 shrink_buffers(sh, conf->raid_disks); 470 shrink_buffers(sh, conf->pool_size);
343 kmem_cache_free(conf->slab_cache, sh); 471 kmem_cache_free(conf->slab_cache, sh);
344 atomic_dec(&conf->active_stripes); 472 atomic_dec(&conf->active_stripes);
345 return 1; 473 return 1;
@@ -360,7 +488,7 @@ static int raid5_end_read_request(struct bio * bi, unsigned int bytes_done,
360{ 488{
361 struct stripe_head *sh = bi->bi_private; 489 struct stripe_head *sh = bi->bi_private;
362 raid5_conf_t *conf = sh->raid_conf; 490 raid5_conf_t *conf = sh->raid_conf;
363 int disks = conf->raid_disks, i; 491 int disks = sh->disks, i;
364 int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags); 492 int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags);
365 493
366 if (bi->bi_size) 494 if (bi->bi_size)
@@ -458,7 +586,7 @@ static int raid5_end_write_request (struct bio *bi, unsigned int bytes_done,
458{ 586{
459 struct stripe_head *sh = bi->bi_private; 587 struct stripe_head *sh = bi->bi_private;
460 raid5_conf_t *conf = sh->raid_conf; 588 raid5_conf_t *conf = sh->raid_conf;
461 int disks = conf->raid_disks, i; 589 int disks = sh->disks, i;
462 unsigned long flags; 590 unsigned long flags;
463 int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags); 591 int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags);
464 592
@@ -612,7 +740,7 @@ static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks,
612static sector_t compute_blocknr(struct stripe_head *sh, int i) 740static sector_t compute_blocknr(struct stripe_head *sh, int i)
613{ 741{
614 raid5_conf_t *conf = sh->raid_conf; 742 raid5_conf_t *conf = sh->raid_conf;
615 int raid_disks = conf->raid_disks, data_disks = raid_disks - 1; 743 int raid_disks = sh->disks, data_disks = raid_disks - 1;
616 sector_t new_sector = sh->sector, check; 744 sector_t new_sector = sh->sector, check;
617 int sectors_per_chunk = conf->chunk_size >> 9; 745 int sectors_per_chunk = conf->chunk_size >> 9;
618 sector_t stripe; 746 sector_t stripe;
@@ -713,8 +841,7 @@ static void copy_data(int frombio, struct bio *bio,
713 841
714static void compute_block(struct stripe_head *sh, int dd_idx) 842static void compute_block(struct stripe_head *sh, int dd_idx)
715{ 843{
716 raid5_conf_t *conf = sh->raid_conf; 844 int i, count, disks = sh->disks;
717 int i, count, disks = conf->raid_disks;
718 void *ptr[MAX_XOR_BLOCKS], *p; 845 void *ptr[MAX_XOR_BLOCKS], *p;
719 846
720 PRINTK("compute_block, stripe %llu, idx %d\n", 847 PRINTK("compute_block, stripe %llu, idx %d\n",
@@ -744,7 +871,7 @@ static void compute_block(struct stripe_head *sh, int dd_idx)
744static void compute_parity(struct stripe_head *sh, int method) 871static void compute_parity(struct stripe_head *sh, int method)
745{ 872{
746 raid5_conf_t *conf = sh->raid_conf; 873 raid5_conf_t *conf = sh->raid_conf;
747 int i, pd_idx = sh->pd_idx, disks = conf->raid_disks, count; 874 int i, pd_idx = sh->pd_idx, disks = sh->disks, count;
748 void *ptr[MAX_XOR_BLOCKS]; 875 void *ptr[MAX_XOR_BLOCKS];
749 struct bio *chosen; 876 struct bio *chosen;
750 877
@@ -910,6 +1037,20 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in
910 return 0; 1037 return 0;
911} 1038}
912 1039
1040static void end_reshape(raid5_conf_t *conf);
1041
1042static int stripe_to_pdidx(sector_t stripe, raid5_conf_t *conf, int disks)
1043{
1044 int sectors_per_chunk = conf->chunk_size >> 9;
1045 sector_t x = stripe;
1046 int pd_idx, dd_idx;
1047 int chunk_offset = sector_div(x, sectors_per_chunk);
1048 stripe = x;
1049 raid5_compute_sector(stripe*(disks-1)*sectors_per_chunk
1050 + chunk_offset, disks, disks-1, &dd_idx, &pd_idx, conf);
1051 return pd_idx;
1052}
1053
913 1054
914/* 1055/*
915 * handle_stripe - do things to a stripe. 1056 * handle_stripe - do things to a stripe.
@@ -932,11 +1073,11 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in
932static void handle_stripe(struct stripe_head *sh) 1073static void handle_stripe(struct stripe_head *sh)
933{ 1074{
934 raid5_conf_t *conf = sh->raid_conf; 1075 raid5_conf_t *conf = sh->raid_conf;
935 int disks = conf->raid_disks; 1076 int disks = sh->disks;
936 struct bio *return_bi= NULL; 1077 struct bio *return_bi= NULL;
937 struct bio *bi; 1078 struct bio *bi;
938 int i; 1079 int i;
939 int syncing; 1080 int syncing, expanding, expanded;
940 int locked=0, uptodate=0, to_read=0, to_write=0, failed=0, written=0; 1081 int locked=0, uptodate=0, to_read=0, to_write=0, failed=0, written=0;
941 int non_overwrite = 0; 1082 int non_overwrite = 0;
942 int failed_num=0; 1083 int failed_num=0;
@@ -951,6 +1092,8 @@ static void handle_stripe(struct stripe_head *sh)
951 clear_bit(STRIPE_DELAYED, &sh->state); 1092 clear_bit(STRIPE_DELAYED, &sh->state);
952 1093
953 syncing = test_bit(STRIPE_SYNCING, &sh->state); 1094 syncing = test_bit(STRIPE_SYNCING, &sh->state);
1095 expanding = test_bit(STRIPE_EXPAND_SOURCE, &sh->state);
1096 expanded = test_bit(STRIPE_EXPAND_READY, &sh->state);
954 /* Now to look around and see what can be done */ 1097 /* Now to look around and see what can be done */
955 1098
956 rcu_read_lock(); 1099 rcu_read_lock();
@@ -1143,13 +1286,14 @@ static void handle_stripe(struct stripe_head *sh)
1143 * parity, or to satisfy requests 1286 * parity, or to satisfy requests
1144 * or to load a block that is being partially written. 1287 * or to load a block that is being partially written.
1145 */ 1288 */
1146 if (to_read || non_overwrite || (syncing && (uptodate < disks))) { 1289 if (to_read || non_overwrite || (syncing && (uptodate < disks)) || expanding) {
1147 for (i=disks; i--;) { 1290 for (i=disks; i--;) {
1148 dev = &sh->dev[i]; 1291 dev = &sh->dev[i];
1149 if (!test_bit(R5_LOCKED, &dev->flags) && !test_bit(R5_UPTODATE, &dev->flags) && 1292 if (!test_bit(R5_LOCKED, &dev->flags) && !test_bit(R5_UPTODATE, &dev->flags) &&
1150 (dev->toread || 1293 (dev->toread ||
1151 (dev->towrite && !test_bit(R5_OVERWRITE, &dev->flags)) || 1294 (dev->towrite && !test_bit(R5_OVERWRITE, &dev->flags)) ||
1152 syncing || 1295 syncing ||
1296 expanding ||
1153 (failed && (sh->dev[failed_num].toread || 1297 (failed && (sh->dev[failed_num].toread ||
1154 (sh->dev[failed_num].towrite && !test_bit(R5_OVERWRITE, &sh->dev[failed_num].flags)))) 1298 (sh->dev[failed_num].towrite && !test_bit(R5_OVERWRITE, &sh->dev[failed_num].flags))))
1155 ) 1299 )
@@ -1339,13 +1483,77 @@ static void handle_stripe(struct stripe_head *sh)
1339 set_bit(R5_Wantwrite, &dev->flags); 1483 set_bit(R5_Wantwrite, &dev->flags);
1340 set_bit(R5_ReWrite, &dev->flags); 1484 set_bit(R5_ReWrite, &dev->flags);
1341 set_bit(R5_LOCKED, &dev->flags); 1485 set_bit(R5_LOCKED, &dev->flags);
1486 locked++;
1342 } else { 1487 } else {
1343 /* let's read it back */ 1488 /* let's read it back */
1344 set_bit(R5_Wantread, &dev->flags); 1489 set_bit(R5_Wantread, &dev->flags);
1345 set_bit(R5_LOCKED, &dev->flags); 1490 set_bit(R5_LOCKED, &dev->flags);
1491 locked++;
1346 } 1492 }
1347 } 1493 }
1348 1494
1495 if (expanded && test_bit(STRIPE_EXPANDING, &sh->state)) {
1496 /* Need to write out all blocks after computing parity */
1497 sh->disks = conf->raid_disks;
1498 sh->pd_idx = stripe_to_pdidx(sh->sector, conf, conf->raid_disks);
1499 compute_parity(sh, RECONSTRUCT_WRITE);
1500 for (i= conf->raid_disks; i--;) {
1501 set_bit(R5_LOCKED, &sh->dev[i].flags);
1502 locked++;
1503 set_bit(R5_Wantwrite, &sh->dev[i].flags);
1504 }
1505 clear_bit(STRIPE_EXPANDING, &sh->state);
1506 } else if (expanded) {
1507 clear_bit(STRIPE_EXPAND_READY, &sh->state);
1508 atomic_dec(&conf->reshape_stripes);
1509 wake_up(&conf->wait_for_overlap);
1510 md_done_sync(conf->mddev, STRIPE_SECTORS, 1);
1511 }
1512
1513 if (expanding && locked == 0) {
1514 /* We have read all the blocks in this stripe and now we need to
1515 * copy some of them into a target stripe for expand.
1516 */
1517 clear_bit(STRIPE_EXPAND_SOURCE, &sh->state);
1518 for (i=0; i< sh->disks; i++)
1519 if (i != sh->pd_idx) {
1520 int dd_idx, pd_idx, j;
1521 struct stripe_head *sh2;
1522
1523 sector_t bn = compute_blocknr(sh, i);
1524 sector_t s = raid5_compute_sector(bn, conf->raid_disks,
1525 conf->raid_disks-1,
1526 &dd_idx, &pd_idx, conf);
1527 sh2 = get_active_stripe(conf, s, conf->raid_disks, pd_idx, 1);
1528 if (sh2 == NULL)
1529 /* so far only the early blocks of this stripe
1530 * have been requested. When later blocks
1531 * get requested, we will try again
1532 */
1533 continue;
1534 if(!test_bit(STRIPE_EXPANDING, &sh2->state) ||
1535 test_bit(R5_Expanded, &sh2->dev[dd_idx].flags)) {
1536 /* must have already done this block */
1537 release_stripe(sh2);
1538 continue;
1539 }
1540 memcpy(page_address(sh2->dev[dd_idx].page),
1541 page_address(sh->dev[i].page),
1542 STRIPE_SIZE);
1543 set_bit(R5_Expanded, &sh2->dev[dd_idx].flags);
1544 set_bit(R5_UPTODATE, &sh2->dev[dd_idx].flags);
1545 for (j=0; j<conf->raid_disks; j++)
1546 if (j != sh2->pd_idx &&
1547 !test_bit(R5_Expanded, &sh2->dev[j].flags))
1548 break;
1549 if (j == conf->raid_disks) {
1550 set_bit(STRIPE_EXPAND_READY, &sh2->state);
1551 set_bit(STRIPE_HANDLE, &sh2->state);
1552 }
1553 release_stripe(sh2);
1554 }
1555 }
1556
1349 spin_unlock(&sh->lock); 1557 spin_unlock(&sh->lock);
1350 1558
1351 while ((bi=return_bi)) { 1559 while ((bi=return_bi)) {
@@ -1384,7 +1592,7 @@ static void handle_stripe(struct stripe_head *sh)
1384 rcu_read_unlock(); 1592 rcu_read_unlock();
1385 1593
1386 if (rdev) { 1594 if (rdev) {
1387 if (syncing) 1595 if (syncing || expanding || expanded)
1388 md_sync_acct(rdev->bdev, STRIPE_SECTORS); 1596 md_sync_acct(rdev->bdev, STRIPE_SECTORS);
1389 1597
1390 bi->bi_bdev = rdev->bdev; 1598 bi->bi_bdev = rdev->bdev;
@@ -1526,17 +1734,16 @@ static inline void raid5_plug_device(raid5_conf_t *conf)
1526 spin_unlock_irq(&conf->device_lock); 1734 spin_unlock_irq(&conf->device_lock);
1527} 1735}
1528 1736
1529static int make_request (request_queue_t *q, struct bio * bi) 1737static int make_request(request_queue_t *q, struct bio * bi)
1530{ 1738{
1531 mddev_t *mddev = q->queuedata; 1739 mddev_t *mddev = q->queuedata;
1532 raid5_conf_t *conf = mddev_to_conf(mddev); 1740 raid5_conf_t *conf = mddev_to_conf(mddev);
1533 const unsigned int raid_disks = conf->raid_disks;
1534 const unsigned int data_disks = raid_disks - 1;
1535 unsigned int dd_idx, pd_idx; 1741 unsigned int dd_idx, pd_idx;
1536 sector_t new_sector; 1742 sector_t new_sector;
1537 sector_t logical_sector, last_sector; 1743 sector_t logical_sector, last_sector;
1538 struct stripe_head *sh; 1744 struct stripe_head *sh;
1539 const int rw = bio_data_dir(bi); 1745 const int rw = bio_data_dir(bi);
1746 int remaining;
1540 1747
1541 if (unlikely(bio_barrier(bi))) { 1748 if (unlikely(bio_barrier(bi))) {
1542 bio_endio(bi, bi->bi_size, -EOPNOTSUPP); 1749 bio_endio(bi, bi->bi_size, -EOPNOTSUPP);
@@ -1555,20 +1762,77 @@ static int make_request (request_queue_t *q, struct bio * bi)
1555 1762
1556 for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) { 1763 for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) {
1557 DEFINE_WAIT(w); 1764 DEFINE_WAIT(w);
1558 1765 int disks;
1559 new_sector = raid5_compute_sector(logical_sector,
1560 raid_disks, data_disks, &dd_idx, &pd_idx, conf);
1561 1766
1767 retry:
1768 prepare_to_wait(&conf->wait_for_overlap, &w, TASK_UNINTERRUPTIBLE);
1769 if (likely(conf->expand_progress == MaxSector))
1770 disks = conf->raid_disks;
1771 else {
1772 /* spinlock is needed as expand_progress may be
1773 * 64bit on a 32bit platform, and so it might be
1774 * possible to see a half-updated value
1775 * Ofcourse expand_progress could change after
1776 * the lock is dropped, so once we get a reference
1777 * to the stripe that we think it is, we will have
1778 * to check again.
1779 */
1780 spin_lock_irq(&conf->device_lock);
1781 disks = conf->raid_disks;
1782 if (logical_sector >= conf->expand_progress)
1783 disks = conf->previous_raid_disks;
1784 else {
1785 if (logical_sector >= conf->expand_lo) {
1786 spin_unlock_irq(&conf->device_lock);
1787 schedule();
1788 goto retry;
1789 }
1790 }
1791 spin_unlock_irq(&conf->device_lock);
1792 }
1793 new_sector = raid5_compute_sector(logical_sector, disks, disks - 1,
1794 &dd_idx, &pd_idx, conf);
1562 PRINTK("raid5: make_request, sector %llu logical %llu\n", 1795 PRINTK("raid5: make_request, sector %llu logical %llu\n",
1563 (unsigned long long)new_sector, 1796 (unsigned long long)new_sector,
1564 (unsigned long long)logical_sector); 1797 (unsigned long long)logical_sector);
1565 1798
1566 retry: 1799 sh = get_active_stripe(conf, new_sector, disks, pd_idx, (bi->bi_rw&RWA_MASK));
1567 prepare_to_wait(&conf->wait_for_overlap, &w, TASK_UNINTERRUPTIBLE);
1568 sh = get_active_stripe(conf, new_sector, pd_idx, (bi->bi_rw&RWA_MASK));
1569 if (sh) { 1800 if (sh) {
1570 if (!add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK))) { 1801 if (unlikely(conf->expand_progress != MaxSector)) {
1571 /* Add failed due to overlap. Flush everything 1802 /* expansion might have moved on while waiting for a
1803 * stripe, so we must do the range check again.
1804 * Expansion could still move past after this
1805 * test, but as we are holding a reference to
1806 * 'sh', we know that if that happens,
1807 * STRIPE_EXPANDING will get set and the expansion
1808 * won't proceed until we finish with the stripe.
1809 */
1810 int must_retry = 0;
1811 spin_lock_irq(&conf->device_lock);
1812 if (logical_sector < conf->expand_progress &&
1813 disks == conf->previous_raid_disks)
1814 /* mismatch, need to try again */
1815 must_retry = 1;
1816 spin_unlock_irq(&conf->device_lock);
1817 if (must_retry) {
1818 release_stripe(sh);
1819 goto retry;
1820 }
1821 }
1822 /* FIXME what if we get a false positive because these
1823 * are being updated.
1824 */
1825 if (logical_sector >= mddev->suspend_lo &&
1826 logical_sector < mddev->suspend_hi) {
1827 release_stripe(sh);
1828 schedule();
1829 goto retry;
1830 }
1831
1832 if (test_bit(STRIPE_EXPANDING, &sh->state) ||
1833 !add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK))) {
1834 /* Stripe is busy expanding or
1835 * add failed due to overlap. Flush everything
1572 * and wait a while 1836 * and wait a while
1573 */ 1837 */
1574 raid5_unplug_device(mddev->queue); 1838 raid5_unplug_device(mddev->queue);
@@ -1580,7 +1844,6 @@ static int make_request (request_queue_t *q, struct bio * bi)
1580 raid5_plug_device(conf); 1844 raid5_plug_device(conf);
1581 handle_stripe(sh); 1845 handle_stripe(sh);
1582 release_stripe(sh); 1846 release_stripe(sh);
1583
1584 } else { 1847 } else {
1585 /* cannot get stripe for read-ahead, just give-up */ 1848 /* cannot get stripe for read-ahead, just give-up */
1586 clear_bit(BIO_UPTODATE, &bi->bi_flags); 1849 clear_bit(BIO_UPTODATE, &bi->bi_flags);
@@ -1590,7 +1853,9 @@ static int make_request (request_queue_t *q, struct bio * bi)
1590 1853
1591 } 1854 }
1592 spin_lock_irq(&conf->device_lock); 1855 spin_lock_irq(&conf->device_lock);
1593 if (--bi->bi_phys_segments == 0) { 1856 remaining = --bi->bi_phys_segments;
1857 spin_unlock_irq(&conf->device_lock);
1858 if (remaining == 0) {
1594 int bytes = bi->bi_size; 1859 int bytes = bi->bi_size;
1595 1860
1596 if ( bio_data_dir(bi) == WRITE ) 1861 if ( bio_data_dir(bi) == WRITE )
@@ -1598,7 +1863,6 @@ static int make_request (request_queue_t *q, struct bio * bi)
1598 bi->bi_size = 0; 1863 bi->bi_size = 0;
1599 bi->bi_end_io(bi, bytes, 0); 1864 bi->bi_end_io(bi, bytes, 0);
1600 } 1865 }
1601 spin_unlock_irq(&conf->device_lock);
1602 return 0; 1866 return 0;
1603} 1867}
1604 1868
@@ -1607,12 +1871,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1607{ 1871{
1608 raid5_conf_t *conf = (raid5_conf_t *) mddev->private; 1872 raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
1609 struct stripe_head *sh; 1873 struct stripe_head *sh;
1610 int sectors_per_chunk = conf->chunk_size >> 9; 1874 int pd_idx;
1611 sector_t x; 1875 sector_t first_sector, last_sector;
1612 unsigned long stripe;
1613 int chunk_offset;
1614 int dd_idx, pd_idx;
1615 sector_t first_sector;
1616 int raid_disks = conf->raid_disks; 1876 int raid_disks = conf->raid_disks;
1617 int data_disks = raid_disks-1; 1877 int data_disks = raid_disks-1;
1618 sector_t max_sector = mddev->size << 1; 1878 sector_t max_sector = mddev->size << 1;
@@ -1621,6 +1881,10 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1621 if (sector_nr >= max_sector) { 1881 if (sector_nr >= max_sector) {
1622 /* just being told to finish up .. nothing much to do */ 1882 /* just being told to finish up .. nothing much to do */
1623 unplug_slaves(mddev); 1883 unplug_slaves(mddev);
1884 if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) {
1885 end_reshape(conf);
1886 return 0;
1887 }
1624 1888
1625 if (mddev->curr_resync < max_sector) /* aborted */ 1889 if (mddev->curr_resync < max_sector) /* aborted */
1626 bitmap_end_sync(mddev->bitmap, mddev->curr_resync, 1890 bitmap_end_sync(mddev->bitmap, mddev->curr_resync,
@@ -1631,6 +1895,123 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1631 1895
1632 return 0; 1896 return 0;
1633 } 1897 }
1898
1899 if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) {
1900 /* reshaping is quite different to recovery/resync so it is
1901 * handled quite separately ... here.
1902 *
1903 * On each call to sync_request, we gather one chunk worth of
1904 * destination stripes and flag them as expanding.
1905 * Then we find all the source stripes and request reads.
1906 * As the reads complete, handle_stripe will copy the data
1907 * into the destination stripe and release that stripe.
1908 */
1909 int i;
1910 int dd_idx;
1911 sector_t writepos, safepos, gap;
1912
1913 if (sector_nr == 0 &&
1914 conf->expand_progress != 0) {
1915 /* restarting in the middle, skip the initial sectors */
1916 sector_nr = conf->expand_progress;
1917 sector_div(sector_nr, conf->raid_disks-1);
1918 *skipped = 1;
1919 return sector_nr;
1920 }
1921
1922 /* we update the metadata when there is more than 3Meg
1923 * in the block range (that is rather arbitrary, should
1924 * probably be time based) or when the data about to be
1925 * copied would over-write the source of the data at
1926 * the front of the range.
1927 * i.e. one new_stripe forward from expand_progress new_maps
1928 * to after where expand_lo old_maps to
1929 */
1930 writepos = conf->expand_progress +
1931 conf->chunk_size/512*(conf->raid_disks-1);
1932 sector_div(writepos, conf->raid_disks-1);
1933 safepos = conf->expand_lo;
1934 sector_div(safepos, conf->previous_raid_disks-1);
1935 gap = conf->expand_progress - conf->expand_lo;
1936
1937 if (writepos >= safepos ||
1938 gap > (conf->raid_disks-1)*3000*2 /*3Meg*/) {
1939 /* Cannot proceed until we've updated the superblock... */
1940 wait_event(conf->wait_for_overlap,
1941 atomic_read(&conf->reshape_stripes)==0);
1942 mddev->reshape_position = conf->expand_progress;
1943 mddev->sb_dirty = 1;
1944 md_wakeup_thread(mddev->thread);
1945 wait_event(mddev->sb_wait, mddev->sb_dirty == 0 ||
1946 kthread_should_stop());
1947 spin_lock_irq(&conf->device_lock);
1948 conf->expand_lo = mddev->reshape_position;
1949 spin_unlock_irq(&conf->device_lock);
1950 wake_up(&conf->wait_for_overlap);
1951 }
1952
1953 for (i=0; i < conf->chunk_size/512; i+= STRIPE_SECTORS) {
1954 int j;
1955 int skipped = 0;
1956 pd_idx = stripe_to_pdidx(sector_nr+i, conf, conf->raid_disks);
1957 sh = get_active_stripe(conf, sector_nr+i,
1958 conf->raid_disks, pd_idx, 0);
1959 set_bit(STRIPE_EXPANDING, &sh->state);
1960 atomic_inc(&conf->reshape_stripes);
1961 /* If any of this stripe is beyond the end of the old
1962 * array, then we need to zero those blocks
1963 */
1964 for (j=sh->disks; j--;) {
1965 sector_t s;
1966 if (j == sh->pd_idx)
1967 continue;
1968 s = compute_blocknr(sh, j);
1969 if (s < (mddev->array_size<<1)) {
1970 skipped = 1;
1971 continue;
1972 }
1973 memset(page_address(sh->dev[j].page), 0, STRIPE_SIZE);
1974 set_bit(R5_Expanded, &sh->dev[j].flags);
1975 set_bit(R5_UPTODATE, &sh->dev[j].flags);
1976 }
1977 if (!skipped) {
1978 set_bit(STRIPE_EXPAND_READY, &sh->state);
1979 set_bit(STRIPE_HANDLE, &sh->state);
1980 }
1981 release_stripe(sh);
1982 }
1983 spin_lock_irq(&conf->device_lock);
1984 conf->expand_progress = (sector_nr + i)*(conf->raid_disks-1);
1985 spin_unlock_irq(&conf->device_lock);
1986 /* Ok, those stripe are ready. We can start scheduling
1987 * reads on the source stripes.
1988 * The source stripes are determined by mapping the first and last
1989 * block on the destination stripes.
1990 */
1991 raid_disks = conf->previous_raid_disks;
1992 data_disks = raid_disks - 1;
1993 first_sector =
1994 raid5_compute_sector(sector_nr*(conf->raid_disks-1),
1995 raid_disks, data_disks,
1996 &dd_idx, &pd_idx, conf);
1997 last_sector =
1998 raid5_compute_sector((sector_nr+conf->chunk_size/512)
1999 *(conf->raid_disks-1) -1,
2000 raid_disks, data_disks,
2001 &dd_idx, &pd_idx, conf);
2002 if (last_sector >= (mddev->size<<1))
2003 last_sector = (mddev->size<<1)-1;
2004 while (first_sector <= last_sector) {
2005 pd_idx = stripe_to_pdidx(first_sector, conf, conf->previous_raid_disks);
2006 sh = get_active_stripe(conf, first_sector,
2007 conf->previous_raid_disks, pd_idx, 0);
2008 set_bit(STRIPE_EXPAND_SOURCE, &sh->state);
2009 set_bit(STRIPE_HANDLE, &sh->state);
2010 release_stripe(sh);
2011 first_sector += STRIPE_SECTORS;
2012 }
2013 return conf->chunk_size>>9;
2014 }
1634 /* if there is 1 or more failed drives and we are trying 2015 /* if there is 1 or more failed drives and we are trying
1635 * to resync, then assert that we are finished, because there is 2016 * to resync, then assert that we are finished, because there is
1636 * nothing we can do. 2017 * nothing we can do.
@@ -1649,16 +2030,10 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1649 return sync_blocks * STRIPE_SECTORS; /* keep things rounded to whole stripes */ 2030 return sync_blocks * STRIPE_SECTORS; /* keep things rounded to whole stripes */
1650 } 2031 }
1651 2032
1652 x = sector_nr; 2033 pd_idx = stripe_to_pdidx(sector_nr, conf, raid_disks);
1653 chunk_offset = sector_div(x, sectors_per_chunk); 2034 sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 1);
1654 stripe = x;
1655 BUG_ON(x != stripe);
1656
1657 first_sector = raid5_compute_sector((sector_t)stripe*data_disks*sectors_per_chunk
1658 + chunk_offset, raid_disks, data_disks, &dd_idx, &pd_idx, conf);
1659 sh = get_active_stripe(conf, sector_nr, pd_idx, 1);
1660 if (sh == NULL) { 2035 if (sh == NULL) {
1661 sh = get_active_stripe(conf, sector_nr, pd_idx, 0); 2036 sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 0);
1662 /* make sure we don't swamp the stripe cache if someone else 2037 /* make sure we don't swamp the stripe cache if someone else
1663 * is trying to get access 2038 * is trying to get access
1664 */ 2039 */
@@ -1822,11 +2197,64 @@ static int run(mddev_t *mddev)
1822 return -EIO; 2197 return -EIO;
1823 } 2198 }
1824 2199
1825 mddev->private = kzalloc(sizeof (raid5_conf_t) 2200 if (mddev->reshape_position != MaxSector) {
1826 + mddev->raid_disks * sizeof(struct disk_info), 2201 /* Check that we can continue the reshape.
1827 GFP_KERNEL); 2202 * Currently only disks can change, it must
2203 * increase, and we must be past the point where
2204 * a stripe over-writes itself
2205 */
2206 sector_t here_new, here_old;
2207 int old_disks;
2208
2209 if (mddev->new_level != mddev->level ||
2210 mddev->new_layout != mddev->layout ||
2211 mddev->new_chunk != mddev->chunk_size) {
2212 printk(KERN_ERR "raid5: %s: unsupported reshape required - aborting.\n",
2213 mdname(mddev));
2214 return -EINVAL;
2215 }
2216 if (mddev->delta_disks <= 0) {
2217 printk(KERN_ERR "raid5: %s: unsupported reshape (reduce disks) required - aborting.\n",
2218 mdname(mddev));
2219 return -EINVAL;
2220 }
2221 old_disks = mddev->raid_disks - mddev->delta_disks;
2222 /* reshape_position must be on a new-stripe boundary, and one
2223 * further up in new geometry must map after here in old geometry.
2224 */
2225 here_new = mddev->reshape_position;
2226 if (sector_div(here_new, (mddev->chunk_size>>9)*(mddev->raid_disks-1))) {
2227 printk(KERN_ERR "raid5: reshape_position not on a stripe boundary\n");
2228 return -EINVAL;
2229 }
2230 /* here_new is the stripe we will write to */
2231 here_old = mddev->reshape_position;
2232 sector_div(here_old, (mddev->chunk_size>>9)*(old_disks-1));
2233 /* here_old is the first stripe that we might need to read from */
2234 if (here_new >= here_old) {
2235 /* Reading from the same stripe as writing to - bad */
2236 printk(KERN_ERR "raid5: reshape_position too early for auto-recovery - aborting.\n");
2237 return -EINVAL;
2238 }
2239 printk(KERN_INFO "raid5: reshape will continue\n");
2240 /* OK, we should be able to continue; */
2241 }
2242
2243
2244 mddev->private = kzalloc(sizeof (raid5_conf_t), GFP_KERNEL);
1828 if ((conf = mddev->private) == NULL) 2245 if ((conf = mddev->private) == NULL)
1829 goto abort; 2246 goto abort;
2247 if (mddev->reshape_position == MaxSector) {
2248 conf->previous_raid_disks = conf->raid_disks = mddev->raid_disks;
2249 } else {
2250 conf->raid_disks = mddev->raid_disks;
2251 conf->previous_raid_disks = mddev->raid_disks - mddev->delta_disks;
2252 }
2253
2254 conf->disks = kzalloc(conf->raid_disks * sizeof(struct disk_info),
2255 GFP_KERNEL);
2256 if (!conf->disks)
2257 goto abort;
1830 2258
1831 conf->mddev = mddev; 2259 conf->mddev = mddev;
1832 2260
@@ -1847,7 +2275,7 @@ static int run(mddev_t *mddev)
1847 2275
1848 ITERATE_RDEV(mddev,rdev,tmp) { 2276 ITERATE_RDEV(mddev,rdev,tmp) {
1849 raid_disk = rdev->raid_disk; 2277 raid_disk = rdev->raid_disk;
1850 if (raid_disk >= mddev->raid_disks 2278 if (raid_disk >= conf->raid_disks
1851 || raid_disk < 0) 2279 || raid_disk < 0)
1852 continue; 2280 continue;
1853 disk = conf->disks + raid_disk; 2281 disk = conf->disks + raid_disk;
@@ -1863,7 +2291,6 @@ static int run(mddev_t *mddev)
1863 } 2291 }
1864 } 2292 }
1865 2293
1866 conf->raid_disks = mddev->raid_disks;
1867 /* 2294 /*
1868 * 0 for a fully functional array, 1 for a degraded array. 2295 * 0 for a fully functional array, 1 for a degraded array.
1869 */ 2296 */
@@ -1873,6 +2300,7 @@ static int run(mddev_t *mddev)
1873 conf->level = mddev->level; 2300 conf->level = mddev->level;
1874 conf->algorithm = mddev->layout; 2301 conf->algorithm = mddev->layout;
1875 conf->max_nr_stripes = NR_STRIPES; 2302 conf->max_nr_stripes = NR_STRIPES;
2303 conf->expand_progress = mddev->reshape_position;
1876 2304
1877 /* device size must be a multiple of chunk size */ 2305 /* device size must be a multiple of chunk size */
1878 mddev->size &= ~(mddev->chunk_size/1024 -1); 2306 mddev->size &= ~(mddev->chunk_size/1024 -1);
@@ -1945,6 +2373,21 @@ static int run(mddev_t *mddev)
1945 2373
1946 print_raid5_conf(conf); 2374 print_raid5_conf(conf);
1947 2375
2376 if (conf->expand_progress != MaxSector) {
2377 printk("...ok start reshape thread\n");
2378 conf->expand_lo = conf->expand_progress;
2379 atomic_set(&conf->reshape_stripes, 0);
2380 clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
2381 clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
2382 set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery);
2383 set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
2384 mddev->sync_thread = md_register_thread(md_do_sync, mddev,
2385 "%s_reshape");
2386 /* FIXME if md_register_thread fails?? */
2387 md_wakeup_thread(mddev->sync_thread);
2388
2389 }
2390
1948 /* read-ahead size must cover two whole stripes, which is 2391 /* read-ahead size must cover two whole stripes, which is
1949 * 2 * (n-1) * chunksize where 'n' is the number of raid devices 2392 * 2 * (n-1) * chunksize where 'n' is the number of raid devices
1950 */ 2393 */
@@ -1960,12 +2403,13 @@ static int run(mddev_t *mddev)
1960 2403
1961 mddev->queue->unplug_fn = raid5_unplug_device; 2404 mddev->queue->unplug_fn = raid5_unplug_device;
1962 mddev->queue->issue_flush_fn = raid5_issue_flush; 2405 mddev->queue->issue_flush_fn = raid5_issue_flush;
2406 mddev->array_size = mddev->size * (conf->previous_raid_disks - 1);
1963 2407
1964 mddev->array_size = mddev->size * (mddev->raid_disks - 1);
1965 return 0; 2408 return 0;
1966abort: 2409abort:
1967 if (conf) { 2410 if (conf) {
1968 print_raid5_conf(conf); 2411 print_raid5_conf(conf);
2412 kfree(conf->disks);
1969 kfree(conf->stripe_hashtbl); 2413 kfree(conf->stripe_hashtbl);
1970 kfree(conf); 2414 kfree(conf);
1971 } 2415 }
@@ -1986,6 +2430,7 @@ static int stop(mddev_t *mddev)
1986 kfree(conf->stripe_hashtbl); 2430 kfree(conf->stripe_hashtbl);
1987 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ 2431 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
1988 sysfs_remove_group(&mddev->kobj, &raid5_attrs_group); 2432 sysfs_remove_group(&mddev->kobj, &raid5_attrs_group);
2433 kfree(conf->disks);
1989 kfree(conf); 2434 kfree(conf);
1990 mddev->private = NULL; 2435 mddev->private = NULL;
1991 return 0; 2436 return 0;
@@ -2001,7 +2446,7 @@ static void print_sh (struct stripe_head *sh)
2001 printk("sh %llu, count %d.\n", 2446 printk("sh %llu, count %d.\n",
2002 (unsigned long long)sh->sector, atomic_read(&sh->count)); 2447 (unsigned long long)sh->sector, atomic_read(&sh->count));
2003 printk("sh %llu, ", (unsigned long long)sh->sector); 2448 printk("sh %llu, ", (unsigned long long)sh->sector);
2004 for (i = 0; i < sh->raid_conf->raid_disks; i++) { 2449 for (i = 0; i < sh->disks; i++) {
2005 printk("(cache%d: %p %ld) ", 2450 printk("(cache%d: %p %ld) ",
2006 i, sh->dev[i].page, sh->dev[i].flags); 2451 i, sh->dev[i].page, sh->dev[i].flags);
2007 } 2452 }
@@ -2132,7 +2577,7 @@ static int raid5_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
2132 /* 2577 /*
2133 * find the disk ... 2578 * find the disk ...
2134 */ 2579 */
2135 for (disk=0; disk < mddev->raid_disks; disk++) 2580 for (disk=0; disk < conf->raid_disks; disk++)
2136 if ((p=conf->disks + disk)->rdev == NULL) { 2581 if ((p=conf->disks + disk)->rdev == NULL) {
2137 clear_bit(In_sync, &rdev->flags); 2582 clear_bit(In_sync, &rdev->flags);
2138 rdev->raid_disk = disk; 2583 rdev->raid_disk = disk;
@@ -2168,11 +2613,146 @@ static int raid5_resize(mddev_t *mddev, sector_t sectors)
2168 return 0; 2613 return 0;
2169} 2614}
2170 2615
2616#ifdef CONFIG_MD_RAID5_RESHAPE
2617static int raid5_check_reshape(mddev_t *mddev)
2618{
2619 raid5_conf_t *conf = mddev_to_conf(mddev);
2620 int err;
2621
2622 if (mddev->delta_disks < 0 ||
2623 mddev->new_level != mddev->level)
2624 return -EINVAL; /* Cannot shrink array or change level yet */
2625 if (mddev->delta_disks == 0)
2626 return 0; /* nothing to do */
2627
2628 /* Can only proceed if there are plenty of stripe_heads.
2629 * We need a minimum of one full stripe,, and for sensible progress
2630 * it is best to have about 4 times that.
2631 * If we require 4 times, then the default 256 4K stripe_heads will
2632 * allow for chunk sizes up to 256K, which is probably OK.
2633 * If the chunk size is greater, user-space should request more
2634 * stripe_heads first.
2635 */
2636 if ((mddev->chunk_size / STRIPE_SIZE) * 4 > conf->max_nr_stripes ||
2637 (mddev->new_chunk / STRIPE_SIZE) * 4 > conf->max_nr_stripes) {
2638 printk(KERN_WARNING "raid5: reshape: not enough stripes. Needed %lu\n",
2639 (mddev->chunk_size / STRIPE_SIZE)*4);
2640 return -ENOSPC;
2641 }
2642
2643 err = resize_stripes(conf, conf->raid_disks + mddev->delta_disks);
2644 if (err)
2645 return err;
2646
2647 /* looks like we might be able to manage this */
2648 return 0;
2649}
2650
2651static int raid5_start_reshape(mddev_t *mddev)
2652{
2653 raid5_conf_t *conf = mddev_to_conf(mddev);
2654 mdk_rdev_t *rdev;
2655 struct list_head *rtmp;
2656 int spares = 0;
2657 int added_devices = 0;
2658
2659 if (mddev->degraded ||
2660 test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
2661 return -EBUSY;
2662
2663 ITERATE_RDEV(mddev, rdev, rtmp)
2664 if (rdev->raid_disk < 0 &&
2665 !test_bit(Faulty, &rdev->flags))
2666 spares++;
2667
2668 if (spares < mddev->delta_disks-1)
2669 /* Not enough devices even to make a degraded array
2670 * of that size
2671 */
2672 return -EINVAL;
2673
2674 atomic_set(&conf->reshape_stripes, 0);
2675 spin_lock_irq(&conf->device_lock);
2676 conf->previous_raid_disks = conf->raid_disks;
2677 conf->raid_disks += mddev->delta_disks;
2678 conf->expand_progress = 0;
2679 conf->expand_lo = 0;
2680 spin_unlock_irq(&conf->device_lock);
2681
2682 /* Add some new drives, as many as will fit.
2683 * We know there are enough to make the newly sized array work.
2684 */
2685 ITERATE_RDEV(mddev, rdev, rtmp)
2686 if (rdev->raid_disk < 0 &&
2687 !test_bit(Faulty, &rdev->flags)) {
2688 if (raid5_add_disk(mddev, rdev)) {
2689 char nm[20];
2690 set_bit(In_sync, &rdev->flags);
2691 conf->working_disks++;
2692 added_devices++;
2693 sprintf(nm, "rd%d", rdev->raid_disk);
2694 sysfs_create_link(&mddev->kobj, &rdev->kobj, nm);
2695 } else
2696 break;
2697 }
2698
2699 mddev->degraded = (conf->raid_disks - conf->previous_raid_disks) - added_devices;
2700 mddev->raid_disks = conf->raid_disks;
2701 mddev->reshape_position = 0;
2702 mddev->sb_dirty = 1;
2703
2704 clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
2705 clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
2706 set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery);
2707 set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
2708 mddev->sync_thread = md_register_thread(md_do_sync, mddev,
2709 "%s_reshape");
2710 if (!mddev->sync_thread) {
2711 mddev->recovery = 0;
2712 spin_lock_irq(&conf->device_lock);
2713 mddev->raid_disks = conf->raid_disks = conf->previous_raid_disks;
2714 conf->expand_progress = MaxSector;
2715 spin_unlock_irq(&conf->device_lock);
2716 return -EAGAIN;
2717 }
2718 md_wakeup_thread(mddev->sync_thread);
2719 md_new_event(mddev);
2720 return 0;
2721}
2722#endif
2723
2724static void end_reshape(raid5_conf_t *conf)
2725{
2726 struct block_device *bdev;
2727
2728 if (!test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) {
2729 conf->mddev->array_size = conf->mddev->size * (conf->raid_disks-1);
2730 set_capacity(conf->mddev->gendisk, conf->mddev->array_size << 1);
2731 conf->mddev->changed = 1;
2732
2733 bdev = bdget_disk(conf->mddev->gendisk, 0);
2734 if (bdev) {
2735 mutex_lock(&bdev->bd_inode->i_mutex);
2736 i_size_write(bdev->bd_inode, conf->mddev->array_size << 10);
2737 mutex_unlock(&bdev->bd_inode->i_mutex);
2738 bdput(bdev);
2739 }
2740 spin_lock_irq(&conf->device_lock);
2741 conf->expand_progress = MaxSector;
2742 spin_unlock_irq(&conf->device_lock);
2743 conf->mddev->reshape_position = MaxSector;
2744 }
2745}
2746
2171static void raid5_quiesce(mddev_t *mddev, int state) 2747static void raid5_quiesce(mddev_t *mddev, int state)
2172{ 2748{
2173 raid5_conf_t *conf = mddev_to_conf(mddev); 2749 raid5_conf_t *conf = mddev_to_conf(mddev);
2174 2750
2175 switch(state) { 2751 switch(state) {
2752 case 2: /* resume for a suspend */
2753 wake_up(&conf->wait_for_overlap);
2754 break;
2755
2176 case 1: /* stop all writes */ 2756 case 1: /* stop all writes */
2177 spin_lock_irq(&conf->device_lock); 2757 spin_lock_irq(&conf->device_lock);
2178 conf->quiesce = 1; 2758 conf->quiesce = 1;
@@ -2186,6 +2766,7 @@ static void raid5_quiesce(mddev_t *mddev, int state)
2186 spin_lock_irq(&conf->device_lock); 2766 spin_lock_irq(&conf->device_lock);
2187 conf->quiesce = 0; 2767 conf->quiesce = 0;
2188 wake_up(&conf->wait_for_stripe); 2768 wake_up(&conf->wait_for_stripe);
2769 wake_up(&conf->wait_for_overlap);
2189 spin_unlock_irq(&conf->device_lock); 2770 spin_unlock_irq(&conf->device_lock);
2190 break; 2771 break;
2191 } 2772 }
@@ -2206,6 +2787,10 @@ static struct mdk_personality raid5_personality =
2206 .spare_active = raid5_spare_active, 2787 .spare_active = raid5_spare_active,
2207 .sync_request = sync_request, 2788 .sync_request = sync_request,
2208 .resize = raid5_resize, 2789 .resize = raid5_resize,
2790#ifdef CONFIG_MD_RAID5_RESHAPE
2791 .check_reshape = raid5_check_reshape,
2792 .start_reshape = raid5_start_reshape,
2793#endif
2209 .quiesce = raid5_quiesce, 2794 .quiesce = raid5_quiesce,
2210}; 2795};
2211 2796
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c
index cd477ebf2ee4..6df4930fddec 100644
--- a/drivers/md/raid6main.c
+++ b/drivers/md/raid6main.c
@@ -331,9 +331,9 @@ static int grow_stripes(raid6_conf_t *conf, int num)
331 kmem_cache_t *sc; 331 kmem_cache_t *sc;
332 int devs = conf->raid_disks; 332 int devs = conf->raid_disks;
333 333
334 sprintf(conf->cache_name, "raid6/%s", mdname(conf->mddev)); 334 sprintf(conf->cache_name[0], "raid6/%s", mdname(conf->mddev));
335 335
336 sc = kmem_cache_create(conf->cache_name, 336 sc = kmem_cache_create(conf->cache_name[0],
337 sizeof(struct stripe_head)+(devs-1)*sizeof(struct r5dev), 337 sizeof(struct stripe_head)+(devs-1)*sizeof(struct r5dev),
338 0, 0, NULL, NULL); 338 0, 0, NULL, NULL);
339 if (!sc) 339 if (!sc)
@@ -2006,11 +2006,14 @@ static int run(mddev_t *mddev)
2006 return -EIO; 2006 return -EIO;
2007 } 2007 }
2008 2008
2009 mddev->private = kzalloc(sizeof (raid6_conf_t) 2009 mddev->private = kzalloc(sizeof (raid6_conf_t), GFP_KERNEL);
2010 + mddev->raid_disks * sizeof(struct disk_info),
2011 GFP_KERNEL);
2012 if ((conf = mddev->private) == NULL) 2010 if ((conf = mddev->private) == NULL)
2013 goto abort; 2011 goto abort;
2012 conf->disks = kzalloc(mddev->raid_disks * sizeof(struct disk_info),
2013 GFP_KERNEL);
2014 if (!conf->disks)
2015 goto abort;
2016
2014 conf->mddev = mddev; 2017 conf->mddev = mddev;
2015 2018
2016 if ((conf->stripe_hashtbl = kzalloc(PAGE_SIZE, GFP_KERNEL)) == NULL) 2019 if ((conf->stripe_hashtbl = kzalloc(PAGE_SIZE, GFP_KERNEL)) == NULL)
@@ -2158,6 +2161,7 @@ abort:
2158 print_raid6_conf(conf); 2161 print_raid6_conf(conf);
2159 safe_put_page(conf->spare_page); 2162 safe_put_page(conf->spare_page);
2160 kfree(conf->stripe_hashtbl); 2163 kfree(conf->stripe_hashtbl);
2164 kfree(conf->disks);
2161 kfree(conf); 2165 kfree(conf);
2162 } 2166 }
2163 mddev->private = NULL; 2167 mddev->private = NULL;
diff --git a/drivers/misc/ibmasm/heartbeat.c b/drivers/misc/ibmasm/heartbeat.c
index f295401fac21..7fd7a43e38de 100644
--- a/drivers/misc/ibmasm/heartbeat.c
+++ b/drivers/misc/ibmasm/heartbeat.c
@@ -52,12 +52,13 @@ static struct notifier_block panic_notifier = { panic_happened, NULL, 1 };
52 52
53void ibmasm_register_panic_notifier(void) 53void ibmasm_register_panic_notifier(void)
54{ 54{
55 notifier_chain_register(&panic_notifier_list, &panic_notifier); 55 atomic_notifier_chain_register(&panic_notifier_list, &panic_notifier);
56} 56}
57 57
58void ibmasm_unregister_panic_notifier(void) 58void ibmasm_unregister_panic_notifier(void)
59{ 59{
60 notifier_chain_unregister(&panic_notifier_list, &panic_notifier); 60 atomic_notifier_chain_unregister(&panic_notifier_list,
61 &panic_notifier);
61} 62}
62 63
63 64
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 2d0ac169a86c..f13a539dc169 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3159,7 +3159,7 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave
3159 * bond_netdev_event: handle netdev notifier chain events. 3159 * bond_netdev_event: handle netdev notifier chain events.
3160 * 3160 *
3161 * This function receives events for the netdev chain. The caller (an 3161 * This function receives events for the netdev chain. The caller (an
3162 * ioctl handler calling notifier_call_chain) holds the necessary 3162 * ioctl handler calling blocking_notifier_call_chain) holds the necessary
3163 * locks for us to safely manipulate the slave devices (RTNL lock, 3163 * locks for us to safely manipulate the slave devices (RTNL lock,
3164 * dev_probe_lock). 3164 * dev_probe_lock).
3165 */ 3165 */
diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c
index 83141a3ff546..9aa074b44dd3 100644
--- a/drivers/net/irda/nsc-ircc.c
+++ b/drivers/net/irda/nsc-ircc.c
@@ -207,7 +207,7 @@ static int __init nsc_ircc_init(void)
207 /* Register with PnP subsystem to detect disable ports */ 207 /* Register with PnP subsystem to detect disable ports */
208 ret = pnp_register_driver(&nsc_ircc_pnp_driver); 208 ret = pnp_register_driver(&nsc_ircc_pnp_driver);
209 209
210 if (ret >= 0) 210 if (!ret)
211 pnp_registered = 1; 211 pnp_registered = 1;
212 212
213 ret = -ENODEV; 213 ret = -ENODEV;
diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c
index 3627a2d7f79f..298f2ddb2c17 100644
--- a/drivers/parisc/led.c
+++ b/drivers/parisc/led.c
@@ -499,11 +499,16 @@ static int led_halt(struct notifier_block *, unsigned long, void *);
499static struct notifier_block led_notifier = { 499static struct notifier_block led_notifier = {
500 .notifier_call = led_halt, 500 .notifier_call = led_halt,
501}; 501};
502static int notifier_disabled = 0;
502 503
503static int led_halt(struct notifier_block *nb, unsigned long event, void *buf) 504static int led_halt(struct notifier_block *nb, unsigned long event, void *buf)
504{ 505{
505 char *txt; 506 char *txt;
506 507
508 if (notifier_disabled)
509 return NOTIFY_OK;
510
511 notifier_disabled = 1;
507 switch (event) { 512 switch (event) {
508 case SYS_RESTART: txt = "SYSTEM RESTART"; 513 case SYS_RESTART: txt = "SYSTEM RESTART";
509 break; 514 break;
@@ -527,7 +532,6 @@ static int led_halt(struct notifier_block *nb, unsigned long event, void *buf)
527 if (led_func_ptr) 532 if (led_func_ptr)
528 led_func_ptr(0xff); /* turn all LEDs ON */ 533 led_func_ptr(0xff); /* turn all LEDs ON */
529 534
530 unregister_reboot_notifier(&led_notifier);
531 return NOTIFY_OK; 535 return NOTIFY_OK;
532} 536}
533 537
@@ -758,6 +762,12 @@ not_found:
758 return 1; 762 return 1;
759} 763}
760 764
765static void __exit led_exit(void)
766{
767 unregister_reboot_notifier(&led_notifier);
768 return;
769}
770
761#ifdef CONFIG_PROC_FS 771#ifdef CONFIG_PROC_FS
762module_init(led_create_procfs) 772module_init(led_create_procfs)
763#endif 773#endif
diff --git a/drivers/parisc/power.c b/drivers/parisc/power.c
index 54b2b7f20b96..0bcab83b4080 100644
--- a/drivers/parisc/power.c
+++ b/drivers/parisc/power.c
@@ -251,7 +251,8 @@ static int __init power_init(void)
251 } 251 }
252 252
253 /* Register a call for panic conditions. */ 253 /* Register a call for panic conditions. */
254 notifier_chain_register(&panic_notifier_list, &parisc_panic_block); 254 atomic_notifier_chain_register(&panic_notifier_list,
255 &parisc_panic_block);
255 256
256 tasklet_enable(&power_tasklet); 257 tasklet_enable(&power_tasklet);
257 258
@@ -264,7 +265,8 @@ static void __exit power_exit(void)
264 return; 265 return;
265 266
266 tasklet_disable(&power_tasklet); 267 tasklet_disable(&power_tasklet);
267 notifier_chain_unregister(&panic_notifier_list, &parisc_panic_block); 268 atomic_notifier_chain_unregister(&panic_notifier_list,
269 &parisc_panic_block);
268 power_tasklet.func = NULL; 270 power_tasklet.func = NULL;
269 pdc_soft_power_button(0); 271 pdc_soft_power_button(0);
270} 272}
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index 9302b8fd7461..d5890027f8af 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -3126,9 +3126,9 @@ parport_pc_find_isa_ports (int autoirq, int autodma)
3126 * autoirq is PARPORT_IRQ_NONE, PARPORT_IRQ_AUTO, or PARPORT_IRQ_PROBEONLY 3126 * autoirq is PARPORT_IRQ_NONE, PARPORT_IRQ_AUTO, or PARPORT_IRQ_PROBEONLY
3127 * autodma is PARPORT_DMA_NONE or PARPORT_DMA_AUTO 3127 * autodma is PARPORT_DMA_NONE or PARPORT_DMA_AUTO
3128 */ 3128 */
3129static int __init parport_pc_find_ports (int autoirq, int autodma) 3129static void __init parport_pc_find_ports (int autoirq, int autodma)
3130{ 3130{
3131 int count = 0, r; 3131 int count = 0, err;
3132 3132
3133#ifdef CONFIG_PARPORT_PC_SUPERIO 3133#ifdef CONFIG_PARPORT_PC_SUPERIO
3134 detect_and_report_winbond (); 3134 detect_and_report_winbond ();
@@ -3140,23 +3140,17 @@ static int __init parport_pc_find_ports (int autoirq, int autodma)
3140 3140
3141 /* PnP ports, skip detection if SuperIO already found them */ 3141 /* PnP ports, skip detection if SuperIO already found them */
3142 if (!count) { 3142 if (!count) {
3143 r = pnp_register_driver (&parport_pc_pnp_driver); 3143 err = pnp_register_driver (&parport_pc_pnp_driver);
3144 if (r >= 0) { 3144 if (!err)
3145 pnp_registered_parport = 1; 3145 pnp_registered_parport = 1;
3146 count += r;
3147 }
3148 } 3146 }
3149 3147
3150 /* ISA ports and whatever (see asm/parport.h). */ 3148 /* ISA ports and whatever (see asm/parport.h). */
3151 count += parport_pc_find_nonpci_ports (autoirq, autodma); 3149 parport_pc_find_nonpci_ports (autoirq, autodma);
3152
3153 r = pci_register_driver (&parport_pc_pci_driver);
3154 if (r)
3155 return r;
3156 pci_registered_parport = 1;
3157 count += 1;
3158 3150
3159 return count; 3151 err = pci_register_driver (&parport_pc_pci_driver);
3152 if (!err)
3153 pci_registered_parport = 1;
3160} 3154}
3161 3155
3162/* 3156/*
@@ -3381,8 +3375,6 @@ __setup("parport_init_mode=",parport_init_mode_setup);
3381 3375
3382static int __init parport_pc_init(void) 3376static int __init parport_pc_init(void)
3383{ 3377{
3384 int count = 0;
3385
3386 if (parse_parport_params()) 3378 if (parse_parport_params())
3387 return -EINVAL; 3379 return -EINVAL;
3388 3380
@@ -3395,12 +3387,11 @@ static int __init parport_pc_init(void)
3395 break; 3387 break;
3396 if ((io_hi[i]) == PARPORT_IOHI_AUTO) 3388 if ((io_hi[i]) == PARPORT_IOHI_AUTO)
3397 io_hi[i] = 0x400 + io[i]; 3389 io_hi[i] = 0x400 + io[i];
3398 if (parport_pc_probe_port(io[i], io_hi[i], 3390 parport_pc_probe_port(io[i], io_hi[i],
3399 irqval[i], dmaval[i], NULL)) 3391 irqval[i], dmaval[i], NULL);
3400 count++;
3401 } 3392 }
3402 } else 3393 } else
3403 count += parport_pc_find_ports (irqval[0], dmaval[0]); 3394 parport_pc_find_ports (irqval[0], dmaval[0]);
3404 3395
3405 return 0; 3396 return 0;
3406} 3397}
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c
index b68eef251614..bb19c64073c6 100644
--- a/drivers/pnp/card.c
+++ b/drivers/pnp/card.c
@@ -47,7 +47,7 @@ static void card_remove(struct pnp_dev * dev)
47{ 47{
48 dev->card_link = NULL; 48 dev->card_link = NULL;
49} 49}
50 50
51static void card_remove_first(struct pnp_dev * dev) 51static void card_remove_first(struct pnp_dev * dev)
52{ 52{
53 struct pnp_card_driver * drv = to_pnp_card_driver(dev->driver); 53 struct pnp_card_driver * drv = to_pnp_card_driver(dev->driver);
@@ -361,7 +361,7 @@ static int card_resume(struct pnp_dev *dev)
361 361
362int pnp_register_card_driver(struct pnp_card_driver * drv) 362int pnp_register_card_driver(struct pnp_card_driver * drv)
363{ 363{
364 int count; 364 int error;
365 struct list_head *pos, *temp; 365 struct list_head *pos, *temp;
366 366
367 drv->link.name = drv->name; 367 drv->link.name = drv->name;
@@ -372,21 +372,19 @@ int pnp_register_card_driver(struct pnp_card_driver * drv)
372 drv->link.suspend = drv->suspend ? card_suspend : NULL; 372 drv->link.suspend = drv->suspend ? card_suspend : NULL;
373 drv->link.resume = drv->resume ? card_resume : NULL; 373 drv->link.resume = drv->resume ? card_resume : NULL;
374 374
375 count = pnp_register_driver(&drv->link); 375 error = pnp_register_driver(&drv->link);
376 if (count < 0) 376 if (error < 0)
377 return count; 377 return error;
378 378
379 spin_lock(&pnp_lock); 379 spin_lock(&pnp_lock);
380 list_add_tail(&drv->global_list, &pnp_card_drivers); 380 list_add_tail(&drv->global_list, &pnp_card_drivers);
381 spin_unlock(&pnp_lock); 381 spin_unlock(&pnp_lock);
382 382
383 count = 0;
384
385 list_for_each_safe(pos,temp,&pnp_cards){ 383 list_for_each_safe(pos,temp,&pnp_cards){
386 struct pnp_card *card = list_entry(pos, struct pnp_card, global_list); 384 struct pnp_card *card = list_entry(pos, struct pnp_card, global_list);
387 count += card_probe(card,drv); 385 card_probe(card,drv);
388 } 386 }
389 return count; 387 return 0;
390} 388}
391 389
392/** 390/**
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c
index 7cafacdd12b0..e54c15383193 100644
--- a/drivers/pnp/driver.c
+++ b/drivers/pnp/driver.c
@@ -201,31 +201,14 @@ struct bus_type pnp_bus_type = {
201 .resume = pnp_bus_resume, 201 .resume = pnp_bus_resume,
202}; 202};
203 203
204
205static int count_devices(struct device * dev, void * c)
206{
207 int * count = c;
208 (*count)++;
209 return 0;
210}
211
212int pnp_register_driver(struct pnp_driver *drv) 204int pnp_register_driver(struct pnp_driver *drv)
213{ 205{
214 int count;
215
216 pnp_dbg("the driver '%s' has been registered", drv->name); 206 pnp_dbg("the driver '%s' has been registered", drv->name);
217 207
218 drv->driver.name = drv->name; 208 drv->driver.name = drv->name;
219 drv->driver.bus = &pnp_bus_type; 209 drv->driver.bus = &pnp_bus_type;
220 210
221 count = driver_register(&drv->driver); 211 return driver_register(&drv->driver);
222
223 /* get the number of initial matches */
224 if (count >= 0){
225 count = 0;
226 driver_for_each_device(&drv->driver, NULL, &count, count_devices);
227 }
228 return count;
229} 212}
230 213
231void pnp_unregister_driver(struct pnp_driver *drv) 214void pnp_unregister_driver(struct pnp_driver *drv)
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
new file mode 100644
index 000000000000..929dd8090578
--- /dev/null
+++ b/drivers/rtc/Kconfig
@@ -0,0 +1,165 @@
1\#
2# RTC class/drivers configuration
3#
4
5menu "Real Time Clock"
6
7config RTC_LIB
8 tristate
9
10config RTC_CLASS
11 tristate "RTC class"
12 depends on EXPERIMENTAL
13 default n
14 select RTC_LIB
15 help
16 Generic RTC class support. If you say yes here, you will
17 be allowed to plug one or more RTCs to your system. You will
18 probably want to enable one of more of the interfaces below.
19
20 This driver can also be built as a module. If so, the module
21 will be called rtc-class.
22
23config RTC_HCTOSYS
24 bool "Set system time from RTC on startup"
25 depends on RTC_CLASS = y
26 default y
27 help
28 If you say yes here, the system time will be set using
29 the value read from the specified RTC device. This is useful
30 in order to avoid unnecessary fschk runs.
31
32config RTC_HCTOSYS_DEVICE
33 string "The RTC to read the time from"
34 depends on RTC_HCTOSYS = y
35 default "rtc0"
36 help
37 The RTC device that will be used as the source for
38 the system time, usually rtc0.
39
40comment "RTC interfaces"
41 depends on RTC_CLASS
42
43config RTC_INTF_SYSFS
44 tristate "sysfs"
45 depends on RTC_CLASS && SYSFS
46 default RTC_CLASS
47 help
48 Say yes here if you want to use your RTC using the sysfs
49 interface, /sys/class/rtc/rtcX .
50
51 This driver can also be built as a module. If so, the module
52 will be called rtc-sysfs.
53
54config RTC_INTF_PROC
55 tristate "proc"
56 depends on RTC_CLASS && PROC_FS
57 default RTC_CLASS
58 help
59 Say yes here if you want to use your RTC using the proc
60 interface, /proc/driver/rtc .
61
62 This driver can also be built as a module. If so, the module
63 will be called rtc-proc.
64
65config RTC_INTF_DEV
66 tristate "dev"
67 depends on RTC_CLASS
68 default RTC_CLASS
69 help
70 Say yes here if you want to use your RTC using the dev
71 interface, /dev/rtc .
72
73 This driver can also be built as a module. If so, the module
74 will be called rtc-dev.
75
76comment "RTC drivers"
77 depends on RTC_CLASS
78
79config RTC_DRV_X1205
80 tristate "Xicor/Intersil X1205"
81 depends on RTC_CLASS && I2C
82 help
83 If you say yes here you get support for the
84 Xicor/Intersil X1205 RTC chip.
85
86 This driver can also be built as a module. If so, the module
87 will be called rtc-x1205.
88
89config RTC_DRV_DS1672
90 tristate "Dallas/Maxim DS1672"
91 depends on RTC_CLASS && I2C
92 help
93 If you say yes here you get support for the
94 Dallas/Maxim DS1672 timekeeping chip.
95
96 This driver can also be built as a module. If so, the module
97 will be called rtc-ds1672.
98
99config RTC_DRV_PCF8563
100 tristate "Philips PCF8563/Epson RTC8564"
101 depends on RTC_CLASS && I2C
102 help
103 If you say yes here you get support for the
104 Philips PCF8563 RTC chip. The Epson RTC8564
105 should work as well.
106
107 This driver can also be built as a module. If so, the module
108 will be called rtc-pcf8563.
109
110config RTC_DRV_RS5C372
111 tristate "Ricoh RS5C372A/B"
112 depends on RTC_CLASS && I2C
113 help
114 If you say yes here you get support for the
115 Ricoh RS5C372A and RS5C372B RTC chips.
116
117 This driver can also be built as a module. If so, the module
118 will be called rtc-rs5c372.
119
120config RTC_DRV_M48T86
121 tristate "ST M48T86/Dallas DS12887"
122 depends on RTC_CLASS
123 help
124 If you say Y here you will get support for the
125 ST M48T86 and Dallas DS12887 RTC chips.
126
127 This driver can also be built as a module. If so, the module
128 will be called rtc-m48t86.
129
130config RTC_DRV_EP93XX
131 tristate "Cirrus Logic EP93XX"
132 depends on RTC_CLASS && ARCH_EP93XX
133 help
134 If you say yes here you get support for the
135 RTC embedded in the Cirrus Logic EP93XX processors.
136
137 This driver can also be built as a module. If so, the module
138 will be called rtc-ep93xx.
139
140config RTC_DRV_SA1100
141 tristate "SA11x0/PXA2xx"
142 depends on RTC_CLASS && (ARCH_SA1100 || ARCH_PXA)
143 help
144 If you say Y here you will get access to the real time clock
145 built into your SA11x0 or PXA2xx CPU.
146
147 To compile this driver as a module, choose M here: the
148 module will be called rtc-sa1100.
149
150config RTC_DRV_TEST
151 tristate "Test driver/device"
152 depends on RTC_CLASS
153 help
154 If you say yes here you get support for the
155 RTC test driver. It's a software RTC which can be
156 used to test the RTC subsystem APIs. It gets
157 the time from the system clock.
158 You want this driver only if you are doing development
159 on the RTC subsystem. Please read the source code
160 for further details.
161
162 This driver can also be built as a module. If so, the module
163 will be called rtc-test.
164
165endmenu
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
new file mode 100644
index 000000000000..8d4c7fe88d58
--- /dev/null
+++ b/drivers/rtc/Makefile
@@ -0,0 +1,21 @@
1#
2# Makefile for RTC class/drivers.
3#
4
5obj-$(CONFIG_RTC_LIB) += rtc-lib.o
6obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o
7obj-$(CONFIG_RTC_CLASS) += rtc-core.o
8rtc-core-y := class.o interface.o
9
10obj-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o
11obj-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o
12obj-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o
13
14obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o
15obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o
16obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o
17obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
18obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o
19obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o
20obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o
21obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
new file mode 100644
index 000000000000..8533936d50d8
--- /dev/null
+++ b/drivers/rtc/class.c
@@ -0,0 +1,145 @@
1/*
2 * RTC subsystem, base class
3 *
4 * Copyright (C) 2005 Tower Technologies
5 * Author: Alessandro Zummo <a.zummo@towertech.it>
6 *
7 * class skeleton from drivers/hwmon/hwmon.c
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/module.h>
15#include <linux/rtc.h>
16#include <linux/kdev_t.h>
17#include <linux/idr.h>
18
19static DEFINE_IDR(rtc_idr);
20static DEFINE_MUTEX(idr_lock);
21struct class *rtc_class;
22
23static void rtc_device_release(struct class_device *class_dev)
24{
25 struct rtc_device *rtc = to_rtc_device(class_dev);
26 mutex_lock(&idr_lock);
27 idr_remove(&rtc_idr, rtc->id);
28 mutex_unlock(&idr_lock);
29 kfree(rtc);
30}
31
32/**
33 * rtc_device_register - register w/ RTC class
34 * @dev: the device to register
35 *
36 * rtc_device_unregister() must be called when the class device is no
37 * longer needed.
38 *
39 * Returns the pointer to the new struct class device.
40 */
41struct rtc_device *rtc_device_register(const char *name, struct device *dev,
42 struct rtc_class_ops *ops,
43 struct module *owner)
44{
45 struct rtc_device *rtc;
46 int id, err;
47
48 if (idr_pre_get(&rtc_idr, GFP_KERNEL) == 0) {
49 err = -ENOMEM;
50 goto exit;
51 }
52
53
54 mutex_lock(&idr_lock);
55 err = idr_get_new(&rtc_idr, NULL, &id);
56 mutex_unlock(&idr_lock);
57
58 if (err < 0)
59 goto exit;
60
61 id = id & MAX_ID_MASK;
62
63 rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL);
64 if (rtc == NULL) {
65 err = -ENOMEM;
66 goto exit_idr;
67 }
68
69 rtc->id = id;
70 rtc->ops = ops;
71 rtc->owner = owner;
72 rtc->class_dev.dev = dev;
73 rtc->class_dev.class = rtc_class;
74 rtc->class_dev.release = rtc_device_release;
75
76 mutex_init(&rtc->ops_lock);
77 spin_lock_init(&rtc->irq_lock);
78 spin_lock_init(&rtc->irq_task_lock);
79
80 strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE);
81 snprintf(rtc->class_dev.class_id, BUS_ID_SIZE, "rtc%d", id);
82
83 err = class_device_register(&rtc->class_dev);
84 if (err)
85 goto exit_kfree;
86
87 dev_info(dev, "rtc core: registered %s as %s\n",
88 rtc->name, rtc->class_dev.class_id);
89
90 return rtc;
91
92exit_kfree:
93 kfree(rtc);
94
95exit_idr:
96 idr_remove(&rtc_idr, id);
97
98exit:
99 return ERR_PTR(err);
100}
101EXPORT_SYMBOL_GPL(rtc_device_register);
102
103
104/**
105 * rtc_device_unregister - removes the previously registered RTC class device
106 *
107 * @rtc: the RTC class device to destroy
108 */
109void rtc_device_unregister(struct rtc_device *rtc)
110{
111 mutex_lock(&rtc->ops_lock);
112 rtc->ops = NULL;
113 mutex_unlock(&rtc->ops_lock);
114 class_device_unregister(&rtc->class_dev);
115}
116EXPORT_SYMBOL_GPL(rtc_device_unregister);
117
118int rtc_interface_register(struct class_interface *intf)
119{
120 intf->class = rtc_class;
121 return class_interface_register(intf);
122}
123EXPORT_SYMBOL_GPL(rtc_interface_register);
124
125static int __init rtc_init(void)
126{
127 rtc_class = class_create(THIS_MODULE, "rtc");
128 if (IS_ERR(rtc_class)) {
129 printk(KERN_ERR "%s: couldn't create class\n", __FILE__);
130 return PTR_ERR(rtc_class);
131 }
132 return 0;
133}
134
135static void __exit rtc_exit(void)
136{
137 class_destroy(rtc_class);
138}
139
140module_init(rtc_init);
141module_exit(rtc_exit);
142
143MODULE_AUTHOR("Alessandro Zummo <a.zummo@towerteh.it>");
144MODULE_DESCRIPTION("RTC class support");
145MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c
new file mode 100644
index 000000000000..d02fe9a0001f
--- /dev/null
+++ b/drivers/rtc/hctosys.c
@@ -0,0 +1,69 @@
1/*
2 * RTC subsystem, initialize system time on startup
3 *
4 * Copyright (C) 2005 Tower Technologies
5 * Author: Alessandro Zummo <a.zummo@towertech.it>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10*/
11
12#include <linux/rtc.h>
13
14/* IMPORTANT: the RTC only stores whole seconds. It is arbitrary
15 * whether it stores the most close value or the value with partial
16 * seconds truncated. However, it is important that we use it to store
17 * the truncated value. This is because otherwise it is necessary,
18 * in an rtc sync function, to read both xtime.tv_sec and
19 * xtime.tv_nsec. On some processors (i.e. ARM), an atomic read
20 * of >32bits is not possible. So storing the most close value would
21 * slow down the sync API. So here we have the truncated value and
22 * the best guess is to add 0.5s.
23 */
24
25static int __init rtc_hctosys(void)
26{
27 int err;
28 struct rtc_time tm;
29 struct class_device *class_dev = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
30
31 if (class_dev == NULL) {
32 printk("%s: unable to open rtc device (%s)\n",
33 __FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
34 return -ENODEV;
35 }
36
37 err = rtc_read_time(class_dev, &tm);
38 if (err == 0) {
39 err = rtc_valid_tm(&tm);
40 if (err == 0) {
41 struct timespec tv;
42
43 tv.tv_nsec = NSEC_PER_SEC >> 1;
44
45 rtc_tm_to_time(&tm, &tv.tv_sec);
46
47 do_settimeofday(&tv);
48
49 dev_info(class_dev->dev,
50 "setting the system clock to "
51 "%d-%02d-%02d %02d:%02d:%02d (%u)\n",
52 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
53 tm.tm_hour, tm.tm_min, tm.tm_sec,
54 (unsigned int) tv.tv_sec);
55 }
56 else
57 dev_err(class_dev->dev,
58 "hctosys: invalid date/time\n");
59 }
60 else
61 dev_err(class_dev->dev,
62 "hctosys: unable to read the hardware clock\n");
63
64 rtc_class_close(class_dev);
65
66 return 0;
67}
68
69late_initcall(rtc_hctosys);
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
new file mode 100644
index 000000000000..56e490709b87
--- /dev/null
+++ b/drivers/rtc/interface.c
@@ -0,0 +1,277 @@
1/*
2 * RTC subsystem, interface functions
3 *
4 * Copyright (C) 2005 Tower Technologies
5 * Author: Alessandro Zummo <a.zummo@towertech.it>
6 *
7 * based on arch/arm/common/rtctime.c
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/rtc.h>
15
16int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm)
17{
18 int err;
19 struct rtc_device *rtc = to_rtc_device(class_dev);
20
21 err = mutex_lock_interruptible(&rtc->ops_lock);
22 if (err)
23 return -EBUSY;
24
25 if (!rtc->ops)
26 err = -ENODEV;
27 else if (!rtc->ops->read_time)
28 err = -EINVAL;
29 else {
30 memset(tm, 0, sizeof(struct rtc_time));
31 err = rtc->ops->read_time(class_dev->dev, tm);
32 }
33
34 mutex_unlock(&rtc->ops_lock);
35 return err;
36}
37EXPORT_SYMBOL_GPL(rtc_read_time);
38
39int rtc_set_time(struct class_device *class_dev, struct rtc_time *tm)
40{
41 int err;
42 struct rtc_device *rtc = to_rtc_device(class_dev);
43
44 err = rtc_valid_tm(tm);
45 if (err != 0)
46 return err;
47
48 err = mutex_lock_interruptible(&rtc->ops_lock);
49 if (err)
50 return -EBUSY;
51
52 if (!rtc->ops)
53 err = -ENODEV;
54 else if (!rtc->ops->set_time)
55 err = -EINVAL;
56 else
57 err = rtc->ops->set_time(class_dev->dev, tm);
58
59 mutex_unlock(&rtc->ops_lock);
60 return err;
61}
62EXPORT_SYMBOL_GPL(rtc_set_time);
63
64int rtc_set_mmss(struct class_device *class_dev, unsigned long secs)
65{
66 int err;
67 struct rtc_device *rtc = to_rtc_device(class_dev);
68
69 err = mutex_lock_interruptible(&rtc->ops_lock);
70 if (err)
71 return -EBUSY;
72
73 if (!rtc->ops)
74 err = -ENODEV;
75 else if (rtc->ops->set_mmss)
76 err = rtc->ops->set_mmss(class_dev->dev, secs);
77 else if (rtc->ops->read_time && rtc->ops->set_time) {
78 struct rtc_time new, old;
79
80 err = rtc->ops->read_time(class_dev->dev, &old);
81 if (err == 0) {
82 rtc_time_to_tm(secs, &new);
83
84 /*
85 * avoid writing when we're going to change the day of
86 * the month. We will retry in the next minute. This
87 * basically means that if the RTC must not drift
88 * by more than 1 minute in 11 minutes.
89 */
90 if (!((old.tm_hour == 23 && old.tm_min == 59) ||
91 (new.tm_hour == 23 && new.tm_min == 59)))
92 err = rtc->ops->set_time(class_dev->dev, &new);
93 }
94 }
95 else
96 err = -EINVAL;
97
98 mutex_unlock(&rtc->ops_lock);
99
100 return err;
101}
102EXPORT_SYMBOL_GPL(rtc_set_mmss);
103
104int rtc_read_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm)
105{
106 int err;
107 struct rtc_device *rtc = to_rtc_device(class_dev);
108
109 err = mutex_lock_interruptible(&rtc->ops_lock);
110 if (err)
111 return -EBUSY;
112
113 if (rtc->ops == NULL)
114 err = -ENODEV;
115 else if (!rtc->ops->read_alarm)
116 err = -EINVAL;
117 else {
118 memset(alarm, 0, sizeof(struct rtc_wkalrm));
119 err = rtc->ops->read_alarm(class_dev->dev, alarm);
120 }
121
122 mutex_unlock(&rtc->ops_lock);
123 return err;
124}
125EXPORT_SYMBOL_GPL(rtc_read_alarm);
126
127int rtc_set_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm)
128{
129 int err;
130 struct rtc_device *rtc = to_rtc_device(class_dev);
131
132 err = mutex_lock_interruptible(&rtc->ops_lock);
133 if (err)
134 return -EBUSY;
135
136 if (!rtc->ops)
137 err = -ENODEV;
138 else if (!rtc->ops->set_alarm)
139 err = -EINVAL;
140 else
141 err = rtc->ops->set_alarm(class_dev->dev, alarm);
142
143 mutex_unlock(&rtc->ops_lock);
144 return err;
145}
146EXPORT_SYMBOL_GPL(rtc_set_alarm);
147
148void rtc_update_irq(struct class_device *class_dev,
149 unsigned long num, unsigned long events)
150{
151 struct rtc_device *rtc = to_rtc_device(class_dev);
152
153 spin_lock(&rtc->irq_lock);
154 rtc->irq_data = (rtc->irq_data + (num << 8)) | events;
155 spin_unlock(&rtc->irq_lock);
156
157 spin_lock(&rtc->irq_task_lock);
158 if (rtc->irq_task)
159 rtc->irq_task->func(rtc->irq_task->private_data);
160 spin_unlock(&rtc->irq_task_lock);
161
162 wake_up_interruptible(&rtc->irq_queue);
163 kill_fasync(&rtc->async_queue, SIGIO, POLL_IN);
164}
165EXPORT_SYMBOL_GPL(rtc_update_irq);
166
167struct class_device *rtc_class_open(char *name)
168{
169 struct class_device *class_dev = NULL,
170 *class_dev_tmp;
171
172 down(&rtc_class->sem);
173 list_for_each_entry(class_dev_tmp, &rtc_class->children, node) {
174 if (strncmp(class_dev_tmp->class_id, name, BUS_ID_SIZE) == 0) {
175 class_dev = class_dev_tmp;
176 break;
177 }
178 }
179
180 if (class_dev) {
181 if (!try_module_get(to_rtc_device(class_dev)->owner))
182 class_dev = NULL;
183 }
184 up(&rtc_class->sem);
185
186 return class_dev;
187}
188EXPORT_SYMBOL_GPL(rtc_class_open);
189
190void rtc_class_close(struct class_device *class_dev)
191{
192 module_put(to_rtc_device(class_dev)->owner);
193}
194EXPORT_SYMBOL_GPL(rtc_class_close);
195
196int rtc_irq_register(struct class_device *class_dev, struct rtc_task *task)
197{
198 int retval = -EBUSY;
199 struct rtc_device *rtc = to_rtc_device(class_dev);
200
201 if (task == NULL || task->func == NULL)
202 return -EINVAL;
203
204 spin_lock(&rtc->irq_task_lock);
205 if (rtc->irq_task == NULL) {
206 rtc->irq_task = task;
207 retval = 0;
208 }
209 spin_unlock(&rtc->irq_task_lock);
210
211 return retval;
212}
213EXPORT_SYMBOL_GPL(rtc_irq_register);
214
215void rtc_irq_unregister(struct class_device *class_dev, struct rtc_task *task)
216{
217 struct rtc_device *rtc = to_rtc_device(class_dev);
218
219 spin_lock(&rtc->irq_task_lock);
220 if (rtc->irq_task == task)
221 rtc->irq_task = NULL;
222 spin_unlock(&rtc->irq_task_lock);
223}
224EXPORT_SYMBOL_GPL(rtc_irq_unregister);
225
226int rtc_irq_set_state(struct class_device *class_dev, struct rtc_task *task, int enabled)
227{
228 int err = 0;
229 unsigned long flags;
230 struct rtc_device *rtc = to_rtc_device(class_dev);
231
232 spin_lock_irqsave(&rtc->irq_task_lock, flags);
233 if (rtc->irq_task != task)
234 err = -ENXIO;
235 spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
236
237 if (err == 0)
238 err = rtc->ops->irq_set_state(class_dev->dev, enabled);
239
240 return err;
241}
242EXPORT_SYMBOL_GPL(rtc_irq_set_state);
243
244int rtc_irq_set_freq(struct class_device *class_dev, struct rtc_task *task, int freq)
245{
246 int err = 0, tmp = 0;
247 unsigned long flags;
248 struct rtc_device *rtc = to_rtc_device(class_dev);
249
250 /* allowed range is 2-8192 */
251 if (freq < 2 || freq > 8192)
252 return -EINVAL;
253/*
254 FIXME: this does not belong here, will move where appropriate
255 at a later stage. It cannot hurt right now, trust me :)
256 if ((freq > rtc_max_user_freq) && (!capable(CAP_SYS_RESOURCE)))
257 return -EACCES;
258*/
259 /* check if freq is a power of 2 */
260 while (freq > (1 << tmp))
261 tmp++;
262
263 if (freq != (1 << tmp))
264 return -EINVAL;
265
266 spin_lock_irqsave(&rtc->irq_task_lock, flags);
267 if (rtc->irq_task != task)
268 err = -ENXIO;
269 spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
270
271 if (err == 0) {
272 err = rtc->ops->irq_set_freq(class_dev->dev, freq);
273 if (err == 0)
274 rtc->irq_freq = freq;
275 }
276 return err;
277}
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
new file mode 100644
index 000000000000..b1e3e6179e56
--- /dev/null
+++ b/drivers/rtc/rtc-dev.c
@@ -0,0 +1,382 @@
1/*
2 * RTC subsystem, dev interface
3 *
4 * Copyright (C) 2005 Tower Technologies
5 * Author: Alessandro Zummo <a.zummo@towertech.it>
6 *
7 * based on arch/arm/common/rtctime.c
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/module.h>
15#include <linux/rtc.h>
16
17static struct class *rtc_dev_class;
18static dev_t rtc_devt;
19
20#define RTC_DEV_MAX 16 /* 16 RTCs should be enough for everyone... */
21
22static int rtc_dev_open(struct inode *inode, struct file *file)
23{
24 int err;
25 struct rtc_device *rtc = container_of(inode->i_cdev,
26 struct rtc_device, char_dev);
27 struct rtc_class_ops *ops = rtc->ops;
28
29 /* We keep the lock as long as the device is in use
30 * and return immediately if busy
31 */
32 if (!(mutex_trylock(&rtc->char_lock)))
33 return -EBUSY;
34
35 file->private_data = &rtc->class_dev;
36
37 err = ops->open ? ops->open(rtc->class_dev.dev) : 0;
38 if (err == 0) {
39 spin_lock_irq(&rtc->irq_lock);
40 rtc->irq_data = 0;
41 spin_unlock_irq(&rtc->irq_lock);
42
43 return 0;
44 }
45
46 /* something has gone wrong, release the lock */
47 mutex_unlock(&rtc->char_lock);
48 return err;
49}
50
51
52static ssize_t
53rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
54{
55 struct rtc_device *rtc = to_rtc_device(file->private_data);
56
57 DECLARE_WAITQUEUE(wait, current);
58 unsigned long data;
59 ssize_t ret;
60
61 if (count < sizeof(unsigned long))
62 return -EINVAL;
63
64 add_wait_queue(&rtc->irq_queue, &wait);
65 do {
66 __set_current_state(TASK_INTERRUPTIBLE);
67
68 spin_lock_irq(&rtc->irq_lock);
69 data = rtc->irq_data;
70 rtc->irq_data = 0;
71 spin_unlock_irq(&rtc->irq_lock);
72
73 if (data != 0) {
74 ret = 0;
75 break;
76 }
77 if (file->f_flags & O_NONBLOCK) {
78 ret = -EAGAIN;
79 break;
80 }
81 if (signal_pending(current)) {
82 ret = -ERESTARTSYS;
83 break;
84 }
85 schedule();
86 } while (1);
87 set_current_state(TASK_RUNNING);
88 remove_wait_queue(&rtc->irq_queue, &wait);
89
90 if (ret == 0) {
91 /* Check for any data updates */
92 if (rtc->ops->read_callback)
93 data = rtc->ops->read_callback(rtc->class_dev.dev, data);
94
95 ret = put_user(data, (unsigned long __user *)buf);
96 if (ret == 0)
97 ret = sizeof(unsigned long);
98 }
99 return ret;
100}
101
102static unsigned int rtc_dev_poll(struct file *file, poll_table *wait)
103{
104 struct rtc_device *rtc = to_rtc_device(file->private_data);
105 unsigned long data;
106
107 poll_wait(file, &rtc->irq_queue, wait);
108
109 data = rtc->irq_data;
110
111 return (data != 0) ? (POLLIN | POLLRDNORM) : 0;
112}
113
114static int rtc_dev_ioctl(struct inode *inode, struct file *file,
115 unsigned int cmd, unsigned long arg)
116{
117 int err = 0;
118 struct class_device *class_dev = file->private_data;
119 struct rtc_device *rtc = to_rtc_device(class_dev);
120 struct rtc_class_ops *ops = rtc->ops;
121 struct rtc_time tm;
122 struct rtc_wkalrm alarm;
123 void __user *uarg = (void __user *) arg;
124
125 /* avoid conflicting IRQ users */
126 if (cmd == RTC_PIE_ON || cmd == RTC_PIE_OFF || cmd == RTC_IRQP_SET) {
127 spin_lock(&rtc->irq_task_lock);
128 if (rtc->irq_task)
129 err = -EBUSY;
130 spin_unlock(&rtc->irq_task_lock);
131
132 if (err < 0)
133 return err;
134 }
135
136 /* try the driver's ioctl interface */
137 if (ops->ioctl) {
138 err = ops->ioctl(class_dev->dev, cmd, arg);
139 if (err != -EINVAL)
140 return err;
141 }
142
143 /* if the driver does not provide the ioctl interface
144 * or if that particular ioctl was not implemented
145 * (-EINVAL), we will try to emulate here.
146 */
147
148 switch (cmd) {
149 case RTC_ALM_READ:
150 err = rtc_read_alarm(class_dev, &alarm);
151 if (err < 0)
152 return err;
153
154 if (copy_to_user(uarg, &alarm.time, sizeof(tm)))
155 return -EFAULT;
156 break;
157
158 case RTC_ALM_SET:
159 if (copy_from_user(&alarm.time, uarg, sizeof(tm)))
160 return -EFAULT;
161
162 alarm.enabled = 0;
163 alarm.pending = 0;
164 alarm.time.tm_mday = -1;
165 alarm.time.tm_mon = -1;
166 alarm.time.tm_year = -1;
167 alarm.time.tm_wday = -1;
168 alarm.time.tm_yday = -1;
169 alarm.time.tm_isdst = -1;
170 err = rtc_set_alarm(class_dev, &alarm);
171 break;
172
173 case RTC_RD_TIME:
174 err = rtc_read_time(class_dev, &tm);
175 if (err < 0)
176 return err;
177
178 if (copy_to_user(uarg, &tm, sizeof(tm)))
179 return -EFAULT;
180 break;
181
182 case RTC_SET_TIME:
183 if (!capable(CAP_SYS_TIME))
184 return -EACCES;
185
186 if (copy_from_user(&tm, uarg, sizeof(tm)))
187 return -EFAULT;
188
189 err = rtc_set_time(class_dev, &tm);
190 break;
191#if 0
192 case RTC_EPOCH_SET:
193#ifndef rtc_epoch
194 /*
195 * There were no RTC clocks before 1900.
196 */
197 if (arg < 1900) {
198 err = -EINVAL;
199 break;
200 }
201 if (!capable(CAP_SYS_TIME)) {
202 err = -EACCES;
203 break;
204 }
205 rtc_epoch = arg;
206 err = 0;
207#endif
208 break;
209
210 case RTC_EPOCH_READ:
211 err = put_user(rtc_epoch, (unsigned long __user *)uarg);
212 break;
213#endif
214 case RTC_WKALM_SET:
215 if (copy_from_user(&alarm, uarg, sizeof(alarm)))
216 return -EFAULT;
217
218 err = rtc_set_alarm(class_dev, &alarm);
219 break;
220
221 case RTC_WKALM_RD:
222 err = rtc_read_alarm(class_dev, &alarm);
223 if (err < 0)
224 return err;
225
226 if (copy_to_user(uarg, &alarm, sizeof(alarm)))
227 return -EFAULT;
228 break;
229
230 default:
231 err = -EINVAL;
232 break;
233 }
234
235 return err;
236}
237
238static int rtc_dev_release(struct inode *inode, struct file *file)
239{
240 struct rtc_device *rtc = to_rtc_device(file->private_data);
241
242 if (rtc->ops->release)
243 rtc->ops->release(rtc->class_dev.dev);
244
245 mutex_unlock(&rtc->char_lock);
246 return 0;
247}
248
249static int rtc_dev_fasync(int fd, struct file *file, int on)
250{
251 struct rtc_device *rtc = to_rtc_device(file->private_data);
252 return fasync_helper(fd, file, on, &rtc->async_queue);
253}
254
255static struct file_operations rtc_dev_fops = {
256 .owner = THIS_MODULE,
257 .llseek = no_llseek,
258 .read = rtc_dev_read,
259 .poll = rtc_dev_poll,
260 .ioctl = rtc_dev_ioctl,
261 .open = rtc_dev_open,
262 .release = rtc_dev_release,
263 .fasync = rtc_dev_fasync,
264};
265
266/* insertion/removal hooks */
267
268static int rtc_dev_add_device(struct class_device *class_dev,
269 struct class_interface *class_intf)
270{
271 int err = 0;
272 struct rtc_device *rtc = to_rtc_device(class_dev);
273
274 if (rtc->id >= RTC_DEV_MAX) {
275 dev_err(class_dev->dev, "too many RTCs\n");
276 return -EINVAL;
277 }
278
279 mutex_init(&rtc->char_lock);
280 spin_lock_init(&rtc->irq_lock);
281 init_waitqueue_head(&rtc->irq_queue);
282
283 cdev_init(&rtc->char_dev, &rtc_dev_fops);
284 rtc->char_dev.owner = rtc->owner;
285
286 if (cdev_add(&rtc->char_dev, MKDEV(MAJOR(rtc_devt), rtc->id), 1)) {
287 cdev_del(&rtc->char_dev);
288 dev_err(class_dev->dev,
289 "failed to add char device %d:%d\n",
290 MAJOR(rtc_devt), rtc->id);
291 return -ENODEV;
292 }
293
294 rtc->rtc_dev = class_device_create(rtc_dev_class, NULL,
295 MKDEV(MAJOR(rtc_devt), rtc->id),
296 class_dev->dev, "rtc%d", rtc->id);
297 if (IS_ERR(rtc->rtc_dev)) {
298 dev_err(class_dev->dev, "cannot create rtc_dev device\n");
299 err = PTR_ERR(rtc->rtc_dev);
300 goto err_cdev_del;
301 }
302
303 dev_info(class_dev->dev, "rtc intf: dev (%d:%d)\n",
304 MAJOR(rtc->rtc_dev->devt),
305 MINOR(rtc->rtc_dev->devt));
306
307 return 0;
308
309err_cdev_del:
310
311 cdev_del(&rtc->char_dev);
312 return err;
313}
314
315static void rtc_dev_remove_device(struct class_device *class_dev,
316 struct class_interface *class_intf)
317{
318 struct rtc_device *rtc = to_rtc_device(class_dev);
319
320 if (rtc->rtc_dev) {
321 dev_dbg(class_dev->dev, "removing char %d:%d\n",
322 MAJOR(rtc->rtc_dev->devt),
323 MINOR(rtc->rtc_dev->devt));
324
325 class_device_unregister(rtc->rtc_dev);
326 cdev_del(&rtc->char_dev);
327 }
328}
329
330/* interface registration */
331
332static struct class_interface rtc_dev_interface = {
333 .add = &rtc_dev_add_device,
334 .remove = &rtc_dev_remove_device,
335};
336
337static int __init rtc_dev_init(void)
338{
339 int err;
340
341 rtc_dev_class = class_create(THIS_MODULE, "rtc-dev");
342 if (IS_ERR(rtc_dev_class))
343 return PTR_ERR(rtc_dev_class);
344
345 err = alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MAX, "rtc");
346 if (err < 0) {
347 printk(KERN_ERR "%s: failed to allocate char dev region\n",
348 __FILE__);
349 goto err_destroy_class;
350 }
351
352 err = rtc_interface_register(&rtc_dev_interface);
353 if (err < 0) {
354 printk(KERN_ERR "%s: failed to register the interface\n",
355 __FILE__);
356 goto err_unregister_chrdev;
357 }
358
359 return 0;
360
361err_unregister_chrdev:
362 unregister_chrdev_region(rtc_devt, RTC_DEV_MAX);
363
364err_destroy_class:
365 class_destroy(rtc_dev_class);
366
367 return err;
368}
369
370static void __exit rtc_dev_exit(void)
371{
372 class_interface_unregister(&rtc_dev_interface);
373 class_destroy(rtc_dev_class);
374 unregister_chrdev_region(rtc_devt, RTC_DEV_MAX);
375}
376
377module_init(rtc_dev_init);
378module_exit(rtc_dev_exit);
379
380MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
381MODULE_DESCRIPTION("RTC class dev interface");
382MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c
new file mode 100644
index 000000000000..358695a416f3
--- /dev/null
+++ b/drivers/rtc/rtc-ds1672.c
@@ -0,0 +1,233 @@
1/*
2 * An rtc/i2c driver for the Dallas DS1672
3 * Copyright 2005 Alessandro Zummo
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#include <linux/module.h>
11#include <linux/i2c.h>
12#include <linux/rtc.h>
13
14#define DRV_VERSION "0.2"
15
16/* Addresses to scan: none. This chip cannot be detected. */
17static unsigned short normal_i2c[] = { I2C_CLIENT_END };
18
19/* Insmod parameters */
20I2C_CLIENT_INSMOD;
21
22/* Registers */
23
24#define DS1672_REG_CNT_BASE 0
25#define DS1672_REG_CONTROL 4
26#define DS1672_REG_TRICKLE 5
27
28
29/* Prototypes */
30static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind);
31
32/*
33 * In the routines that deal directly with the ds1672 hardware, we use
34 * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch
35 * Epoch is initialized as 2000. Time is set to UTC.
36 */
37static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm)
38{
39 unsigned long time;
40 unsigned char addr = DS1672_REG_CNT_BASE;
41 unsigned char buf[4];
42
43 struct i2c_msg msgs[] = {
44 { client->addr, 0, 1, &addr }, /* setup read ptr */
45 { client->addr, I2C_M_RD, 4, buf }, /* read date */
46 };
47
48 /* read date registers */
49 if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
50 dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
51 return -EIO;
52 }
53
54 dev_dbg(&client->dev,
55 "%s: raw read data - counters=%02x,%02x,%02x,%02x\n"
56 __FUNCTION__,
57 buf[0], buf[1], buf[2], buf[3]);
58
59 time = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
60
61 rtc_time_to_tm(time, tm);
62
63 dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
64 "mday=%d, mon=%d, year=%d, wday=%d\n",
65 __FUNCTION__,
66 tm->tm_sec, tm->tm_min, tm->tm_hour,
67 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
68
69 return 0;
70}
71
72static int ds1672_set_mmss(struct i2c_client *client, unsigned long secs)
73{
74 int xfer;
75 unsigned char buf[5];
76
77 buf[0] = DS1672_REG_CNT_BASE;
78 buf[1] = secs & 0x000000FF;
79 buf[2] = (secs & 0x0000FF00) >> 8;
80 buf[3] = (secs & 0x00FF0000) >> 16;
81 buf[4] = (secs & 0xFF000000) >> 24;
82
83 xfer = i2c_master_send(client, buf, 5);
84 if (xfer != 5) {
85 dev_err(&client->dev, "%s: send: %d\n", __FUNCTION__, xfer);
86 return -EIO;
87 }
88
89 return 0;
90}
91
92static int ds1672_set_datetime(struct i2c_client *client, struct rtc_time *tm)
93{
94 unsigned long secs;
95
96 dev_dbg(&client->dev,
97 "%s: secs=%d, mins=%d, hours=%d, ",
98 "mday=%d, mon=%d, year=%d, wday=%d\n",
99 __FUNCTION__,
100 tm->tm_sec, tm->tm_min, tm->tm_hour,
101 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
102
103 rtc_tm_to_time(tm, &secs);
104
105 return ds1672_set_mmss(client, secs);
106}
107
108static int ds1672_rtc_read_time(struct device *dev, struct rtc_time *tm)
109{
110 return ds1672_get_datetime(to_i2c_client(dev), tm);
111}
112
113static int ds1672_rtc_set_time(struct device *dev, struct rtc_time *tm)
114{
115 return ds1672_set_datetime(to_i2c_client(dev), tm);
116}
117
118static int ds1672_rtc_set_mmss(struct device *dev, unsigned long secs)
119{
120 return ds1672_set_mmss(to_i2c_client(dev), secs);
121}
122
123static struct rtc_class_ops ds1672_rtc_ops = {
124 .read_time = ds1672_rtc_read_time,
125 .set_time = ds1672_rtc_set_time,
126 .set_mmss = ds1672_rtc_set_mmss,
127};
128
129static int ds1672_attach(struct i2c_adapter *adapter)
130{
131 dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
132 return i2c_probe(adapter, &addr_data, ds1672_probe);
133}
134
135static int ds1672_detach(struct i2c_client *client)
136{
137 int err;
138 struct rtc_device *rtc = i2c_get_clientdata(client);
139
140 dev_dbg(&client->dev, "%s\n", __FUNCTION__);
141
142 if (rtc)
143 rtc_device_unregister(rtc);
144
145 if ((err = i2c_detach_client(client)))
146 return err;
147
148 kfree(client);
149
150 return 0;
151}
152
153static struct i2c_driver ds1672_driver = {
154 .driver = {
155 .name = "ds1672",
156 },
157 .id = I2C_DRIVERID_DS1672,
158 .attach_adapter = &ds1672_attach,
159 .detach_client = &ds1672_detach,
160};
161
162static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind)
163{
164 int err = 0;
165 struct i2c_client *client;
166 struct rtc_device *rtc;
167
168 dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
169
170 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
171 err = -ENODEV;
172 goto exit;
173 }
174
175 if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
176 err = -ENOMEM;
177 goto exit;
178 }
179
180 /* I2C client */
181 client->addr = address;
182 client->driver = &ds1672_driver;
183 client->adapter = adapter;
184
185 strlcpy(client->name, ds1672_driver.driver.name, I2C_NAME_SIZE);
186
187 /* Inform the i2c layer */
188 if ((err = i2c_attach_client(client)))
189 goto exit_kfree;
190
191 dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
192
193 rtc = rtc_device_register(ds1672_driver.driver.name, &client->dev,
194 &ds1672_rtc_ops, THIS_MODULE);
195
196 if (IS_ERR(rtc)) {
197 err = PTR_ERR(rtc);
198 dev_err(&client->dev,
199 "unable to register the class device\n");
200 goto exit_detach;
201 }
202
203 i2c_set_clientdata(client, rtc);
204
205 return 0;
206
207exit_detach:
208 i2c_detach_client(client);
209
210exit_kfree:
211 kfree(client);
212
213exit:
214 return err;
215}
216
217static int __init ds1672_init(void)
218{
219 return i2c_add_driver(&ds1672_driver);
220}
221
222static void __exit ds1672_exit(void)
223{
224 i2c_del_driver(&ds1672_driver);
225}
226
227MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
228MODULE_DESCRIPTION("Dallas/Maxim DS1672 timekeeper driver");
229MODULE_LICENSE("GPL");
230MODULE_VERSION(DRV_VERSION);
231
232module_init(ds1672_init);
233module_exit(ds1672_exit);
diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c
new file mode 100644
index 000000000000..0dd80ea686a9
--- /dev/null
+++ b/drivers/rtc/rtc-ep93xx.c
@@ -0,0 +1,162 @@
1/*
2 * A driver for the RTC embedded in the Cirrus Logic EP93XX processors
3 * Copyright (c) 2006 Tower Technologies
4 *
5 * Author: Alessandro Zummo <a.zummo@towertech.it>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/rtc.h>
14#include <linux/platform_device.h>
15#include <asm/hardware.h>
16
17#define EP93XX_RTC_REG(x) (EP93XX_RTC_BASE + (x))
18#define EP93XX_RTC_DATA EP93XX_RTC_REG(0x0000)
19#define EP93XX_RTC_LOAD EP93XX_RTC_REG(0x000C)
20#define EP93XX_RTC_SWCOMP EP93XX_RTC_REG(0x0108)
21
22#define DRV_VERSION "0.2"
23
24static int ep93xx_get_swcomp(struct device *dev, unsigned short *preload,
25 unsigned short *delete)
26{
27 unsigned short comp = __raw_readl(EP93XX_RTC_SWCOMP);
28
29 if (preload)
30 *preload = comp & 0xffff;
31
32 if (delete)
33 *delete = (comp >> 16) & 0x1f;
34
35 return 0;
36}
37
38static int ep93xx_rtc_read_time(struct device *dev, struct rtc_time *tm)
39{
40 unsigned long time = __raw_readl(EP93XX_RTC_DATA);
41
42 rtc_time_to_tm(time, tm);
43 return 0;
44}
45
46static int ep93xx_rtc_set_mmss(struct device *dev, unsigned long secs)
47{
48 __raw_writel(secs + 1, EP93XX_RTC_LOAD);
49 return 0;
50}
51
52static int ep93xx_rtc_set_time(struct device *dev, struct rtc_time *tm)
53{
54 int err;
55 unsigned long secs;
56
57 err = rtc_tm_to_time(tm, &secs);
58 if (err != 0)
59 return err;
60
61 return ep93xx_rtc_set_mmss(dev, secs);
62}
63
64static int ep93xx_rtc_proc(struct device *dev, struct seq_file *seq)
65{
66 unsigned short preload, delete;
67
68 ep93xx_get_swcomp(dev, &preload, &delete);
69
70 seq_printf(seq, "24hr\t\t: yes\n");
71 seq_printf(seq, "preload\t\t: %d\n", preload);
72 seq_printf(seq, "delete\t\t: %d\n", delete);
73
74 return 0;
75}
76
77static struct rtc_class_ops ep93xx_rtc_ops = {
78 .read_time = ep93xx_rtc_read_time,
79 .set_time = ep93xx_rtc_set_time,
80 .set_mmss = ep93xx_rtc_set_mmss,
81 .proc = ep93xx_rtc_proc,
82};
83
84static ssize_t ep93xx_sysfs_show_comp_preload(struct device *dev,
85 struct device_attribute *attr, char *buf)
86{
87 unsigned short preload;
88
89 ep93xx_get_swcomp(dev, &preload, NULL);
90
91 return sprintf(buf, "%d\n", preload);
92}
93static DEVICE_ATTR(comp_preload, S_IRUGO, ep93xx_sysfs_show_comp_preload, NULL);
94
95static ssize_t ep93xx_sysfs_show_comp_delete(struct device *dev,
96 struct device_attribute *attr, char *buf)
97{
98 unsigned short delete;
99
100 ep93xx_get_swcomp(dev, NULL, &delete);
101
102 return sprintf(buf, "%d\n", delete);
103}
104static DEVICE_ATTR(comp_delete, S_IRUGO, ep93xx_sysfs_show_comp_delete, NULL);
105
106
107static int __devinit ep93xx_rtc_probe(struct platform_device *dev)
108{
109 struct rtc_device *rtc = rtc_device_register("ep93xx",
110 &dev->dev, &ep93xx_rtc_ops, THIS_MODULE);
111
112 if (IS_ERR(rtc)) {
113 dev_err(&dev->dev, "unable to register\n");
114 return PTR_ERR(rtc);
115 }
116
117 platform_set_drvdata(dev, rtc);
118
119 device_create_file(&dev->dev, &dev_attr_comp_preload);
120 device_create_file(&dev->dev, &dev_attr_comp_delete);
121
122 return 0;
123}
124
125static int __devexit ep93xx_rtc_remove(struct platform_device *dev)
126{
127 struct rtc_device *rtc = platform_get_drvdata(dev);
128
129 if (rtc)
130 rtc_device_unregister(rtc);
131
132 platform_set_drvdata(dev, NULL);
133
134 return 0;
135}
136
137static struct platform_driver ep93xx_rtc_platform_driver = {
138 .driver = {
139 .name = "ep93xx-rtc",
140 .owner = THIS_MODULE,
141 },
142 .probe = ep93xx_rtc_probe,
143 .remove = __devexit_p(ep93xx_rtc_remove),
144};
145
146static int __init ep93xx_rtc_init(void)
147{
148 return platform_driver_register(&ep93xx_rtc_platform_driver);
149}
150
151static void __exit ep93xx_rtc_exit(void)
152{
153 platform_driver_unregister(&ep93xx_rtc_platform_driver);
154}
155
156MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
157MODULE_DESCRIPTION("EP93XX RTC driver");
158MODULE_LICENSE("GPL");
159MODULE_VERSION(DRV_VERSION);
160
161module_init(ep93xx_rtc_init);
162module_exit(ep93xx_rtc_exit);
diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c
new file mode 100644
index 000000000000..cfedc1d28ee1
--- /dev/null
+++ b/drivers/rtc/rtc-lib.c
@@ -0,0 +1,101 @@
1/*
2 * rtc and date/time utility functions
3 *
4 * Copyright (C) 2005-06 Tower Technologies
5 * Author: Alessandro Zummo <a.zummo@towertech.it>
6 *
7 * based on arch/arm/common/rtctime.c and other bits
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/module.h>
15#include <linux/rtc.h>
16
17static const unsigned char rtc_days_in_month[] = {
18 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
19};
20
21#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400)
22#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400))
23
24int rtc_month_days(unsigned int month, unsigned int year)
25{
26 return rtc_days_in_month[month] + (LEAP_YEAR(year) && month == 1);
27}
28EXPORT_SYMBOL(rtc_month_days);
29
30/*
31 * Convert seconds since 01-01-1970 00:00:00 to Gregorian date.
32 */
33void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
34{
35 register int days, month, year;
36
37 days = time / 86400;
38 time -= days * 86400;
39
40 /* day of the week, 1970-01-01 was a Thursday */
41 tm->tm_wday = (days + 4) % 7;
42
43 year = 1970 + days / 365;
44 days -= (year - 1970) * 365
45 + LEAPS_THRU_END_OF(year - 1)
46 - LEAPS_THRU_END_OF(1970 - 1);
47 if (days < 0) {
48 year -= 1;
49 days += 365 + LEAP_YEAR(year);
50 }
51 tm->tm_year = year - 1900;
52 tm->tm_yday = days + 1;
53
54 for (month = 0; month < 11; month++) {
55 int newdays;
56
57 newdays = days - rtc_month_days(month, year);
58 if (newdays < 0)
59 break;
60 days = newdays;
61 }
62 tm->tm_mon = month;
63 tm->tm_mday = days + 1;
64
65 tm->tm_hour = time / 3600;
66 time -= tm->tm_hour * 3600;
67 tm->tm_min = time / 60;
68 tm->tm_sec = time - tm->tm_min * 60;
69}
70EXPORT_SYMBOL(rtc_time_to_tm);
71
72/*
73 * Does the rtc_time represent a valid date/time?
74 */
75int rtc_valid_tm(struct rtc_time *tm)
76{
77 if (tm->tm_year < 70
78 || tm->tm_mon >= 12
79 || tm->tm_mday < 1
80 || tm->tm_mday > rtc_month_days(tm->tm_mon, tm->tm_year + 1900)
81 || tm->tm_hour >= 24
82 || tm->tm_min >= 60
83 || tm->tm_sec >= 60)
84 return -EINVAL;
85
86 return 0;
87}
88EXPORT_SYMBOL(rtc_valid_tm);
89
90/*
91 * Convert Gregorian date to seconds since 01-01-1970 00:00:00.
92 */
93int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time)
94{
95 *time = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
96 tm->tm_hour, tm->tm_min, tm->tm_sec);
97 return 0;
98}
99EXPORT_SYMBOL(rtc_tm_to_time);
100
101MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c
new file mode 100644
index 000000000000..db445c872b1b
--- /dev/null
+++ b/drivers/rtc/rtc-m48t86.c
@@ -0,0 +1,209 @@
1/*
2 * ST M48T86 / Dallas DS12887 RTC driver
3 * Copyright (c) 2006 Tower Technologies
4 *
5 * Author: Alessandro Zummo <a.zummo@towertech.it>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This drivers only supports the clock running in BCD and 24H mode.
12 * If it will be ever adapted to binary and 12H mode, care must be taken
13 * to not introduce bugs.
14 */
15
16#include <linux/module.h>
17#include <linux/rtc.h>
18#include <linux/platform_device.h>
19#include <linux/m48t86.h>
20#include <linux/bcd.h>
21
22#define M48T86_REG_SEC 0x00
23#define M48T86_REG_SECALRM 0x01
24#define M48T86_REG_MIN 0x02
25#define M48T86_REG_MINALRM 0x03
26#define M48T86_REG_HOUR 0x04
27#define M48T86_REG_HOURALRM 0x05
28#define M48T86_REG_DOW 0x06 /* 1 = sunday */
29#define M48T86_REG_DOM 0x07
30#define M48T86_REG_MONTH 0x08 /* 1 - 12 */
31#define M48T86_REG_YEAR 0x09 /* 0 - 99 */
32#define M48T86_REG_A 0x0A
33#define M48T86_REG_B 0x0B
34#define M48T86_REG_C 0x0C
35#define M48T86_REG_D 0x0D
36
37#define M48T86_REG_B_H24 (1 << 1)
38#define M48T86_REG_B_DM (1 << 2)
39#define M48T86_REG_B_SET (1 << 7)
40#define M48T86_REG_D_VRT (1 << 7)
41
42#define DRV_VERSION "0.1"
43
44
45static int m48t86_rtc_read_time(struct device *dev, struct rtc_time *tm)
46{
47 unsigned char reg;
48 struct platform_device *pdev = to_platform_device(dev);
49 struct m48t86_ops *ops = pdev->dev.platform_data;
50
51 reg = ops->readb(M48T86_REG_B);
52
53 if (reg & M48T86_REG_B_DM) {
54 /* data (binary) mode */
55 tm->tm_sec = ops->readb(M48T86_REG_SEC);
56 tm->tm_min = ops->readb(M48T86_REG_MIN);
57 tm->tm_hour = ops->readb(M48T86_REG_HOUR) & 0x3F;
58 tm->tm_mday = ops->readb(M48T86_REG_DOM);
59 /* tm_mon is 0-11 */
60 tm->tm_mon = ops->readb(M48T86_REG_MONTH) - 1;
61 tm->tm_year = ops->readb(M48T86_REG_YEAR) + 100;
62 tm->tm_wday = ops->readb(M48T86_REG_DOW);
63 } else {
64 /* bcd mode */
65 tm->tm_sec = BCD2BIN(ops->readb(M48T86_REG_SEC));
66 tm->tm_min = BCD2BIN(ops->readb(M48T86_REG_MIN));
67 tm->tm_hour = BCD2BIN(ops->readb(M48T86_REG_HOUR) & 0x3F);
68 tm->tm_mday = BCD2BIN(ops->readb(M48T86_REG_DOM));
69 /* tm_mon is 0-11 */
70 tm->tm_mon = BCD2BIN(ops->readb(M48T86_REG_MONTH)) - 1;
71 tm->tm_year = BCD2BIN(ops->readb(M48T86_REG_YEAR)) + 100;
72 tm->tm_wday = BCD2BIN(ops->readb(M48T86_REG_DOW));
73 }
74
75 /* correct the hour if the clock is in 12h mode */
76 if (!(reg & M48T86_REG_B_H24))
77 if (ops->readb(M48T86_REG_HOUR) & 0x80)
78 tm->tm_hour += 12;
79
80 return 0;
81}
82
83static int m48t86_rtc_set_time(struct device *dev, struct rtc_time *tm)
84{
85 unsigned char reg;
86 struct platform_device *pdev = to_platform_device(dev);
87 struct m48t86_ops *ops = pdev->dev.platform_data;
88
89 reg = ops->readb(M48T86_REG_B);
90
91 /* update flag and 24h mode */
92 reg |= M48T86_REG_B_SET | M48T86_REG_B_H24;
93 ops->writeb(reg, M48T86_REG_B);
94
95 if (reg & M48T86_REG_B_DM) {
96 /* data (binary) mode */
97 ops->writeb(tm->tm_sec, M48T86_REG_SEC);
98 ops->writeb(tm->tm_min, M48T86_REG_MIN);
99 ops->writeb(tm->tm_hour, M48T86_REG_HOUR);
100 ops->writeb(tm->tm_mday, M48T86_REG_DOM);
101 ops->writeb(tm->tm_mon + 1, M48T86_REG_MONTH);
102 ops->writeb(tm->tm_year % 100, M48T86_REG_YEAR);
103 ops->writeb(tm->tm_wday, M48T86_REG_DOW);
104 } else {
105 /* bcd mode */
106 ops->writeb(BIN2BCD(tm->tm_sec), M48T86_REG_SEC);
107 ops->writeb(BIN2BCD(tm->tm_min), M48T86_REG_MIN);
108 ops->writeb(BIN2BCD(tm->tm_hour), M48T86_REG_HOUR);
109 ops->writeb(BIN2BCD(tm->tm_mday), M48T86_REG_DOM);
110 ops->writeb(BIN2BCD(tm->tm_mon + 1), M48T86_REG_MONTH);
111 ops->writeb(BIN2BCD(tm->tm_year % 100), M48T86_REG_YEAR);
112 ops->writeb(BIN2BCD(tm->tm_wday), M48T86_REG_DOW);
113 }
114
115 /* update ended */
116 reg &= ~M48T86_REG_B_SET;
117 ops->writeb(reg, M48T86_REG_B);
118
119 return 0;
120}
121
122static int m48t86_rtc_proc(struct device *dev, struct seq_file *seq)
123{
124 unsigned char reg;
125 struct platform_device *pdev = to_platform_device(dev);
126 struct m48t86_ops *ops = pdev->dev.platform_data;
127
128 reg = ops->readb(M48T86_REG_B);
129
130 seq_printf(seq, "24hr\t\t: %s\n",
131 (reg & M48T86_REG_B_H24) ? "yes" : "no");
132
133 seq_printf(seq, "mode\t\t: %s\n",
134 (reg & M48T86_REG_B_DM) ? "binary" : "bcd");
135
136 reg = ops->readb(M48T86_REG_D);
137
138 seq_printf(seq, "battery\t\t: %s\n",
139 (reg & M48T86_REG_D_VRT) ? "ok" : "exhausted");
140
141 return 0;
142}
143
144static struct rtc_class_ops m48t86_rtc_ops = {
145 .read_time = m48t86_rtc_read_time,
146 .set_time = m48t86_rtc_set_time,
147 .proc = m48t86_rtc_proc,
148};
149
150static int __devinit m48t86_rtc_probe(struct platform_device *dev)
151{
152 unsigned char reg;
153 struct m48t86_ops *ops = dev->dev.platform_data;
154 struct rtc_device *rtc = rtc_device_register("m48t86",
155 &dev->dev, &m48t86_rtc_ops, THIS_MODULE);
156
157 if (IS_ERR(rtc)) {
158 dev_err(&dev->dev, "unable to register\n");
159 return PTR_ERR(rtc);
160 }
161
162 platform_set_drvdata(dev, rtc);
163
164 /* read battery status */
165 reg = ops->readb(M48T86_REG_D);
166 dev_info(&dev->dev, "battery %s\n",
167 (reg & M48T86_REG_D_VRT) ? "ok" : "exhausted");
168
169 return 0;
170}
171
172static int __devexit m48t86_rtc_remove(struct platform_device *dev)
173{
174 struct rtc_device *rtc = platform_get_drvdata(dev);
175
176 if (rtc)
177 rtc_device_unregister(rtc);
178
179 platform_set_drvdata(dev, NULL);
180
181 return 0;
182}
183
184static struct platform_driver m48t86_rtc_platform_driver = {
185 .driver = {
186 .name = "rtc-m48t86",
187 .owner = THIS_MODULE,
188 },
189 .probe = m48t86_rtc_probe,
190 .remove = __devexit_p(m48t86_rtc_remove),
191};
192
193static int __init m48t86_rtc_init(void)
194{
195 return platform_driver_register(&m48t86_rtc_platform_driver);
196}
197
198static void __exit m48t86_rtc_exit(void)
199{
200 platform_driver_unregister(&m48t86_rtc_platform_driver);
201}
202
203MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
204MODULE_DESCRIPTION("M48T86 RTC driver");
205MODULE_LICENSE("GPL");
206MODULE_VERSION(DRV_VERSION);
207
208module_init(m48t86_rtc_init);
209module_exit(m48t86_rtc_exit);
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
new file mode 100644
index 000000000000..d857d45bdbe8
--- /dev/null
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -0,0 +1,353 @@
1/*
2 * An I2C driver for the Philips PCF8563 RTC
3 * Copyright 2005-06 Tower Technologies
4 *
5 * Author: Alessandro Zummo <a.zummo@towertech.it>
6 * Maintainers: http://www.nslu2-linux.org/
7 *
8 * based on the other drivers in this same directory.
9 *
10 * http://www.semiconductors.philips.com/acrobat/datasheets/PCF8563-04.pdf
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/i2c.h>
18#include <linux/bcd.h>
19#include <linux/rtc.h>
20
21#define DRV_VERSION "0.4.2"
22
23/* Addresses to scan: none
24 * This chip cannot be reliably autodetected. An empty eeprom
25 * located at 0x51 will pass the validation routine due to
26 * the way the registers are implemented.
27 */
28static unsigned short normal_i2c[] = { I2C_CLIENT_END };
29
30/* Module parameters */
31I2C_CLIENT_INSMOD;
32
33#define PCF8563_REG_ST1 0x00 /* status */
34#define PCF8563_REG_ST2 0x01
35
36#define PCF8563_REG_SC 0x02 /* datetime */
37#define PCF8563_REG_MN 0x03
38#define PCF8563_REG_HR 0x04
39#define PCF8563_REG_DM 0x05
40#define PCF8563_REG_DW 0x06
41#define PCF8563_REG_MO 0x07
42#define PCF8563_REG_YR 0x08
43
44#define PCF8563_REG_AMN 0x09 /* alarm */
45#define PCF8563_REG_AHR 0x0A
46#define PCF8563_REG_ADM 0x0B
47#define PCF8563_REG_ADW 0x0C
48
49#define PCF8563_REG_CLKO 0x0D /* clock out */
50#define PCF8563_REG_TMRC 0x0E /* timer control */
51#define PCF8563_REG_TMR 0x0F /* timer */
52
53#define PCF8563_SC_LV 0x80 /* low voltage */
54#define PCF8563_MO_C 0x80 /* century */
55
56static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind);
57static int pcf8563_detach(struct i2c_client *client);
58
59/*
60 * In the routines that deal directly with the pcf8563 hardware, we use
61 * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
62 */
63static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
64{
65 unsigned char buf[13] = { PCF8563_REG_ST1 };
66
67 struct i2c_msg msgs[] = {
68 { client->addr, 0, 1, buf }, /* setup read ptr */
69 { client->addr, I2C_M_RD, 13, buf }, /* read status + date */
70 };
71
72 /* read registers */
73 if ((i2c_transfer(client->adapter, msgs, 2)) != 2) {
74 dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
75 return -EIO;
76 }
77
78 if (buf[PCF8563_REG_SC] & PCF8563_SC_LV)
79 dev_info(&client->dev,
80 "low voltage detected, date/time is not reliable.\n");
81
82 dev_dbg(&client->dev,
83 "%s: raw data is st1=%02x, st2=%02x, sec=%02x, min=%02x, hr=%02x, "
84 "mday=%02x, wday=%02x, mon=%02x, year=%02x\n",
85 __FUNCTION__,
86 buf[0], buf[1], buf[2], buf[3],
87 buf[4], buf[5], buf[6], buf[7],
88 buf[8]);
89
90
91 tm->tm_sec = BCD2BIN(buf[PCF8563_REG_SC] & 0x7F);
92 tm->tm_min = BCD2BIN(buf[PCF8563_REG_MN] & 0x7F);
93 tm->tm_hour = BCD2BIN(buf[PCF8563_REG_HR] & 0x3F); /* rtc hr 0-23 */
94 tm->tm_mday = BCD2BIN(buf[PCF8563_REG_DM] & 0x3F);
95 tm->tm_wday = buf[PCF8563_REG_DW] & 0x07;
96 tm->tm_mon = BCD2BIN(buf[PCF8563_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
97 tm->tm_year = BCD2BIN(buf[PCF8563_REG_YR])
98 + (buf[PCF8563_REG_MO] & PCF8563_MO_C ? 100 : 0);
99
100 dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
101 "mday=%d, mon=%d, year=%d, wday=%d\n",
102 __FUNCTION__,
103 tm->tm_sec, tm->tm_min, tm->tm_hour,
104 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
105
106 /* the clock can give out invalid datetime, but we cannot return
107 * -EINVAL otherwise hwclock will refuse to set the time on bootup.
108 */
109 if (rtc_valid_tm(tm) < 0)
110 dev_err(&client->dev, "retrieved date/time is not valid.\n");
111
112 return 0;
113}
114
115static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm)
116{
117 int i, err;
118 unsigned char buf[9];
119
120 dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
121 "mday=%d, mon=%d, year=%d, wday=%d\n",
122 __FUNCTION__,
123 tm->tm_sec, tm->tm_min, tm->tm_hour,
124 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
125
126 /* hours, minutes and seconds */
127 buf[PCF8563_REG_SC] = BIN2BCD(tm->tm_sec);
128 buf[PCF8563_REG_MN] = BIN2BCD(tm->tm_min);
129 buf[PCF8563_REG_HR] = BIN2BCD(tm->tm_hour);
130
131 buf[PCF8563_REG_DM] = BIN2BCD(tm->tm_mday);
132
133 /* month, 1 - 12 */
134 buf[PCF8563_REG_MO] = BIN2BCD(tm->tm_mon + 1);
135
136 /* year and century */
137 buf[PCF8563_REG_YR] = BIN2BCD(tm->tm_year % 100);
138 if (tm->tm_year / 100)
139 buf[PCF8563_REG_MO] |= PCF8563_MO_C;
140
141 buf[PCF8563_REG_DW] = tm->tm_wday & 0x07;
142
143 /* write register's data */
144 for (i = 0; i < 7; i++) {
145 unsigned char data[2] = { PCF8563_REG_SC + i,
146 buf[PCF8563_REG_SC + i] };
147
148 err = i2c_master_send(client, data, sizeof(data));
149 if (err != sizeof(data)) {
150 dev_err(&client->dev,
151 "%s: err=%d addr=%02x, data=%02x\n",
152 __FUNCTION__, err, data[0], data[1]);
153 return -EIO;
154 }
155 };
156
157 return 0;
158}
159
160struct pcf8563_limit
161{
162 unsigned char reg;
163 unsigned char mask;
164 unsigned char min;
165 unsigned char max;
166};
167
168static int pcf8563_validate_client(struct i2c_client *client)
169{
170 int i;
171
172 static const struct pcf8563_limit pattern[] = {
173 /* register, mask, min, max */
174 { PCF8563_REG_SC, 0x7F, 0, 59 },
175 { PCF8563_REG_MN, 0x7F, 0, 59 },
176 { PCF8563_REG_HR, 0x3F, 0, 23 },
177 { PCF8563_REG_DM, 0x3F, 0, 31 },
178 { PCF8563_REG_MO, 0x1F, 0, 12 },
179 };
180
181 /* check limits (only registers with bcd values) */
182 for (i = 0; i < ARRAY_SIZE(pattern); i++) {
183 int xfer;
184 unsigned char value;
185 unsigned char buf = pattern[i].reg;
186
187 struct i2c_msg msgs[] = {
188 { client->addr, 0, 1, &buf },
189 { client->addr, I2C_M_RD, 1, &buf },
190 };
191
192 xfer = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
193
194 if (xfer != ARRAY_SIZE(msgs)) {
195 dev_err(&client->adapter->dev,
196 "%s: could not read register 0x%02X\n",
197 __FUNCTION__, pattern[i].reg);
198
199 return -EIO;
200 }
201
202 value = BCD2BIN(buf & pattern[i].mask);
203
204 if (value > pattern[i].max ||
205 value < pattern[i].min) {
206 dev_dbg(&client->adapter->dev,
207 "%s: pattern=%d, reg=%x, mask=0x%02x, min=%d, "
208 "max=%d, value=%d, raw=0x%02X\n",
209 __FUNCTION__, i, pattern[i].reg, pattern[i].mask,
210 pattern[i].min, pattern[i].max,
211 value, buf);
212
213 return -ENODEV;
214 }
215 }
216
217 return 0;
218}
219
220static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
221{
222 return pcf8563_get_datetime(to_i2c_client(dev), tm);
223}
224
225static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm)
226{
227 return pcf8563_set_datetime(to_i2c_client(dev), tm);
228}
229
230static int pcf8563_rtc_proc(struct device *dev, struct seq_file *seq)
231{
232 seq_printf(seq, "24hr\t\t: yes\n");
233 return 0;
234}
235
236static struct rtc_class_ops pcf8563_rtc_ops = {
237 .proc = pcf8563_rtc_proc,
238 .read_time = pcf8563_rtc_read_time,
239 .set_time = pcf8563_rtc_set_time,
240};
241
242static int pcf8563_attach(struct i2c_adapter *adapter)
243{
244 return i2c_probe(adapter, &addr_data, pcf8563_probe);
245}
246
247static struct i2c_driver pcf8563_driver = {
248 .driver = {
249 .name = "pcf8563",
250 },
251 .id = I2C_DRIVERID_PCF8563,
252 .attach_adapter = &pcf8563_attach,
253 .detach_client = &pcf8563_detach,
254};
255
256static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind)
257{
258 struct i2c_client *client;
259 struct rtc_device *rtc;
260
261 int err = 0;
262
263 dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
264
265 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
266 err = -ENODEV;
267 goto exit;
268 }
269
270 if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
271 err = -ENOMEM;
272 goto exit;
273 }
274
275 client->addr = address;
276 client->driver = &pcf8563_driver;
277 client->adapter = adapter;
278
279 strlcpy(client->name, pcf8563_driver.driver.name, I2C_NAME_SIZE);
280
281 /* Verify the chip is really an PCF8563 */
282 if (kind < 0) {
283 if (pcf8563_validate_client(client) < 0) {
284 err = -ENODEV;
285 goto exit_kfree;
286 }
287 }
288
289 /* Inform the i2c layer */
290 if ((err = i2c_attach_client(client)))
291 goto exit_kfree;
292
293 dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
294
295 rtc = rtc_device_register(pcf8563_driver.driver.name, &client->dev,
296 &pcf8563_rtc_ops, THIS_MODULE);
297
298 if (IS_ERR(rtc)) {
299 err = PTR_ERR(rtc);
300 dev_err(&client->dev,
301 "unable to register the class device\n");
302 goto exit_detach;
303 }
304
305 i2c_set_clientdata(client, rtc);
306
307 return 0;
308
309exit_detach:
310 i2c_detach_client(client);
311
312exit_kfree:
313 kfree(client);
314
315exit:
316 return err;
317}
318
319static int pcf8563_detach(struct i2c_client *client)
320{
321 int err;
322 struct rtc_device *rtc = i2c_get_clientdata(client);
323
324 dev_dbg(&client->dev, "%s\n", __FUNCTION__);
325
326 if (rtc)
327 rtc_device_unregister(rtc);
328
329 if ((err = i2c_detach_client(client)))
330 return err;
331
332 kfree(client);
333
334 return 0;
335}
336
337static int __init pcf8563_init(void)
338{
339 return i2c_add_driver(&pcf8563_driver);
340}
341
342static void __exit pcf8563_exit(void)
343{
344 i2c_del_driver(&pcf8563_driver);
345}
346
347MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
348MODULE_DESCRIPTION("Philips PCF8563/Epson RTC8564 RTC driver");
349MODULE_LICENSE("GPL");
350MODULE_VERSION(DRV_VERSION);
351
352module_init(pcf8563_init);
353module_exit(pcf8563_exit);
diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c
new file mode 100644
index 000000000000..90b8a97a0919
--- /dev/null
+++ b/drivers/rtc/rtc-proc.c
@@ -0,0 +1,162 @@
1/*
2 * RTC subsystem, proc interface
3 *
4 * Copyright (C) 2005-06 Tower Technologies
5 * Author: Alessandro Zummo <a.zummo@towertech.it>
6 *
7 * based on arch/arm/common/rtctime.c
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/module.h>
15#include <linux/rtc.h>
16#include <linux/proc_fs.h>
17#include <linux/seq_file.h>
18
19static struct class_device *rtc_dev = NULL;
20static DEFINE_MUTEX(rtc_lock);
21
22static int rtc_proc_show(struct seq_file *seq, void *offset)
23{
24 int err;
25 struct class_device *class_dev = seq->private;
26 struct rtc_class_ops *ops = to_rtc_device(class_dev)->ops;
27 struct rtc_wkalrm alrm;
28 struct rtc_time tm;
29
30 err = rtc_read_time(class_dev, &tm);
31 if (err == 0) {
32 seq_printf(seq,
33 "rtc_time\t: %02d:%02d:%02d\n"
34 "rtc_date\t: %04d-%02d-%02d\n",
35 tm.tm_hour, tm.tm_min, tm.tm_sec,
36 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
37 }
38
39 err = rtc_read_alarm(class_dev, &alrm);
40 if (err == 0) {
41 seq_printf(seq, "alrm_time\t: ");
42 if ((unsigned int)alrm.time.tm_hour <= 24)
43 seq_printf(seq, "%02d:", alrm.time.tm_hour);
44 else
45 seq_printf(seq, "**:");
46 if ((unsigned int)alrm.time.tm_min <= 59)
47 seq_printf(seq, "%02d:", alrm.time.tm_min);
48 else
49 seq_printf(seq, "**:");
50 if ((unsigned int)alrm.time.tm_sec <= 59)
51 seq_printf(seq, "%02d\n", alrm.time.tm_sec);
52 else
53 seq_printf(seq, "**\n");
54
55 seq_printf(seq, "alrm_date\t: ");
56 if ((unsigned int)alrm.time.tm_year <= 200)
57 seq_printf(seq, "%04d-", alrm.time.tm_year + 1900);
58 else
59 seq_printf(seq, "****-");
60 if ((unsigned int)alrm.time.tm_mon <= 11)
61 seq_printf(seq, "%02d-", alrm.time.tm_mon + 1);
62 else
63 seq_printf(seq, "**-");
64 if ((unsigned int)alrm.time.tm_mday <= 31)
65 seq_printf(seq, "%02d\n", alrm.time.tm_mday);
66 else
67 seq_printf(seq, "**\n");
68 seq_printf(seq, "alrm_wakeup\t: %s\n",
69 alrm.enabled ? "yes" : "no");
70 seq_printf(seq, "alrm_pending\t: %s\n",
71 alrm.pending ? "yes" : "no");
72 }
73
74 if (ops->proc)
75 ops->proc(class_dev->dev, seq);
76
77 return 0;
78}
79
80static int rtc_proc_open(struct inode *inode, struct file *file)
81{
82 struct class_device *class_dev = PDE(inode)->data;
83
84 if (!try_module_get(THIS_MODULE))
85 return -ENODEV;
86
87 return single_open(file, rtc_proc_show, class_dev);
88}
89
90static int rtc_proc_release(struct inode *inode, struct file *file)
91{
92 int res = single_release(inode, file);
93 module_put(THIS_MODULE);
94 return res;
95}
96
97static struct file_operations rtc_proc_fops = {
98 .open = rtc_proc_open,
99 .read = seq_read,
100 .llseek = seq_lseek,
101 .release = rtc_proc_release,
102};
103
104static int rtc_proc_add_device(struct class_device *class_dev,
105 struct class_interface *class_intf)
106{
107 mutex_lock(&rtc_lock);
108 if (rtc_dev == NULL) {
109 struct proc_dir_entry *ent;
110
111 rtc_dev = class_dev;
112
113 ent = create_proc_entry("driver/rtc", 0, NULL);
114 if (ent) {
115 struct rtc_device *rtc = to_rtc_device(class_dev);
116
117 ent->proc_fops = &rtc_proc_fops;
118 ent->owner = rtc->owner;
119 ent->data = class_dev;
120
121 dev_info(class_dev->dev, "rtc intf: proc\n");
122 }
123 else
124 rtc_dev = NULL;
125 }
126 mutex_unlock(&rtc_lock);
127
128 return 0;
129}
130
131static void rtc_proc_remove_device(struct class_device *class_dev,
132 struct class_interface *class_intf)
133{
134 mutex_lock(&rtc_lock);
135 if (rtc_dev == class_dev) {
136 remove_proc_entry("driver/rtc", NULL);
137 rtc_dev = NULL;
138 }
139 mutex_unlock(&rtc_lock);
140}
141
142static struct class_interface rtc_proc_interface = {
143 .add = &rtc_proc_add_device,
144 .remove = &rtc_proc_remove_device,
145};
146
147static int __init rtc_proc_init(void)
148{
149 return rtc_interface_register(&rtc_proc_interface);
150}
151
152static void __exit rtc_proc_exit(void)
153{
154 class_interface_unregister(&rtc_proc_interface);
155}
156
157module_init(rtc_proc_init);
158module_exit(rtc_proc_exit);
159
160MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
161MODULE_DESCRIPTION("RTC class proc interface");
162MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
new file mode 100644
index 000000000000..396c8681f66c
--- /dev/null
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -0,0 +1,294 @@
1/*
2 * An I2C driver for the Ricoh RS5C372 RTC
3 *
4 * Copyright (C) 2005 Pavel Mironchik <pmironchik@optifacio.net>
5 * Copyright (C) 2006 Tower Technologies
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/i2c.h>
13#include <linux/rtc.h>
14#include <linux/bcd.h>
15
16#define DRV_VERSION "0.2"
17
18/* Addresses to scan */
19static unsigned short normal_i2c[] = { /* 0x32,*/ I2C_CLIENT_END };
20
21/* Insmod parameters */
22I2C_CLIENT_INSMOD;
23
24#define RS5C372_REG_SECS 0
25#define RS5C372_REG_MINS 1
26#define RS5C372_REG_HOURS 2
27#define RS5C372_REG_WDAY 3
28#define RS5C372_REG_DAY 4
29#define RS5C372_REG_MONTH 5
30#define RS5C372_REG_YEAR 6
31#define RS5C372_REG_TRIM 7
32
33#define RS5C372_TRIM_XSL 0x80
34#define RS5C372_TRIM_MASK 0x7F
35
36#define RS5C372_REG_BASE 0
37
38static int rs5c372_attach(struct i2c_adapter *adapter);
39static int rs5c372_detach(struct i2c_client *client);
40static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind);
41
42static struct i2c_driver rs5c372_driver = {
43 .driver = {
44 .name = "rs5c372",
45 },
46 .attach_adapter = &rs5c372_attach,
47 .detach_client = &rs5c372_detach,
48};
49
50static int rs5c372_get_datetime(struct i2c_client *client, struct rtc_time *tm)
51{
52 unsigned char buf[7] = { RS5C372_REG_BASE };
53
54 /* this implements the 1st reading method, according
55 * to the datasheet. buf[0] is initialized with
56 * address ptr and transmission format register.
57 */
58 struct i2c_msg msgs[] = {
59 { client->addr, 0, 1, buf },
60 { client->addr, I2C_M_RD, 7, buf },
61 };
62
63 if ((i2c_transfer(client->adapter, msgs, 2)) != 2) {
64 dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
65 return -EIO;
66 }
67
68 tm->tm_sec = BCD2BIN(buf[RS5C372_REG_SECS] & 0x7f);
69 tm->tm_min = BCD2BIN(buf[RS5C372_REG_MINS] & 0x7f);
70 tm->tm_hour = BCD2BIN(buf[RS5C372_REG_HOURS] & 0x3f);
71 tm->tm_wday = BCD2BIN(buf[RS5C372_REG_WDAY] & 0x07);
72 tm->tm_mday = BCD2BIN(buf[RS5C372_REG_DAY] & 0x3f);
73
74 /* tm->tm_mon is zero-based */
75 tm->tm_mon = BCD2BIN(buf[RS5C372_REG_MONTH] & 0x1f) - 1;
76
77 /* year is 1900 + tm->tm_year */
78 tm->tm_year = BCD2BIN(buf[RS5C372_REG_YEAR]) + 100;
79
80 dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
81 "mday=%d, mon=%d, year=%d, wday=%d\n",
82 __FUNCTION__,
83 tm->tm_sec, tm->tm_min, tm->tm_hour,
84 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
85
86 return 0;
87}
88
89static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm)
90{
91 unsigned char buf[8] = { RS5C372_REG_BASE };
92
93 dev_dbg(&client->dev,
94 "%s: secs=%d, mins=%d, hours=%d ",
95 "mday=%d, mon=%d, year=%d, wday=%d\n",
96 __FUNCTION__, tm->tm_sec, tm->tm_min, tm->tm_hour,
97 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
98
99 buf[1] = BIN2BCD(tm->tm_sec);
100 buf[2] = BIN2BCD(tm->tm_min);
101 buf[3] = BIN2BCD(tm->tm_hour);
102 buf[4] = BIN2BCD(tm->tm_wday);
103 buf[5] = BIN2BCD(tm->tm_mday);
104 buf[6] = BIN2BCD(tm->tm_mon + 1);
105 buf[7] = BIN2BCD(tm->tm_year - 100);
106
107 if ((i2c_master_send(client, buf, 8)) != 8) {
108 dev_err(&client->dev, "%s: write error\n", __FUNCTION__);
109 return -EIO;
110 }
111
112 return 0;
113}
114
115static int rs5c372_get_trim(struct i2c_client *client, int *osc, int *trim)
116{
117 unsigned char buf = RS5C372_REG_TRIM;
118
119 struct i2c_msg msgs[] = {
120 { client->addr, 0, 1, &buf },
121 { client->addr, I2C_M_RD, 1, &buf },
122 };
123
124 if ((i2c_transfer(client->adapter, msgs, 2)) != 2) {
125 dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
126 return -EIO;
127 }
128
129 dev_dbg(&client->dev, "%s: raw trim=%x\n", __FUNCTION__, trim);
130
131 if (osc)
132 *osc = (buf & RS5C372_TRIM_XSL) ? 32000 : 32768;
133
134 if (trim)
135 *trim = buf & RS5C372_TRIM_MASK;
136
137 return 0;
138}
139
140static int rs5c372_rtc_read_time(struct device *dev, struct rtc_time *tm)
141{
142 return rs5c372_get_datetime(to_i2c_client(dev), tm);
143}
144
145static int rs5c372_rtc_set_time(struct device *dev, struct rtc_time *tm)
146{
147 return rs5c372_set_datetime(to_i2c_client(dev), tm);
148}
149
150static int rs5c372_rtc_proc(struct device *dev, struct seq_file *seq)
151{
152 int err, osc, trim;
153
154 seq_printf(seq, "24hr\t\t: yes\n");
155
156 if ((err = rs5c372_get_trim(to_i2c_client(dev), &osc, &trim)) == 0) {
157 seq_printf(seq, "%d.%03d KHz\n", osc / 1000, osc % 1000);
158 seq_printf(seq, "trim\t: %d\n", trim);
159 }
160
161 return 0;
162}
163
164static struct rtc_class_ops rs5c372_rtc_ops = {
165 .proc = rs5c372_rtc_proc,
166 .read_time = rs5c372_rtc_read_time,
167 .set_time = rs5c372_rtc_set_time,
168};
169
170static ssize_t rs5c372_sysfs_show_trim(struct device *dev,
171 struct device_attribute *attr, char *buf)
172{
173 int trim;
174
175 if (rs5c372_get_trim(to_i2c_client(dev), NULL, &trim) == 0)
176 return sprintf(buf, "0x%2x\n", trim);
177
178 return 0;
179}
180static DEVICE_ATTR(trim, S_IRUGO, rs5c372_sysfs_show_trim, NULL);
181
182static ssize_t rs5c372_sysfs_show_osc(struct device *dev,
183 struct device_attribute *attr, char *buf)
184{
185 int osc;
186
187 if (rs5c372_get_trim(to_i2c_client(dev), &osc, NULL) == 0)
188 return sprintf(buf, "%d.%03d KHz\n", osc / 1000, osc % 1000);
189
190 return 0;
191}
192static DEVICE_ATTR(osc, S_IRUGO, rs5c372_sysfs_show_osc, NULL);
193
194static int rs5c372_attach(struct i2c_adapter *adapter)
195{
196 dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
197 return i2c_probe(adapter, &addr_data, rs5c372_probe);
198}
199
200static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind)
201{
202 int err = 0;
203 struct i2c_client *client;
204 struct rtc_device *rtc;
205
206 dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
207
208 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
209 err = -ENODEV;
210 goto exit;
211 }
212
213 if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
214 err = -ENOMEM;
215 goto exit;
216 }
217
218 /* I2C client */
219 client->addr = address;
220 client->driver = &rs5c372_driver;
221 client->adapter = adapter;
222
223 strlcpy(client->name, rs5c372_driver.driver.name, I2C_NAME_SIZE);
224
225 /* Inform the i2c layer */
226 if ((err = i2c_attach_client(client)))
227 goto exit_kfree;
228
229 dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
230
231 rtc = rtc_device_register(rs5c372_driver.driver.name, &client->dev,
232 &rs5c372_rtc_ops, THIS_MODULE);
233
234 if (IS_ERR(rtc)) {
235 err = PTR_ERR(rtc);
236 dev_err(&client->dev,
237 "unable to register the class device\n");
238 goto exit_detach;
239 }
240
241 i2c_set_clientdata(client, rtc);
242
243 device_create_file(&client->dev, &dev_attr_trim);
244 device_create_file(&client->dev, &dev_attr_osc);
245
246 return 0;
247
248exit_detach:
249 i2c_detach_client(client);
250
251exit_kfree:
252 kfree(client);
253
254exit:
255 return err;
256}
257
258static int rs5c372_detach(struct i2c_client *client)
259{
260 int err;
261 struct rtc_device *rtc = i2c_get_clientdata(client);
262
263 dev_dbg(&client->dev, "%s\n", __FUNCTION__);
264
265 if (rtc)
266 rtc_device_unregister(rtc);
267
268 if ((err = i2c_detach_client(client)))
269 return err;
270
271 kfree(client);
272
273 return 0;
274}
275
276static __init int rs5c372_init(void)
277{
278 return i2c_add_driver(&rs5c372_driver);
279}
280
281static __exit void rs5c372_exit(void)
282{
283 i2c_del_driver(&rs5c372_driver);
284}
285
286module_init(rs5c372_init);
287module_exit(rs5c372_exit);
288
289MODULE_AUTHOR(
290 "Pavel Mironchik <pmironchik@optifacio.net>, "
291 "Alessandro Zummo <a.zummo@towertech.it>");
292MODULE_DESCRIPTION("Ricoh RS5C372 RTC driver");
293MODULE_LICENSE("GPL");
294MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
new file mode 100644
index 000000000000..83b2bb480a16
--- /dev/null
+++ b/drivers/rtc/rtc-sa1100.c
@@ -0,0 +1,388 @@
1/*
2 * Real Time Clock interface for StrongARM SA1x00 and XScale PXA2xx
3 *
4 * Copyright (c) 2000 Nils Faerber
5 *
6 * Based on rtc.c by Paul Gortmaker
7 *
8 * Original Driver by Nils Faerber <nils@kernelconcepts.de>
9 *
10 * Modifications from:
11 * CIH <cih@coventive.com>
12 * Nicolas Pitre <nico@cam.org>
13 * Andrew Christian <andrew.christian@hp.com>
14 *
15 * Converted to the RTC subsystem and Driver Model
16 * by Richard Purdie <rpurdie@rpsys.net>
17 *
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version
21 * 2 of the License, or (at your option) any later version.
22 */
23
24#include <linux/platform_device.h>
25#include <linux/module.h>
26#include <linux/rtc.h>
27#include <linux/init.h>
28#include <linux/fs.h>
29#include <linux/interrupt.h>
30#include <linux/string.h>
31#include <linux/pm.h>
32
33#include <asm/bitops.h>
34#include <asm/hardware.h>
35#include <asm/irq.h>
36#include <asm/rtc.h>
37
38#ifdef CONFIG_ARCH_PXA
39#include <asm/arch/pxa-regs.h>
40#endif
41
42#define TIMER_FREQ CLOCK_TICK_RATE
43#define RTC_DEF_DIVIDER 32768 - 1
44#define RTC_DEF_TRIM 0
45
46static unsigned long rtc_freq = 1024;
47static struct rtc_time rtc_alarm;
48static spinlock_t sa1100_rtc_lock = SPIN_LOCK_UNLOCKED;
49
50static int rtc_update_alarm(struct rtc_time *alrm)
51{
52 struct rtc_time alarm_tm, now_tm;
53 unsigned long now, time;
54 int ret;
55
56 do {
57 now = RCNR;
58 rtc_time_to_tm(now, &now_tm);
59 rtc_next_alarm_time(&alarm_tm, &now_tm, alrm);
60 ret = rtc_tm_to_time(&alarm_tm, &time);
61 if (ret != 0)
62 break;
63
64 RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL);
65 RTAR = time;
66 } while (now != RCNR);
67
68 return ret;
69}
70
71static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id,
72 struct pt_regs *regs)
73{
74 struct platform_device *pdev = to_platform_device(dev_id);
75 struct rtc_device *rtc = platform_get_drvdata(pdev);
76 unsigned int rtsr;
77 unsigned long events = 0;
78
79 spin_lock(&sa1100_rtc_lock);
80
81 rtsr = RTSR;
82 /* clear interrupt sources */
83 RTSR = 0;
84 RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2);
85
86 /* clear alarm interrupt if it has occurred */
87 if (rtsr & RTSR_AL)
88 rtsr &= ~RTSR_ALE;
89 RTSR = rtsr & (RTSR_ALE | RTSR_HZE);
90
91 /* update irq data & counter */
92 if (rtsr & RTSR_AL)
93 events |= RTC_AF | RTC_IRQF;
94 if (rtsr & RTSR_HZ)
95 events |= RTC_UF | RTC_IRQF;
96
97 rtc_update_irq(&rtc->class_dev, 1, events);
98
99 if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm))
100 rtc_update_alarm(&rtc_alarm);
101
102 spin_unlock(&sa1100_rtc_lock);
103
104 return IRQ_HANDLED;
105}
106
107static int rtc_timer1_count;
108
109static irqreturn_t timer1_interrupt(int irq, void *dev_id,
110 struct pt_regs *regs)
111{
112 struct platform_device *pdev = to_platform_device(dev_id);
113 struct rtc_device *rtc = platform_get_drvdata(pdev);
114
115 /*
116 * If we match for the first time, rtc_timer1_count will be 1.
117 * Otherwise, we wrapped around (very unlikely but
118 * still possible) so compute the amount of missed periods.
119 * The match reg is updated only when the data is actually retrieved
120 * to avoid unnecessary interrupts.
121 */
122 OSSR = OSSR_M1; /* clear match on timer1 */
123
124 rtc_update_irq(&rtc->class_dev, rtc_timer1_count, RTC_PF | RTC_IRQF);
125
126 if (rtc_timer1_count == 1)
127 rtc_timer1_count = (rtc_freq * ((1<<30)/(TIMER_FREQ>>2)));
128
129 return IRQ_HANDLED;
130}
131
132static int sa1100_rtc_read_callback(struct device *dev, int data)
133{
134 if (data & RTC_PF) {
135 /* interpolate missed periods and set match for the next */
136 unsigned long period = TIMER_FREQ/rtc_freq;
137 unsigned long oscr = OSCR;
138 unsigned long osmr1 = OSMR1;
139 unsigned long missed = (oscr - osmr1)/period;
140 data += missed << 8;
141 OSSR = OSSR_M1; /* clear match on timer 1 */
142 OSMR1 = osmr1 + (missed + 1)*period;
143 /* Ensure we didn't miss another match in the mean time.
144 * Here we compare (match - OSCR) 8 instead of 0 --
145 * see comment in pxa_timer_interrupt() for explanation.
146 */
147 while( (signed long)((osmr1 = OSMR1) - OSCR) <= 8 ) {
148 data += 0x100;
149 OSSR = OSSR_M1; /* clear match on timer 1 */
150 OSMR1 = osmr1 + period;
151 }
152 }
153 return data;
154}
155
156static int sa1100_rtc_open(struct device *dev)
157{
158 int ret;
159
160 ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, SA_INTERRUPT,
161 "rtc 1Hz", dev);
162 if (ret) {
163 printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTC1Hz);
164 goto fail_ui;
165 }
166 ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, SA_INTERRUPT,
167 "rtc Alrm", dev);
168 if (ret) {
169 printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTCAlrm);
170 goto fail_ai;
171 }
172 ret = request_irq(IRQ_OST1, timer1_interrupt, SA_INTERRUPT,
173 "rtc timer", dev);
174 if (ret) {
175 printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_OST1);
176 goto fail_pi;
177 }
178 return 0;
179
180 fail_pi:
181 free_irq(IRQ_RTCAlrm, NULL);
182 fail_ai:
183 free_irq(IRQ_RTC1Hz, NULL);
184 fail_ui:
185 return ret;
186}
187
188static void sa1100_rtc_release(struct device *dev)
189{
190 spin_lock_irq(&sa1100_rtc_lock);
191 RTSR = 0;
192 OIER &= ~OIER_E1;
193 OSSR = OSSR_M1;
194 spin_unlock_irq(&sa1100_rtc_lock);
195
196 free_irq(IRQ_OST1, dev);
197 free_irq(IRQ_RTCAlrm, dev);
198 free_irq(IRQ_RTC1Hz, dev);
199}
200
201
202static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd,
203 unsigned long arg)
204{
205 switch(cmd) {
206 case RTC_AIE_OFF:
207 spin_lock_irq(&sa1100_rtc_lock);
208 RTSR &= ~RTSR_ALE;
209 spin_unlock_irq(&sa1100_rtc_lock);
210 return 0;
211 case RTC_AIE_ON:
212 spin_lock_irq(&sa1100_rtc_lock);
213 RTSR |= RTSR_ALE;
214 spin_unlock_irq(&sa1100_rtc_lock);
215 return 0;
216 case RTC_UIE_OFF:
217 spin_lock_irq(&sa1100_rtc_lock);
218 RTSR &= ~RTSR_HZE;
219 spin_unlock_irq(&sa1100_rtc_lock);
220 return 0;
221 case RTC_UIE_ON:
222 spin_lock_irq(&sa1100_rtc_lock);
223 RTSR |= RTSR_HZE;
224 spin_unlock_irq(&sa1100_rtc_lock);
225 return 0;
226 case RTC_PIE_OFF:
227 spin_lock_irq(&sa1100_rtc_lock);
228 OIER &= ~OIER_E1;
229 spin_unlock_irq(&sa1100_rtc_lock);
230 return 0;
231 case RTC_PIE_ON:
232 if ((rtc_freq > 64) && !capable(CAP_SYS_RESOURCE))
233 return -EACCES;
234 spin_lock_irq(&sa1100_rtc_lock);
235 OSMR1 = TIMER_FREQ/rtc_freq + OSCR;
236 OIER |= OIER_E1;
237 rtc_timer1_count = 1;
238 spin_unlock_irq(&sa1100_rtc_lock);
239 return 0;
240 case RTC_IRQP_READ:
241 return put_user(rtc_freq, (unsigned long *)arg);
242 case RTC_IRQP_SET:
243 if (arg < 1 || arg > TIMER_FREQ)
244 return -EINVAL;
245 if ((arg > 64) && (!capable(CAP_SYS_RESOURCE)))
246 return -EACCES;
247 rtc_freq = arg;
248 return 0;
249 }
250 return -EINVAL;
251}
252
253static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm)
254{
255 rtc_time_to_tm(RCNR, tm);
256 return 0;
257}
258
259static int sa1100_rtc_set_time(struct device *dev, struct rtc_time *tm)
260{
261 unsigned long time;
262 int ret;
263
264 ret = rtc_tm_to_time(tm, &time);
265 if (ret == 0)
266 RCNR = time;
267 return ret;
268}
269
270static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
271{
272 memcpy(&alrm->time, &rtc_alarm, sizeof(struct rtc_time));
273 alrm->pending = RTSR & RTSR_AL ? 1 : 0;
274 return 0;
275}
276
277static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
278{
279 int ret;
280
281 spin_lock_irq(&sa1100_rtc_lock);
282 ret = rtc_update_alarm(&alrm->time);
283 if (ret == 0) {
284 memcpy(&rtc_alarm, &alrm->time, sizeof(struct rtc_time));
285
286 if (alrm->enabled)
287 enable_irq_wake(IRQ_RTCAlrm);
288 else
289 disable_irq_wake(IRQ_RTCAlrm);
290 }
291 spin_unlock_irq(&sa1100_rtc_lock);
292
293 return ret;
294}
295
296static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq)
297{
298 seq_printf(seq, "trim/divider\t: 0x%08x\n", RTTR);
299 seq_printf(seq, "alarm_IRQ\t: %s\n",
300 (RTSR & RTSR_ALE) ? "yes" : "no" );
301 seq_printf(seq, "update_IRQ\t: %s\n",
302 (RTSR & RTSR_HZE) ? "yes" : "no");
303 seq_printf(seq, "periodic_IRQ\t: %s\n",
304 (OIER & OIER_E1) ? "yes" : "no");
305 seq_printf(seq, "periodic_freq\t: %ld\n", rtc_freq);
306
307 return 0;
308}
309
310static struct rtc_class_ops sa1100_rtc_ops = {
311 .open = sa1100_rtc_open,
312 .read_callback = sa1100_rtc_read_callback,
313 .release = sa1100_rtc_release,
314 .ioctl = sa1100_rtc_ioctl,
315 .read_time = sa1100_rtc_read_time,
316 .set_time = sa1100_rtc_set_time,
317 .read_alarm = sa1100_rtc_read_alarm,
318 .set_alarm = sa1100_rtc_set_alarm,
319 .proc = sa1100_rtc_proc,
320};
321
322static int sa1100_rtc_probe(struct platform_device *pdev)
323{
324 struct rtc_device *rtc;
325
326 /*
327 * According to the manual we should be able to let RTTR be zero
328 * and then a default diviser for a 32.768KHz clock is used.
329 * Apparently this doesn't work, at least for my SA1110 rev 5.
330 * If the clock divider is uninitialized then reset it to the
331 * default value to get the 1Hz clock.
332 */
333 if (RTTR == 0) {
334 RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16);
335 printk(KERN_WARNING "rtc: warning: initializing default clock divider/trim value\n");
336 /* The current RTC value probably doesn't make sense either */
337 RCNR = 0;
338 }
339
340 rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops,
341 THIS_MODULE);
342
343 if (IS_ERR(rtc)) {
344 dev_err(&pdev->dev, "Unable to register the RTC device\n");
345 return PTR_ERR(rtc);
346 }
347
348 platform_set_drvdata(pdev, rtc);
349
350 dev_info(&pdev->dev, "SA11xx/PXA2xx RTC Registered\n");
351
352 return 0;
353}
354
355static int sa1100_rtc_remove(struct platform_device *pdev)
356{
357 struct rtc_device *rtc = platform_get_drvdata(pdev);
358
359 if (rtc)
360 rtc_device_unregister(rtc);
361
362 return 0;
363}
364
365static struct platform_driver sa1100_rtc_driver = {
366 .probe = sa1100_rtc_probe,
367 .remove = sa1100_rtc_remove,
368 .driver = {
369 .name = "sa1100-rtc",
370 },
371};
372
373static int __init sa1100_rtc_init(void)
374{
375 return platform_driver_register(&sa1100_rtc_driver);
376}
377
378static void __exit sa1100_rtc_exit(void)
379{
380 platform_driver_unregister(&sa1100_rtc_driver);
381}
382
383module_init(sa1100_rtc_init);
384module_exit(sa1100_rtc_exit);
385
386MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
387MODULE_DESCRIPTION("SA11x0/PXA2xx Realtime Clock Driver (RTC)");
388MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c
new file mode 100644
index 000000000000..7c1f3d2e53c4
--- /dev/null
+++ b/drivers/rtc/rtc-sysfs.c
@@ -0,0 +1,124 @@
1/*
2 * RTC subsystem, sysfs interface
3 *
4 * Copyright (C) 2005 Tower Technologies
5 * Author: Alessandro Zummo <a.zummo@towertech.it>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10*/
11
12#include <linux/module.h>
13#include <linux/rtc.h>
14
15/* device attributes */
16
17static ssize_t rtc_sysfs_show_name(struct class_device *dev, char *buf)
18{
19 return sprintf(buf, "%s\n", to_rtc_device(dev)->name);
20}
21static CLASS_DEVICE_ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL);
22
23static ssize_t rtc_sysfs_show_date(struct class_device *dev, char *buf)
24{
25 ssize_t retval;
26 struct rtc_time tm;
27
28 retval = rtc_read_time(dev, &tm);
29 if (retval == 0) {
30 retval = sprintf(buf, "%04d-%02d-%02d\n",
31 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
32 }
33
34 return retval;
35}
36static CLASS_DEVICE_ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL);
37
38static ssize_t rtc_sysfs_show_time(struct class_device *dev, char *buf)
39{
40 ssize_t retval;
41 struct rtc_time tm;
42
43 retval = rtc_read_time(dev, &tm);
44 if (retval == 0) {
45 retval = sprintf(buf, "%02d:%02d:%02d\n",
46 tm.tm_hour, tm.tm_min, tm.tm_sec);
47 }
48
49 return retval;
50}
51static CLASS_DEVICE_ATTR(time, S_IRUGO, rtc_sysfs_show_time, NULL);
52
53static ssize_t rtc_sysfs_show_since_epoch(struct class_device *dev, char *buf)
54{
55 ssize_t retval;
56 struct rtc_time tm;
57
58 retval = rtc_read_time(dev, &tm);
59 if (retval == 0) {
60 unsigned long time;
61 rtc_tm_to_time(&tm, &time);
62 retval = sprintf(buf, "%lu\n", time);
63 }
64
65 return retval;
66}
67static CLASS_DEVICE_ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL);
68
69static struct attribute *rtc_attrs[] = {
70 &class_device_attr_name.attr,
71 &class_device_attr_date.attr,
72 &class_device_attr_time.attr,
73 &class_device_attr_since_epoch.attr,
74 NULL,
75};
76
77static struct attribute_group rtc_attr_group = {
78 .attrs = rtc_attrs,
79};
80
81static int __devinit rtc_sysfs_add_device(struct class_device *class_dev,
82 struct class_interface *class_intf)
83{
84 int err;
85
86 dev_info(class_dev->dev, "rtc intf: sysfs\n");
87
88 err = sysfs_create_group(&class_dev->kobj, &rtc_attr_group);
89 if (err)
90 dev_err(class_dev->dev,
91 "failed to create sysfs attributes\n");
92
93 return err;
94}
95
96static void rtc_sysfs_remove_device(struct class_device *class_dev,
97 struct class_interface *class_intf)
98{
99 sysfs_remove_group(&class_dev->kobj, &rtc_attr_group);
100}
101
102/* interface registration */
103
104static struct class_interface rtc_sysfs_interface = {
105 .add = &rtc_sysfs_add_device,
106 .remove = &rtc_sysfs_remove_device,
107};
108
109static int __init rtc_sysfs_init(void)
110{
111 return rtc_interface_register(&rtc_sysfs_interface);
112}
113
114static void __exit rtc_sysfs_exit(void)
115{
116 class_interface_unregister(&rtc_sysfs_interface);
117}
118
119module_init(rtc_sysfs_init);
120module_exit(rtc_sysfs_exit);
121
122MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
123MODULE_DESCRIPTION("RTC class sysfs interface");
124MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c
new file mode 100644
index 000000000000..43d107487820
--- /dev/null
+++ b/drivers/rtc/rtc-test.c
@@ -0,0 +1,204 @@
1/*
2 * An RTC test device/driver
3 * Copyright (C) 2005 Tower Technologies
4 * Author: Alessandro Zummo <a.zummo@towertech.it>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12#include <linux/err.h>
13#include <linux/rtc.h>
14#include <linux/platform_device.h>
15
16static struct platform_device *test0 = NULL, *test1 = NULL;
17
18static int test_rtc_read_alarm(struct device *dev,
19 struct rtc_wkalrm *alrm)
20{
21 return 0;
22}
23
24static int test_rtc_set_alarm(struct device *dev,
25 struct rtc_wkalrm *alrm)
26{
27 return 0;
28}
29
30static int test_rtc_read_time(struct device *dev,
31 struct rtc_time *tm)
32{
33 rtc_time_to_tm(get_seconds(), tm);
34 return 0;
35}
36
37static int test_rtc_set_time(struct device *dev,
38 struct rtc_time *tm)
39{
40 return 0;
41}
42
43static int test_rtc_set_mmss(struct device *dev, unsigned long secs)
44{
45 return 0;
46}
47
48static int test_rtc_proc(struct device *dev, struct seq_file *seq)
49{
50 struct platform_device *plat_dev = to_platform_device(dev);
51
52 seq_printf(seq, "24hr\t\t: yes\n");
53 seq_printf(seq, "test\t\t: yes\n");
54 seq_printf(seq, "id\t\t: %d\n", plat_dev->id);
55
56 return 0;
57}
58
59static int test_rtc_ioctl(struct device *dev, unsigned int cmd,
60 unsigned long arg)
61{
62 /* We do support interrupts, they're generated
63 * using the sysfs interface.
64 */
65 switch (cmd) {
66 case RTC_PIE_ON:
67 case RTC_PIE_OFF:
68 case RTC_UIE_ON:
69 case RTC_UIE_OFF:
70 case RTC_AIE_ON:
71 case RTC_AIE_OFF:
72 return 0;
73
74 default:
75 return -EINVAL;
76 }
77}
78
79static struct rtc_class_ops test_rtc_ops = {
80 .proc = test_rtc_proc,
81 .read_time = test_rtc_read_time,
82 .set_time = test_rtc_set_time,
83 .read_alarm = test_rtc_read_alarm,
84 .set_alarm = test_rtc_set_alarm,
85 .set_mmss = test_rtc_set_mmss,
86 .ioctl = test_rtc_ioctl,
87};
88
89static ssize_t test_irq_show(struct device *dev,
90 struct device_attribute *attr, char *buf)
91{
92 return sprintf(buf, "%d\n", 42);
93}
94static ssize_t test_irq_store(struct device *dev,
95 struct device_attribute *attr,
96 const char *buf, size_t count)
97{
98 int retval;
99 struct platform_device *plat_dev = to_platform_device(dev);
100 struct rtc_device *rtc = platform_get_drvdata(plat_dev);
101
102 retval = count;
103 if (strncmp(buf, "tick", 4) == 0)
104 rtc_update_irq(&rtc->class_dev, 1, RTC_PF | RTC_IRQF);
105 else if (strncmp(buf, "alarm", 5) == 0)
106 rtc_update_irq(&rtc->class_dev, 1, RTC_AF | RTC_IRQF);
107 else if (strncmp(buf, "update", 6) == 0)
108 rtc_update_irq(&rtc->class_dev, 1, RTC_UF | RTC_IRQF);
109 else
110 retval = -EINVAL;
111
112 return retval;
113}
114static DEVICE_ATTR(irq, S_IRUGO | S_IWUSR, test_irq_show, test_irq_store);
115
116static int test_probe(struct platform_device *plat_dev)
117{
118 int err;
119 struct rtc_device *rtc = rtc_device_register("test", &plat_dev->dev,
120 &test_rtc_ops, THIS_MODULE);
121 if (IS_ERR(rtc)) {
122 err = PTR_ERR(rtc);
123 dev_err(&plat_dev->dev,
124 "unable to register the class device\n");
125 return err;
126 }
127 device_create_file(&plat_dev->dev, &dev_attr_irq);
128
129 platform_set_drvdata(plat_dev, rtc);
130
131 return 0;
132}
133
134static int __devexit test_remove(struct platform_device *plat_dev)
135{
136 struct rtc_device *rtc = platform_get_drvdata(plat_dev);
137
138 rtc_device_unregister(rtc);
139 device_remove_file(&plat_dev->dev, &dev_attr_irq);
140
141 return 0;
142}
143
144static struct platform_driver test_drv = {
145 .probe = test_probe,
146 .remove = __devexit_p(test_remove),
147 .driver = {
148 .name = "rtc-test",
149 .owner = THIS_MODULE,
150 },
151};
152
153static int __init test_init(void)
154{
155 int err;
156
157 if ((err = platform_driver_register(&test_drv)))
158 return err;
159
160 if ((test0 = platform_device_alloc("rtc-test", 0)) == NULL) {
161 err = -ENOMEM;
162 goto exit_driver_unregister;
163 }
164
165 if ((test1 = platform_device_alloc("rtc-test", 1)) == NULL) {
166 err = -ENOMEM;
167 goto exit_free_test0;
168 }
169
170 if ((err = platform_device_add(test0)))
171 goto exit_free_test1;
172
173 if ((err = platform_device_add(test1)))
174 goto exit_device_unregister;
175
176 return 0;
177
178exit_device_unregister:
179 platform_device_unregister(test0);
180
181exit_free_test1:
182 platform_device_put(test1);
183
184exit_free_test0:
185 platform_device_put(test0);
186
187exit_driver_unregister:
188 platform_driver_unregister(&test_drv);
189 return err;
190}
191
192static void __exit test_exit(void)
193{
194 platform_device_unregister(test0);
195 platform_device_unregister(test1);
196 platform_driver_unregister(&test_drv);
197}
198
199MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
200MODULE_DESCRIPTION("RTC test driver/device");
201MODULE_LICENSE("GPL");
202
203module_init(test_init);
204module_exit(test_exit);
diff --git a/drivers/i2c/chips/x1205.c b/drivers/rtc/rtc-x1205.c
index 245fffa92dbd..621d17afc0d9 100644
--- a/drivers/i2c/chips/x1205.c
+++ b/drivers/rtc/rtc-x1205.c
@@ -1,32 +1,25 @@
1/* 1/*
2 * x1205.c - An i2c driver for the Xicor X1205 RTC 2 * An i2c driver for the Xicor/Intersil X1205 RTC
3 * Copyright 2004 Karen Spearel 3 * Copyright 2004 Karen Spearel
4 * Copyright 2005 Alessandro Zummo 4 * Copyright 2005 Alessandro Zummo
5 * 5 *
6 * please send all reports to: 6 * please send all reports to:
7 * kas11 at tampabay dot rr dot com 7 * Karen Spearel <kas111 at gmail dot com>
8 * a dot zummo at towertech dot it 8 * Alessandro Zummo <a.zummo@towertech.it>
9 * 9 *
10 * based on the other drivers in this same directory. 10 * based on a lot of other RTC drivers.
11 * 11 *
12 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by 13 * it under the terms of the GNU General Public License version 2 as
14 * the Free Software Foundation; either version 2 of the License, or 14 * published by the Free Software Foundation.
15 * (at your option) any later version.
16 */ 15 */
17 16
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/slab.h>
21#include <linux/i2c.h> 17#include <linux/i2c.h>
22#include <linux/string.h>
23#include <linux/bcd.h> 18#include <linux/bcd.h>
24#include <linux/rtc.h> 19#include <linux/rtc.h>
25#include <linux/list.h> 20#include <linux/delay.h>
26 21
27#include <linux/x1205.h> 22#define DRV_VERSION "1.0.6"
28
29#define DRV_VERSION "0.9.9"
30 23
31/* Addresses to scan: none. This chip is located at 24/* Addresses to scan: none. This chip is located at
32 * 0x6f and uses a two bytes register addressing. 25 * 0x6f and uses a two bytes register addressing.
@@ -40,8 +33,6 @@ static unsigned short normal_i2c[] = { I2C_CLIENT_END };
40 33
41/* Insmod parameters */ 34/* Insmod parameters */
42I2C_CLIENT_INSMOD; 35I2C_CLIENT_INSMOD;
43I2C_CLIENT_MODULE_PARM(hctosys,
44 "Set the system time from the hardware clock upon initialization");
45 36
46/* offsets into CCR area */ 37/* offsets into CCR area */
47 38
@@ -101,107 +92,35 @@ I2C_CLIENT_MODULE_PARM(hctosys,
101static int x1205_attach(struct i2c_adapter *adapter); 92static int x1205_attach(struct i2c_adapter *adapter);
102static int x1205_detach(struct i2c_client *client); 93static int x1205_detach(struct i2c_client *client);
103static int x1205_probe(struct i2c_adapter *adapter, int address, int kind); 94static int x1205_probe(struct i2c_adapter *adapter, int address, int kind);
104static int x1205_command(struct i2c_client *client, unsigned int cmd,
105 void *arg);
106 95
107static struct i2c_driver x1205_driver = { 96static struct i2c_driver x1205_driver = {
108 .driver = { 97 .driver = {
109 .name = "x1205", 98 .name = "x1205",
110 }, 99 },
100 .id = I2C_DRIVERID_X1205,
111 .attach_adapter = &x1205_attach, 101 .attach_adapter = &x1205_attach,
112 .detach_client = &x1205_detach, 102 .detach_client = &x1205_detach,
113}; 103};
114 104
115struct x1205_data {
116 struct i2c_client client;
117 struct list_head list;
118 unsigned int epoch;
119};
120
121static const unsigned char days_in_mo[] =
122 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
123
124static LIST_HEAD(x1205_clients);
125
126/* Workaround until the I2C subsytem will allow to send
127 * commands to a specific client. This function will send the command
128 * to the first client.
129 */
130int x1205_do_command(unsigned int cmd, void *arg)
131{
132 struct list_head *walk;
133 struct list_head *tmp;
134 struct x1205_data *data;
135
136 list_for_each_safe(walk, tmp, &x1205_clients) {
137 data = list_entry(walk, struct x1205_data, list);
138 return x1205_command(&data->client, cmd, arg);
139 }
140
141 return -ENODEV;
142}
143
144#define is_leap(year) \
145 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
146
147/* make sure the rtc_time values are in bounds */
148static int x1205_validate_tm(struct rtc_time *tm)
149{
150 int year = tm->tm_year + 1900;
151
152 if ((tm->tm_year < 70) || (tm->tm_year > 255))
153 return -EINVAL;
154
155 if ((tm->tm_mon > 11) || (tm->tm_mday == 0))
156 return -EINVAL;
157
158 if (tm->tm_mday > days_in_mo[tm->tm_mon]
159 + ((tm->tm_mon == 1) && is_leap(year)))
160 return -EINVAL;
161
162 if ((tm->tm_hour >= 24) || (tm->tm_min >= 60) || (tm->tm_sec >= 60))
163 return -EINVAL;
164
165 return 0;
166}
167
168/* 105/*
169 * In the routines that deal directly with the x1205 hardware, we use 106 * In the routines that deal directly with the x1205 hardware, we use
170 * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch 107 * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch
171 * Epoch is initialized as 2000. Time is set to UTC. 108 * Epoch is initialized as 2000. Time is set to UTC.
172 */ 109 */
173static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm, 110static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm,
174 u8 reg_base) 111 unsigned char reg_base)
175{ 112{
176 unsigned char dt_addr[2] = { 0, reg_base }; 113 unsigned char dt_addr[2] = { 0, reg_base };
177 static unsigned char sr_addr[2] = { 0, X1205_REG_SR };
178 114
179 unsigned char buf[8], sr; 115 unsigned char buf[8];
180 116
181 struct i2c_msg msgs[] = { 117 struct i2c_msg msgs[] = {
182 { client->addr, 0, 2, sr_addr }, /* setup read ptr */
183 { client->addr, I2C_M_RD, 1, &sr }, /* read status */
184 { client->addr, 0, 2, dt_addr }, /* setup read ptr */ 118 { client->addr, 0, 2, dt_addr }, /* setup read ptr */
185 { client->addr, I2C_M_RD, 8, buf }, /* read date */ 119 { client->addr, I2C_M_RD, 8, buf }, /* read date */
186 }; 120 };
187 121
188 struct x1205_data *data = i2c_get_clientdata(client);
189
190 /* read status register */
191 if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
192 dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
193 return -EIO;
194 }
195
196 /* check for battery failure */
197 if (sr & X1205_SR_RTCF) {
198 dev_warn(&client->dev,
199 "Clock had a power failure, you must set the date.\n");
200 return -EINVAL;
201 }
202
203 /* read date registers */ 122 /* read date registers */
204 if ((i2c_transfer(client->adapter, &msgs[2], 2)) != 2) { 123 if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
205 dev_err(&client->dev, "%s: read error\n", __FUNCTION__); 124 dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
206 return -EIO; 125 return -EIO;
207 } 126 }
@@ -217,9 +136,9 @@ static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm,
217 tm->tm_min = BCD2BIN(buf[CCR_MIN]); 136 tm->tm_min = BCD2BIN(buf[CCR_MIN]);
218 tm->tm_hour = BCD2BIN(buf[CCR_HOUR] & 0x3F); /* hr is 0-23 */ 137 tm->tm_hour = BCD2BIN(buf[CCR_HOUR] & 0x3F); /* hr is 0-23 */
219 tm->tm_mday = BCD2BIN(buf[CCR_MDAY]); 138 tm->tm_mday = BCD2BIN(buf[CCR_MDAY]);
220 tm->tm_mon = BCD2BIN(buf[CCR_MONTH]); 139 tm->tm_mon = BCD2BIN(buf[CCR_MONTH]) - 1; /* mon is 0-11 */
221 data->epoch = BCD2BIN(buf[CCR_Y2K]) * 100; 140 tm->tm_year = BCD2BIN(buf[CCR_YEAR])
222 tm->tm_year = BCD2BIN(buf[CCR_YEAR]) + data->epoch - 1900; 141 + (BCD2BIN(buf[CCR_Y2K]) * 100) - 1900;
223 tm->tm_wday = buf[CCR_WDAY]; 142 tm->tm_wday = buf[CCR_WDAY];
224 143
225 dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " 144 dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
@@ -231,11 +150,28 @@ static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm,
231 return 0; 150 return 0;
232} 151}
233 152
153static int x1205_get_status(struct i2c_client *client, unsigned char *sr)
154{
155 static unsigned char sr_addr[2] = { 0, X1205_REG_SR };
156
157 struct i2c_msg msgs[] = {
158 { client->addr, 0, 2, sr_addr }, /* setup read ptr */
159 { client->addr, I2C_M_RD, 1, sr }, /* read status */
160 };
161
162 /* read status register */
163 if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
164 dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
165 return -EIO;
166 }
167
168 return 0;
169}
170
234static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm, 171static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm,
235 int datetoo, u8 reg_base) 172 int datetoo, u8 reg_base)
236{ 173{
237 int i, err, xfer; 174 int i, xfer;
238
239 unsigned char buf[8]; 175 unsigned char buf[8];
240 176
241 static const unsigned char wel[3] = { 0, X1205_REG_SR, 177 static const unsigned char wel[3] = { 0, X1205_REG_SR,
@@ -246,17 +182,10 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm,
246 182
247 static const unsigned char diswe[3] = { 0, X1205_REG_SR, 0 }; 183 static const unsigned char diswe[3] = { 0, X1205_REG_SR, 0 };
248 184
249 struct x1205_data *data = i2c_get_clientdata(client); 185 dev_dbg(&client->dev,
250 186 "%s: secs=%d, mins=%d, hours=%d\n",
251 /* check if all values in the tm struct are correct */
252 if ((err = x1205_validate_tm(tm)) < 0)
253 return err;
254
255 dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
256 "mday=%d, mon=%d, year=%d, wday=%d\n",
257 __FUNCTION__, 187 __FUNCTION__,
258 tm->tm_sec, tm->tm_min, tm->tm_hour, 188 tm->tm_sec, tm->tm_min, tm->tm_hour);
259 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
260 189
261 buf[CCR_SEC] = BIN2BCD(tm->tm_sec); 190 buf[CCR_SEC] = BIN2BCD(tm->tm_sec);
262 buf[CCR_MIN] = BIN2BCD(tm->tm_min); 191 buf[CCR_MIN] = BIN2BCD(tm->tm_min);
@@ -266,26 +195,29 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm,
266 195
267 /* should we also set the date? */ 196 /* should we also set the date? */
268 if (datetoo) { 197 if (datetoo) {
198 dev_dbg(&client->dev,
199 "%s: mday=%d, mon=%d, year=%d, wday=%d\n",
200 __FUNCTION__,
201 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
202
269 buf[CCR_MDAY] = BIN2BCD(tm->tm_mday); 203 buf[CCR_MDAY] = BIN2BCD(tm->tm_mday);
270 204
271 /* month, 0 - 11 */ 205 /* month, 1 - 12 */
272 buf[CCR_MONTH] = BIN2BCD(tm->tm_mon); 206 buf[CCR_MONTH] = BIN2BCD(tm->tm_mon + 1);
273 207
274 /* year, since 1900 */ 208 /* year, since the rtc epoch*/
275 buf[CCR_YEAR] = BIN2BCD(tm->tm_year + 1900 - data->epoch); 209 buf[CCR_YEAR] = BIN2BCD(tm->tm_year % 100);
276 buf[CCR_WDAY] = tm->tm_wday & 0x07; 210 buf[CCR_WDAY] = tm->tm_wday & 0x07;
277 buf[CCR_Y2K] = BIN2BCD(data->epoch / 100); 211 buf[CCR_Y2K] = BIN2BCD(tm->tm_year / 100);
278 } 212 }
279 213
280 /* this sequence is required to unlock the chip */ 214 /* this sequence is required to unlock the chip */
281 xfer = i2c_master_send(client, wel, 3); 215 if ((xfer = i2c_master_send(client, wel, 3)) != 3) {
282 if (xfer != 3) {
283 dev_err(&client->dev, "%s: wel - %d\n", __FUNCTION__, xfer); 216 dev_err(&client->dev, "%s: wel - %d\n", __FUNCTION__, xfer);
284 return -EIO; 217 return -EIO;
285 } 218 }
286 219
287 xfer = i2c_master_send(client, rwel, 3); 220 if ((xfer = i2c_master_send(client, rwel, 3)) != 3) {
288 if (xfer != 3) {
289 dev_err(&client->dev, "%s: rwel - %d\n", __FUNCTION__, xfer); 221 dev_err(&client->dev, "%s: rwel - %d\n", __FUNCTION__, xfer);
290 return -EIO; 222 return -EIO;
291 } 223 }
@@ -305,8 +237,7 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm,
305 }; 237 };
306 238
307 /* disable further writes */ 239 /* disable further writes */
308 xfer = i2c_master_send(client, diswe, 3); 240 if ((xfer = i2c_master_send(client, diswe, 3)) != 3) {
309 if (xfer != 3) {
310 dev_err(&client->dev, "%s: diswe - %d\n", __FUNCTION__, xfer); 241 dev_err(&client->dev, "%s: diswe - %d\n", __FUNCTION__, xfer);
311 return -EIO; 242 return -EIO;
312 } 243 }
@@ -314,6 +245,20 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm,
314 return 0; 245 return 0;
315} 246}
316 247
248static int x1205_fix_osc(struct i2c_client *client)
249{
250 int err;
251 struct rtc_time tm;
252
253 tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
254
255 if ((err = x1205_set_datetime(client, &tm, 0, X1205_CCR_BASE)) < 0)
256 dev_err(&client->dev,
257 "unable to restart the oscillator\n");
258
259 return err;
260}
261
317static int x1205_get_dtrim(struct i2c_client *client, int *trim) 262static int x1205_get_dtrim(struct i2c_client *client, int *trim)
318{ 263{
319 unsigned char dtr; 264 unsigned char dtr;
@@ -380,60 +325,9 @@ static int x1205_get_atrim(struct i2c_client *client, int *trim)
380 return 0; 325 return 0;
381} 326}
382 327
383static int x1205_hctosys(struct i2c_client *client)
384{
385 int err;
386
387 struct rtc_time tm;
388 struct timespec tv;
389
390 err = x1205_command(client, X1205_CMD_GETDATETIME, &tm);
391
392 if (err) {
393 dev_err(&client->dev,
394 "Unable to set the system clock\n");
395 return err;
396 }
397
398 /* IMPORTANT: the RTC only stores whole seconds. It is arbitrary
399 * whether it stores the most close value or the value with partial
400 * seconds truncated. However, it is important that we use it to store
401 * the truncated value. This is because otherwise it is necessary,
402 * in an rtc sync function, to read both xtime.tv_sec and
403 * xtime.tv_nsec. On some processors (i.e. ARM), an atomic read
404 * of >32bits is not possible. So storing the most close value would
405 * slow down the sync API. So here we have the truncated value and
406 * the best guess is to add 0.5s.
407 */
408
409 tv.tv_nsec = NSEC_PER_SEC >> 1;
410
411 /* WARNING: this is not the C library 'mktime' call, it is a built in
412 * inline function from include/linux/time.h. It expects (requires)
413 * the month to be in the range 1-12
414 */
415
416 tv.tv_sec = mktime(tm.tm_year + 1900, tm.tm_mon + 1,
417 tm.tm_mday, tm.tm_hour,
418 tm.tm_min, tm.tm_sec);
419
420 do_settimeofday(&tv);
421
422 dev_info(&client->dev,
423 "setting the system clock to %d-%d-%d %d:%d:%d\n",
424 tm.tm_year + 1900, tm.tm_mon + 1,
425 tm.tm_mday, tm.tm_hour, tm.tm_min,
426 tm.tm_sec);
427
428 return 0;
429}
430
431struct x1205_limit 328struct x1205_limit
432{ 329{
433 unsigned char reg; 330 unsigned char reg, mask, min, max;
434 unsigned char mask;
435 unsigned char min;
436 unsigned char max;
437}; 331};
438 332
439static int x1205_validate_client(struct i2c_client *client) 333static int x1205_validate_client(struct i2c_client *client)
@@ -477,11 +371,10 @@ static int x1205_validate_client(struct i2c_client *client)
477 { client->addr, I2C_M_RD, 1, &buf }, 371 { client->addr, I2C_M_RD, 1, &buf },
478 }; 372 };
479 373
480 xfer = i2c_transfer(client->adapter, msgs, 2); 374 if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) {
481 if (xfer != 2) {
482 dev_err(&client->adapter->dev, 375 dev_err(&client->adapter->dev,
483 "%s: could not read register %x\n", 376 "%s: could not read register %x\n",
484 __FUNCTION__, addr[1]); 377 __FUNCTION__, probe_zero_pattern[i]);
485 378
486 return -EIO; 379 return -EIO;
487 } 380 }
@@ -489,7 +382,7 @@ static int x1205_validate_client(struct i2c_client *client)
489 if ((buf & probe_zero_pattern[i+1]) != 0) { 382 if ((buf & probe_zero_pattern[i+1]) != 0) {
490 dev_err(&client->adapter->dev, 383 dev_err(&client->adapter->dev,
491 "%s: register=%02x, zero pattern=%d, value=%x\n", 384 "%s: register=%02x, zero pattern=%d, value=%x\n",
492 __FUNCTION__, addr[1], i, buf); 385 __FUNCTION__, probe_zero_pattern[i], i, buf);
493 386
494 return -ENODEV; 387 return -ENODEV;
495 } 388 }
@@ -506,12 +399,10 @@ static int x1205_validate_client(struct i2c_client *client)
506 { client->addr, I2C_M_RD, 1, &reg }, 399 { client->addr, I2C_M_RD, 1, &reg },
507 }; 400 };
508 401
509 xfer = i2c_transfer(client->adapter, msgs, 2); 402 if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) {
510
511 if (xfer != 2) {
512 dev_err(&client->adapter->dev, 403 dev_err(&client->adapter->dev,
513 "%s: could not read register %x\n", 404 "%s: could not read register %x\n",
514 __FUNCTION__, addr[1]); 405 __FUNCTION__, probe_limits_pattern[i].reg);
515 406
516 return -EIO; 407 return -EIO;
517 } 408 }
@@ -522,7 +413,8 @@ static int x1205_validate_client(struct i2c_client *client)
522 value < probe_limits_pattern[i].min) { 413 value < probe_limits_pattern[i].min) {
523 dev_dbg(&client->adapter->dev, 414 dev_dbg(&client->adapter->dev,
524 "%s: register=%x, lim pattern=%d, value=%d\n", 415 "%s: register=%x, lim pattern=%d, value=%d\n",
525 __FUNCTION__, addr[1], i, value); 416 __FUNCTION__, probe_limits_pattern[i].reg,
417 i, value);
526 418
527 return -ENODEV; 419 return -ENODEV;
528 } 420 }
@@ -531,37 +423,89 @@ static int x1205_validate_client(struct i2c_client *client)
531 return 0; 423 return 0;
532} 424}
533 425
534static int x1205_attach(struct i2c_adapter *adapter) 426static int x1205_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
535{ 427{
536 dev_dbg(&adapter->dev, "%s\n", __FUNCTION__); 428 return x1205_get_datetime(to_i2c_client(dev),
429 &alrm->time, X1205_ALM0_BASE);
430}
537 431
538 return i2c_probe(adapter, &addr_data, x1205_probe); 432static int x1205_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
433{
434 return x1205_set_datetime(to_i2c_client(dev),
435 &alrm->time, 1, X1205_ALM0_BASE);
539} 436}
540 437
541int x1205_direct_attach(int adapter_id, 438static int x1205_rtc_read_time(struct device *dev, struct rtc_time *tm)
542 struct i2c_client_address_data *address_data)
543{ 439{
544 int err; 440 return x1205_get_datetime(to_i2c_client(dev),
545 struct i2c_adapter *adapter = i2c_get_adapter(adapter_id); 441 tm, X1205_CCR_BASE);
442}
546 443
547 if (adapter) { 444static int x1205_rtc_set_time(struct device *dev, struct rtc_time *tm)
548 err = i2c_probe(adapter, 445{
549 address_data, x1205_probe); 446 return x1205_set_datetime(to_i2c_client(dev),
447 tm, 1, X1205_CCR_BASE);
448}
550 449
551 i2c_put_adapter(adapter); 450static int x1205_rtc_proc(struct device *dev, struct seq_file *seq)
451{
452 int err, dtrim, atrim;
552 453
553 return err; 454 seq_printf(seq, "24hr\t\t: yes\n");
554 }
555 455
556 return -ENODEV; 456 if ((err = x1205_get_dtrim(to_i2c_client(dev), &dtrim)) == 0)
457 seq_printf(seq, "digital_trim\t: %d ppm\n", dtrim);
458
459 if ((err = x1205_get_atrim(to_i2c_client(dev), &atrim)) == 0)
460 seq_printf(seq, "analog_trim\t: %d.%02d pF\n",
461 atrim / 1000, atrim % 1000);
462 return 0;
557} 463}
558 464
559static int x1205_probe(struct i2c_adapter *adapter, int address, int kind) 465static struct rtc_class_ops x1205_rtc_ops = {
466 .proc = x1205_rtc_proc,
467 .read_time = x1205_rtc_read_time,
468 .set_time = x1205_rtc_set_time,
469 .read_alarm = x1205_rtc_read_alarm,
470 .set_alarm = x1205_rtc_set_alarm,
471};
472
473static ssize_t x1205_sysfs_show_atrim(struct device *dev,
474 struct device_attribute *attr, char *buf)
560{ 475{
561 struct i2c_client *client; 476 int atrim;
562 struct x1205_data *data; 477
478 if (x1205_get_atrim(to_i2c_client(dev), &atrim) == 0)
479 return sprintf(buf, "%d.%02d pF\n",
480 atrim / 1000, atrim % 1000);
481 return 0;
482}
483static DEVICE_ATTR(atrim, S_IRUGO, x1205_sysfs_show_atrim, NULL);
484
485static ssize_t x1205_sysfs_show_dtrim(struct device *dev,
486 struct device_attribute *attr, char *buf)
487{
488 int dtrim;
489
490 if (x1205_get_dtrim(to_i2c_client(dev), &dtrim) == 0)
491 return sprintf(buf, "%d ppm\n", dtrim);
492
493 return 0;
494}
495static DEVICE_ATTR(dtrim, S_IRUGO, x1205_sysfs_show_dtrim, NULL);
563 496
497static int x1205_attach(struct i2c_adapter *adapter)
498{
499 dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
500 return i2c_probe(adapter, &addr_data, x1205_probe);
501}
502
503static int x1205_probe(struct i2c_adapter *adapter, int address, int kind)
504{
564 int err = 0; 505 int err = 0;
506 unsigned char sr;
507 struct i2c_client *client;
508 struct rtc_device *rtc;
565 509
566 dev_dbg(&adapter->dev, "%s\n", __FUNCTION__); 510 dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
567 511
@@ -570,22 +514,17 @@ static int x1205_probe(struct i2c_adapter *adapter, int address, int kind)
570 goto exit; 514 goto exit;
571 } 515 }
572 516
573 if (!(data = kzalloc(sizeof(struct x1205_data), GFP_KERNEL))) { 517 if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
574 err = -ENOMEM; 518 err = -ENOMEM;
575 goto exit; 519 goto exit;
576 } 520 }
577 521
578 /* Initialize our structures */ 522 /* I2C client */
579 data->epoch = 2000;
580
581 client = &data->client;
582 client->addr = address; 523 client->addr = address;
583 client->driver = &x1205_driver; 524 client->driver = &x1205_driver;
584 client->adapter = adapter; 525 client->adapter = adapter;
585 526
586 strlcpy(client->name, "x1205", I2C_NAME_SIZE); 527 strlcpy(client->name, x1205_driver.driver.name, I2C_NAME_SIZE);
587
588 i2c_set_clientdata(client, data);
589 528
590 /* Verify the chip is really an X1205 */ 529 /* Verify the chip is really an X1205 */
591 if (kind < 0) { 530 if (kind < 0) {
@@ -599,18 +538,43 @@ static int x1205_probe(struct i2c_adapter *adapter, int address, int kind)
599 if ((err = i2c_attach_client(client))) 538 if ((err = i2c_attach_client(client)))
600 goto exit_kfree; 539 goto exit_kfree;
601 540
602 list_add(&data->list, &x1205_clients);
603
604 dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); 541 dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
605 542
606 /* If requested, set the system time */ 543 rtc = rtc_device_register(x1205_driver.driver.name, &client->dev,
607 if (hctosys) 544 &x1205_rtc_ops, THIS_MODULE);
608 x1205_hctosys(client); 545
546 if (IS_ERR(rtc)) {
547 err = PTR_ERR(rtc);
548 dev_err(&client->dev,
549 "unable to register the class device\n");
550 goto exit_detach;
551 }
552
553 i2c_set_clientdata(client, rtc);
554
555 /* Check for power failures and eventualy enable the osc */
556 if ((err = x1205_get_status(client, &sr)) == 0) {
557 if (sr & X1205_SR_RTCF) {
558 dev_err(&client->dev,
559 "power failure detected, "
560 "please set the clock\n");
561 udelay(50);
562 x1205_fix_osc(client);
563 }
564 }
565 else
566 dev_err(&client->dev, "couldn't read status\n");
567
568 device_create_file(&client->dev, &dev_attr_atrim);
569 device_create_file(&client->dev, &dev_attr_dtrim);
609 570
610 return 0; 571 return 0;
611 572
573exit_detach:
574 i2c_detach_client(client);
575
612exit_kfree: 576exit_kfree:
613 kfree(data); 577 kfree(client);
614 578
615exit: 579exit:
616 return err; 580 return err;
@@ -619,61 +583,21 @@ exit:
619static int x1205_detach(struct i2c_client *client) 583static int x1205_detach(struct i2c_client *client)
620{ 584{
621 int err; 585 int err;
622 struct x1205_data *data = i2c_get_clientdata(client); 586 struct rtc_device *rtc = i2c_get_clientdata(client);
623 587
624 dev_dbg(&client->dev, "%s\n", __FUNCTION__); 588 dev_dbg(&client->dev, "%s\n", __FUNCTION__);
625 589
590 if (rtc)
591 rtc_device_unregister(rtc);
592
626 if ((err = i2c_detach_client(client))) 593 if ((err = i2c_detach_client(client)))
627 return err; 594 return err;
628 595
629 list_del(&data->list); 596 kfree(client);
630
631 kfree(data);
632 597
633 return 0; 598 return 0;
634} 599}
635 600
636static int x1205_command(struct i2c_client *client, unsigned int cmd,
637 void *param)
638{
639 if (param == NULL)
640 return -EINVAL;
641
642 if (!capable(CAP_SYS_TIME))
643 return -EACCES;
644
645 dev_dbg(&client->dev, "%s: cmd=%d\n", __FUNCTION__, cmd);
646
647 switch (cmd) {
648 case X1205_CMD_GETDATETIME:
649 return x1205_get_datetime(client, param, X1205_CCR_BASE);
650
651 case X1205_CMD_SETTIME:
652 return x1205_set_datetime(client, param, 0,
653 X1205_CCR_BASE);
654
655 case X1205_CMD_SETDATETIME:
656 return x1205_set_datetime(client, param, 1,
657 X1205_CCR_BASE);
658
659 case X1205_CMD_GETALARM:
660 return x1205_get_datetime(client, param, X1205_ALM0_BASE);
661
662 case X1205_CMD_SETALARM:
663 return x1205_set_datetime(client, param, 1,
664 X1205_ALM0_BASE);
665
666 case X1205_CMD_GETDTRIM:
667 return x1205_get_dtrim(client, param);
668
669 case X1205_CMD_GETATRIM:
670 return x1205_get_atrim(client, param);
671
672 default:
673 return -EINVAL;
674 }
675}
676
677static int __init x1205_init(void) 601static int __init x1205_init(void)
678{ 602{
679 return i2c_add_driver(&x1205_driver); 603 return i2c_add_driver(&x1205_driver);
@@ -685,14 +609,11 @@ static void __exit x1205_exit(void)
685} 609}
686 610
687MODULE_AUTHOR( 611MODULE_AUTHOR(
688 "Karen Spearel <kas11@tampabay.rr.com>, " 612 "Karen Spearel <kas111 at gmail dot com>, "
689 "Alessandro Zummo <a.zummo@towertech.it>"); 613 "Alessandro Zummo <a.zummo@towertech.it>");
690MODULE_DESCRIPTION("Xicor X1205 RTC driver"); 614MODULE_DESCRIPTION("Xicor/Intersil X1205 RTC driver");
691MODULE_LICENSE("GPL"); 615MODULE_LICENSE("GPL");
692MODULE_VERSION(DRV_VERSION); 616MODULE_VERSION(DRV_VERSION);
693 617
694EXPORT_SYMBOL_GPL(x1205_do_command);
695EXPORT_SYMBOL_GPL(x1205_direct_attach);
696
697module_init(x1205_init); 618module_init(x1205_init);
698module_exit(x1205_exit); 619module_exit(x1205_exit);
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 62e3cda859af..7f7013e80a88 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -671,7 +671,7 @@ static struct file_operations gdth_fops = {
671static struct notifier_block gdth_notifier = { 671static struct notifier_block gdth_notifier = {
672 gdth_halt, NULL, 0 672 gdth_halt, NULL, 0
673}; 673};
674 674static int notifier_disabled = 0;
675 675
676static void gdth_delay(int milliseconds) 676static void gdth_delay(int milliseconds)
677{ 677{
@@ -4595,13 +4595,13 @@ static int __init gdth_detect(struct scsi_host_template *shtp)
4595 add_timer(&gdth_timer); 4595 add_timer(&gdth_timer);
4596#endif 4596#endif
4597 major = register_chrdev(0,"gdth",&gdth_fops); 4597 major = register_chrdev(0,"gdth",&gdth_fops);
4598 notifier_disabled = 0;
4598 register_reboot_notifier(&gdth_notifier); 4599 register_reboot_notifier(&gdth_notifier);
4599 } 4600 }
4600 gdth_polling = FALSE; 4601 gdth_polling = FALSE;
4601 return gdth_ctr_vcount; 4602 return gdth_ctr_vcount;
4602} 4603}
4603 4604
4604
4605static int gdth_release(struct Scsi_Host *shp) 4605static int gdth_release(struct Scsi_Host *shp)
4606{ 4606{
4607 int hanum; 4607 int hanum;
@@ -5632,10 +5632,14 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf)
5632 char cmnd[MAX_COMMAND_SIZE]; 5632 char cmnd[MAX_COMMAND_SIZE];
5633#endif 5633#endif
5634 5634
5635 if (notifier_disabled)
5636 return NOTIFY_OK;
5637
5635 TRACE2(("gdth_halt() event %d\n",(int)event)); 5638 TRACE2(("gdth_halt() event %d\n",(int)event));
5636 if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF) 5639 if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF)
5637 return NOTIFY_DONE; 5640 return NOTIFY_DONE;
5638 5641
5642 notifier_disabled = 1;
5639 printk("GDT-HA: Flushing all host drives .. "); 5643 printk("GDT-HA: Flushing all host drives .. ");
5640 for (hanum = 0; hanum < gdth_ctr_count; ++hanum) { 5644 for (hanum = 0; hanum < gdth_ctr_count; ++hanum) {
5641 gdth_flush(hanum); 5645 gdth_flush(hanum);
@@ -5679,7 +5683,6 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf)
5679#ifdef GDTH_STATISTICS 5683#ifdef GDTH_STATISTICS
5680 del_timer(&gdth_timer); 5684 del_timer(&gdth_timer);
5681#endif 5685#endif
5682 unregister_reboot_notifier(&gdth_notifier);
5683 return NOTIFY_OK; 5686 return NOTIFY_OK;
5684} 5687}
5685 5688
diff --git a/drivers/usb/core/notify.c b/drivers/usb/core/notify.c
index 4b55285de9a0..fe0ed54fa0ae 100644
--- a/drivers/usb/core/notify.c
+++ b/drivers/usb/core/notify.c
@@ -16,57 +16,7 @@
16#include <linux/mutex.h> 16#include <linux/mutex.h>
17#include "usb.h" 17#include "usb.h"
18 18
19 19static BLOCKING_NOTIFIER_HEAD(usb_notifier_list);
20static struct notifier_block *usb_notifier_list;
21static DEFINE_MUTEX(usb_notifier_lock);
22
23static void usb_notifier_chain_register(struct notifier_block **list,
24 struct notifier_block *n)
25{
26 mutex_lock(&usb_notifier_lock);
27 while (*list) {
28 if (n->priority > (*list)->priority)
29 break;
30 list = &((*list)->next);
31 }
32 n->next = *list;
33 *list = n;
34 mutex_unlock(&usb_notifier_lock);
35}
36
37static void usb_notifier_chain_unregister(struct notifier_block **nl,
38 struct notifier_block *n)
39{
40 mutex_lock(&usb_notifier_lock);
41 while ((*nl)!=NULL) {
42 if ((*nl)==n) {
43 *nl = n->next;
44 goto exit;
45 }
46 nl=&((*nl)->next);
47 }
48exit:
49 mutex_unlock(&usb_notifier_lock);
50}
51
52static int usb_notifier_call_chain(struct notifier_block **n,
53 unsigned long val, void *v)
54{
55 int ret=NOTIFY_DONE;
56 struct notifier_block *nb = *n;
57
58 mutex_lock(&usb_notifier_lock);
59 while (nb) {
60 ret = nb->notifier_call(nb,val,v);
61 if (ret&NOTIFY_STOP_MASK) {
62 goto exit;
63 }
64 nb = nb->next;
65 }
66exit:
67 mutex_unlock(&usb_notifier_lock);
68 return ret;
69}
70 20
71/** 21/**
72 * usb_register_notify - register a notifier callback whenever a usb change happens 22 * usb_register_notify - register a notifier callback whenever a usb change happens
@@ -76,7 +26,7 @@ exit:
76 */ 26 */
77void usb_register_notify(struct notifier_block *nb) 27void usb_register_notify(struct notifier_block *nb)
78{ 28{
79 usb_notifier_chain_register(&usb_notifier_list, nb); 29 blocking_notifier_chain_register(&usb_notifier_list, nb);
80} 30}
81EXPORT_SYMBOL_GPL(usb_register_notify); 31EXPORT_SYMBOL_GPL(usb_register_notify);
82 32
@@ -89,27 +39,28 @@ EXPORT_SYMBOL_GPL(usb_register_notify);
89 */ 39 */
90void usb_unregister_notify(struct notifier_block *nb) 40void usb_unregister_notify(struct notifier_block *nb)
91{ 41{
92 usb_notifier_chain_unregister(&usb_notifier_list, nb); 42 blocking_notifier_chain_unregister(&usb_notifier_list, nb);
93} 43}
94EXPORT_SYMBOL_GPL(usb_unregister_notify); 44EXPORT_SYMBOL_GPL(usb_unregister_notify);
95 45
96 46
97void usb_notify_add_device(struct usb_device *udev) 47void usb_notify_add_device(struct usb_device *udev)
98{ 48{
99 usb_notifier_call_chain(&usb_notifier_list, USB_DEVICE_ADD, udev); 49 blocking_notifier_call_chain(&usb_notifier_list, USB_DEVICE_ADD, udev);
100} 50}
101 51
102void usb_notify_remove_device(struct usb_device *udev) 52void usb_notify_remove_device(struct usb_device *udev)
103{ 53{
104 usb_notifier_call_chain(&usb_notifier_list, USB_DEVICE_REMOVE, udev); 54 blocking_notifier_call_chain(&usb_notifier_list,
55 USB_DEVICE_REMOVE, udev);
105} 56}
106 57
107void usb_notify_add_bus(struct usb_bus *ubus) 58void usb_notify_add_bus(struct usb_bus *ubus)
108{ 59{
109 usb_notifier_call_chain(&usb_notifier_list, USB_BUS_ADD, ubus); 60 blocking_notifier_call_chain(&usb_notifier_list, USB_BUS_ADD, ubus);
110} 61}
111 62
112void usb_notify_remove_bus(struct usb_bus *ubus) 63void usb_notify_remove_bus(struct usb_bus *ubus)
113{ 64{
114 usb_notifier_call_chain(&usb_notifier_list, USB_BUS_REMOVE, ubus); 65 blocking_notifier_call_chain(&usb_notifier_list, USB_BUS_REMOVE, ubus);
115} 66}
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index fdebd60a3250..22e9d696fdd2 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -70,6 +70,22 @@ config FB_MACMODES
70 depends on FB 70 depends on FB
71 default n 71 default n
72 72
73config FB_FIRMWARE_EDID
74 bool "Enable firmware EDID"
75 depends on FB
76 default y
77 ---help---
78 This enables access to the EDID transferred from the firmware.
79 On the i386, this is from the Video BIOS. Enable this if DDC/I2C
80 transfers do not work for your driver and if you are using
81 nvidiafb, i810fb or savagefb.
82
83 In general, choosing Y for this option is safe. If you
84 experience extremely long delays while booting before you get
85 something on your display, try setting this to N. Matrox cards in
86 combination with certain motherboards and monitors are known to
87 suffer from this problem.
88
73config FB_MODE_HELPERS 89config FB_MODE_HELPERS
74 bool "Enable Video Mode Handling Helpers" 90 bool "Enable Video Mode Handling Helpers"
75 depends on FB 91 depends on FB
@@ -1202,6 +1218,17 @@ config FB_AU1100
1202 bool "Au1100 LCD Driver" 1218 bool "Au1100 LCD Driver"
1203 depends on (FB = y) && EXPERIMENTAL && PCI && MIPS && MIPS_PB1100=y 1219 depends on (FB = y) && EXPERIMENTAL && PCI && MIPS && MIPS_PB1100=y
1204 1220
1221config FB_AU1200
1222 bool "Au1200 LCD Driver"
1223 depends on FB && MIPS && SOC_AU1200
1224 select FB_CFB_FILLRECT
1225 select FB_CFB_COPYAREA
1226 select FB_CFB_IMAGEBLIT
1227 help
1228 This is the framebuffer driver for the AMD Au1200 SOC. It can drive
1229 various panels and CRTs by passing in kernel cmd line option
1230 au1200fb:panel=<name>.
1231
1205source "drivers/video/geode/Kconfig" 1232source "drivers/video/geode/Kconfig"
1206 1233
1207config FB_FFB 1234config FB_FFB
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index aa434e725c0d..cb90218515ac 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -86,6 +86,7 @@ obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o
86obj-$(CONFIG_FB_PXA) += pxafb.o 86obj-$(CONFIG_FB_PXA) += pxafb.o
87obj-$(CONFIG_FB_W100) += w100fb.o 87obj-$(CONFIG_FB_W100) += w100fb.o
88obj-$(CONFIG_FB_AU1100) += au1100fb.o 88obj-$(CONFIG_FB_AU1100) += au1100fb.o
89obj-$(CONFIG_FB_AU1200) += au1200fb.o
89obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o 90obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o
90obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o 91obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o
91obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o 92obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o
diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c
index 76448d6ae896..98baecccb3fd 100644
--- a/drivers/video/acornfb.c
+++ b/drivers/video/acornfb.c
@@ -1308,7 +1308,7 @@ static int __init acornfb_probe(struct platform_device *dev)
1308 /* 1308 /*
1309 * Try to select a suitable default mode 1309 * Try to select a suitable default mode
1310 */ 1310 */
1311 for (i = 0; i < sizeof(modedb) / sizeof(*modedb); i++) { 1311 for (i = 0; i < ARRAY_SIZE(modedb); i++) {
1312 unsigned long hs; 1312 unsigned long hs;
1313 1313
1314 hs = modedb[i].refresh * 1314 hs = modedb[i].refresh *
@@ -1380,7 +1380,7 @@ static int __init acornfb_probe(struct platform_device *dev)
1380 */ 1380 */
1381 free_unused_pages(PAGE_OFFSET + size, PAGE_OFFSET + MAX_SIZE); 1381 free_unused_pages(PAGE_OFFSET + size, PAGE_OFFSET + MAX_SIZE);
1382#endif 1382#endif
1383 1383
1384 fb_info.fix.smem_len = size; 1384 fb_info.fix.smem_len = size;
1385 current_par.palette_size = VIDC_PALETTE_SIZE; 1385 current_par.palette_size = VIDC_PALETTE_SIZE;
1386 1386
@@ -1391,7 +1391,7 @@ static int __init acornfb_probe(struct platform_device *dev)
1391 */ 1391 */
1392 do { 1392 do {
1393 rc = fb_find_mode(&fb_info.var, &fb_info, NULL, modedb, 1393 rc = fb_find_mode(&fb_info.var, &fb_info, NULL, modedb,
1394 sizeof(modedb) / sizeof(*modedb), 1394 ARRAY_SIZE(modedb),
1395 &acornfb_default_mode, DEFAULT_BPP); 1395 &acornfb_default_mode, DEFAULT_BPP);
1396 /* 1396 /*
1397 * If we found an exact match, all ok. 1397 * If we found an exact match, all ok.
@@ -1408,7 +1408,7 @@ static int __init acornfb_probe(struct platform_device *dev)
1408 break; 1408 break;
1409 1409
1410 rc = fb_find_mode(&fb_info.var, &fb_info, NULL, modedb, 1410 rc = fb_find_mode(&fb_info.var, &fb_info, NULL, modedb,
1411 sizeof(modedb) / sizeof(*modedb), 1411 ARRAY_SIZE(modedb),
1412 &acornfb_default_mode, DEFAULT_BPP); 1412 &acornfb_default_mode, DEFAULT_BPP);
1413 if (rc) 1413 if (rc)
1414 break; 1414 break;
diff --git a/drivers/video/asiliantfb.c b/drivers/video/asiliantfb.c
index c924d81f7978..29f9f0dfe3b4 100644
--- a/drivers/video/asiliantfb.c
+++ b/drivers/video/asiliantfb.c
@@ -353,8 +353,6 @@ struct chips_init_reg {
353 unsigned char data; 353 unsigned char data;
354}; 354};
355 355
356#define N_ELTS(x) (sizeof(x) / sizeof(x[0]))
357
358static struct chips_init_reg chips_init_sr[] = 356static struct chips_init_reg chips_init_sr[] =
359{ 357{
360 {0x00, 0x03}, /* Reset register */ 358 {0x00, 0x03}, /* Reset register */
@@ -460,22 +458,22 @@ static void __devinit chips_hw_init(struct fb_info *p)
460{ 458{
461 int i; 459 int i;
462 460
463 for (i = 0; i < N_ELTS(chips_init_xr); ++i) 461 for (i = 0; i < ARRAY_SIZE(chips_init_xr); ++i)
464 write_xr(chips_init_xr[i].addr, chips_init_xr[i].data); 462 write_xr(chips_init_xr[i].addr, chips_init_xr[i].data);
465 write_xr(0x81, 0x12); 463 write_xr(0x81, 0x12);
466 write_xr(0x82, 0x08); 464 write_xr(0x82, 0x08);
467 write_xr(0x20, 0x00); 465 write_xr(0x20, 0x00);
468 for (i = 0; i < N_ELTS(chips_init_sr); ++i) 466 for (i = 0; i < ARRAY_SIZE(chips_init_sr); ++i)
469 write_sr(chips_init_sr[i].addr, chips_init_sr[i].data); 467 write_sr(chips_init_sr[i].addr, chips_init_sr[i].data);
470 for (i = 0; i < N_ELTS(chips_init_gr); ++i) 468 for (i = 0; i < ARRAY_SIZE(chips_init_gr); ++i)
471 write_gr(chips_init_gr[i].addr, chips_init_gr[i].data); 469 write_gr(chips_init_gr[i].addr, chips_init_gr[i].data);
472 for (i = 0; i < N_ELTS(chips_init_ar); ++i) 470 for (i = 0; i < ARRAY_SIZE(chips_init_ar); ++i)
473 write_ar(chips_init_ar[i].addr, chips_init_ar[i].data); 471 write_ar(chips_init_ar[i].addr, chips_init_ar[i].data);
474 /* Enable video output in attribute index register */ 472 /* Enable video output in attribute index register */
475 writeb(0x20, mmio_base + 0x780); 473 writeb(0x20, mmio_base + 0x780);
476 for (i = 0; i < N_ELTS(chips_init_cr); ++i) 474 for (i = 0; i < ARRAY_SIZE(chips_init_cr); ++i)
477 write_cr(chips_init_cr[i].addr, chips_init_cr[i].data); 475 write_cr(chips_init_cr[i].addr, chips_init_cr[i].data);
478 for (i = 0; i < N_ELTS(chips_init_fr); ++i) 476 for (i = 0; i < ARRAY_SIZE(chips_init_fr); ++i)
479 write_fr(chips_init_fr[i].addr, chips_init_fr[i].data); 477 write_fr(chips_init_fr[i].addr, chips_init_fr[i].data);
480} 478}
481 479
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index 620c9a934e0e..821c6da8e42c 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -1725,9 +1725,9 @@ static int __init aty128_init(struct pci_dev *pdev, const struct pci_device_id *
1725 strcpy(video_card, "Rage128 XX "); 1725 strcpy(video_card, "Rage128 XX ");
1726 video_card[8] = ent->device >> 8; 1726 video_card[8] = ent->device >> 8;
1727 video_card[9] = ent->device & 0xFF; 1727 video_card[9] = ent->device & 0xFF;
1728 1728
1729 /* range check to make sure */ 1729 /* range check to make sure */
1730 if (ent->driver_data < (sizeof(r128_family)/sizeof(char *))) 1730 if (ent->driver_data < ARRAY_SIZE(r128_family))
1731 strncat(video_card, r128_family[ent->driver_data], sizeof(video_card)); 1731 strncat(video_card, r128_family[ent->driver_data], sizeof(video_card));
1732 1732
1733 printk(KERN_INFO "aty128fb: %s [chip rev 0x%x] ", video_card, chip_rev); 1733 printk(KERN_INFO "aty128fb: %s [chip rev 0x%x] ", video_card, chip_rev);
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 485be386a8ff..e799fcca365a 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -434,7 +434,7 @@ static int __devinit correct_chipset(struct atyfb_par *par)
434 const char *name; 434 const char *name;
435 int i; 435 int i;
436 436
437 for (i = sizeof(aty_chips) / sizeof(*aty_chips) - 1; i >= 0; i--) 437 for (i = ARRAY_SIZE(aty_chips) - 1; i >= 0; i--)
438 if (par->pci_id == aty_chips[i].pci_id) 438 if (par->pci_id == aty_chips[i].pci_id)
439 break; 439 break;
440 440
@@ -2168,10 +2168,10 @@ static void __init aty_calc_mem_refresh(struct atyfb_par *par, int xclk)
2168 2168
2169 if (IS_XL(par->pci_id) || IS_MOBILITY(par->pci_id)) { 2169 if (IS_XL(par->pci_id) || IS_MOBILITY(par->pci_id)) {
2170 refresh_tbl = ragexl_tbl; 2170 refresh_tbl = ragexl_tbl;
2171 size = sizeof(ragexl_tbl)/sizeof(int); 2171 size = ARRAY_SIZE(ragexl_tbl);
2172 } else { 2172 } else {
2173 refresh_tbl = ragepro_tbl; 2173 refresh_tbl = ragepro_tbl;
2174 size = sizeof(ragepro_tbl)/sizeof(int); 2174 size = ARRAY_SIZE(ragepro_tbl);
2175 } 2175 }
2176 2176
2177 for (i=0; i < size; i++) { 2177 for (i=0; i < size; i++) {
@@ -2298,6 +2298,10 @@ static int __init aty_init(struct fb_info *info, const char *name)
2298 case CLK_ATI18818_1: 2298 case CLK_ATI18818_1:
2299 par->pll_ops = &aty_pll_ati18818_1; 2299 par->pll_ops = &aty_pll_ati18818_1;
2300 break; 2300 break;
2301 case CLK_IBMRGB514:
2302 par->pll_ops = &aty_pll_ibm514;
2303 break;
2304#if 0 /* dead code */
2301 case CLK_STG1703: 2305 case CLK_STG1703:
2302 par->pll_ops = &aty_pll_stg1703; 2306 par->pll_ops = &aty_pll_stg1703;
2303 break; 2307 break;
@@ -2307,9 +2311,7 @@ static int __init aty_init(struct fb_info *info, const char *name)
2307 case CLK_ATT20C408: 2311 case CLK_ATT20C408:
2308 par->pll_ops = &aty_pll_att20c408; 2312 par->pll_ops = &aty_pll_att20c408;
2309 break; 2313 break;
2310 case CLK_IBMRGB514: 2314#endif
2311 par->pll_ops = &aty_pll_ibm514;
2312 break;
2313 default: 2315 default:
2314 PRINTKI("aty_init: CLK type not implemented yet!"); 2316 PRINTKI("aty_init: CLK type not implemented yet!");
2315 par->pll_ops = &aty_pll_unsupported; 2317 par->pll_ops = &aty_pll_unsupported;
@@ -3397,7 +3399,7 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi
3397 struct atyfb_par *par; 3399 struct atyfb_par *par;
3398 int i, rc = -ENOMEM; 3400 int i, rc = -ENOMEM;
3399 3401
3400 for (i = sizeof(aty_chips) / sizeof(*aty_chips) - 1; i >= 0; i--) 3402 for (i = ARRAY_SIZE(aty_chips); i >= 0; i--)
3401 if (pdev->device == aty_chips[i].pci_id) 3403 if (pdev->device == aty_chips[i].pci_id)
3402 break; 3404 break;
3403 3405
diff --git a/drivers/video/aty/mach64_gx.c b/drivers/video/aty/mach64_gx.c
index 01fdff79483b..2045639cb671 100644
--- a/drivers/video/aty/mach64_gx.c
+++ b/drivers/video/aty/mach64_gx.c
@@ -149,8 +149,7 @@ static int aty_var_to_pll_514(const struct fb_info *info, u32 vclk_per,
149 }; 149 };
150 int i; 150 int i;
151 151
152 for (i = 0; i < sizeof(RGB514_clocks) / sizeof(*RGB514_clocks); 152 for (i = 0; i < ARRAY_SIZE(RGB514_clocks); i++)
153 i++)
154 if (vclk_per <= RGB514_clocks[i].limit) { 153 if (vclk_per <= RGB514_clocks[i].limit) {
155 pll->ibm514.m = RGB514_clocks[i].m; 154 pll->ibm514.m = RGB514_clocks[i].m;
156 pll->ibm514.n = RGB514_clocks[i].n; 155 pll->ibm514.n = RGB514_clocks[i].n;
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index c9f0c5a07e6e..9a6b5b39b88e 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -1067,7 +1067,7 @@ static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green,
1067 1067
1068 1068
1069 if (regno > 255) 1069 if (regno > 255)
1070 return 1; 1070 return -EINVAL;
1071 1071
1072 red >>= 8; 1072 red >>= 8;
1073 green >>= 8; 1073 green >>= 8;
@@ -1086,9 +1086,9 @@ static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green,
1086 pindex = regno * 8; 1086 pindex = regno * 8;
1087 1087
1088 if (rinfo->depth == 16 && regno > 63) 1088 if (rinfo->depth == 16 && regno > 63)
1089 return 1; 1089 return -EINVAL;
1090 if (rinfo->depth == 15 && regno > 31) 1090 if (rinfo->depth == 15 && regno > 31)
1091 return 1; 1091 return -EINVAL;
1092 1092
1093 /* For 565, the green component is mixed one order 1093 /* For 565, the green component is mixed one order
1094 * below 1094 * below
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
new file mode 100644
index 000000000000..b367de30b98c
--- /dev/null
+++ b/drivers/video/au1200fb.c
@@ -0,0 +1,3844 @@
1/*
2 * BRIEF MODULE DESCRIPTION
3 * Au1200 LCD Driver.
4 *
5 * Copyright 2004-2005 AMD
6 * Author: AMD
7 *
8 * Based on:
9 * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device
10 * Created 28 Dec 1997 by Geert Uytterhoeven
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
20 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * You should have received a copy of the GNU General Public License along
29 * with this program; if not, write to the Free Software Foundation, Inc.,
30 * 675 Mass Ave, Cambridge, MA 02139, USA.
31 */
32
33#include <linux/module.h>
34#include <linux/platform_device.h>
35#include <linux/kernel.h>
36#include <linux/errno.h>
37#include <linux/string.h>
38#include <linux/mm.h>
39#include <linux/fb.h>
40#include <linux/init.h>
41#include <linux/interrupt.h>
42#include <linux/ctype.h>
43#include <linux/dma-mapping.h>
44
45#include <asm/mach-au1x00/au1000.h>
46#include "au1200fb.h"
47
48#ifdef CONFIG_PM
49#include <asm/mach-au1x00/au1xxx_pm.h>
50#endif
51
52#ifndef CONFIG_FB_AU1200_DEVS
53#define CONFIG_FB_AU1200_DEVS 4
54#endif
55
56#define DRIVER_NAME "au1200fb"
57#define DRIVER_DESC "LCD controller driver for AU1200 processors"
58
59#define DEBUG 1
60
61#define print_err(f, arg...) printk(KERN_ERR DRIVER_NAME ": " f "\n", ## arg)
62#define print_warn(f, arg...) printk(KERN_WARNING DRIVER_NAME ": " f "\n", ## arg)
63#define print_info(f, arg...) printk(KERN_INFO DRIVER_NAME ": " f "\n", ## arg)
64
65#if DEBUG
66#define print_dbg(f, arg...) printk(KERN_DEBUG __FILE__ ": " f "\n", ## arg)
67#else
68#define print_dbg(f, arg...) do {} while (0)
69#endif
70
71
72#define AU1200_LCD_FB_IOCTL 0x46FF
73
74#define AU1200_LCD_SET_SCREEN 1
75#define AU1200_LCD_GET_SCREEN 2
76#define AU1200_LCD_SET_WINDOW 3
77#define AU1200_LCD_GET_WINDOW 4
78#define AU1200_LCD_SET_PANEL 5
79#define AU1200_LCD_GET_PANEL 6
80
81#define SCREEN_SIZE (1<< 1)
82#define SCREEN_BACKCOLOR (1<< 2)
83#define SCREEN_BRIGHTNESS (1<< 3)
84#define SCREEN_COLORKEY (1<< 4)
85#define SCREEN_MASK (1<< 5)
86
87struct au1200_lcd_global_regs_t {
88 unsigned int flags;
89 unsigned int xsize;
90 unsigned int ysize;
91 unsigned int backcolor;
92 unsigned int brightness;
93 unsigned int colorkey;
94 unsigned int mask;
95 unsigned int panel_choice;
96 char panel_desc[80];
97
98};
99
100#define WIN_POSITION (1<< 0)
101#define WIN_ALPHA_COLOR (1<< 1)
102#define WIN_ALPHA_MODE (1<< 2)
103#define WIN_PRIORITY (1<< 3)
104#define WIN_CHANNEL (1<< 4)
105#define WIN_BUFFER_FORMAT (1<< 5)
106#define WIN_COLOR_ORDER (1<< 6)
107#define WIN_PIXEL_ORDER (1<< 7)
108#define WIN_SIZE (1<< 8)
109#define WIN_COLORKEY_MODE (1<< 9)
110#define WIN_DOUBLE_BUFFER_MODE (1<< 10)
111#define WIN_RAM_ARRAY_MODE (1<< 11)
112#define WIN_BUFFER_SCALE (1<< 12)
113#define WIN_ENABLE (1<< 13)
114
115struct au1200_lcd_window_regs_t {
116 unsigned int flags;
117 unsigned int xpos;
118 unsigned int ypos;
119 unsigned int alpha_color;
120 unsigned int alpha_mode;
121 unsigned int priority;
122 unsigned int channel;
123 unsigned int buffer_format;
124 unsigned int color_order;
125 unsigned int pixel_order;
126 unsigned int xsize;
127 unsigned int ysize;
128 unsigned int colorkey_mode;
129 unsigned int double_buffer_mode;
130 unsigned int ram_array_mode;
131 unsigned int xscale;
132 unsigned int yscale;
133 unsigned int enable;
134};
135
136
137struct au1200_lcd_iodata_t {
138 unsigned int subcmd;
139 struct au1200_lcd_global_regs_t global;
140 struct au1200_lcd_window_regs_t window;
141};
142
143#if defined(__BIG_ENDIAN)
144#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_11
145#else
146#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_00
147#endif
148#define LCD_CONTROL_DEFAULT_SBPPF LCD_CONTROL_SBPPF_565
149
150/* Private, per-framebuffer management information (independent of the panel itself) */
151struct au1200fb_device {
152 struct fb_info fb_info; /* FB driver info record */
153
154 int plane;
155 unsigned char* fb_mem; /* FrameBuffer memory map */
156 unsigned int fb_len;
157 dma_addr_t fb_phys;
158};
159
160static struct au1200fb_device _au1200fb_devices[CONFIG_FB_AU1200_DEVS];
161/********************************************************************/
162
163/* LCD controller restrictions */
164#define AU1200_LCD_MAX_XRES 1280
165#define AU1200_LCD_MAX_YRES 1024
166#define AU1200_LCD_MAX_BPP 32
167#define AU1200_LCD_MAX_CLK 96000000 /* fixme: this needs to go away ? */
168#define AU1200_LCD_NBR_PALETTE_ENTRIES 256
169
170/* Default number of visible screen buffer to allocate */
171#define AU1200FB_NBR_VIDEO_BUFFERS 1
172
173/********************************************************************/
174
175static struct au1200_lcd *lcd = (struct au1200_lcd *) AU1200_LCD_ADDR;
176static int window_index = 2; /* default is zero */
177static int panel_index = 2; /* default is zero */
178static struct window_settings *win;
179static struct panel_settings *panel;
180static int noblanking = 1;
181static int nohwcursor = 0;
182
183struct window_settings {
184 unsigned char name[64];
185 uint32 mode_backcolor;
186 uint32 mode_colorkey;
187 uint32 mode_colorkeymsk;
188 struct {
189 int xres;
190 int yres;
191 int xpos;
192 int ypos;
193 uint32 mode_winctrl1; /* winctrl1[FRM,CCO,PO,PIPE] */
194 uint32 mode_winenable;
195 } w[4];
196};
197
198#if defined(__BIG_ENDIAN)
199#define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_00
200#else
201#define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_01
202#endif
203
204extern int board_au1200fb_panel_init (void);
205extern int board_au1200fb_panel_shutdown (void);
206
207#ifdef CONFIG_PM
208int au1200fb_pm_callback(au1xxx_power_dev_t *dev,
209 au1xxx_request_t request, void *data);
210au1xxx_power_dev_t *LCD_pm_dev;
211#endif
212
213/*
214 * Default window configurations
215 */
216static struct window_settings windows[] = {
217 { /* Index 0 */
218 "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
219 /* mode_backcolor */ 0x006600ff,
220 /* mode_colorkey,msk*/ 0, 0,
221 {
222 {
223 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
224 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
225 LCD_WINCTRL1_PO_16BPP,
226 /* mode_winenable*/ LCD_WINENABLE_WEN0,
227 },
228 {
229 /* xres, yres, xpos, ypos */ 100, 100, 100, 100,
230 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
231 LCD_WINCTRL1_PO_16BPP |
232 LCD_WINCTRL1_PIPE,
233 /* mode_winenable*/ LCD_WINENABLE_WEN1,
234 },
235 {
236 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
237 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
238 LCD_WINCTRL1_PO_16BPP,
239 /* mode_winenable*/ 0,
240 },
241 {
242 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
243 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
244 LCD_WINCTRL1_PO_16BPP |
245 LCD_WINCTRL1_PIPE,
246 /* mode_winenable*/ 0,
247 },
248 },
249 },
250
251 { /* Index 1 */
252 "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
253 /* mode_backcolor */ 0x006600ff,
254 /* mode_colorkey,msk*/ 0, 0,
255 {
256 {
257 /* xres, yres, xpos, ypos */ 320, 240, 5, 5,
258 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_24BPP |
259 LCD_WINCTRL1_PO_00,
260 /* mode_winenable*/ LCD_WINENABLE_WEN0,
261 },
262 {
263 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
264 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565
265 | LCD_WINCTRL1_PO_16BPP,
266 /* mode_winenable*/ 0,
267 },
268 {
269 /* xres, yres, xpos, ypos */ 100, 100, 0, 0,
270 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
271 LCD_WINCTRL1_PO_16BPP |
272 LCD_WINCTRL1_PIPE,
273 /* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/,
274 },
275 {
276 /* xres, yres, xpos, ypos */ 200, 25, 0, 0,
277 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
278 LCD_WINCTRL1_PO_16BPP |
279 LCD_WINCTRL1_PIPE,
280 /* mode_winenable*/ 0,
281 },
282 },
283 },
284 { /* Index 2 */
285 "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
286 /* mode_backcolor */ 0x006600ff,
287 /* mode_colorkey,msk*/ 0, 0,
288 {
289 {
290 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
291 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
292 LCD_WINCTRL1_PO_16BPP,
293 /* mode_winenable*/ LCD_WINENABLE_WEN0,
294 },
295 {
296 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
297 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
298 LCD_WINCTRL1_PO_16BPP,
299 /* mode_winenable*/ 0,
300 },
301 {
302 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
303 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_32BPP |
304 LCD_WINCTRL1_PO_00|LCD_WINCTRL1_PIPE,
305 /* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/,
306 },
307 {
308 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
309 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
310 LCD_WINCTRL1_PO_16BPP |
311 LCD_WINCTRL1_PIPE,
312 /* mode_winenable*/ 0,
313 },
314 },
315 },
316 /* Need VGA 640 @ 24bpp, @ 32bpp */
317 /* Need VGA 800 @ 24bpp, @ 32bpp */
318 /* Need VGA 1024 @ 24bpp, @ 32bpp */
319};
320
321/*
322 * Controller configurations for various panels.
323 */
324
325struct panel_settings
326{
327 const char name[25]; /* Full name <vendor>_<model> */
328
329 struct fb_monspecs monspecs; /* FB monitor specs */
330
331 /* panel timings */
332 uint32 mode_screen;
333 uint32 mode_horztiming;
334 uint32 mode_verttiming;
335 uint32 mode_clkcontrol;
336 uint32 mode_pwmdiv;
337 uint32 mode_pwmhi;
338 uint32 mode_outmask;
339 uint32 mode_fifoctrl;
340 uint32 mode_toyclksrc;
341 uint32 mode_backlight;
342 uint32 mode_auxpll;
343 int (*device_init)(void);
344 int (*device_shutdown)(void);
345#define Xres min_xres
346#define Yres min_yres
347 u32 min_xres; /* Minimum horizontal resolution */
348 u32 max_xres; /* Maximum horizontal resolution */
349 u32 min_yres; /* Minimum vertical resolution */
350 u32 max_yres; /* Maximum vertical resolution */
351};
352
353/********************************************************************/
354/* fixme: Maybe a modedb for the CRT ? otherwise panels should be as-is */
355
356/* List of panels known to work with the AU1200 LCD controller.
357 * To add a new panel, enter the same specifications as the
358 * Generic_TFT one, and MAKE SURE that it doesn't conflicts
359 * with the controller restrictions. Restrictions are:
360 *
361 * STN color panels: max_bpp <= 12
362 * STN mono panels: max_bpp <= 4
363 * TFT panels: max_bpp <= 16
364 * max_xres <= 800
365 * max_yres <= 600
366 */
367static struct panel_settings known_lcd_panels[] =
368{
369 [0] = { /* QVGA 320x240 H:33.3kHz V:110Hz */
370 .name = "QVGA_320x240",
371 .monspecs = {
372 .modedb = NULL,
373 .modedb_len = 0,
374 .hfmin = 30000,
375 .hfmax = 70000,
376 .vfmin = 60,
377 .vfmax = 60,
378 .dclkmin = 6000000,
379 .dclkmax = 28000000,
380 .input = FB_DISP_RGB,
381 },
382 .mode_screen = LCD_SCREEN_SX_N(320) |
383 LCD_SCREEN_SY_N(240),
384 .mode_horztiming = 0x00c4623b,
385 .mode_verttiming = 0x00502814,
386 .mode_clkcontrol = 0x00020002, /* /4=24Mhz */
387 .mode_pwmdiv = 0x00000000,
388 .mode_pwmhi = 0x00000000,
389 .mode_outmask = 0x00FFFFFF,
390 .mode_fifoctrl = 0x2f2f2f2f,
391 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
392 .mode_backlight = 0x00000000,
393 .mode_auxpll = 8, /* 96MHz AUXPLL */
394 .device_init = NULL,
395 .device_shutdown = NULL,
396 320, 320,
397 240, 240,
398 },
399
400 [1] = { /* VGA 640x480 H:30.3kHz V:58Hz */
401 .name = "VGA_640x480",
402 .monspecs = {
403 .modedb = NULL,
404 .modedb_len = 0,
405 .hfmin = 30000,
406 .hfmax = 70000,
407 .vfmin = 60,
408 .vfmax = 60,
409 .dclkmin = 6000000,
410 .dclkmax = 28000000,
411 .input = FB_DISP_RGB,
412 },
413 .mode_screen = 0x13f9df80,
414 .mode_horztiming = 0x003c5859,
415 .mode_verttiming = 0x00741201,
416 .mode_clkcontrol = 0x00020001, /* /4=24Mhz */
417 .mode_pwmdiv = 0x00000000,
418 .mode_pwmhi = 0x00000000,
419 .mode_outmask = 0x00FFFFFF,
420 .mode_fifoctrl = 0x2f2f2f2f,
421 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
422 .mode_backlight = 0x00000000,
423 .mode_auxpll = 8, /* 96MHz AUXPLL */
424 .device_init = NULL,
425 .device_shutdown = NULL,
426 640, 480,
427 640, 480,
428 },
429
430 [2] = { /* SVGA 800x600 H:46.1kHz V:69Hz */
431 .name = "SVGA_800x600",
432 .monspecs = {
433 .modedb = NULL,
434 .modedb_len = 0,
435 .hfmin = 30000,
436 .hfmax = 70000,
437 .vfmin = 60,
438 .vfmax = 60,
439 .dclkmin = 6000000,
440 .dclkmax = 28000000,
441 .input = FB_DISP_RGB,
442 },
443 .mode_screen = 0x18fa5780,
444 .mode_horztiming = 0x00dc7e77,
445 .mode_verttiming = 0x00584805,
446 .mode_clkcontrol = 0x00020000, /* /2=48Mhz */
447 .mode_pwmdiv = 0x00000000,
448 .mode_pwmhi = 0x00000000,
449 .mode_outmask = 0x00FFFFFF,
450 .mode_fifoctrl = 0x2f2f2f2f,
451 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
452 .mode_backlight = 0x00000000,
453 .mode_auxpll = 8, /* 96MHz AUXPLL */
454 .device_init = NULL,
455 .device_shutdown = NULL,
456 800, 800,
457 600, 600,
458 },
459
460 [3] = { /* XVGA 1024x768 H:56.2kHz V:70Hz */
461 .name = "XVGA_1024x768",
462 .monspecs = {
463 .modedb = NULL,
464 .modedb_len = 0,
465 .hfmin = 30000,
466 .hfmax = 70000,
467 .vfmin = 60,
468 .vfmax = 60,
469 .dclkmin = 6000000,
470 .dclkmax = 28000000,
471 .input = FB_DISP_RGB,
472 },
473 .mode_screen = 0x1ffaff80,
474 .mode_horztiming = 0x007d0e57,
475 .mode_verttiming = 0x00740a01,
476 .mode_clkcontrol = 0x000A0000, /* /1 */
477 .mode_pwmdiv = 0x00000000,
478 .mode_pwmhi = 0x00000000,
479 .mode_outmask = 0x00FFFFFF,
480 .mode_fifoctrl = 0x2f2f2f2f,
481 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
482 .mode_backlight = 0x00000000,
483 .mode_auxpll = 6, /* 72MHz AUXPLL */
484 .device_init = NULL,
485 .device_shutdown = NULL,
486 1024, 1024,
487 768, 768,
488 },
489
490 [4] = { /* XVGA XVGA 1280x1024 H:68.5kHz V:65Hz */
491 .name = "XVGA_1280x1024",
492 .monspecs = {
493 .modedb = NULL,
494 .modedb_len = 0,
495 .hfmin = 30000,
496 .hfmax = 70000,
497 .vfmin = 60,
498 .vfmax = 60,
499 .dclkmin = 6000000,
500 .dclkmax = 28000000,
501 .input = FB_DISP_RGB,
502 },
503 .mode_screen = 0x27fbff80,
504 .mode_horztiming = 0x00cdb2c7,
505 .mode_verttiming = 0x00600002,
506 .mode_clkcontrol = 0x000A0000, /* /1 */
507 .mode_pwmdiv = 0x00000000,
508 .mode_pwmhi = 0x00000000,
509 .mode_outmask = 0x00FFFFFF,
510 .mode_fifoctrl = 0x2f2f2f2f,
511 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
512 .mode_backlight = 0x00000000,
513 .mode_auxpll = 10, /* 120MHz AUXPLL */
514 .device_init = NULL,
515 .device_shutdown = NULL,
516 1280, 1280,
517 1024, 1024,
518 },
519
520 [5] = { /* Samsung 1024x768 TFT */
521 .name = "Samsung_1024x768_TFT",
522 .monspecs = {
523 .modedb = NULL,
524 .modedb_len = 0,
525 .hfmin = 30000,
526 .hfmax = 70000,
527 .vfmin = 60,
528 .vfmax = 60,
529 .dclkmin = 6000000,
530 .dclkmax = 28000000,
531 .input = FB_DISP_RGB,
532 },
533 .mode_screen = 0x1ffaff80,
534 .mode_horztiming = 0x018cc677,
535 .mode_verttiming = 0x00241217,
536 .mode_clkcontrol = 0x00000000, /* SCB 0x1 /4=24Mhz */
537 .mode_pwmdiv = 0x8000063f, /* SCB 0x0 */
538 .mode_pwmhi = 0x03400000, /* SCB 0x0 */
539 .mode_outmask = 0x00FFFFFF,
540 .mode_fifoctrl = 0x2f2f2f2f,
541 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
542 .mode_backlight = 0x00000000,
543 .mode_auxpll = 8, /* 96MHz AUXPLL */
544 .device_init = board_au1200fb_panel_init,
545 .device_shutdown = board_au1200fb_panel_shutdown,
546 1024, 1024,
547 768, 768,
548 },
549
550 [6] = { /* Toshiba 640x480 TFT */
551 .name = "Toshiba_640x480_TFT",
552 .monspecs = {
553 .modedb = NULL,
554 .modedb_len = 0,
555 .hfmin = 30000,
556 .hfmax = 70000,
557 .vfmin = 60,
558 .vfmax = 60,
559 .dclkmin = 6000000,
560 .dclkmax = 28000000,
561 .input = FB_DISP_RGB,
562 },
563 .mode_screen = LCD_SCREEN_SX_N(640) |
564 LCD_SCREEN_SY_N(480),
565 .mode_horztiming = LCD_HORZTIMING_HPW_N(96) |
566 LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(51),
567 .mode_verttiming = LCD_VERTTIMING_VPW_N(2) |
568 LCD_VERTTIMING_VND1_N(11) | LCD_VERTTIMING_VND2_N(32),
569 .mode_clkcontrol = 0x00000000, /* /4=24Mhz */
570 .mode_pwmdiv = 0x8000063f,
571 .mode_pwmhi = 0x03400000,
572 .mode_outmask = 0x00fcfcfc,
573 .mode_fifoctrl = 0x2f2f2f2f,
574 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
575 .mode_backlight = 0x00000000,
576 .mode_auxpll = 8, /* 96MHz AUXPLL */
577 .device_init = board_au1200fb_panel_init,
578 .device_shutdown = board_au1200fb_panel_shutdown,
579 640, 480,
580 640, 480,
581 },
582
583 [7] = { /* Sharp 320x240 TFT */
584 .name = "Sharp_320x240_TFT",
585 .monspecs = {
586 .modedb = NULL,
587 .modedb_len = 0,
588 .hfmin = 12500,
589 .hfmax = 20000,
590 .vfmin = 38,
591 .vfmax = 81,
592 .dclkmin = 4500000,
593 .dclkmax = 6800000,
594 .input = FB_DISP_RGB,
595 },
596 .mode_screen = LCD_SCREEN_SX_N(320) |
597 LCD_SCREEN_SY_N(240),
598 .mode_horztiming = LCD_HORZTIMING_HPW_N(60) |
599 LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(2),
600 .mode_verttiming = LCD_VERTTIMING_VPW_N(2) |
601 LCD_VERTTIMING_VND1_N(2) | LCD_VERTTIMING_VND2_N(5),
602 .mode_clkcontrol = LCD_CLKCONTROL_PCD_N(7), /*16=6Mhz*/
603 .mode_pwmdiv = 0x8000063f,
604 .mode_pwmhi = 0x03400000,
605 .mode_outmask = 0x00fcfcfc,
606 .mode_fifoctrl = 0x2f2f2f2f,
607 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
608 .mode_backlight = 0x00000000,
609 .mode_auxpll = 8, /* 96MHz AUXPLL */
610 .device_init = board_au1200fb_panel_init,
611 .device_shutdown = board_au1200fb_panel_shutdown,
612 320, 320,
613 240, 240,
614 },
615
616 [8] = { /* Toppoly TD070WGCB2 7" 856x480 TFT */
617 .name = "Toppoly_TD070WGCB2",
618 .monspecs = {
619 .modedb = NULL,
620 .modedb_len = 0,
621 .hfmin = 30000,
622 .hfmax = 70000,
623 .vfmin = 60,
624 .vfmax = 60,
625 .dclkmin = 6000000,
626 .dclkmax = 28000000,
627 .input = FB_DISP_RGB,
628 },
629 .mode_screen = LCD_SCREEN_SX_N(856) |
630 LCD_SCREEN_SY_N(480),
631 .mode_horztiming = LCD_HORZTIMING_HND2_N(43) |
632 LCD_HORZTIMING_HND1_N(43) | LCD_HORZTIMING_HPW_N(114),
633 .mode_verttiming = LCD_VERTTIMING_VND2_N(20) |
634 LCD_VERTTIMING_VND1_N(21) | LCD_VERTTIMING_VPW_N(4),
635 .mode_clkcontrol = 0x00020001, /* /4=24Mhz */
636 .mode_pwmdiv = 0x8000063f,
637 .mode_pwmhi = 0x03400000,
638 .mode_outmask = 0x00fcfcfc,
639 .mode_fifoctrl = 0x2f2f2f2f,
640 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
641 .mode_backlight = 0x00000000,
642 .mode_auxpll = 8, /* 96MHz AUXPLL */
643 .device_init = board_au1200fb_panel_init,
644 .device_shutdown = board_au1200fb_panel_shutdown,
645 856, 856,
646 480, 480,
647 },
648};
649
650#define NUM_PANELS (ARRAY_SIZE(known_lcd_panels))
651
652/********************************************************************/
653
654#ifdef CONFIG_PM
655static int set_brightness(unsigned int brightness)
656{
657 unsigned int hi1, divider;
658
659 /* limit brightness pwm duty to >= 30/1600 */
660 if (brightness < 30) {
661 brightness = 30;
662 }
663 divider = (lcd->pwmdiv & 0x3FFFF) + 1;
664 hi1 = (lcd->pwmhi >> 16) + 1;
665 hi1 = (((brightness & 0xFF) + 1) * divider >> 8);
666 lcd->pwmhi &= 0xFFFF;
667 lcd->pwmhi |= (hi1 << 16);
668
669 return brightness;
670}
671#endif /* CONFIG_PM */
672
673static int winbpp (unsigned int winctrl1)
674{
675 int bits = 0;
676
677 /* how many bits are needed for each pixel format */
678 switch (winctrl1 & LCD_WINCTRL1_FRM) {
679 case LCD_WINCTRL1_FRM_1BPP:
680 bits = 1;
681 break;
682 case LCD_WINCTRL1_FRM_2BPP:
683 bits = 2;
684 break;
685 case LCD_WINCTRL1_FRM_4BPP:
686 bits = 4;
687 break;
688 case LCD_WINCTRL1_FRM_8BPP:
689 bits = 8;
690 break;
691 case LCD_WINCTRL1_FRM_12BPP:
692 case LCD_WINCTRL1_FRM_16BPP655:
693 case LCD_WINCTRL1_FRM_16BPP565:
694 case LCD_WINCTRL1_FRM_16BPP556:
695 case LCD_WINCTRL1_FRM_16BPPI1555:
696 case LCD_WINCTRL1_FRM_16BPPI5551:
697 case LCD_WINCTRL1_FRM_16BPPA1555:
698 case LCD_WINCTRL1_FRM_16BPPA5551:
699 bits = 16;
700 break;
701 case LCD_WINCTRL1_FRM_24BPP:
702 case LCD_WINCTRL1_FRM_32BPP:
703 bits = 32;
704 break;
705 }
706
707 return bits;
708}
709
710static int fbinfo2index (struct fb_info *fb_info)
711{
712 int i;
713
714 for (i = 0; i < CONFIG_FB_AU1200_DEVS; ++i) {
715 if (fb_info == (struct fb_info *)(&_au1200fb_devices[i].fb_info))
716 return i;
717 }
718 printk("au1200fb: ERROR: fbinfo2index failed!\n");
719 return -1;
720}
721
722static int au1200_setlocation (struct au1200fb_device *fbdev, int plane,
723 int xpos, int ypos)
724{
725 uint32 winctrl0, winctrl1, winenable, fb_offset = 0;
726 int xsz, ysz;
727
728 /* FIX!!! NOT CHECKING FOR COMPLETE OFFSCREEN YET */
729
730 winctrl0 = lcd->window[plane].winctrl0;
731 winctrl1 = lcd->window[plane].winctrl1;
732 winctrl0 &= (LCD_WINCTRL0_A | LCD_WINCTRL0_AEN);
733 winctrl1 &= ~(LCD_WINCTRL1_SZX | LCD_WINCTRL1_SZY);
734
735 /* Check for off-screen adjustments */
736 xsz = win->w[plane].xres;
737 ysz = win->w[plane].yres;
738 if ((xpos + win->w[plane].xres) > panel->Xres) {
739 /* Off-screen to the right */
740 xsz = panel->Xres - xpos; /* off by 1 ??? */
741 /*printk("off screen right\n");*/
742 }
743
744 if ((ypos + win->w[plane].yres) > panel->Yres) {
745 /* Off-screen to the bottom */
746 ysz = panel->Yres - ypos; /* off by 1 ??? */
747 /*printk("off screen bottom\n");*/
748 }
749
750 if (xpos < 0) {
751 /* Off-screen to the left */
752 xsz = win->w[plane].xres + xpos;
753 fb_offset += (((0 - xpos) * winbpp(lcd->window[plane].winctrl1))/8);
754 xpos = 0;
755 /*printk("off screen left\n");*/
756 }
757
758 if (ypos < 0) {
759 /* Off-screen to the top */
760 ysz = win->w[plane].yres + ypos;
761 /* fixme: fb_offset += ((0-ypos)*fb_pars[plane].line_length); */
762 ypos = 0;
763 /*printk("off screen top\n");*/
764 }
765
766 /* record settings */
767 win->w[plane].xpos = xpos;
768 win->w[plane].ypos = ypos;
769
770 xsz -= 1;
771 ysz -= 1;
772 winctrl0 |= (xpos << 21);
773 winctrl0 |= (ypos << 10);
774 winctrl1 |= (xsz << 11);
775 winctrl1 |= (ysz << 0);
776
777 /* Disable the window while making changes, then restore WINEN */
778 winenable = lcd->winenable & (1 << plane);
779 au_sync();
780 lcd->winenable &= ~(1 << plane);
781 lcd->window[plane].winctrl0 = winctrl0;
782 lcd->window[plane].winctrl1 = winctrl1;
783 lcd->window[plane].winbuf0 =
784 lcd->window[plane].winbuf1 = fbdev->fb_phys;
785 lcd->window[plane].winbufctrl = 0; /* select winbuf0 */
786 lcd->winenable |= winenable;
787 au_sync();
788
789 return 0;
790}
791
792static void au1200_setpanel (struct panel_settings *newpanel)
793{
794 /*
795 * Perform global setup/init of LCD controller
796 */
797 uint32 winenable;
798
799 /* Make sure all windows disabled */
800 winenable = lcd->winenable;
801 lcd->winenable = 0;
802 au_sync();
803 /*
804 * Ensure everything is disabled before reconfiguring
805 */
806 if (lcd->screen & LCD_SCREEN_SEN) {
807 /* Wait for vertical sync period */
808 lcd->intstatus = LCD_INT_SS;
809 while ((lcd->intstatus & LCD_INT_SS) == 0) {
810 au_sync();
811 }
812
813 lcd->screen &= ~LCD_SCREEN_SEN; /*disable the controller*/
814
815 do {
816 lcd->intstatus = lcd->intstatus; /*clear interrupts*/
817 au_sync();
818 /*wait for controller to shut down*/
819 } while ((lcd->intstatus & LCD_INT_SD) == 0);
820
821 /* Call shutdown of current panel (if up) */
822 /* this must occur last, because if an external clock is driving
823 the controller, the clock cannot be turned off before first
824 shutting down the controller.
825 */
826 if (panel->device_shutdown != NULL)
827 panel->device_shutdown();
828 }
829
830 /* Newpanel == NULL indicates a shutdown operation only */
831 if (newpanel == NULL)
832 return;
833
834 panel = newpanel;
835
836 printk("Panel(%s), %dx%d\n", panel->name, panel->Xres, panel->Yres);
837
838 /*
839 * Setup clocking if internal LCD clock source (assumes sys_auxpll valid)
840 */
841 if (!(panel->mode_clkcontrol & LCD_CLKCONTROL_EXT))
842 {
843 uint32 sys_clksrc;
844 au_writel(panel->mode_auxpll, SYS_AUXPLL);
845 sys_clksrc = au_readl(SYS_CLKSRC) & ~0x0000001f;
846 sys_clksrc |= panel->mode_toyclksrc;
847 au_writel(sys_clksrc, SYS_CLKSRC);
848 }
849
850 /*
851 * Configure panel timings
852 */
853 lcd->screen = panel->mode_screen;
854 lcd->horztiming = panel->mode_horztiming;
855 lcd->verttiming = panel->mode_verttiming;
856 lcd->clkcontrol = panel->mode_clkcontrol;
857 lcd->pwmdiv = panel->mode_pwmdiv;
858 lcd->pwmhi = panel->mode_pwmhi;
859 lcd->outmask = panel->mode_outmask;
860 lcd->fifoctrl = panel->mode_fifoctrl;
861 au_sync();
862
863 /* fixme: Check window settings to make sure still valid
864 * for new geometry */
865#if 0
866 au1200_setlocation(fbdev, 0, win->w[0].xpos, win->w[0].ypos);
867 au1200_setlocation(fbdev, 1, win->w[1].xpos, win->w[1].ypos);
868 au1200_setlocation(fbdev, 2, win->w[2].xpos, win->w[2].ypos);
869 au1200_setlocation(fbdev, 3, win->w[3].xpos, win->w[3].ypos);
870#endif
871 lcd->winenable = winenable;
872
873 /*
874 * Re-enable screen now that it is configured
875 */
876 lcd->screen |= LCD_SCREEN_SEN;
877 au_sync();
878
879 /* Call init of panel */
880 if (panel->device_init != NULL) panel->device_init();
881
882 /* FIX!!!! not appropriate on panel change!!! Global setup/init */
883 lcd->intenable = 0;
884 lcd->intstatus = ~0;
885 lcd->backcolor = win->mode_backcolor;
886
887 /* Setup Color Key - FIX!!! */
888 lcd->colorkey = win->mode_colorkey;
889 lcd->colorkeymsk = win->mode_colorkeymsk;
890
891 /* Setup HWCursor - FIX!!! Need to support this eventually */
892 lcd->hwc.cursorctrl = 0;
893 lcd->hwc.cursorpos = 0;
894 lcd->hwc.cursorcolor0 = 0;
895 lcd->hwc.cursorcolor1 = 0;
896 lcd->hwc.cursorcolor2 = 0;
897 lcd->hwc.cursorcolor3 = 0;
898
899
900#if 0
901#define D(X) printk("%25s: %08X\n", #X, X)
902 D(lcd->screen);
903 D(lcd->horztiming);
904 D(lcd->verttiming);
905 D(lcd->clkcontrol);
906 D(lcd->pwmdiv);
907 D(lcd->pwmhi);
908 D(lcd->outmask);
909 D(lcd->fifoctrl);
910 D(lcd->window[0].winctrl0);
911 D(lcd->window[0].winctrl1);
912 D(lcd->window[0].winctrl2);
913 D(lcd->window[0].winbuf0);
914 D(lcd->window[0].winbuf1);
915 D(lcd->window[0].winbufctrl);
916 D(lcd->window[1].winctrl0);
917 D(lcd->window[1].winctrl1);
918 D(lcd->window[1].winctrl2);
919 D(lcd->window[1].winbuf0);
920 D(lcd->window[1].winbuf1);
921 D(lcd->window[1].winbufctrl);
922 D(lcd->window[2].winctrl0);
923 D(lcd->window[2].winctrl1);
924 D(lcd->window[2].winctrl2);
925 D(lcd->window[2].winbuf0);
926 D(lcd->window[2].winbuf1);
927 D(lcd->window[2].winbufctrl);
928 D(lcd->window[3].winctrl0);
929 D(lcd->window[3].winctrl1);
930 D(lcd->window[3].winctrl2);
931 D(lcd->window[3].winbuf0);
932 D(lcd->window[3].winbuf1);
933 D(lcd->window[3].winbufctrl);
934 D(lcd->winenable);
935 D(lcd->intenable);
936 D(lcd->intstatus);
937 D(lcd->backcolor);
938 D(lcd->winenable);
939 D(lcd->colorkey);
940 D(lcd->colorkeymsk);
941 D(lcd->hwc.cursorctrl);
942 D(lcd->hwc.cursorpos);
943 D(lcd->hwc.cursorcolor0);
944 D(lcd->hwc.cursorcolor1);
945 D(lcd->hwc.cursorcolor2);
946 D(lcd->hwc.cursorcolor3);
947#endif
948}
949
950static void au1200_setmode(struct au1200fb_device *fbdev)
951{
952 int plane = fbdev->plane;
953 /* Window/plane setup */
954 lcd->window[plane].winctrl1 = ( 0
955 | LCD_WINCTRL1_PRI_N(plane)
956 | win->w[plane].mode_winctrl1 /* FRM,CCO,PO,PIPE */
957 ) ;
958
959 au1200_setlocation(fbdev, plane, win->w[plane].xpos, win->w[plane].ypos);
960
961 lcd->window[plane].winctrl2 = ( 0
962 | LCD_WINCTRL2_CKMODE_00
963 | LCD_WINCTRL2_DBM
964 | LCD_WINCTRL2_BX_N( fbdev->fb_info.fix.line_length)
965 | LCD_WINCTRL2_SCX_1
966 | LCD_WINCTRL2_SCY_1
967 ) ;
968 lcd->winenable |= win->w[plane].mode_winenable;
969 au_sync();
970}
971
972
973/* Inline helpers */
974
975/*#define panel_is_dual(panel) ((panel->mode_screen & LCD_SCREEN_PT) == LCD_SCREEN_PT_010)*/
976/*#define panel_is_active(panel)((panel->mode_screen & LCD_SCREEN_PT) == LCD_SCREEN_PT_010)*/
977
978#define panel_is_color(panel) ((panel->mode_screen & LCD_SCREEN_PT) <= LCD_SCREEN_PT_CDSTN)
979
980/* Bitfields format supported by the controller. */
981static struct fb_bitfield rgb_bitfields[][4] = {
982 /* Red, Green, Blue, Transp */
983 [LCD_WINCTRL1_FRM_16BPP655 >> 25] =
984 { { 10, 6, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
985
986 [LCD_WINCTRL1_FRM_16BPP565 >> 25] =
987 { { 11, 5, 0 }, { 5, 6, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
988
989 [LCD_WINCTRL1_FRM_16BPP556 >> 25] =
990 { { 11, 5, 0 }, { 6, 5, 0 }, { 0, 6, 0 }, { 0, 0, 0 } },
991
992 [LCD_WINCTRL1_FRM_16BPPI1555 >> 25] =
993 { { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
994
995 [LCD_WINCTRL1_FRM_16BPPI5551 >> 25] =
996 { { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 0, 0 } },
997
998 [LCD_WINCTRL1_FRM_16BPPA1555 >> 25] =
999 { { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 15, 1, 0 } },
1000
1001 [LCD_WINCTRL1_FRM_16BPPA5551 >> 25] =
1002 { { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 1, 0 } },
1003
1004 [LCD_WINCTRL1_FRM_24BPP >> 25] =
1005 { { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 0, 0, 0 } },
1006
1007 [LCD_WINCTRL1_FRM_32BPP >> 25] =
1008 { { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 24, 0, 0 } },
1009};
1010
1011/*-------------------------------------------------------------------------*/
1012
1013/* Helpers */
1014
1015static void au1200fb_update_fbinfo(struct fb_info *fbi)
1016{
1017 /* FIX!!!! This also needs to take the window pixel format into account!!! */
1018
1019 /* Update var-dependent FB info */
1020 if (panel_is_color(panel)) {
1021 if (fbi->var.bits_per_pixel <= 8) {
1022 /* palettized */
1023 fbi->fix.visual = FB_VISUAL_PSEUDOCOLOR;
1024 fbi->fix.line_length = fbi->var.xres_virtual /
1025 (8/fbi->var.bits_per_pixel);
1026 } else {
1027 /* non-palettized */
1028 fbi->fix.visual = FB_VISUAL_TRUECOLOR;
1029 fbi->fix.line_length = fbi->var.xres_virtual * (fbi->var.bits_per_pixel / 8);
1030 }
1031 } else {
1032 /* mono FIX!!! mono 8 and 4 bits */
1033 fbi->fix.visual = FB_VISUAL_MONO10;
1034 fbi->fix.line_length = fbi->var.xres_virtual / 8;
1035 }
1036
1037 fbi->screen_size = fbi->fix.line_length * fbi->var.yres_virtual;
1038 print_dbg("line length: %d\n", fbi->fix.line_length);
1039 print_dbg("bits_per_pixel: %d\n", fbi->var.bits_per_pixel);
1040}
1041
1042/*-------------------------------------------------------------------------*/
1043
1044/* AU1200 framebuffer driver */
1045
1046/* fb_check_var
1047 * Validate var settings with hardware restrictions and modify it if necessary
1048 */
1049static int au1200fb_fb_check_var(struct fb_var_screeninfo *var,
1050 struct fb_info *fbi)
1051{
1052 struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi;
1053 u32 pixclock;
1054 int screen_size, plane;
1055
1056 plane = fbdev->plane;
1057
1058 /* Make sure that the mode respect all LCD controller and
1059 * panel restrictions. */
1060 var->xres = win->w[plane].xres;
1061 var->yres = win->w[plane].yres;
1062
1063 /* No need for virtual resolution support */
1064 var->xres_virtual = var->xres;
1065 var->yres_virtual = var->yres;
1066
1067 var->bits_per_pixel = winbpp(win->w[plane].mode_winctrl1);
1068
1069 screen_size = var->xres_virtual * var->yres_virtual;
1070 if (var->bits_per_pixel > 8) screen_size *= (var->bits_per_pixel / 8);
1071 else screen_size /= (8/var->bits_per_pixel);
1072
1073 if (fbdev->fb_len < screen_size)
1074 return -EINVAL; /* Virtual screen is to big, abort */
1075
1076 /* FIX!!!! what are the implicaitons of ignoring this for windows ??? */
1077 /* The max LCD clock is fixed to 48MHz (value of AUX_CLK). The pixel
1078 * clock can only be obtain by dividing this value by an even integer.
1079 * Fallback to a slower pixel clock if necessary. */
1080 pixclock = max((u32)(PICOS2KHZ(var->pixclock) * 1000), fbi->monspecs.dclkmin);
1081 pixclock = min(pixclock, min(fbi->monspecs.dclkmax, (u32)AU1200_LCD_MAX_CLK/2));
1082
1083 if (AU1200_LCD_MAX_CLK % pixclock) {
1084 int diff = AU1200_LCD_MAX_CLK % pixclock;
1085 pixclock -= diff;
1086 }
1087
1088 var->pixclock = KHZ2PICOS(pixclock/1000);
1089#if 0
1090 if (!panel_is_active(panel)) {
1091 int pcd = AU1200_LCD_MAX_CLK / (pixclock * 2) - 1;
1092
1093 if (!panel_is_color(panel)
1094 && (panel->control_base & LCD_CONTROL_MPI) && (pcd < 3)) {
1095 /* STN 8bit mono panel support is up to 6MHz pixclock */
1096 var->pixclock = KHZ2PICOS(6000);
1097 } else if (!pcd) {
1098 /* Other STN panel support is up to 12MHz */
1099 var->pixclock = KHZ2PICOS(12000);
1100 }
1101 }
1102#endif
1103 /* Set bitfield accordingly */
1104 switch (var->bits_per_pixel) {
1105 case 16:
1106 {
1107 /* 16bpp True color.
1108 * These must be set to MATCH WINCTRL[FORM] */
1109 int idx;
1110 idx = (win->w[0].mode_winctrl1 & LCD_WINCTRL1_FRM) >> 25;
1111 var->red = rgb_bitfields[idx][0];
1112 var->green = rgb_bitfields[idx][1];
1113 var->blue = rgb_bitfields[idx][2];
1114 var->transp = rgb_bitfields[idx][3];
1115 break;
1116 }
1117
1118 case 32:
1119 {
1120 /* 32bpp True color.
1121 * These must be set to MATCH WINCTRL[FORM] */
1122 int idx;
1123 idx = (win->w[0].mode_winctrl1 & LCD_WINCTRL1_FRM) >> 25;
1124 var->red = rgb_bitfields[idx][0];
1125 var->green = rgb_bitfields[idx][1];
1126 var->blue = rgb_bitfields[idx][2];
1127 var->transp = rgb_bitfields[idx][3];
1128 break;
1129 }
1130 default:
1131 print_dbg("Unsupported depth %dbpp", var->bits_per_pixel);
1132 return -EINVAL;
1133 }
1134
1135 return 0;
1136}
1137
1138/* fb_set_par
1139 * Set hardware with var settings. This will enable the controller with a
1140 * specific mode, normally validated with the fb_check_var method
1141 */
1142static int au1200fb_fb_set_par(struct fb_info *fbi)
1143{
1144 struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi;
1145
1146 au1200fb_update_fbinfo(fbi);
1147 au1200_setmode(fbdev);
1148
1149 return 0;
1150}
1151
1152/* fb_setcolreg
1153 * Set color in LCD palette.
1154 */
1155static int au1200fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green,
1156 unsigned blue, unsigned transp, struct fb_info *fbi)
1157{
1158 volatile u32 *palette = lcd->palette;
1159 u32 value;
1160
1161 if (regno > (AU1200_LCD_NBR_PALETTE_ENTRIES - 1))
1162 return -EINVAL;
1163
1164 if (fbi->var.grayscale) {
1165 /* Convert color to grayscale */
1166 red = green = blue =
1167 (19595 * red + 38470 * green + 7471 * blue) >> 16;
1168 }
1169
1170 if (fbi->fix.visual == FB_VISUAL_TRUECOLOR) {
1171 /* Place color in the pseudopalette */
1172 if (regno > 16)
1173 return -EINVAL;
1174
1175 palette = (u32*) fbi->pseudo_palette;
1176
1177 red >>= (16 - fbi->var.red.length);
1178 green >>= (16 - fbi->var.green.length);
1179 blue >>= (16 - fbi->var.blue.length);
1180
1181 value = (red << fbi->var.red.offset) |
1182 (green << fbi->var.green.offset)|
1183 (blue << fbi->var.blue.offset);
1184 value &= 0xFFFF;
1185
1186 } else if (1 /*FIX!!! panel_is_active(fbdev->panel)*/) {
1187 /* COLOR TFT PALLETTIZED (use RGB 565) */
1188 value = (red & 0xF800)|((green >> 5) &
1189 0x07E0)|((blue >> 11) & 0x001F);
1190 value &= 0xFFFF;
1191
1192 } else if (0 /*panel_is_color(fbdev->panel)*/) {
1193 /* COLOR STN MODE */
1194 value = 0x1234;
1195 value &= 0xFFF;
1196 } else {
1197 /* MONOCHROME MODE */
1198 value = (green >> 12) & 0x000F;
1199 value &= 0xF;
1200 }
1201
1202 palette[regno] = value;
1203
1204 return 0;
1205}
1206
1207/* fb_blank
1208 * Blank the screen. Depending on the mode, the screen will be
1209 * activated with the backlight color, or desactivated
1210 */
1211static int au1200fb_fb_blank(int blank_mode, struct fb_info *fbi)
1212{
1213 /* Short-circuit screen blanking */
1214 if (noblanking)
1215 return 0;
1216
1217 switch (blank_mode) {
1218
1219 case FB_BLANK_UNBLANK:
1220 case FB_BLANK_NORMAL:
1221 /* printk("turn on panel\n"); */
1222 au1200_setpanel(panel);
1223 break;
1224 case FB_BLANK_VSYNC_SUSPEND:
1225 case FB_BLANK_HSYNC_SUSPEND:
1226 case FB_BLANK_POWERDOWN:
1227 /* printk("turn off panel\n"); */
1228 au1200_setpanel(NULL);
1229 break;
1230 default:
1231 break;
1232
1233 }
1234
1235 /* FB_BLANK_NORMAL is a soft blank */
1236 return (blank_mode == FB_BLANK_NORMAL) ? -EINVAL : 0;
1237}
1238
1239/* fb_mmap
1240 * Map video memory in user space. We don't use the generic fb_mmap
1241 * method mainly to allow the use of the TLB streaming flag (CCA=6)
1242 */
1243static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
1244
1245{
1246 unsigned int len;
1247 unsigned long start=0, off;
1248 struct au1200fb_device *fbdev = (struct au1200fb_device *) info;
1249
1250#ifdef CONFIG_PM
1251 au1xxx_pm_access(LCD_pm_dev);
1252#endif
1253
1254 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
1255 return -EINVAL;
1256 }
1257
1258 start = fbdev->fb_phys & PAGE_MASK;
1259 len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len);
1260
1261 off = vma->vm_pgoff << PAGE_SHIFT;
1262
1263 if ((vma->vm_end - vma->vm_start + off) > len) {
1264 return -EINVAL;
1265 }
1266
1267 off += start;
1268 vma->vm_pgoff = off >> PAGE_SHIFT;
1269
1270 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1271 pgprot_val(vma->vm_page_prot) |= _CACHE_MASK; /* CCA=7 */
1272
1273 vma->vm_flags |= VM_IO;
1274
1275 return io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
1276 vma->vm_end - vma->vm_start,
1277 vma->vm_page_prot);
1278
1279 return 0;
1280}
1281
1282static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata)
1283{
1284
1285 unsigned int hi1, divider;
1286
1287 /* SCREEN_SIZE: user cannot reset size, must switch panel choice */
1288
1289 if (pdata->flags & SCREEN_BACKCOLOR)
1290 lcd->backcolor = pdata->backcolor;
1291
1292 if (pdata->flags & SCREEN_BRIGHTNESS) {
1293
1294 // limit brightness pwm duty to >= 30/1600
1295 if (pdata->brightness < 30) {
1296 pdata->brightness = 30;
1297 }
1298 divider = (lcd->pwmdiv & 0x3FFFF) + 1;
1299 hi1 = (lcd->pwmhi >> 16) + 1;
1300 hi1 = (((pdata->brightness & 0xFF)+1) * divider >> 8);
1301 lcd->pwmhi &= 0xFFFF;
1302 lcd->pwmhi |= (hi1 << 16);
1303 }
1304
1305 if (pdata->flags & SCREEN_COLORKEY)
1306 lcd->colorkey = pdata->colorkey;
1307
1308 if (pdata->flags & SCREEN_MASK)
1309 lcd->colorkeymsk = pdata->mask;
1310 au_sync();
1311}
1312
1313static void get_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata)
1314{
1315 unsigned int hi1, divider;
1316
1317 pdata->xsize = ((lcd->screen & LCD_SCREEN_SX) >> 19) + 1;
1318 pdata->ysize = ((lcd->screen & LCD_SCREEN_SY) >> 8) + 1;
1319
1320 pdata->backcolor = lcd->backcolor;
1321 pdata->colorkey = lcd->colorkey;
1322 pdata->mask = lcd->colorkeymsk;
1323
1324 // brightness
1325 hi1 = (lcd->pwmhi >> 16) + 1;
1326 divider = (lcd->pwmdiv & 0x3FFFF) + 1;
1327 pdata->brightness = ((hi1 << 8) / divider) - 1;
1328 au_sync();
1329}
1330
1331static void set_window(unsigned int plane,
1332 struct au1200_lcd_window_regs_t *pdata)
1333{
1334 unsigned int val, bpp;
1335
1336 /* Window control register 0 */
1337 if (pdata->flags & WIN_POSITION) {
1338 val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_OX |
1339 LCD_WINCTRL0_OY);
1340 val |= ((pdata->xpos << 21) & LCD_WINCTRL0_OX);
1341 val |= ((pdata->ypos << 10) & LCD_WINCTRL0_OY);
1342 lcd->window[plane].winctrl0 = val;
1343 }
1344 if (pdata->flags & WIN_ALPHA_COLOR) {
1345 val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_A);
1346 val |= ((pdata->alpha_color << 2) & LCD_WINCTRL0_A);
1347 lcd->window[plane].winctrl0 = val;
1348 }
1349 if (pdata->flags & WIN_ALPHA_MODE) {
1350 val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_AEN);
1351 val |= ((pdata->alpha_mode << 1) & LCD_WINCTRL0_AEN);
1352 lcd->window[plane].winctrl0 = val;
1353 }
1354
1355 /* Window control register 1 */
1356 if (pdata->flags & WIN_PRIORITY) {
1357 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PRI);
1358 val |= ((pdata->priority << 30) & LCD_WINCTRL1_PRI);
1359 lcd->window[plane].winctrl1 = val;
1360 }
1361 if (pdata->flags & WIN_CHANNEL) {
1362 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PIPE);
1363 val |= ((pdata->channel << 29) & LCD_WINCTRL1_PIPE);
1364 lcd->window[plane].winctrl1 = val;
1365 }
1366 if (pdata->flags & WIN_BUFFER_FORMAT) {
1367 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_FRM);
1368 val |= ((pdata->buffer_format << 25) & LCD_WINCTRL1_FRM);
1369 lcd->window[plane].winctrl1 = val;
1370 }
1371 if (pdata->flags & WIN_COLOR_ORDER) {
1372 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_CCO);
1373 val |= ((pdata->color_order << 24) & LCD_WINCTRL1_CCO);
1374 lcd->window[plane].winctrl1 = val;
1375 }
1376 if (pdata->flags & WIN_PIXEL_ORDER) {
1377 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PO);
1378 val |= ((pdata->pixel_order << 22) & LCD_WINCTRL1_PO);
1379 lcd->window[plane].winctrl1 = val;
1380 }
1381 if (pdata->flags & WIN_SIZE) {
1382 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_SZX |
1383 LCD_WINCTRL1_SZY);
1384 val |= (((pdata->xsize << 11) - 1) & LCD_WINCTRL1_SZX);
1385 val |= (((pdata->ysize) - 1) & LCD_WINCTRL1_SZY);
1386 lcd->window[plane].winctrl1 = val;
1387 /* program buffer line width */
1388 bpp = winbpp(val) / 8;
1389 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_BX);
1390 val |= (((pdata->xsize * bpp) << 8) & LCD_WINCTRL2_BX);
1391 lcd->window[plane].winctrl2 = val;
1392 }
1393
1394 /* Window control register 2 */
1395 if (pdata->flags & WIN_COLORKEY_MODE) {
1396 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_CKMODE);
1397 val |= ((pdata->colorkey_mode << 24) & LCD_WINCTRL2_CKMODE);
1398 lcd->window[plane].winctrl2 = val;
1399 }
1400 if (pdata->flags & WIN_DOUBLE_BUFFER_MODE) {
1401 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_DBM);
1402 val |= ((pdata->double_buffer_mode << 23) & LCD_WINCTRL2_DBM);
1403 lcd->window[plane].winctrl2 = val;
1404 }
1405 if (pdata->flags & WIN_RAM_ARRAY_MODE) {
1406 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_RAM);
1407 val |= ((pdata->ram_array_mode << 21) & LCD_WINCTRL2_RAM);
1408 lcd->window[plane].winctrl2 = val;
1409 }
1410
1411 /* Buffer line width programmed with WIN_SIZE */
1412
1413 if (pdata->flags & WIN_BUFFER_SCALE) {
1414 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_SCX |
1415 LCD_WINCTRL2_SCY);
1416 val |= ((pdata->xsize << 11) & LCD_WINCTRL2_SCX);
1417 val |= ((pdata->ysize) & LCD_WINCTRL2_SCY);
1418 lcd->window[plane].winctrl2 = val;
1419 }
1420
1421 if (pdata->flags & WIN_ENABLE) {
1422 val = lcd->winenable;
1423 val &= ~(1<<plane);
1424 val |= (pdata->enable & 1) << plane;
1425 lcd->winenable = val;
1426 }
1427 au_sync();
1428}
1429
1430static void get_window(unsigned int plane,
1431 struct au1200_lcd_window_regs_t *pdata)
1432{
1433 /* Window control register 0 */
1434 pdata->xpos = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OX) >> 21;
1435 pdata->ypos = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OY) >> 10;
1436 pdata->alpha_color = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_A) >> 2;
1437 pdata->alpha_mode = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_AEN) >> 1;
1438
1439 /* Window control register 1 */
1440 pdata->priority = (lcd->window[plane].winctrl1& LCD_WINCTRL1_PRI) >> 30;
1441 pdata->channel = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_PIPE) >> 29;
1442 pdata->buffer_format = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_FRM) >> 25;
1443 pdata->color_order = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_CCO) >> 24;
1444 pdata->pixel_order = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_PO) >> 22;
1445 pdata->xsize = ((lcd->window[plane].winctrl1 & LCD_WINCTRL1_SZX) >> 11) + 1;
1446 pdata->ysize = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_SZY) + 1;
1447
1448 /* Window control register 2 */
1449 pdata->colorkey_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_CKMODE) >> 24;
1450 pdata->double_buffer_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_DBM) >> 23;
1451 pdata->ram_array_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_RAM) >> 21;
1452
1453 pdata->enable = (lcd->winenable >> plane) & 1;
1454 au_sync();
1455}
1456
1457static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd,
1458 unsigned long arg)
1459{
1460 int plane;
1461 int val;
1462
1463#ifdef CONFIG_PM
1464 au1xxx_pm_access(LCD_pm_dev);
1465#endif
1466
1467 plane = fbinfo2index(info);
1468 print_dbg("au1200fb: ioctl %d on plane %d\n", cmd, plane);
1469
1470 if (cmd == AU1200_LCD_FB_IOCTL) {
1471 struct au1200_lcd_iodata_t iodata;
1472
1473 if (copy_from_user(&iodata, (void __user *) arg, sizeof(iodata)))
1474 return -EFAULT;
1475
1476 print_dbg("FB IOCTL called\n");
1477
1478 switch (iodata.subcmd) {
1479 case AU1200_LCD_SET_SCREEN:
1480 print_dbg("AU1200_LCD_SET_SCREEN\n");
1481 set_global(cmd, &iodata.global);
1482 break;
1483
1484 case AU1200_LCD_GET_SCREEN:
1485 print_dbg("AU1200_LCD_GET_SCREEN\n");
1486 get_global(cmd, &iodata.global);
1487 break;
1488
1489 case AU1200_LCD_SET_WINDOW:
1490 print_dbg("AU1200_LCD_SET_WINDOW\n");
1491 set_window(plane, &iodata.window);
1492 break;
1493
1494 case AU1200_LCD_GET_WINDOW:
1495 print_dbg("AU1200_LCD_GET_WINDOW\n");
1496 get_window(plane, &iodata.window);
1497 break;
1498
1499 case AU1200_LCD_SET_PANEL:
1500 print_dbg("AU1200_LCD_SET_PANEL\n");
1501 if ((iodata.global.panel_choice >= 0) &&
1502 (iodata.global.panel_choice <
1503 NUM_PANELS))
1504 {
1505 struct panel_settings *newpanel;
1506 panel_index = iodata.global.panel_choice;
1507 newpanel = &known_lcd_panels[panel_index];
1508 au1200_setpanel(newpanel);
1509 }
1510 break;
1511
1512 case AU1200_LCD_GET_PANEL:
1513 print_dbg("AU1200_LCD_GET_PANEL\n");
1514 iodata.global.panel_choice = panel_index;
1515 break;
1516
1517 default:
1518 return -EINVAL;
1519 }
1520
1521 val = copy_to_user((void __user *) arg, &iodata, sizeof(iodata));
1522 if (val) {
1523 print_dbg("error: could not copy %d bytes\n", val);
1524 return -EFAULT;
1525 }
1526 }
1527
1528 return 0;
1529}
1530
1531
1532static struct fb_ops au1200fb_fb_ops = {
1533 .owner = THIS_MODULE,
1534 .fb_check_var = au1200fb_fb_check_var,
1535 .fb_set_par = au1200fb_fb_set_par,
1536 .fb_setcolreg = au1200fb_fb_setcolreg,
1537 .fb_blank = au1200fb_fb_blank,
1538 .fb_fillrect = cfb_fillrect,
1539 .fb_copyarea = cfb_copyarea,
1540 .fb_imageblit = cfb_imageblit,
1541 .fb_sync = NULL,
1542 .fb_ioctl = au1200fb_ioctl,
1543 .fb_mmap = au1200fb_fb_mmap,
1544};
1545
1546/*-------------------------------------------------------------------------*/
1547
1548static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id, struct pt_regs *regs)
1549{
1550 /* Nothing to do for now, just clear any pending interrupt */
1551 lcd->intstatus = lcd->intstatus;
1552 au_sync();
1553
1554 return IRQ_HANDLED;
1555}
1556
1557/*-------------------------------------------------------------------------*/
1558
1559/* AU1200 LCD device probe helpers */
1560
1561static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
1562{
1563 struct fb_info *fbi = &fbdev->fb_info;
1564 int bpp;
1565
1566 memset(fbi, 0, sizeof(struct fb_info));
1567 fbi->fbops = &au1200fb_fb_ops;
1568
1569 bpp = winbpp(win->w[fbdev->plane].mode_winctrl1);
1570
1571 /* Copy monitor specs from panel data */
1572 /* fixme: we're setting up LCD controller windows, so these dont give a
1573 damn as to what the monitor specs are (the panel itself does, but that
1574 isnt done here...so maybe need a generic catchall monitor setting??? */
1575 memcpy(&fbi->monspecs, &panel->monspecs, sizeof(struct fb_monspecs));
1576
1577 /* We first try the user mode passed in argument. If that failed,
1578 * or if no one has been specified, we default to the first mode of the
1579 * panel list. Note that after this call, var data will be set */
1580 if (!fb_find_mode(&fbi->var,
1581 fbi,
1582 NULL, /* drv_info.opt_mode, */
1583 fbi->monspecs.modedb,
1584 fbi->monspecs.modedb_len,
1585 fbi->monspecs.modedb,
1586 bpp)) {
1587
1588 print_err("Cannot find valid mode for panel %s", panel->name);
1589 return -EFAULT;
1590 }
1591
1592 fbi->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
1593 if (!fbi->pseudo_palette) {
1594 return -ENOMEM;
1595 }
1596 memset(fbi->pseudo_palette, 0, sizeof(u32) * 16);
1597
1598 if (fb_alloc_cmap(&fbi->cmap, AU1200_LCD_NBR_PALETTE_ENTRIES, 0) < 0) {
1599 print_err("Fail to allocate colormap (%d entries)",
1600 AU1200_LCD_NBR_PALETTE_ENTRIES);
1601 kfree(fbi->pseudo_palette);
1602 return -EFAULT;
1603 }
1604
1605 strncpy(fbi->fix.id, "AU1200", sizeof(fbi->fix.id));
1606 fbi->fix.smem_start = fbdev->fb_phys;
1607 fbi->fix.smem_len = fbdev->fb_len;
1608 fbi->fix.type = FB_TYPE_PACKED_PIXELS;
1609 fbi->fix.xpanstep = 0;
1610 fbi->fix.ypanstep = 0;
1611 fbi->fix.mmio_start = 0;
1612 fbi->fix.mmio_len = 0;
1613 fbi->fix.accel = FB_ACCEL_NONE;
1614
1615 fbi->screen_base = (char __iomem *) fbdev->fb_mem;
1616
1617 au1200fb_update_fbinfo(fbi);
1618
1619 return 0;
1620}
1621
1622/*-------------------------------------------------------------------------*/
1623
1624/* AU1200 LCD controller device driver */
1625
1626static int au1200fb_drv_probe(struct device *dev)
1627{
1628 struct au1200fb_device *fbdev;
1629 unsigned long page;
1630 int bpp, plane, ret;
1631
1632 if (!dev)
1633 return -EINVAL;
1634
1635 for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) {
1636 bpp = winbpp(win->w[plane].mode_winctrl1);
1637 if (win->w[plane].xres == 0)
1638 win->w[plane].xres = panel->Xres;
1639 if (win->w[plane].yres == 0)
1640 win->w[plane].yres = panel->Yres;
1641
1642 fbdev = &_au1200fb_devices[plane];
1643 memset(fbdev, 0, sizeof(struct au1200fb_device));
1644 fbdev->plane = plane;
1645
1646 /* Allocate the framebuffer to the maximum screen size */
1647 fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8;
1648
1649 fbdev->fb_mem = dma_alloc_noncoherent(dev,
1650 PAGE_ALIGN(fbdev->fb_len),
1651 &fbdev->fb_phys, GFP_KERNEL);
1652 if (!fbdev->fb_mem) {
1653 print_err("fail to allocate frambuffer (size: %dK))",
1654 fbdev->fb_len / 1024);
1655 return -ENOMEM;
1656 }
1657
1658 /*
1659 * Set page reserved so that mmap will work. This is necessary
1660 * since we'll be remapping normal memory.
1661 */
1662 for (page = (unsigned long)fbdev->fb_phys;
1663 page < PAGE_ALIGN((unsigned long)fbdev->fb_phys +
1664 fbdev->fb_len);
1665 page += PAGE_SIZE) {
1666 SetPageReserved(pfn_to_page(page >> PAGE_SHIFT)); /* LCD DMA is NOT coherent on Au1200 */
1667 }
1668 print_dbg("Framebuffer memory map at %p", fbdev->fb_mem);
1669 print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024);
1670
1671 /* Init FB data */
1672 if ((ret = au1200fb_init_fbinfo(fbdev)) < 0)
1673 goto failed;
1674
1675 /* Register new framebuffer */
1676 if ((ret = register_framebuffer(&fbdev->fb_info)) < 0) {
1677 print_err("cannot register new framebuffer");
1678 goto failed;
1679 }
1680
1681 au1200fb_fb_set_par(&fbdev->fb_info);
1682
1683#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
1684 if (plane == 0)
1685 if (fb_prepare_logo(&fbdev->fb_info, FB_ROTATE_UR)) {
1686 /* Start display and show logo on boot */
1687 fb_set_cmap(&fbdev->fb_info.cmap,
1688 &fbdev->fb_info);
1689
1690 fb_show_logo(&fbdev->fb_info, FB_ROTATE_UR);
1691 }
1692#endif
1693 }
1694
1695 /* Now hook interrupt too */
1696 if ((ret = request_irq(AU1200_LCD_INT, au1200fb_handle_irq,
1697 SA_INTERRUPT | SA_SHIRQ, "lcd", (void *)dev)) < 0) {
1698 print_err("fail to request interrupt line %d (err: %d)",
1699 AU1200_LCD_INT, ret);
1700 goto failed;
1701 }
1702
1703 return 0;
1704
1705failed:
1706 /* NOTE: This only does the current plane/window that failed; others are still active */
1707 if (fbdev->fb_mem)
1708 dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len),
1709 fbdev->fb_mem, fbdev->fb_phys);
1710 if (fbdev->fb_info.cmap.len != 0)
1711 fb_dealloc_cmap(&fbdev->fb_info.cmap);
1712 if (fbdev->fb_info.pseudo_palette)
1713 kfree(fbdev->fb_info.pseudo_palette);
1714 if (plane == 0)
1715 free_irq(AU1200_LCD_INT, (void*)dev);
1716 return ret;
1717}
1718
1719static int au1200fb_drv_remove(struct device *dev)
1720{
1721 struct au1200fb_device *fbdev;
1722 int plane;
1723
1724 if (!dev)
1725 return -ENODEV;
1726
1727 /* Turn off the panel */
1728 au1200_setpanel(NULL);
1729
1730 for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane)
1731 {
1732 fbdev = &_au1200fb_devices[plane];
1733
1734 /* Clean up all probe data */
1735 unregister_framebuffer(&fbdev->fb_info);
1736 if (fbdev->fb_mem)
1737 dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len),
1738 fbdev->fb_mem, fbdev->fb_phys);
1739 if (fbdev->fb_info.cmap.len != 0)
1740 fb_dealloc_cmap(&fbdev->fb_info.cmap);
1741 if (fbdev->fb_info.pseudo_palette)
1742 kfree(fbdev->fb_info.pseudo_palette);
1743 }
1744
1745 free_irq(AU1200_LCD_INT, (void *)dev);
1746
1747 return 0;
1748}
1749
1750#ifdef CONFIG_PM
1751static int au1200fb_drv_suspend(struct device *dev, u32 state, u32 level)
1752{
1753 /* TODO */
1754 return 0;
1755}
1756
1757static int au1200fb_drv_resume(struct device *dev, u32 level)
1758{
1759 /* TODO */
1760 return 0;
1761}
1762#endif /* CONFIG_PM */
1763
1764static struct device_driver au1200fb_driver = {
1765 .name = "au1200-lcd",
1766 .bus = &platform_bus_type,
1767 .probe = au1200fb_drv_probe,
1768 .remove = au1200fb_drv_remove,
1769#ifdef CONFIG_PM
1770 .suspend = au1200fb_drv_suspend,
1771 .resume = au1200fb_drv_resume,
1772#endif
1773};
1774
1775/*-------------------------------------------------------------------------*/
1776
1777/* Kernel driver */
1778
1779static void au1200fb_setup(void)
1780{
1781 char* options = NULL;
1782 char* this_opt;
1783 int num_panels = ARRAY_SIZE(known_lcd_panels);
1784 int panel_idx = -1;
1785
1786 fb_get_options(DRIVER_NAME, &options);
1787
1788 if (options) {
1789 while ((this_opt = strsep(&options,",")) != NULL) {
1790 /* Panel option - can be panel name,
1791 * "bs" for board-switch, or number/index */
1792 if (!strncmp(this_opt, "panel:", 6)) {
1793 int i;
1794 long int li;
1795 char *endptr;
1796 this_opt += 6;
1797 /* First check for index, which allows
1798 * to short circuit this mess */
1799 li = simple_strtol(this_opt, &endptr, 0);
1800 if (*endptr == '\0') {
1801 panel_idx = (int)li;
1802 }
1803 else if (strcmp(this_opt, "bs") == 0) {
1804 extern int board_au1200fb_panel(void);
1805 panel_idx = board_au1200fb_panel();
1806 }
1807
1808 else
1809 for (i = 0; i < num_panels; i++) {
1810 if (!strcmp(this_opt, known_lcd_panels[i].name)) {
1811 panel_idx = i;
1812 break;
1813 }
1814 }
1815
1816 if ((panel_idx < 0) || (panel_idx >= num_panels)) {
1817 print_warn("Panel %s not supported!", this_opt);
1818 }
1819 else
1820 panel_index = panel_idx;
1821 }
1822
1823 else if (strncmp(this_opt, "nohwcursor", 10) == 0) {
1824 nohwcursor = 1;
1825 }
1826
1827 /* Unsupported option */
1828 else {
1829 print_warn("Unsupported option \"%s\"", this_opt);
1830 }
1831 }
1832 }
1833}
1834
1835#ifdef CONFIG_PM
1836static int au1200fb_pm_callback(au1xxx_power_dev_t *dev,
1837 au1xxx_request_t request, void *data) {
1838 int retval = -1;
1839 unsigned int d = 0;
1840 unsigned int brightness = 0;
1841
1842 if (request == AU1XXX_PM_SLEEP) {
1843 board_au1200fb_panel_shutdown();
1844 }
1845 else if (request == AU1XXX_PM_WAKEUP) {
1846 if(dev->prev_state == SLEEP_STATE)
1847 {
1848 int plane;
1849 au1200_setpanel(panel);
1850 for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) {
1851 struct au1200fb_device *fbdev;
1852 fbdev = &_au1200fb_devices[plane];
1853 au1200fb_fb_set_par(&fbdev->fb_info);
1854 }
1855 }
1856
1857 d = *((unsigned int*)data);
1858 if(d <=10) brightness = 26;
1859 else if(d<=20) brightness = 51;
1860 else if(d<=30) brightness = 77;
1861 else if(d<=40) brightness = 102;
1862 else if(d<=50) brightness = 128;
1863 else if(d<=60) brightness = 153;
1864 else if(d<=70) brightness = 179;
1865 else if(d<=80) brightness = 204;
1866 else if(d<=90) brightness = 230;
1867 else brightness = 255;
1868 set_brightness(brightness);
1869 } else if (request == AU1XXX_PM_GETSTATUS) {
1870 return dev->cur_state;
1871 } else if (request == AU1XXX_PM_ACCESS) {
1872 if (dev->cur_state != SLEEP_STATE)
1873 return retval;
1874 else {
1875 au1200_setpanel(panel);
1876 }
1877 } else if (request == AU1XXX_PM_IDLE) {
1878 } else if (request == AU1XXX_PM_CLEANUP) {
1879 }
1880
1881 return retval;
1882}
1883#endif
1884
1885static int __init au1200fb_init(void)
1886{
1887 print_info("" DRIVER_DESC "");
1888
1889 /* Setup driver with options */
1890 au1200fb_setup();
1891
1892 /* Point to the panel selected */
1893 panel = &known_lcd_panels[panel_index];
1894 win = &windows[window_index];
1895
1896 printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name);
1897 printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name);
1898
1899 /* Kickstart the panel, the framebuffers/windows come soon enough */
1900 au1200_setpanel(panel);
1901
1902 #ifdef CONFIG_PM
1903 LCD_pm_dev = new_au1xxx_power_device("LCD", &au1200fb_pm_callback, NULL);
1904 if ( LCD_pm_dev == NULL)
1905 printk(KERN_INFO "Unable to create a power management device entry for the au1200fb.\n");
1906 else
1907 printk(KERN_INFO "Power management device entry for the au1200fb loaded.\n");
1908 #endif
1909
1910 return driver_register(&au1200fb_driver);
1911}
1912
1913static void __exit au1200fb_cleanup(void)
1914{
1915 driver_unregister(&au1200fb_driver);
1916}
1917
1918module_init(au1200fb_init);
1919module_exit(au1200fb_cleanup);
1920
1921MODULE_DESCRIPTION(DRIVER_DESC);
1922MODULE_LICENSE("GPL");
1923/*
1924 * BRIEF MODULE DESCRIPTION
1925 * Au1200 LCD Driver.
1926 *
1927 * Copyright 2004-2005 AMD
1928 * Author: AMD
1929 *
1930 * Based on:
1931 * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device
1932 * Created 28 Dec 1997 by Geert Uytterhoeven
1933 *
1934 * This program is free software; you can redistribute it and/or modify it
1935 * under the terms of the GNU General Public License as published by the
1936 * Free Software Foundation; either version 2 of the License, or (at your
1937 * option) any later version.
1938 *
1939 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1940 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1941 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
1942 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1943 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1944 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
1945 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1946 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1947 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1948 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1949 *
1950 * You should have received a copy of the GNU General Public License along
1951 * with this program; if not, write to the Free Software Foundation, Inc.,
1952 * 675 Mass Ave, Cambridge, MA 02139, USA.
1953 */
1954
1955#include <linux/module.h>
1956#include <linux/platform_device.h>
1957#include <linux/kernel.h>
1958#include <linux/errno.h>
1959#include <linux/string.h>
1960#include <linux/mm.h>
1961#include <linux/fb.h>
1962#include <linux/init.h>
1963#include <linux/interrupt.h>
1964#include <linux/ctype.h>
1965#include <linux/dma-mapping.h>
1966
1967#include <asm/mach-au1x00/au1000.h>
1968#include "au1200fb.h"
1969
1970#ifdef CONFIG_PM
1971#include <asm/mach-au1x00/au1xxx_pm.h>
1972#endif
1973
1974#ifndef CONFIG_FB_AU1200_DEVS
1975#define CONFIG_FB_AU1200_DEVS 4
1976#endif
1977
1978#define DRIVER_NAME "au1200fb"
1979#define DRIVER_DESC "LCD controller driver for AU1200 processors"
1980
1981#define DEBUG 1
1982
1983#define print_err(f, arg...) printk(KERN_ERR DRIVER_NAME ": " f "\n", ## arg)
1984#define print_warn(f, arg...) printk(KERN_WARNING DRIVER_NAME ": " f "\n", ## arg)
1985#define print_info(f, arg...) printk(KERN_INFO DRIVER_NAME ": " f "\n", ## arg)
1986
1987#if DEBUG
1988#define print_dbg(f, arg...) printk(KERN_DEBUG __FILE__ ": " f "\n", ## arg)
1989#else
1990#define print_dbg(f, arg...) do {} while (0)
1991#endif
1992
1993
1994#define AU1200_LCD_FB_IOCTL 0x46FF
1995
1996#define AU1200_LCD_SET_SCREEN 1
1997#define AU1200_LCD_GET_SCREEN 2
1998#define AU1200_LCD_SET_WINDOW 3
1999#define AU1200_LCD_GET_WINDOW 4
2000#define AU1200_LCD_SET_PANEL 5
2001#define AU1200_LCD_GET_PANEL 6
2002
2003#define SCREEN_SIZE (1<< 1)
2004#define SCREEN_BACKCOLOR (1<< 2)
2005#define SCREEN_BRIGHTNESS (1<< 3)
2006#define SCREEN_COLORKEY (1<< 4)
2007#define SCREEN_MASK (1<< 5)
2008
2009struct au1200_lcd_global_regs_t {
2010 unsigned int flags;
2011 unsigned int xsize;
2012 unsigned int ysize;
2013 unsigned int backcolor;
2014 unsigned int brightness;
2015 unsigned int colorkey;
2016 unsigned int mask;
2017 unsigned int panel_choice;
2018 char panel_desc[80];
2019
2020};
2021
2022#define WIN_POSITION (1<< 0)
2023#define WIN_ALPHA_COLOR (1<< 1)
2024#define WIN_ALPHA_MODE (1<< 2)
2025#define WIN_PRIORITY (1<< 3)
2026#define WIN_CHANNEL (1<< 4)
2027#define WIN_BUFFER_FORMAT (1<< 5)
2028#define WIN_COLOR_ORDER (1<< 6)
2029#define WIN_PIXEL_ORDER (1<< 7)
2030#define WIN_SIZE (1<< 8)
2031#define WIN_COLORKEY_MODE (1<< 9)
2032#define WIN_DOUBLE_BUFFER_MODE (1<< 10)
2033#define WIN_RAM_ARRAY_MODE (1<< 11)
2034#define WIN_BUFFER_SCALE (1<< 12)
2035#define WIN_ENABLE (1<< 13)
2036
2037struct au1200_lcd_window_regs_t {
2038 unsigned int flags;
2039 unsigned int xpos;
2040 unsigned int ypos;
2041 unsigned int alpha_color;
2042 unsigned int alpha_mode;
2043 unsigned int priority;
2044 unsigned int channel;
2045 unsigned int buffer_format;
2046 unsigned int color_order;
2047 unsigned int pixel_order;
2048 unsigned int xsize;
2049 unsigned int ysize;
2050 unsigned int colorkey_mode;
2051 unsigned int double_buffer_mode;
2052 unsigned int ram_array_mode;
2053 unsigned int xscale;
2054 unsigned int yscale;
2055 unsigned int enable;
2056};
2057
2058
2059struct au1200_lcd_iodata_t {
2060 unsigned int subcmd;
2061 struct au1200_lcd_global_regs_t global;
2062 struct au1200_lcd_window_regs_t window;
2063};
2064
2065#if defined(__BIG_ENDIAN)
2066#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_11
2067#else
2068#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_00
2069#endif
2070#define LCD_CONTROL_DEFAULT_SBPPF LCD_CONTROL_SBPPF_565
2071
2072/* Private, per-framebuffer management information (independent of the panel itself) */
2073struct au1200fb_device {
2074 struct fb_info fb_info; /* FB driver info record */
2075
2076 int plane;
2077 unsigned char* fb_mem; /* FrameBuffer memory map */
2078 unsigned int fb_len;
2079 dma_addr_t fb_phys;
2080};
2081
2082static struct au1200fb_device _au1200fb_devices[CONFIG_FB_AU1200_DEVS];
2083/********************************************************************/
2084
2085/* LCD controller restrictions */
2086#define AU1200_LCD_MAX_XRES 1280
2087#define AU1200_LCD_MAX_YRES 1024
2088#define AU1200_LCD_MAX_BPP 32
2089#define AU1200_LCD_MAX_CLK 96000000 /* fixme: this needs to go away ? */
2090#define AU1200_LCD_NBR_PALETTE_ENTRIES 256
2091
2092/* Default number of visible screen buffer to allocate */
2093#define AU1200FB_NBR_VIDEO_BUFFERS 1
2094
2095/********************************************************************/
2096
2097static struct au1200_lcd *lcd = (struct au1200_lcd *) AU1200_LCD_ADDR;
2098static int window_index = 2; /* default is zero */
2099static int panel_index = 2; /* default is zero */
2100static struct window_settings *win;
2101static struct panel_settings *panel;
2102static int noblanking = 1;
2103static int nohwcursor = 0;
2104
2105struct window_settings {
2106 unsigned char name[64];
2107 uint32 mode_backcolor;
2108 uint32 mode_colorkey;
2109 uint32 mode_colorkeymsk;
2110 struct {
2111 int xres;
2112 int yres;
2113 int xpos;
2114 int ypos;
2115 uint32 mode_winctrl1; /* winctrl1[FRM,CCO,PO,PIPE] */
2116 uint32 mode_winenable;
2117 } w[4];
2118};
2119
2120#if defined(__BIG_ENDIAN)
2121#define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_00
2122#else
2123#define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_01
2124#endif
2125
2126extern int board_au1200fb_panel_init (void);
2127extern int board_au1200fb_panel_shutdown (void);
2128
2129#ifdef CONFIG_PM
2130int au1200fb_pm_callback(au1xxx_power_dev_t *dev,
2131 au1xxx_request_t request, void *data);
2132au1xxx_power_dev_t *LCD_pm_dev;
2133#endif
2134
2135/*
2136 * Default window configurations
2137 */
2138static struct window_settings windows[] = {
2139 { /* Index 0 */
2140 "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
2141 /* mode_backcolor */ 0x006600ff,
2142 /* mode_colorkey,msk*/ 0, 0,
2143 {
2144 {
2145 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2146 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2147 LCD_WINCTRL1_PO_16BPP,
2148 /* mode_winenable*/ LCD_WINENABLE_WEN0,
2149 },
2150 {
2151 /* xres, yres, xpos, ypos */ 100, 100, 100, 100,
2152 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2153 LCD_WINCTRL1_PO_16BPP |
2154 LCD_WINCTRL1_PIPE,
2155 /* mode_winenable*/ LCD_WINENABLE_WEN1,
2156 },
2157 {
2158 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2159 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2160 LCD_WINCTRL1_PO_16BPP,
2161 /* mode_winenable*/ 0,
2162 },
2163 {
2164 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2165 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2166 LCD_WINCTRL1_PO_16BPP |
2167 LCD_WINCTRL1_PIPE,
2168 /* mode_winenable*/ 0,
2169 },
2170 },
2171 },
2172
2173 { /* Index 1 */
2174 "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
2175 /* mode_backcolor */ 0x006600ff,
2176 /* mode_colorkey,msk*/ 0, 0,
2177 {
2178 {
2179 /* xres, yres, xpos, ypos */ 320, 240, 5, 5,
2180 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_24BPP |
2181 LCD_WINCTRL1_PO_00,
2182 /* mode_winenable*/ LCD_WINENABLE_WEN0,
2183 },
2184 {
2185 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2186 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565
2187 | LCD_WINCTRL1_PO_16BPP,
2188 /* mode_winenable*/ 0,
2189 },
2190 {
2191 /* xres, yres, xpos, ypos */ 100, 100, 0, 0,
2192 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2193 LCD_WINCTRL1_PO_16BPP |
2194 LCD_WINCTRL1_PIPE,
2195 /* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/,
2196 },
2197 {
2198 /* xres, yres, xpos, ypos */ 200, 25, 0, 0,
2199 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2200 LCD_WINCTRL1_PO_16BPP |
2201 LCD_WINCTRL1_PIPE,
2202 /* mode_winenable*/ 0,
2203 },
2204 },
2205 },
2206 { /* Index 2 */
2207 "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
2208 /* mode_backcolor */ 0x006600ff,
2209 /* mode_colorkey,msk*/ 0, 0,
2210 {
2211 {
2212 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2213 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2214 LCD_WINCTRL1_PO_16BPP,
2215 /* mode_winenable*/ LCD_WINENABLE_WEN0,
2216 },
2217 {
2218 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2219 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2220 LCD_WINCTRL1_PO_16BPP,
2221 /* mode_winenable*/ 0,
2222 },
2223 {
2224 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2225 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_32BPP |
2226 LCD_WINCTRL1_PO_00|LCD_WINCTRL1_PIPE,
2227 /* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/,
2228 },
2229 {
2230 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2231 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2232 LCD_WINCTRL1_PO_16BPP |
2233 LCD_WINCTRL1_PIPE,
2234 /* mode_winenable*/ 0,
2235 },
2236 },
2237 },
2238 /* Need VGA 640 @ 24bpp, @ 32bpp */
2239 /* Need VGA 800 @ 24bpp, @ 32bpp */
2240 /* Need VGA 1024 @ 24bpp, @ 32bpp */
2241};
2242
2243/*
2244 * Controller configurations for various panels.
2245 */
2246
2247struct panel_settings
2248{
2249 const char name[25]; /* Full name <vendor>_<model> */
2250
2251 struct fb_monspecs monspecs; /* FB monitor specs */
2252
2253 /* panel timings */
2254 uint32 mode_screen;
2255 uint32 mode_horztiming;
2256 uint32 mode_verttiming;
2257 uint32 mode_clkcontrol;
2258 uint32 mode_pwmdiv;
2259 uint32 mode_pwmhi;
2260 uint32 mode_outmask;
2261 uint32 mode_fifoctrl;
2262 uint32 mode_toyclksrc;
2263 uint32 mode_backlight;
2264 uint32 mode_auxpll;
2265 int (*device_init)(void);
2266 int (*device_shutdown)(void);
2267#define Xres min_xres
2268#define Yres min_yres
2269 u32 min_xres; /* Minimum horizontal resolution */
2270 u32 max_xres; /* Maximum horizontal resolution */
2271 u32 min_yres; /* Minimum vertical resolution */
2272 u32 max_yres; /* Maximum vertical resolution */
2273};
2274
2275/********************************************************************/
2276/* fixme: Maybe a modedb for the CRT ? otherwise panels should be as-is */
2277
2278/* List of panels known to work with the AU1200 LCD controller.
2279 * To add a new panel, enter the same specifications as the
2280 * Generic_TFT one, and MAKE SURE that it doesn't conflicts
2281 * with the controller restrictions. Restrictions are:
2282 *
2283 * STN color panels: max_bpp <= 12
2284 * STN mono panels: max_bpp <= 4
2285 * TFT panels: max_bpp <= 16
2286 * max_xres <= 800
2287 * max_yres <= 600
2288 */
2289static struct panel_settings known_lcd_panels[] =
2290{
2291 [0] = { /* QVGA 320x240 H:33.3kHz V:110Hz */
2292 .name = "QVGA_320x240",
2293 .monspecs = {
2294 .modedb = NULL,
2295 .modedb_len = 0,
2296 .hfmin = 30000,
2297 .hfmax = 70000,
2298 .vfmin = 60,
2299 .vfmax = 60,
2300 .dclkmin = 6000000,
2301 .dclkmax = 28000000,
2302 .input = FB_DISP_RGB,
2303 },
2304 .mode_screen = LCD_SCREEN_SX_N(320) |
2305 LCD_SCREEN_SY_N(240),
2306 .mode_horztiming = 0x00c4623b,
2307 .mode_verttiming = 0x00502814,
2308 .mode_clkcontrol = 0x00020002, /* /4=24Mhz */
2309 .mode_pwmdiv = 0x00000000,
2310 .mode_pwmhi = 0x00000000,
2311 .mode_outmask = 0x00FFFFFF,
2312 .mode_fifoctrl = 0x2f2f2f2f,
2313 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2314 .mode_backlight = 0x00000000,
2315 .mode_auxpll = 8, /* 96MHz AUXPLL */
2316 .device_init = NULL,
2317 .device_shutdown = NULL,
2318 320, 320,
2319 240, 240,
2320 },
2321
2322 [1] = { /* VGA 640x480 H:30.3kHz V:58Hz */
2323 .name = "VGA_640x480",
2324 .monspecs = {
2325 .modedb = NULL,
2326 .modedb_len = 0,
2327 .hfmin = 30000,
2328 .hfmax = 70000,
2329 .vfmin = 60,
2330 .vfmax = 60,
2331 .dclkmin = 6000000,
2332 .dclkmax = 28000000,
2333 .input = FB_DISP_RGB,
2334 },
2335 .mode_screen = 0x13f9df80,
2336 .mode_horztiming = 0x003c5859,
2337 .mode_verttiming = 0x00741201,
2338 .mode_clkcontrol = 0x00020001, /* /4=24Mhz */
2339 .mode_pwmdiv = 0x00000000,
2340 .mode_pwmhi = 0x00000000,
2341 .mode_outmask = 0x00FFFFFF,
2342 .mode_fifoctrl = 0x2f2f2f2f,
2343 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2344 .mode_backlight = 0x00000000,
2345 .mode_auxpll = 8, /* 96MHz AUXPLL */
2346 .device_init = NULL,
2347 .device_shutdown = NULL,
2348 640, 480,
2349 640, 480,
2350 },
2351
2352 [2] = { /* SVGA 800x600 H:46.1kHz V:69Hz */
2353 .name = "SVGA_800x600",
2354 .monspecs = {
2355 .modedb = NULL,
2356 .modedb_len = 0,
2357 .hfmin = 30000,
2358 .hfmax = 70000,
2359 .vfmin = 60,
2360 .vfmax = 60,
2361 .dclkmin = 6000000,
2362 .dclkmax = 28000000,
2363 .input = FB_DISP_RGB,
2364 },
2365 .mode_screen = 0x18fa5780,
2366 .mode_horztiming = 0x00dc7e77,
2367 .mode_verttiming = 0x00584805,
2368 .mode_clkcontrol = 0x00020000, /* /2=48Mhz */
2369 .mode_pwmdiv = 0x00000000,
2370 .mode_pwmhi = 0x00000000,
2371 .mode_outmask = 0x00FFFFFF,
2372 .mode_fifoctrl = 0x2f2f2f2f,
2373 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2374 .mode_backlight = 0x00000000,
2375 .mode_auxpll = 8, /* 96MHz AUXPLL */
2376 .device_init = NULL,
2377 .device_shutdown = NULL,
2378 800, 800,
2379 600, 600,
2380 },
2381
2382 [3] = { /* XVGA 1024x768 H:56.2kHz V:70Hz */
2383 .name = "XVGA_1024x768",
2384 .monspecs = {
2385 .modedb = NULL,
2386 .modedb_len = 0,
2387 .hfmin = 30000,
2388 .hfmax = 70000,
2389 .vfmin = 60,
2390 .vfmax = 60,
2391 .dclkmin = 6000000,
2392 .dclkmax = 28000000,
2393 .input = FB_DISP_RGB,
2394 },
2395 .mode_screen = 0x1ffaff80,
2396 .mode_horztiming = 0x007d0e57,
2397 .mode_verttiming = 0x00740a01,
2398 .mode_clkcontrol = 0x000A0000, /* /1 */
2399 .mode_pwmdiv = 0x00000000,
2400 .mode_pwmhi = 0x00000000,
2401 .mode_outmask = 0x00FFFFFF,
2402 .mode_fifoctrl = 0x2f2f2f2f,
2403 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2404 .mode_backlight = 0x00000000,
2405 .mode_auxpll = 6, /* 72MHz AUXPLL */
2406 .device_init = NULL,
2407 .device_shutdown = NULL,
2408 1024, 1024,
2409 768, 768,
2410 },
2411
2412 [4] = { /* XVGA XVGA 1280x1024 H:68.5kHz V:65Hz */
2413 .name = "XVGA_1280x1024",
2414 .monspecs = {
2415 .modedb = NULL,
2416 .modedb_len = 0,
2417 .hfmin = 30000,
2418 .hfmax = 70000,
2419 .vfmin = 60,
2420 .vfmax = 60,
2421 .dclkmin = 6000000,
2422 .dclkmax = 28000000,
2423 .input = FB_DISP_RGB,
2424 },
2425 .mode_screen = 0x27fbff80,
2426 .mode_horztiming = 0x00cdb2c7,
2427 .mode_verttiming = 0x00600002,
2428 .mode_clkcontrol = 0x000A0000, /* /1 */
2429 .mode_pwmdiv = 0x00000000,
2430 .mode_pwmhi = 0x00000000,
2431 .mode_outmask = 0x00FFFFFF,
2432 .mode_fifoctrl = 0x2f2f2f2f,
2433 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2434 .mode_backlight = 0x00000000,
2435 .mode_auxpll = 10, /* 120MHz AUXPLL */
2436 .device_init = NULL,
2437 .device_shutdown = NULL,
2438 1280, 1280,
2439 1024, 1024,
2440 },
2441
2442 [5] = { /* Samsung 1024x768 TFT */
2443 .name = "Samsung_1024x768_TFT",
2444 .monspecs = {
2445 .modedb = NULL,
2446 .modedb_len = 0,
2447 .hfmin = 30000,
2448 .hfmax = 70000,
2449 .vfmin = 60,
2450 .vfmax = 60,
2451 .dclkmin = 6000000,
2452 .dclkmax = 28000000,
2453 .input = FB_DISP_RGB,
2454 },
2455 .mode_screen = 0x1ffaff80,
2456 .mode_horztiming = 0x018cc677,
2457 .mode_verttiming = 0x00241217,
2458 .mode_clkcontrol = 0x00000000, /* SCB 0x1 /4=24Mhz */
2459 .mode_pwmdiv = 0x8000063f, /* SCB 0x0 */
2460 .mode_pwmhi = 0x03400000, /* SCB 0x0 */
2461 .mode_outmask = 0x00FFFFFF,
2462 .mode_fifoctrl = 0x2f2f2f2f,
2463 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2464 .mode_backlight = 0x00000000,
2465 .mode_auxpll = 8, /* 96MHz AUXPLL */
2466 .device_init = board_au1200fb_panel_init,
2467 .device_shutdown = board_au1200fb_panel_shutdown,
2468 1024, 1024,
2469 768, 768,
2470 },
2471
2472 [6] = { /* Toshiba 640x480 TFT */
2473 .name = "Toshiba_640x480_TFT",
2474 .monspecs = {
2475 .modedb = NULL,
2476 .modedb_len = 0,
2477 .hfmin = 30000,
2478 .hfmax = 70000,
2479 .vfmin = 60,
2480 .vfmax = 60,
2481 .dclkmin = 6000000,
2482 .dclkmax = 28000000,
2483 .input = FB_DISP_RGB,
2484 },
2485 .mode_screen = LCD_SCREEN_SX_N(640) |
2486 LCD_SCREEN_SY_N(480),
2487 .mode_horztiming = LCD_HORZTIMING_HPW_N(96) |
2488 LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(51),
2489 .mode_verttiming = LCD_VERTTIMING_VPW_N(2) |
2490 LCD_VERTTIMING_VND1_N(11) | LCD_VERTTIMING_VND2_N(32),
2491 .mode_clkcontrol = 0x00000000, /* /4=24Mhz */
2492 .mode_pwmdiv = 0x8000063f,
2493 .mode_pwmhi = 0x03400000,
2494 .mode_outmask = 0x00fcfcfc,
2495 .mode_fifoctrl = 0x2f2f2f2f,
2496 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2497 .mode_backlight = 0x00000000,
2498 .mode_auxpll = 8, /* 96MHz AUXPLL */
2499 .device_init = board_au1200fb_panel_init,
2500 .device_shutdown = board_au1200fb_panel_shutdown,
2501 640, 480,
2502 640, 480,
2503 },
2504
2505 [7] = { /* Sharp 320x240 TFT */
2506 .name = "Sharp_320x240_TFT",
2507 .monspecs = {
2508 .modedb = NULL,
2509 .modedb_len = 0,
2510 .hfmin = 12500,
2511 .hfmax = 20000,
2512 .vfmin = 38,
2513 .vfmax = 81,
2514 .dclkmin = 4500000,
2515 .dclkmax = 6800000,
2516 .input = FB_DISP_RGB,
2517 },
2518 .mode_screen = LCD_SCREEN_SX_N(320) |
2519 LCD_SCREEN_SY_N(240),
2520 .mode_horztiming = LCD_HORZTIMING_HPW_N(60) |
2521 LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(2),
2522 .mode_verttiming = LCD_VERTTIMING_VPW_N(2) |
2523 LCD_VERTTIMING_VND1_N(2) | LCD_VERTTIMING_VND2_N(5),
2524 .mode_clkcontrol = LCD_CLKCONTROL_PCD_N(7), /*16=6Mhz*/
2525 .mode_pwmdiv = 0x8000063f,
2526 .mode_pwmhi = 0x03400000,
2527 .mode_outmask = 0x00fcfcfc,
2528 .mode_fifoctrl = 0x2f2f2f2f,
2529 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2530 .mode_backlight = 0x00000000,
2531 .mode_auxpll = 8, /* 96MHz AUXPLL */
2532 .device_init = board_au1200fb_panel_init,
2533 .device_shutdown = board_au1200fb_panel_shutdown,
2534 320, 320,
2535 240, 240,
2536 },
2537
2538 [8] = { /* Toppoly TD070WGCB2 7" 856x480 TFT */
2539 .name = "Toppoly_TD070WGCB2",
2540 .monspecs = {
2541 .modedb = NULL,
2542 .modedb_len = 0,
2543 .hfmin = 30000,
2544 .hfmax = 70000,
2545 .vfmin = 60,
2546 .vfmax = 60,
2547 .dclkmin = 6000000,
2548 .dclkmax = 28000000,
2549 .input = FB_DISP_RGB,
2550 },
2551 .mode_screen = LCD_SCREEN_SX_N(856) |
2552 LCD_SCREEN_SY_N(480),
2553 .mode_horztiming = LCD_HORZTIMING_HND2_N(43) |
2554 LCD_HORZTIMING_HND1_N(43) | LCD_HORZTIMING_HPW_N(114),
2555 .mode_verttiming = LCD_VERTTIMING_VND2_N(20) |
2556 LCD_VERTTIMING_VND1_N(21) | LCD_VERTTIMING_VPW_N(4),
2557 .mode_clkcontrol = 0x00020001, /* /4=24Mhz */
2558 .mode_pwmdiv = 0x8000063f,
2559 .mode_pwmhi = 0x03400000,
2560 .mode_outmask = 0x00fcfcfc,
2561 .mode_fifoctrl = 0x2f2f2f2f,
2562 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2563 .mode_backlight = 0x00000000,
2564 .mode_auxpll = 8, /* 96MHz AUXPLL */
2565 .device_init = board_au1200fb_panel_init,
2566 .device_shutdown = board_au1200fb_panel_shutdown,
2567 856, 856,
2568 480, 480,
2569 },
2570};
2571
2572#define NUM_PANELS (ARRAY_SIZE(known_lcd_panels))
2573
2574/********************************************************************/
2575
2576#ifdef CONFIG_PM
2577static int set_brightness(unsigned int brightness)
2578{
2579 unsigned int hi1, divider;
2580
2581 /* limit brightness pwm duty to >= 30/1600 */
2582 if (brightness < 30) {
2583 brightness = 30;
2584 }
2585 divider = (lcd->pwmdiv & 0x3FFFF) + 1;
2586 hi1 = (lcd->pwmhi >> 16) + 1;
2587 hi1 = (((brightness & 0xFF) + 1) * divider >> 8);
2588 lcd->pwmhi &= 0xFFFF;
2589 lcd->pwmhi |= (hi1 << 16);
2590
2591 return brightness;
2592}
2593#endif /* CONFIG_PM */
2594
2595static int winbpp (unsigned int winctrl1)
2596{
2597 int bits = 0;
2598
2599 /* how many bits are needed for each pixel format */
2600 switch (winctrl1 & LCD_WINCTRL1_FRM) {
2601 case LCD_WINCTRL1_FRM_1BPP:
2602 bits = 1;
2603 break;
2604 case LCD_WINCTRL1_FRM_2BPP:
2605 bits = 2;
2606 break;
2607 case LCD_WINCTRL1_FRM_4BPP:
2608 bits = 4;
2609 break;
2610 case LCD_WINCTRL1_FRM_8BPP:
2611 bits = 8;
2612 break;
2613 case LCD_WINCTRL1_FRM_12BPP:
2614 case LCD_WINCTRL1_FRM_16BPP655:
2615 case LCD_WINCTRL1_FRM_16BPP565:
2616 case LCD_WINCTRL1_FRM_16BPP556:
2617 case LCD_WINCTRL1_FRM_16BPPI1555:
2618 case LCD_WINCTRL1_FRM_16BPPI5551:
2619 case LCD_WINCTRL1_FRM_16BPPA1555:
2620 case LCD_WINCTRL1_FRM_16BPPA5551:
2621 bits = 16;
2622 break;
2623 case LCD_WINCTRL1_FRM_24BPP:
2624 case LCD_WINCTRL1_FRM_32BPP:
2625 bits = 32;
2626 break;
2627 }
2628
2629 return bits;
2630}
2631
2632static int fbinfo2index (struct fb_info *fb_info)
2633{
2634 int i;
2635
2636 for (i = 0; i < CONFIG_FB_AU1200_DEVS; ++i) {
2637 if (fb_info == (struct fb_info *)(&_au1200fb_devices[i].fb_info))
2638 return i;
2639 }
2640 printk("au1200fb: ERROR: fbinfo2index failed!\n");
2641 return -1;
2642}
2643
2644static int au1200_setlocation (struct au1200fb_device *fbdev, int plane,
2645 int xpos, int ypos)
2646{
2647 uint32 winctrl0, winctrl1, winenable, fb_offset = 0;
2648 int xsz, ysz;
2649
2650 /* FIX!!! NOT CHECKING FOR COMPLETE OFFSCREEN YET */
2651
2652 winctrl0 = lcd->window[plane].winctrl0;
2653 winctrl1 = lcd->window[plane].winctrl1;
2654 winctrl0 &= (LCD_WINCTRL0_A | LCD_WINCTRL0_AEN);
2655 winctrl1 &= ~(LCD_WINCTRL1_SZX | LCD_WINCTRL1_SZY);
2656
2657 /* Check for off-screen adjustments */
2658 xsz = win->w[plane].xres;
2659 ysz = win->w[plane].yres;
2660 if ((xpos + win->w[plane].xres) > panel->Xres) {
2661 /* Off-screen to the right */
2662 xsz = panel->Xres - xpos; /* off by 1 ??? */
2663 /*printk("off screen right\n");*/
2664 }
2665
2666 if ((ypos + win->w[plane].yres) > panel->Yres) {
2667 /* Off-screen to the bottom */
2668 ysz = panel->Yres - ypos; /* off by 1 ??? */
2669 /*printk("off screen bottom\n");*/
2670 }
2671
2672 if (xpos < 0) {
2673 /* Off-screen to the left */
2674 xsz = win->w[plane].xres + xpos;
2675 fb_offset += (((0 - xpos) * winbpp(lcd->window[plane].winctrl1))/8);
2676 xpos = 0;
2677 /*printk("off screen left\n");*/
2678 }
2679
2680 if (ypos < 0) {
2681 /* Off-screen to the top */
2682 ysz = win->w[plane].yres + ypos;
2683 /* fixme: fb_offset += ((0-ypos)*fb_pars[plane].line_length); */
2684 ypos = 0;
2685 /*printk("off screen top\n");*/
2686 }
2687
2688 /* record settings */
2689 win->w[plane].xpos = xpos;
2690 win->w[plane].ypos = ypos;
2691
2692 xsz -= 1;
2693 ysz -= 1;
2694 winctrl0 |= (xpos << 21);
2695 winctrl0 |= (ypos << 10);
2696 winctrl1 |= (xsz << 11);
2697 winctrl1 |= (ysz << 0);
2698
2699 /* Disable the window while making changes, then restore WINEN */
2700 winenable = lcd->winenable & (1 << plane);
2701 au_sync();
2702 lcd->winenable &= ~(1 << plane);
2703 lcd->window[plane].winctrl0 = winctrl0;
2704 lcd->window[plane].winctrl1 = winctrl1;
2705 lcd->window[plane].winbuf0 =
2706 lcd->window[plane].winbuf1 = fbdev->fb_phys;
2707 lcd->window[plane].winbufctrl = 0; /* select winbuf0 */
2708 lcd->winenable |= winenable;
2709 au_sync();
2710
2711 return 0;
2712}
2713
2714static void au1200_setpanel (struct panel_settings *newpanel)
2715{
2716 /*
2717 * Perform global setup/init of LCD controller
2718 */
2719 uint32 winenable;
2720
2721 /* Make sure all windows disabled */
2722 winenable = lcd->winenable;
2723 lcd->winenable = 0;
2724 au_sync();
2725 /*
2726 * Ensure everything is disabled before reconfiguring
2727 */
2728 if (lcd->screen & LCD_SCREEN_SEN) {
2729 /* Wait for vertical sync period */
2730 lcd->intstatus = LCD_INT_SS;
2731 while ((lcd->intstatus & LCD_INT_SS) == 0) {
2732 au_sync();
2733 }
2734
2735 lcd->screen &= ~LCD_SCREEN_SEN; /*disable the controller*/
2736
2737 do {
2738 lcd->intstatus = lcd->intstatus; /*clear interrupts*/
2739 au_sync();
2740 /*wait for controller to shut down*/
2741 } while ((lcd->intstatus & LCD_INT_SD) == 0);
2742
2743 /* Call shutdown of current panel (if up) */
2744 /* this must occur last, because if an external clock is driving
2745 the controller, the clock cannot be turned off before first
2746 shutting down the controller.
2747 */
2748 if (panel->device_shutdown != NULL)
2749 panel->device_shutdown();
2750 }
2751
2752 /* Newpanel == NULL indicates a shutdown operation only */
2753 if (newpanel == NULL)
2754 return;
2755
2756 panel = newpanel;
2757
2758 printk("Panel(%s), %dx%d\n", panel->name, panel->Xres, panel->Yres);
2759
2760 /*
2761 * Setup clocking if internal LCD clock source (assumes sys_auxpll valid)
2762 */
2763 if (!(panel->mode_clkcontrol & LCD_CLKCONTROL_EXT))
2764 {
2765 uint32 sys_clksrc;
2766 au_writel(panel->mode_auxpll, SYS_AUXPLL);
2767 sys_clksrc = au_readl(SYS_CLKSRC) & ~0x0000001f;
2768 sys_clksrc |= panel->mode_toyclksrc;
2769 au_writel(sys_clksrc, SYS_CLKSRC);
2770 }
2771
2772 /*
2773 * Configure panel timings
2774 */
2775 lcd->screen = panel->mode_screen;
2776 lcd->horztiming = panel->mode_horztiming;
2777 lcd->verttiming = panel->mode_verttiming;
2778 lcd->clkcontrol = panel->mode_clkcontrol;
2779 lcd->pwmdiv = panel->mode_pwmdiv;
2780 lcd->pwmhi = panel->mode_pwmhi;
2781 lcd->outmask = panel->mode_outmask;
2782 lcd->fifoctrl = panel->mode_fifoctrl;
2783 au_sync();
2784
2785 /* fixme: Check window settings to make sure still valid
2786 * for new geometry */
2787#if 0
2788 au1200_setlocation(fbdev, 0, win->w[0].xpos, win->w[0].ypos);
2789 au1200_setlocation(fbdev, 1, win->w[1].xpos, win->w[1].ypos);
2790 au1200_setlocation(fbdev, 2, win->w[2].xpos, win->w[2].ypos);
2791 au1200_setlocation(fbdev, 3, win->w[3].xpos, win->w[3].ypos);
2792#endif
2793 lcd->winenable = winenable;
2794
2795 /*
2796 * Re-enable screen now that it is configured
2797 */
2798 lcd->screen |= LCD_SCREEN_SEN;
2799 au_sync();
2800
2801 /* Call init of panel */
2802 if (panel->device_init != NULL) panel->device_init();
2803
2804 /* FIX!!!! not appropriate on panel change!!! Global setup/init */
2805 lcd->intenable = 0;
2806 lcd->intstatus = ~0;
2807 lcd->backcolor = win->mode_backcolor;
2808
2809 /* Setup Color Key - FIX!!! */
2810 lcd->colorkey = win->mode_colorkey;
2811 lcd->colorkeymsk = win->mode_colorkeymsk;
2812
2813 /* Setup HWCursor - FIX!!! Need to support this eventually */
2814 lcd->hwc.cursorctrl = 0;
2815 lcd->hwc.cursorpos = 0;
2816 lcd->hwc.cursorcolor0 = 0;
2817 lcd->hwc.cursorcolor1 = 0;
2818 lcd->hwc.cursorcolor2 = 0;
2819 lcd->hwc.cursorcolor3 = 0;
2820
2821
2822#if 0
2823#define D(X) printk("%25s: %08X\n", #X, X)
2824 D(lcd->screen);
2825 D(lcd->horztiming);
2826 D(lcd->verttiming);
2827 D(lcd->clkcontrol);
2828 D(lcd->pwmdiv);
2829 D(lcd->pwmhi);
2830 D(lcd->outmask);
2831 D(lcd->fifoctrl);
2832 D(lcd->window[0].winctrl0);
2833 D(lcd->window[0].winctrl1);
2834 D(lcd->window[0].winctrl2);
2835 D(lcd->window[0].winbuf0);
2836 D(lcd->window[0].winbuf1);
2837 D(lcd->window[0].winbufctrl);
2838 D(lcd->window[1].winctrl0);
2839 D(lcd->window[1].winctrl1);
2840 D(lcd->window[1].winctrl2);
2841 D(lcd->window[1].winbuf0);
2842 D(lcd->window[1].winbuf1);
2843 D(lcd->window[1].winbufctrl);
2844 D(lcd->window[2].winctrl0);
2845 D(lcd->window[2].winctrl1);
2846 D(lcd->window[2].winctrl2);
2847 D(lcd->window[2].winbuf0);
2848 D(lcd->window[2].winbuf1);
2849 D(lcd->window[2].winbufctrl);
2850 D(lcd->window[3].winctrl0);
2851 D(lcd->window[3].winctrl1);
2852 D(lcd->window[3].winctrl2);
2853 D(lcd->window[3].winbuf0);
2854 D(lcd->window[3].winbuf1);
2855 D(lcd->window[3].winbufctrl);
2856 D(lcd->winenable);
2857 D(lcd->intenable);
2858 D(lcd->intstatus);
2859 D(lcd->backcolor);
2860 D(lcd->winenable);
2861 D(lcd->colorkey);
2862 D(lcd->colorkeymsk);
2863 D(lcd->hwc.cursorctrl);
2864 D(lcd->hwc.cursorpos);
2865 D(lcd->hwc.cursorcolor0);
2866 D(lcd->hwc.cursorcolor1);
2867 D(lcd->hwc.cursorcolor2);
2868 D(lcd->hwc.cursorcolor3);
2869#endif
2870}
2871
2872static void au1200_setmode(struct au1200fb_device *fbdev)
2873{
2874 int plane = fbdev->plane;
2875 /* Window/plane setup */
2876 lcd->window[plane].winctrl1 = ( 0
2877 | LCD_WINCTRL1_PRI_N(plane)
2878 | win->w[plane].mode_winctrl1 /* FRM,CCO,PO,PIPE */
2879 ) ;
2880
2881 au1200_setlocation(fbdev, plane, win->w[plane].xpos, win->w[plane].ypos);
2882
2883 lcd->window[plane].winctrl2 = ( 0
2884 | LCD_WINCTRL2_CKMODE_00
2885 | LCD_WINCTRL2_DBM
2886 | LCD_WINCTRL2_BX_N( fbdev->fb_info.fix.line_length)
2887 | LCD_WINCTRL2_SCX_1
2888 | LCD_WINCTRL2_SCY_1
2889 ) ;
2890 lcd->winenable |= win->w[plane].mode_winenable;
2891 au_sync();
2892}
2893
2894
2895/* Inline helpers */
2896
2897/*#define panel_is_dual(panel) ((panel->mode_screen & LCD_SCREEN_PT) == LCD_SCREEN_PT_010)*/
2898/*#define panel_is_active(panel)((panel->mode_screen & LCD_SCREEN_PT) == LCD_SCREEN_PT_010)*/
2899
2900#define panel_is_color(panel) ((panel->mode_screen & LCD_SCREEN_PT) <= LCD_SCREEN_PT_CDSTN)
2901
2902/* Bitfields format supported by the controller. */
2903static struct fb_bitfield rgb_bitfields[][4] = {
2904 /* Red, Green, Blue, Transp */
2905 [LCD_WINCTRL1_FRM_16BPP655 >> 25] =
2906 { { 10, 6, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
2907
2908 [LCD_WINCTRL1_FRM_16BPP565 >> 25] =
2909 { { 11, 5, 0 }, { 5, 6, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
2910
2911 [LCD_WINCTRL1_FRM_16BPP556 >> 25] =
2912 { { 11, 5, 0 }, { 6, 5, 0 }, { 0, 6, 0 }, { 0, 0, 0 } },
2913
2914 [LCD_WINCTRL1_FRM_16BPPI1555 >> 25] =
2915 { { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
2916
2917 [LCD_WINCTRL1_FRM_16BPPI5551 >> 25] =
2918 { { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 0, 0 } },
2919
2920 [LCD_WINCTRL1_FRM_16BPPA1555 >> 25] =
2921 { { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 15, 1, 0 } },
2922
2923 [LCD_WINCTRL1_FRM_16BPPA5551 >> 25] =
2924 { { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 1, 0 } },
2925
2926 [LCD_WINCTRL1_FRM_24BPP >> 25] =
2927 { { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 0, 0, 0 } },
2928
2929 [LCD_WINCTRL1_FRM_32BPP >> 25] =
2930 { { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 24, 0, 0 } },
2931};
2932
2933/*-------------------------------------------------------------------------*/
2934
2935/* Helpers */
2936
2937static void au1200fb_update_fbinfo(struct fb_info *fbi)
2938{
2939 /* FIX!!!! This also needs to take the window pixel format into account!!! */
2940
2941 /* Update var-dependent FB info */
2942 if (panel_is_color(panel)) {
2943 if (fbi->var.bits_per_pixel <= 8) {
2944 /* palettized */
2945 fbi->fix.visual = FB_VISUAL_PSEUDOCOLOR;
2946 fbi->fix.line_length = fbi->var.xres_virtual /
2947 (8/fbi->var.bits_per_pixel);
2948 } else {
2949 /* non-palettized */
2950 fbi->fix.visual = FB_VISUAL_TRUECOLOR;
2951 fbi->fix.line_length = fbi->var.xres_virtual * (fbi->var.bits_per_pixel / 8);
2952 }
2953 } else {
2954 /* mono FIX!!! mono 8 and 4 bits */
2955 fbi->fix.visual = FB_VISUAL_MONO10;
2956 fbi->fix.line_length = fbi->var.xres_virtual / 8;
2957 }
2958
2959 fbi->screen_size = fbi->fix.line_length * fbi->var.yres_virtual;
2960 print_dbg("line length: %d\n", fbi->fix.line_length);
2961 print_dbg("bits_per_pixel: %d\n", fbi->var.bits_per_pixel);
2962}
2963
2964/*-------------------------------------------------------------------------*/
2965
2966/* AU1200 framebuffer driver */
2967
2968/* fb_check_var
2969 * Validate var settings with hardware restrictions and modify it if necessary
2970 */
2971static int au1200fb_fb_check_var(struct fb_var_screeninfo *var,
2972 struct fb_info *fbi)
2973{
2974 struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi;
2975 u32 pixclock;
2976 int screen_size, plane;
2977
2978 plane = fbdev->plane;
2979
2980 /* Make sure that the mode respect all LCD controller and
2981 * panel restrictions. */
2982 var->xres = win->w[plane].xres;
2983 var->yres = win->w[plane].yres;
2984
2985 /* No need for virtual resolution support */
2986 var->xres_virtual = var->xres;
2987 var->yres_virtual = var->yres;
2988
2989 var->bits_per_pixel = winbpp(win->w[plane].mode_winctrl1);
2990
2991 screen_size = var->xres_virtual * var->yres_virtual;
2992 if (var->bits_per_pixel > 8) screen_size *= (var->bits_per_pixel / 8);
2993 else screen_size /= (8/var->bits_per_pixel);
2994
2995 if (fbdev->fb_len < screen_size)
2996 return -EINVAL; /* Virtual screen is to big, abort */
2997
2998 /* FIX!!!! what are the implicaitons of ignoring this for windows ??? */
2999 /* The max LCD clock is fixed to 48MHz (value of AUX_CLK). The pixel
3000 * clock can only be obtain by dividing this value by an even integer.
3001 * Fallback to a slower pixel clock if necessary. */
3002 pixclock = max((u32)(PICOS2KHZ(var->pixclock) * 1000), fbi->monspecs.dclkmin);
3003 pixclock = min(pixclock, min(fbi->monspecs.dclkmax, (u32)AU1200_LCD_MAX_CLK/2));
3004
3005 if (AU1200_LCD_MAX_CLK % pixclock) {
3006 int diff = AU1200_LCD_MAX_CLK % pixclock;
3007 pixclock -= diff;
3008 }
3009
3010 var->pixclock = KHZ2PICOS(pixclock/1000);
3011#if 0
3012 if (!panel_is_active(panel)) {
3013 int pcd = AU1200_LCD_MAX_CLK / (pixclock * 2) - 1;
3014
3015 if (!panel_is_color(panel)
3016 && (panel->control_base & LCD_CONTROL_MPI) && (pcd < 3)) {
3017 /* STN 8bit mono panel support is up to 6MHz pixclock */
3018 var->pixclock = KHZ2PICOS(6000);
3019 } else if (!pcd) {
3020 /* Other STN panel support is up to 12MHz */
3021 var->pixclock = KHZ2PICOS(12000);
3022 }
3023 }
3024#endif
3025 /* Set bitfield accordingly */
3026 switch (var->bits_per_pixel) {
3027 case 16:
3028 {
3029 /* 16bpp True color.
3030 * These must be set to MATCH WINCTRL[FORM] */
3031 int idx;
3032 idx = (win->w[0].mode_winctrl1 & LCD_WINCTRL1_FRM) >> 25;
3033 var->red = rgb_bitfields[idx][0];
3034 var->green = rgb_bitfields[idx][1];
3035 var->blue = rgb_bitfields[idx][2];
3036 var->transp = rgb_bitfields[idx][3];
3037 break;
3038 }
3039
3040 case 32:
3041 {
3042 /* 32bpp True color.
3043 * These must be set to MATCH WINCTRL[FORM] */
3044 int idx;
3045 idx = (win->w[0].mode_winctrl1 & LCD_WINCTRL1_FRM) >> 25;
3046 var->red = rgb_bitfields[idx][0];
3047 var->green = rgb_bitfields[idx][1];
3048 var->blue = rgb_bitfields[idx][2];
3049 var->transp = rgb_bitfields[idx][3];
3050 break;
3051 }
3052 default:
3053 print_dbg("Unsupported depth %dbpp", var->bits_per_pixel);
3054 return -EINVAL;
3055 }
3056
3057 return 0;
3058}
3059
3060/* fb_set_par
3061 * Set hardware with var settings. This will enable the controller with a
3062 * specific mode, normally validated with the fb_check_var method
3063 */
3064static int au1200fb_fb_set_par(struct fb_info *fbi)
3065{
3066 struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi;
3067
3068 au1200fb_update_fbinfo(fbi);
3069 au1200_setmode(fbdev);
3070
3071 return 0;
3072}
3073
3074/* fb_setcolreg
3075 * Set color in LCD palette.
3076 */
3077static int au1200fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green,
3078 unsigned blue, unsigned transp, struct fb_info *fbi)
3079{
3080 volatile u32 *palette = lcd->palette;
3081 u32 value;
3082
3083 if (regno > (AU1200_LCD_NBR_PALETTE_ENTRIES - 1))
3084 return -EINVAL;
3085
3086 if (fbi->var.grayscale) {
3087 /* Convert color to grayscale */
3088 red = green = blue =
3089 (19595 * red + 38470 * green + 7471 * blue) >> 16;
3090 }
3091
3092 if (fbi->fix.visual == FB_VISUAL_TRUECOLOR) {
3093 /* Place color in the pseudopalette */
3094 if (regno > 16)
3095 return -EINVAL;
3096
3097 palette = (u32*) fbi->pseudo_palette;
3098
3099 red >>= (16 - fbi->var.red.length);
3100 green >>= (16 - fbi->var.green.length);
3101 blue >>= (16 - fbi->var.blue.length);
3102
3103 value = (red << fbi->var.red.offset) |
3104 (green << fbi->var.green.offset)|
3105 (blue << fbi->var.blue.offset);
3106 value &= 0xFFFF;
3107
3108 } else if (1 /*FIX!!! panel_is_active(fbdev->panel)*/) {
3109 /* COLOR TFT PALLETTIZED (use RGB 565) */
3110 value = (red & 0xF800)|((green >> 5) &
3111 0x07E0)|((blue >> 11) & 0x001F);
3112 value &= 0xFFFF;
3113
3114 } else if (0 /*panel_is_color(fbdev->panel)*/) {
3115 /* COLOR STN MODE */
3116 value = 0x1234;
3117 value &= 0xFFF;
3118 } else {
3119 /* MONOCHROME MODE */
3120 value = (green >> 12) & 0x000F;
3121 value &= 0xF;
3122 }
3123
3124 palette[regno] = value;
3125
3126 return 0;
3127}
3128
3129/* fb_blank
3130 * Blank the screen. Depending on the mode, the screen will be
3131 * activated with the backlight color, or desactivated
3132 */
3133static int au1200fb_fb_blank(int blank_mode, struct fb_info *fbi)
3134{
3135 /* Short-circuit screen blanking */
3136 if (noblanking)
3137 return 0;
3138
3139 switch (blank_mode) {
3140
3141 case FB_BLANK_UNBLANK:
3142 case FB_BLANK_NORMAL:
3143 /* printk("turn on panel\n"); */
3144 au1200_setpanel(panel);
3145 break;
3146 case FB_BLANK_VSYNC_SUSPEND:
3147 case FB_BLANK_HSYNC_SUSPEND:
3148 case FB_BLANK_POWERDOWN:
3149 /* printk("turn off panel\n"); */
3150 au1200_setpanel(NULL);
3151 break;
3152 default:
3153 break;
3154
3155 }
3156
3157 /* FB_BLANK_NORMAL is a soft blank */
3158 return (blank_mode == FB_BLANK_NORMAL) ? -EINVAL : 0;
3159}
3160
3161/* fb_mmap
3162 * Map video memory in user space. We don't use the generic fb_mmap
3163 * method mainly to allow the use of the TLB streaming flag (CCA=6)
3164 */
3165static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
3166
3167{
3168 unsigned int len;
3169 unsigned long start=0, off;
3170 struct au1200fb_device *fbdev = (struct au1200fb_device *) info;
3171
3172#ifdef CONFIG_PM
3173 au1xxx_pm_access(LCD_pm_dev);
3174#endif
3175
3176 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
3177 return -EINVAL;
3178 }
3179
3180 start = fbdev->fb_phys & PAGE_MASK;
3181 len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len);
3182
3183 off = vma->vm_pgoff << PAGE_SHIFT;
3184
3185 if ((vma->vm_end - vma->vm_start + off) > len) {
3186 return -EINVAL;
3187 }
3188
3189 off += start;
3190 vma->vm_pgoff = off >> PAGE_SHIFT;
3191
3192 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
3193 pgprot_val(vma->vm_page_prot) |= _CACHE_MASK; /* CCA=7 */
3194
3195 vma->vm_flags |= VM_IO;
3196
3197 return io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
3198 vma->vm_end - vma->vm_start,
3199 vma->vm_page_prot);
3200
3201 return 0;
3202}
3203
3204static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata)
3205{
3206
3207 unsigned int hi1, divider;
3208
3209 /* SCREEN_SIZE: user cannot reset size, must switch panel choice */
3210
3211 if (pdata->flags & SCREEN_BACKCOLOR)
3212 lcd->backcolor = pdata->backcolor;
3213
3214 if (pdata->flags & SCREEN_BRIGHTNESS) {
3215
3216 // limit brightness pwm duty to >= 30/1600
3217 if (pdata->brightness < 30) {
3218 pdata->brightness = 30;
3219 }
3220 divider = (lcd->pwmdiv & 0x3FFFF) + 1;
3221 hi1 = (lcd->pwmhi >> 16) + 1;
3222 hi1 = (((pdata->brightness & 0xFF)+1) * divider >> 8);
3223 lcd->pwmhi &= 0xFFFF;
3224 lcd->pwmhi |= (hi1 << 16);
3225 }
3226
3227 if (pdata->flags & SCREEN_COLORKEY)
3228 lcd->colorkey = pdata->colorkey;
3229
3230 if (pdata->flags & SCREEN_MASK)
3231 lcd->colorkeymsk = pdata->mask;
3232 au_sync();
3233}
3234
3235static void get_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata)
3236{
3237 unsigned int hi1, divider;
3238
3239 pdata->xsize = ((lcd->screen & LCD_SCREEN_SX) >> 19) + 1;
3240 pdata->ysize = ((lcd->screen & LCD_SCREEN_SY) >> 8) + 1;
3241
3242 pdata->backcolor = lcd->backcolor;
3243 pdata->colorkey = lcd->colorkey;
3244 pdata->mask = lcd->colorkeymsk;
3245
3246 // brightness
3247 hi1 = (lcd->pwmhi >> 16) + 1;
3248 divider = (lcd->pwmdiv & 0x3FFFF) + 1;
3249 pdata->brightness = ((hi1 << 8) / divider) - 1;
3250 au_sync();
3251}
3252
3253static void set_window(unsigned int plane,
3254 struct au1200_lcd_window_regs_t *pdata)
3255{
3256 unsigned int val, bpp;
3257
3258 /* Window control register 0 */
3259 if (pdata->flags & WIN_POSITION) {
3260 val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_OX |
3261 LCD_WINCTRL0_OY);
3262 val |= ((pdata->xpos << 21) & LCD_WINCTRL0_OX);
3263 val |= ((pdata->ypos << 10) & LCD_WINCTRL0_OY);
3264 lcd->window[plane].winctrl0 = val;
3265 }
3266 if (pdata->flags & WIN_ALPHA_COLOR) {
3267 val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_A);
3268 val |= ((pdata->alpha_color << 2) & LCD_WINCTRL0_A);
3269 lcd->window[plane].winctrl0 = val;
3270 }
3271 if (pdata->flags & WIN_ALPHA_MODE) {
3272 val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_AEN);
3273 val |= ((pdata->alpha_mode << 1) & LCD_WINCTRL0_AEN);
3274 lcd->window[plane].winctrl0 = val;
3275 }
3276
3277 /* Window control register 1 */
3278 if (pdata->flags & WIN_PRIORITY) {
3279 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PRI);
3280 val |= ((pdata->priority << 30) & LCD_WINCTRL1_PRI);
3281 lcd->window[plane].winctrl1 = val;
3282 }
3283 if (pdata->flags & WIN_CHANNEL) {
3284 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PIPE);
3285 val |= ((pdata->channel << 29) & LCD_WINCTRL1_PIPE);
3286 lcd->window[plane].winctrl1 = val;
3287 }
3288 if (pdata->flags & WIN_BUFFER_FORMAT) {
3289 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_FRM);
3290 val |= ((pdata->buffer_format << 25) & LCD_WINCTRL1_FRM);
3291 lcd->window[plane].winctrl1 = val;
3292 }
3293 if (pdata->flags & WIN_COLOR_ORDER) {
3294 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_CCO);
3295 val |= ((pdata->color_order << 24) & LCD_WINCTRL1_CCO);
3296 lcd->window[plane].winctrl1 = val;
3297 }
3298 if (pdata->flags & WIN_PIXEL_ORDER) {
3299 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PO);
3300 val |= ((pdata->pixel_order << 22) & LCD_WINCTRL1_PO);
3301 lcd->window[plane].winctrl1 = val;
3302 }
3303 if (pdata->flags & WIN_SIZE) {
3304 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_SZX |
3305 LCD_WINCTRL1_SZY);
3306 val |= (((pdata->xsize << 11) - 1) & LCD_WINCTRL1_SZX);
3307 val |= (((pdata->ysize) - 1) & LCD_WINCTRL1_SZY);
3308 lcd->window[plane].winctrl1 = val;
3309 /* program buffer line width */
3310 bpp = winbpp(val) / 8;
3311 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_BX);
3312 val |= (((pdata->xsize * bpp) << 8) & LCD_WINCTRL2_BX);
3313 lcd->window[plane].winctrl2 = val;
3314 }
3315
3316 /* Window control register 2 */
3317 if (pdata->flags & WIN_COLORKEY_MODE) {
3318 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_CKMODE);
3319 val |= ((pdata->colorkey_mode << 24) & LCD_WINCTRL2_CKMODE);
3320 lcd->window[plane].winctrl2 = val;
3321 }
3322 if (pdata->flags & WIN_DOUBLE_BUFFER_MODE) {
3323 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_DBM);
3324 val |= ((pdata->double_buffer_mode << 23) & LCD_WINCTRL2_DBM);
3325 lcd->window[plane].winctrl2 = val;
3326 }
3327 if (pdata->flags & WIN_RAM_ARRAY_MODE) {
3328 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_RAM);
3329 val |= ((pdata->ram_array_mode << 21) & LCD_WINCTRL2_RAM);
3330 lcd->window[plane].winctrl2 = val;
3331 }
3332
3333 /* Buffer line width programmed with WIN_SIZE */
3334
3335 if (pdata->flags & WIN_BUFFER_SCALE) {
3336 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_SCX |
3337 LCD_WINCTRL2_SCY);
3338 val |= ((pdata->xsize << 11) & LCD_WINCTRL2_SCX);
3339 val |= ((pdata->ysize) & LCD_WINCTRL2_SCY);
3340 lcd->window[plane].winctrl2 = val;
3341 }
3342
3343 if (pdata->flags & WIN_ENABLE) {
3344 val = lcd->winenable;
3345 val &= ~(1<<plane);
3346 val |= (pdata->enable & 1) << plane;
3347 lcd->winenable = val;
3348 }
3349 au_sync();
3350}
3351
3352static void get_window(unsigned int plane,
3353 struct au1200_lcd_window_regs_t *pdata)
3354{
3355 /* Window control register 0 */
3356 pdata->xpos = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OX) >> 21;
3357 pdata->ypos = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OY) >> 10;
3358 pdata->alpha_color = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_A) >> 2;
3359 pdata->alpha_mode = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_AEN) >> 1;
3360
3361 /* Window control register 1 */
3362 pdata->priority = (lcd->window[plane].winctrl1& LCD_WINCTRL1_PRI) >> 30;
3363 pdata->channel = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_PIPE) >> 29;
3364 pdata->buffer_format = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_FRM) >> 25;
3365 pdata->color_order = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_CCO) >> 24;
3366 pdata->pixel_order = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_PO) >> 22;
3367 pdata->xsize = ((lcd->window[plane].winctrl1 & LCD_WINCTRL1_SZX) >> 11) + 1;
3368 pdata->ysize = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_SZY) + 1;
3369
3370 /* Window control register 2 */
3371 pdata->colorkey_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_CKMODE) >> 24;
3372 pdata->double_buffer_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_DBM) >> 23;
3373 pdata->ram_array_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_RAM) >> 21;
3374
3375 pdata->enable = (lcd->winenable >> plane) & 1;
3376 au_sync();
3377}
3378
3379static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd,
3380 unsigned long arg)
3381{
3382 int plane;
3383 int val;
3384
3385#ifdef CONFIG_PM
3386 au1xxx_pm_access(LCD_pm_dev);
3387#endif
3388
3389 plane = fbinfo2index(info);
3390 print_dbg("au1200fb: ioctl %d on plane %d\n", cmd, plane);
3391
3392 if (cmd == AU1200_LCD_FB_IOCTL) {
3393 struct au1200_lcd_iodata_t iodata;
3394
3395 if (copy_from_user(&iodata, (void __user *) arg, sizeof(iodata)))
3396 return -EFAULT;
3397
3398 print_dbg("FB IOCTL called\n");
3399
3400 switch (iodata.subcmd) {
3401 case AU1200_LCD_SET_SCREEN:
3402 print_dbg("AU1200_LCD_SET_SCREEN\n");
3403 set_global(cmd, &iodata.global);
3404 break;
3405
3406 case AU1200_LCD_GET_SCREEN:
3407 print_dbg("AU1200_LCD_GET_SCREEN\n");
3408 get_global(cmd, &iodata.global);
3409 break;
3410
3411 case AU1200_LCD_SET_WINDOW:
3412 print_dbg("AU1200_LCD_SET_WINDOW\n");
3413 set_window(plane, &iodata.window);
3414 break;
3415
3416 case AU1200_LCD_GET_WINDOW:
3417 print_dbg("AU1200_LCD_GET_WINDOW\n");
3418 get_window(plane, &iodata.window);
3419 break;
3420
3421 case AU1200_LCD_SET_PANEL:
3422 print_dbg("AU1200_LCD_SET_PANEL\n");
3423 if ((iodata.global.panel_choice >= 0) &&
3424 (iodata.global.panel_choice <
3425 NUM_PANELS))
3426 {
3427 struct panel_settings *newpanel;
3428 panel_index = iodata.global.panel_choice;
3429 newpanel = &known_lcd_panels[panel_index];
3430 au1200_setpanel(newpanel);
3431 }
3432 break;
3433
3434 case AU1200_LCD_GET_PANEL:
3435 print_dbg("AU1200_LCD_GET_PANEL\n");
3436 iodata.global.panel_choice = panel_index;
3437 break;
3438
3439 default:
3440 return -EINVAL;
3441 }
3442
3443 val = copy_to_user((void __user *) arg, &iodata, sizeof(iodata));
3444 if (val) {
3445 print_dbg("error: could not copy %d bytes\n", val);
3446 return -EFAULT;
3447 }
3448 }
3449
3450 return 0;
3451}
3452
3453
3454static struct fb_ops au1200fb_fb_ops = {
3455 .owner = THIS_MODULE,
3456 .fb_check_var = au1200fb_fb_check_var,
3457 .fb_set_par = au1200fb_fb_set_par,
3458 .fb_setcolreg = au1200fb_fb_setcolreg,
3459 .fb_blank = au1200fb_fb_blank,
3460 .fb_fillrect = cfb_fillrect,
3461 .fb_copyarea = cfb_copyarea,
3462 .fb_imageblit = cfb_imageblit,
3463 .fb_sync = NULL,
3464 .fb_ioctl = au1200fb_ioctl,
3465 .fb_mmap = au1200fb_fb_mmap,
3466};
3467
3468/*-------------------------------------------------------------------------*/
3469
3470static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id, struct pt_regs *regs)
3471{
3472 /* Nothing to do for now, just clear any pending interrupt */
3473 lcd->intstatus = lcd->intstatus;
3474 au_sync();
3475
3476 return IRQ_HANDLED;
3477}
3478
3479/*-------------------------------------------------------------------------*/
3480
3481/* AU1200 LCD device probe helpers */
3482
3483static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
3484{
3485 struct fb_info *fbi = &fbdev->fb_info;
3486 int bpp;
3487
3488 memset(fbi, 0, sizeof(struct fb_info));
3489 fbi->fbops = &au1200fb_fb_ops;
3490
3491 bpp = winbpp(win->w[fbdev->plane].mode_winctrl1);
3492
3493 /* Copy monitor specs from panel data */
3494 /* fixme: we're setting up LCD controller windows, so these dont give a
3495 damn as to what the monitor specs are (the panel itself does, but that
3496 isnt done here...so maybe need a generic catchall monitor setting??? */
3497 memcpy(&fbi->monspecs, &panel->monspecs, sizeof(struct fb_monspecs));
3498
3499 /* We first try the user mode passed in argument. If that failed,
3500 * or if no one has been specified, we default to the first mode of the
3501 * panel list. Note that after this call, var data will be set */
3502 if (!fb_find_mode(&fbi->var,
3503 fbi,
3504 NULL, /* drv_info.opt_mode, */
3505 fbi->monspecs.modedb,
3506 fbi->monspecs.modedb_len,
3507 fbi->monspecs.modedb,
3508 bpp)) {
3509
3510 print_err("Cannot find valid mode for panel %s", panel->name);
3511 return -EFAULT;
3512 }
3513
3514 fbi->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
3515 if (!fbi->pseudo_palette) {
3516 return -ENOMEM;
3517 }
3518 memset(fbi->pseudo_palette, 0, sizeof(u32) * 16);
3519
3520 if (fb_alloc_cmap(&fbi->cmap, AU1200_LCD_NBR_PALETTE_ENTRIES, 0) < 0) {
3521 print_err("Fail to allocate colormap (%d entries)",
3522 AU1200_LCD_NBR_PALETTE_ENTRIES);
3523 kfree(fbi->pseudo_palette);
3524 return -EFAULT;
3525 }
3526
3527 strncpy(fbi->fix.id, "AU1200", sizeof(fbi->fix.id));
3528 fbi->fix.smem_start = fbdev->fb_phys;
3529 fbi->fix.smem_len = fbdev->fb_len;
3530 fbi->fix.type = FB_TYPE_PACKED_PIXELS;
3531 fbi->fix.xpanstep = 0;
3532 fbi->fix.ypanstep = 0;
3533 fbi->fix.mmio_start = 0;
3534 fbi->fix.mmio_len = 0;
3535 fbi->fix.accel = FB_ACCEL_NONE;
3536
3537 fbi->screen_base = (char __iomem *) fbdev->fb_mem;
3538
3539 au1200fb_update_fbinfo(fbi);
3540
3541 return 0;
3542}
3543
3544/*-------------------------------------------------------------------------*/
3545
3546/* AU1200 LCD controller device driver */
3547
3548static int au1200fb_drv_probe(struct device *dev)
3549{
3550 struct au1200fb_device *fbdev;
3551 unsigned long page;
3552 int bpp, plane, ret;
3553
3554 if (!dev)
3555 return -EINVAL;
3556
3557 for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) {
3558 bpp = winbpp(win->w[plane].mode_winctrl1);
3559 if (win->w[plane].xres == 0)
3560 win->w[plane].xres = panel->Xres;
3561 if (win->w[plane].yres == 0)
3562 win->w[plane].yres = panel->Yres;
3563
3564 fbdev = &_au1200fb_devices[plane];
3565 memset(fbdev, 0, sizeof(struct au1200fb_device));
3566 fbdev->plane = plane;
3567
3568 /* Allocate the framebuffer to the maximum screen size */
3569 fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8;
3570
3571 fbdev->fb_mem = dma_alloc_noncoherent(dev,
3572 PAGE_ALIGN(fbdev->fb_len),
3573 &fbdev->fb_phys, GFP_KERNEL);
3574 if (!fbdev->fb_mem) {
3575 print_err("fail to allocate frambuffer (size: %dK))",
3576 fbdev->fb_len / 1024);
3577 return -ENOMEM;
3578 }
3579
3580 /*
3581 * Set page reserved so that mmap will work. This is necessary
3582 * since we'll be remapping normal memory.
3583 */
3584 for (page = (unsigned long)fbdev->fb_phys;
3585 page < PAGE_ALIGN((unsigned long)fbdev->fb_phys +
3586 fbdev->fb_len);
3587 page += PAGE_SIZE) {
3588 SetPageReserved(pfn_to_page(page >> PAGE_SHIFT)); /* LCD DMA is NOT coherent on Au1200 */
3589 }
3590 print_dbg("Framebuffer memory map at %p", fbdev->fb_mem);
3591 print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024);
3592
3593 /* Init FB data */
3594 if ((ret = au1200fb_init_fbinfo(fbdev)) < 0)
3595 goto failed;
3596
3597 /* Register new framebuffer */
3598 if ((ret = register_framebuffer(&fbdev->fb_info)) < 0) {
3599 print_err("cannot register new framebuffer");
3600 goto failed;
3601 }
3602
3603 au1200fb_fb_set_par(&fbdev->fb_info);
3604
3605#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
3606 if (plane == 0)
3607 if (fb_prepare_logo(&fbdev->fb_info, FB_ROTATE_UR)) {
3608 /* Start display and show logo on boot */
3609 fb_set_cmap(&fbdev->fb_info.cmap,
3610 &fbdev->fb_info);
3611
3612 fb_show_logo(&fbdev->fb_info, FB_ROTATE_UR);
3613 }
3614#endif
3615 }
3616
3617 /* Now hook interrupt too */
3618 if ((ret = request_irq(AU1200_LCD_INT, au1200fb_handle_irq,
3619 SA_INTERRUPT | SA_SHIRQ, "lcd", (void *)dev)) < 0) {
3620 print_err("fail to request interrupt line %d (err: %d)",
3621 AU1200_LCD_INT, ret);
3622 goto failed;
3623 }
3624
3625 return 0;
3626
3627failed:
3628 /* NOTE: This only does the current plane/window that failed; others are still active */
3629 if (fbdev->fb_mem)
3630 dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len),
3631 fbdev->fb_mem, fbdev->fb_phys);
3632 if (fbdev->fb_info.cmap.len != 0)
3633 fb_dealloc_cmap(&fbdev->fb_info.cmap);
3634 if (fbdev->fb_info.pseudo_palette)
3635 kfree(fbdev->fb_info.pseudo_palette);
3636 if (plane == 0)
3637 free_irq(AU1200_LCD_INT, (void*)dev);
3638 return ret;
3639}
3640
3641static int au1200fb_drv_remove(struct device *dev)
3642{
3643 struct au1200fb_device *fbdev;
3644 int plane;
3645
3646 if (!dev)
3647 return -ENODEV;
3648
3649 /* Turn off the panel */
3650 au1200_setpanel(NULL);
3651
3652 for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane)
3653 {
3654 fbdev = &_au1200fb_devices[plane];
3655
3656 /* Clean up all probe data */
3657 unregister_framebuffer(&fbdev->fb_info);
3658 if (fbdev->fb_mem)
3659 dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len),
3660 fbdev->fb_mem, fbdev->fb_phys);
3661 if (fbdev->fb_info.cmap.len != 0)
3662 fb_dealloc_cmap(&fbdev->fb_info.cmap);
3663 if (fbdev->fb_info.pseudo_palette)
3664 kfree(fbdev->fb_info.pseudo_palette);
3665 }
3666
3667 free_irq(AU1200_LCD_INT, (void *)dev);
3668
3669 return 0;
3670}
3671
3672#ifdef CONFIG_PM
3673static int au1200fb_drv_suspend(struct device *dev, u32 state, u32 level)
3674{
3675 /* TODO */
3676 return 0;
3677}
3678
3679static int au1200fb_drv_resume(struct device *dev, u32 level)
3680{
3681 /* TODO */
3682 return 0;
3683}
3684#endif /* CONFIG_PM */
3685
3686static struct device_driver au1200fb_driver = {
3687 .name = "au1200-lcd",
3688 .bus = &platform_bus_type,
3689 .probe = au1200fb_drv_probe,
3690 .remove = au1200fb_drv_remove,
3691#ifdef CONFIG_PM
3692 .suspend = au1200fb_drv_suspend,
3693 .resume = au1200fb_drv_resume,
3694#endif
3695};
3696
3697/*-------------------------------------------------------------------------*/
3698
3699/* Kernel driver */
3700
3701static void au1200fb_setup(void)
3702{
3703 char* options = NULL;
3704 char* this_opt;
3705 int num_panels = ARRAY_SIZE(known_lcd_panels);
3706 int panel_idx = -1;
3707
3708 fb_get_options(DRIVER_NAME, &options);
3709
3710 if (options) {
3711 while ((this_opt = strsep(&options,",")) != NULL) {
3712 /* Panel option - can be panel name,
3713 * "bs" for board-switch, or number/index */
3714 if (!strncmp(this_opt, "panel:", 6)) {
3715 int i;
3716 long int li;
3717 char *endptr;
3718 this_opt += 6;
3719 /* First check for index, which allows
3720 * to short circuit this mess */
3721 li = simple_strtol(this_opt, &endptr, 0);
3722 if (*endptr == '\0') {
3723 panel_idx = (int)li;
3724 }
3725 else if (strcmp(this_opt, "bs") == 0) {
3726 extern int board_au1200fb_panel(void);
3727 panel_idx = board_au1200fb_panel();
3728 }
3729
3730 else
3731 for (i = 0; i < num_panels; i++) {
3732 if (!strcmp(this_opt, known_lcd_panels[i].name)) {
3733 panel_idx = i;
3734 break;
3735 }
3736 }
3737
3738 if ((panel_idx < 0) || (panel_idx >= num_panels)) {
3739 print_warn("Panel %s not supported!", this_opt);
3740 }
3741 else
3742 panel_index = panel_idx;
3743 }
3744
3745 else if (strncmp(this_opt, "nohwcursor", 10) == 0) {
3746 nohwcursor = 1;
3747 }
3748
3749 /* Unsupported option */
3750 else {
3751 print_warn("Unsupported option \"%s\"", this_opt);
3752 }
3753 }
3754 }
3755}
3756
3757#ifdef CONFIG_PM
3758static int au1200fb_pm_callback(au1xxx_power_dev_t *dev,
3759 au1xxx_request_t request, void *data) {
3760 int retval = -1;
3761 unsigned int d = 0;
3762 unsigned int brightness = 0;
3763
3764 if (request == AU1XXX_PM_SLEEP) {
3765 board_au1200fb_panel_shutdown();
3766 }
3767 else if (request == AU1XXX_PM_WAKEUP) {
3768 if(dev->prev_state == SLEEP_STATE)
3769 {
3770 int plane;
3771 au1200_setpanel(panel);
3772 for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) {
3773 struct au1200fb_device *fbdev;
3774 fbdev = &_au1200fb_devices[plane];
3775 au1200fb_fb_set_par(&fbdev->fb_info);
3776 }
3777 }
3778
3779 d = *((unsigned int*)data);
3780 if(d <=10) brightness = 26;
3781 else if(d<=20) brightness = 51;
3782 else if(d<=30) brightness = 77;
3783 else if(d<=40) brightness = 102;
3784 else if(d<=50) brightness = 128;
3785 else if(d<=60) brightness = 153;
3786 else if(d<=70) brightness = 179;
3787 else if(d<=80) brightness = 204;
3788 else if(d<=90) brightness = 230;
3789 else brightness = 255;
3790 set_brightness(brightness);
3791 } else if (request == AU1XXX_PM_GETSTATUS) {
3792 return dev->cur_state;
3793 } else if (request == AU1XXX_PM_ACCESS) {
3794 if (dev->cur_state != SLEEP_STATE)
3795 return retval;
3796 else {
3797 au1200_setpanel(panel);
3798 }
3799 } else if (request == AU1XXX_PM_IDLE) {
3800 } else if (request == AU1XXX_PM_CLEANUP) {
3801 }
3802
3803 return retval;
3804}
3805#endif
3806
3807static int __init au1200fb_init(void)
3808{
3809 print_info("" DRIVER_DESC "");
3810
3811 /* Setup driver with options */
3812 au1200fb_setup();
3813
3814 /* Point to the panel selected */
3815 panel = &known_lcd_panels[panel_index];
3816 win = &windows[window_index];
3817
3818 printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name);
3819 printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name);
3820
3821 /* Kickstart the panel, the framebuffers/windows come soon enough */
3822 au1200_setpanel(panel);
3823
3824 #ifdef CONFIG_PM
3825 LCD_pm_dev = new_au1xxx_power_device("LCD", &au1200fb_pm_callback, NULL);
3826 if ( LCD_pm_dev == NULL)
3827 printk(KERN_INFO "Unable to create a power management device entry for the au1200fb.\n");
3828 else
3829 printk(KERN_INFO "Power management device entry for the au1200fb loaded.\n");
3830 #endif
3831
3832 return driver_register(&au1200fb_driver);
3833}
3834
3835static void __exit au1200fb_cleanup(void)
3836{
3837 driver_unregister(&au1200fb_driver);
3838}
3839
3840module_init(au1200fb_init);
3841module_exit(au1200fb_cleanup);
3842
3843MODULE_DESCRIPTION(DRIVER_DESC);
3844MODULE_LICENSE("GPL");
diff --git a/drivers/video/au1200fb.h b/drivers/video/au1200fb.h
new file mode 100644
index 000000000000..e2672714d8d4
--- /dev/null
+++ b/drivers/video/au1200fb.h
@@ -0,0 +1,572 @@
1/*
2 * BRIEF MODULE DESCRIPTION
3 * Hardware definitions for the Au1200 LCD controller
4 *
5 * Copyright 2004 AMD
6 * Author: AMD
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
14 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
16 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
19 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29#ifndef _AU1200LCD_H
30#define _AU1200LCD_H
31
32/********************************************************************/
33#define AU1200_LCD_ADDR 0xB5000000
34
35#define uint8 unsigned char
36#define uint32 unsigned int
37
38struct au1200_lcd {
39 volatile uint32 reserved0;
40 volatile uint32 screen;
41 volatile uint32 backcolor;
42 volatile uint32 horztiming;
43 volatile uint32 verttiming;
44 volatile uint32 clkcontrol;
45 volatile uint32 pwmdiv;
46 volatile uint32 pwmhi;
47 volatile uint32 reserved1;
48 volatile uint32 winenable;
49 volatile uint32 colorkey;
50 volatile uint32 colorkeymsk;
51 struct
52 {
53 volatile uint32 cursorctrl;
54 volatile uint32 cursorpos;
55 volatile uint32 cursorcolor0;
56 volatile uint32 cursorcolor1;
57 volatile uint32 cursorcolor2;
58 uint32 cursorcolor3;
59 } hwc;
60 volatile uint32 intstatus;
61 volatile uint32 intenable;
62 volatile uint32 outmask;
63 volatile uint32 fifoctrl;
64 uint32 reserved2[(0x0100-0x0058)/4];
65 struct
66 {
67 volatile uint32 winctrl0;
68 volatile uint32 winctrl1;
69 volatile uint32 winctrl2;
70 volatile uint32 winbuf0;
71 volatile uint32 winbuf1;
72 volatile uint32 winbufctrl;
73 uint32 winreserved0;
74 uint32 winreserved1;
75 } window[4];
76
77 uint32 reserved3[(0x0400-0x0180)/4];
78
79 volatile uint32 palette[(0x0800-0x0400)/4];
80
81 volatile uint8 cursorpattern[256];
82};
83
84/* lcd_screen */
85#define LCD_SCREEN_SEN (1<<31)
86#define LCD_SCREEN_SX (0x07FF<<19)
87#define LCD_SCREEN_SY (0x07FF<< 8)
88#define LCD_SCREEN_SWP (1<<7)
89#define LCD_SCREEN_SWD (1<<6)
90#define LCD_SCREEN_PT (7<<0)
91#define LCD_SCREEN_PT_TFT (0<<0)
92#define LCD_SCREEN_SX_N(WIDTH) ((WIDTH-1)<<19)
93#define LCD_SCREEN_SY_N(HEIGHT) ((HEIGHT-1)<<8)
94#define LCD_SCREEN_PT_CSTN (1<<0)
95#define LCD_SCREEN_PT_CDSTN (2<<0)
96#define LCD_SCREEN_PT_M8STN (3<<0)
97#define LCD_SCREEN_PT_M4STN (4<<0)
98
99/* lcd_backcolor */
100#define LCD_BACKCOLOR_SBGR (0xFF<<16)
101#define LCD_BACKCOLOR_SBGG (0xFF<<8)
102#define LCD_BACKCOLOR_SBGB (0xFF<<0)
103#define LCD_BACKCOLOR_SBGR_N(N) ((N)<<16)
104#define LCD_BACKCOLOR_SBGG_N(N) ((N)<<8)
105#define LCD_BACKCOLOR_SBGB_N(N) ((N)<<0)
106
107/* lcd_winenable */
108#define LCD_WINENABLE_WEN3 (1<<3)
109#define LCD_WINENABLE_WEN2 (1<<2)
110#define LCD_WINENABLE_WEN1 (1<<1)
111#define LCD_WINENABLE_WEN0 (1<<0)
112
113/* lcd_colorkey */
114#define LCD_COLORKEY_CKR (0xFF<<16)
115#define LCD_COLORKEY_CKG (0xFF<<8)
116#define LCD_COLORKEY_CKB (0xFF<<0)
117#define LCD_COLORKEY_CKR_N(N) ((N)<<16)
118#define LCD_COLORKEY_CKG_N(N) ((N)<<8)
119#define LCD_COLORKEY_CKB_N(N) ((N)<<0)
120
121/* lcd_colorkeymsk */
122#define LCD_COLORKEYMSK_CKMR (0xFF<<16)
123#define LCD_COLORKEYMSK_CKMG (0xFF<<8)
124#define LCD_COLORKEYMSK_CKMB (0xFF<<0)
125#define LCD_COLORKEYMSK_CKMR_N(N) ((N)<<16)
126#define LCD_COLORKEYMSK_CKMG_N(N) ((N)<<8)
127#define LCD_COLORKEYMSK_CKMB_N(N) ((N)<<0)
128
129/* lcd windows control 0 */
130#define LCD_WINCTRL0_OX (0x07FF<<21)
131#define LCD_WINCTRL0_OY (0x07FF<<10)
132#define LCD_WINCTRL0_A (0x00FF<<2)
133#define LCD_WINCTRL0_AEN (1<<1)
134#define LCD_WINCTRL0_OX_N(N) ((N)<<21)
135#define LCD_WINCTRL0_OY_N(N) ((N)<<10)
136#define LCD_WINCTRL0_A_N(N) ((N)<<2)
137
138/* lcd windows control 1 */
139#define LCD_WINCTRL1_PRI (3<<30)
140#define LCD_WINCTRL1_PIPE (1<<29)
141#define LCD_WINCTRL1_FRM (0xF<<25)
142#define LCD_WINCTRL1_CCO (1<<24)
143#define LCD_WINCTRL1_PO (3<<22)
144#define LCD_WINCTRL1_SZX (0x07FF<<11)
145#define LCD_WINCTRL1_SZY (0x07FF<<0)
146#define LCD_WINCTRL1_FRM_1BPP (0<<25)
147#define LCD_WINCTRL1_FRM_2BPP (1<<25)
148#define LCD_WINCTRL1_FRM_4BPP (2<<25)
149#define LCD_WINCTRL1_FRM_8BPP (3<<25)
150#define LCD_WINCTRL1_FRM_12BPP (4<<25)
151#define LCD_WINCTRL1_FRM_16BPP655 (5<<25)
152#define LCD_WINCTRL1_FRM_16BPP565 (6<<25)
153#define LCD_WINCTRL1_FRM_16BPP556 (7<<25)
154#define LCD_WINCTRL1_FRM_16BPPI1555 (8<<25)
155#define LCD_WINCTRL1_FRM_16BPPI5551 (9<<25)
156#define LCD_WINCTRL1_FRM_16BPPA1555 (10<<25)
157#define LCD_WINCTRL1_FRM_16BPPA5551 (11<<25)
158#define LCD_WINCTRL1_FRM_24BPP (12<<25)
159#define LCD_WINCTRL1_FRM_32BPP (13<<25)
160#define LCD_WINCTRL1_PRI_N(N) ((N)<<30)
161#define LCD_WINCTRL1_PO_00 (0<<22)
162#define LCD_WINCTRL1_PO_01 (1<<22)
163#define LCD_WINCTRL1_PO_10 (2<<22)
164#define LCD_WINCTRL1_PO_11 (3<<22)
165#define LCD_WINCTRL1_SZX_N(N) ((N-1)<<11)
166#define LCD_WINCTRL1_SZY_N(N) ((N-1)<<0)
167
168/* lcd windows control 2 */
169#define LCD_WINCTRL2_CKMODE (3<<24)
170#define LCD_WINCTRL2_DBM (1<<23)
171#define LCD_WINCTRL2_RAM (3<<21)
172#define LCD_WINCTRL2_BX (0x1FFF<<8)
173#define LCD_WINCTRL2_SCX (0xF<<4)
174#define LCD_WINCTRL2_SCY (0xF<<0)
175#define LCD_WINCTRL2_CKMODE_00 (0<<24)
176#define LCD_WINCTRL2_CKMODE_01 (1<<24)
177#define LCD_WINCTRL2_CKMODE_10 (2<<24)
178#define LCD_WINCTRL2_CKMODE_11 (3<<24)
179#define LCD_WINCTRL2_RAM_NONE (0<<21)
180#define LCD_WINCTRL2_RAM_PALETTE (1<<21)
181#define LCD_WINCTRL2_RAM_GAMMA (2<<21)
182#define LCD_WINCTRL2_RAM_BUFFER (3<<21)
183#define LCD_WINCTRL2_BX_N(N) ((N)<<8)
184#define LCD_WINCTRL2_SCX_1 (0<<4)
185#define LCD_WINCTRL2_SCX_2 (1<<4)
186#define LCD_WINCTRL2_SCX_4 (2<<4)
187#define LCD_WINCTRL2_SCY_1 (0<<0)
188#define LCD_WINCTRL2_SCY_2 (1<<0)
189#define LCD_WINCTRL2_SCY_4 (2<<0)
190
191/* lcd windows buffer control */
192#define LCD_WINBUFCTRL_DB (1<<1)
193#define LCD_WINBUFCTRL_DBN (1<<0)
194
195/* lcd_intstatus, lcd_intenable */
196#define LCD_INT_IFO (0xF<<14)
197#define LCD_INT_IFU (0xF<<10)
198#define LCD_INT_OFO (1<<9)
199#define LCD_INT_OFU (1<<8)
200#define LCD_INT_WAIT (1<<3)
201#define LCD_INT_SD (1<<2)
202#define LCD_INT_SA (1<<1)
203#define LCD_INT_SS (1<<0)
204
205/* lcd_horztiming */
206#define LCD_HORZTIMING_HND2 (0x1FF<<18)
207#define LCD_HORZTIMING_HND1 (0x1FF<<9)
208#define LCD_HORZTIMING_HPW (0x1FF<<0)
209#define LCD_HORZTIMING_HND2_N(N)(((N)-1)<<18)
210#define LCD_HORZTIMING_HND1_N(N)(((N)-1)<<9)
211#define LCD_HORZTIMING_HPW_N(N) (((N)-1)<<0)
212
213/* lcd_verttiming */
214#define LCD_VERTTIMING_VND2 (0x1FF<<18)
215#define LCD_VERTTIMING_VND1 (0x1FF<<9)
216#define LCD_VERTTIMING_VPW (0x1FF<<0)
217#define LCD_VERTTIMING_VND2_N(N)(((N)-1)<<18)
218#define LCD_VERTTIMING_VND1_N(N)(((N)-1)<<9)
219#define LCD_VERTTIMING_VPW_N(N) (((N)-1)<<0)
220
221/* lcd_clkcontrol */
222#define LCD_CLKCONTROL_EXT (1<<22)
223#define LCD_CLKCONTROL_DELAY (3<<20)
224#define LCD_CLKCONTROL_CDD (1<<19)
225#define LCD_CLKCONTROL_IB (1<<18)
226#define LCD_CLKCONTROL_IC (1<<17)
227#define LCD_CLKCONTROL_IH (1<<16)
228#define LCD_CLKCONTROL_IV (1<<15)
229#define LCD_CLKCONTROL_BF (0x1F<<10)
230#define LCD_CLKCONTROL_PCD (0x3FF<<0)
231#define LCD_CLKCONTROL_BF_N(N) (((N)-1)<<10)
232#define LCD_CLKCONTROL_PCD_N(N) ((N)<<0)
233
234/* lcd_pwmdiv */
235#define LCD_PWMDIV_EN (1<<31)
236#define LCD_PWMDIV_PWMDIV (0x1FFFF<<0)
237#define LCD_PWMDIV_PWMDIV_N(N) ((N)<<0)
238
239/* lcd_pwmhi */
240#define LCD_PWMHI_PWMHI1 (0xFFFF<<16)
241#define LCD_PWMHI_PWMHI0 (0xFFFF<<0)
242#define LCD_PWMHI_PWMHI1_N(N) ((N)<<16)
243#define LCD_PWMHI_PWMHI0_N(N) ((N)<<0)
244
245/* lcd_hwccon */
246#define LCD_HWCCON_EN (1<<0)
247
248/* lcd_cursorpos */
249#define LCD_CURSORPOS_HWCXOFF (0x1F<<27)
250#define LCD_CURSORPOS_HWCXPOS (0x07FF<<16)
251#define LCD_CURSORPOS_HWCYOFF (0x1F<<11)
252#define LCD_CURSORPOS_HWCYPOS (0x07FF<<0)
253#define LCD_CURSORPOS_HWCXOFF_N(N) ((N)<<27)
254#define LCD_CURSORPOS_HWCXPOS_N(N) ((N)<<16)
255#define LCD_CURSORPOS_HWCYOFF_N(N) ((N)<<11)
256#define LCD_CURSORPOS_HWCYPOS_N(N) ((N)<<0)
257
258/* lcd_cursorcolor */
259#define LCD_CURSORCOLOR_HWCA (0xFF<<24)
260#define LCD_CURSORCOLOR_HWCR (0xFF<<16)
261#define LCD_CURSORCOLOR_HWCG (0xFF<<8)
262#define LCD_CURSORCOLOR_HWCB (0xFF<<0)
263#define LCD_CURSORCOLOR_HWCA_N(N) ((N)<<24)
264#define LCD_CURSORCOLOR_HWCR_N(N) ((N)<<16)
265#define LCD_CURSORCOLOR_HWCG_N(N) ((N)<<8)
266#define LCD_CURSORCOLOR_HWCB_N(N) ((N)<<0)
267
268/* lcd_fifoctrl */
269#define LCD_FIFOCTRL_F3IF (1<<29)
270#define LCD_FIFOCTRL_F3REQ (0x1F<<24)
271#define LCD_FIFOCTRL_F2IF (1<<29)
272#define LCD_FIFOCTRL_F2REQ (0x1F<<16)
273#define LCD_FIFOCTRL_F1IF (1<<29)
274#define LCD_FIFOCTRL_F1REQ (0x1F<<8)
275#define LCD_FIFOCTRL_F0IF (1<<29)
276#define LCD_FIFOCTRL_F0REQ (0x1F<<0)
277#define LCD_FIFOCTRL_F3REQ_N(N) ((N-1)<<24)
278#define LCD_FIFOCTRL_F2REQ_N(N) ((N-1)<<16)
279#define LCD_FIFOCTRL_F1REQ_N(N) ((N-1)<<8)
280#define LCD_FIFOCTRL_F0REQ_N(N) ((N-1)<<0)
281
282/* lcd_outmask */
283#define LCD_OUTMASK_MASK (0x00FFFFFF)
284
285/********************************************************************/
286#endif /* _AU1200LCD_H */
287/*
288 * BRIEF MODULE DESCRIPTION
289 * Hardware definitions for the Au1200 LCD controller
290 *
291 * Copyright 2004 AMD
292 * Author: AMD
293 *
294 * This program is free software; you can redistribute it and/or modify it
295 * under the terms of the GNU General Public License as published by the
296 * Free Software Foundation; either version 2 of the License, or (at your
297 * option) any later version.
298 *
299 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
300 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
301 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
302 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
303 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
304 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
305 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
306 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
307 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
308 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
309 *
310 * You should have received a copy of the GNU General Public License along
311 * with this program; if not, write to the Free Software Foundation, Inc.,
312 * 675 Mass Ave, Cambridge, MA 02139, USA.
313 */
314
315#ifndef _AU1200LCD_H
316#define _AU1200LCD_H
317
318/********************************************************************/
319#define AU1200_LCD_ADDR 0xB5000000
320
321#define uint8 unsigned char
322#define uint32 unsigned int
323
324struct au1200_lcd {
325 volatile uint32 reserved0;
326 volatile uint32 screen;
327 volatile uint32 backcolor;
328 volatile uint32 horztiming;
329 volatile uint32 verttiming;
330 volatile uint32 clkcontrol;
331 volatile uint32 pwmdiv;
332 volatile uint32 pwmhi;
333 volatile uint32 reserved1;
334 volatile uint32 winenable;
335 volatile uint32 colorkey;
336 volatile uint32 colorkeymsk;
337 struct
338 {
339 volatile uint32 cursorctrl;
340 volatile uint32 cursorpos;
341 volatile uint32 cursorcolor0;
342 volatile uint32 cursorcolor1;
343 volatile uint32 cursorcolor2;
344 uint32 cursorcolor3;
345 } hwc;
346 volatile uint32 intstatus;
347 volatile uint32 intenable;
348 volatile uint32 outmask;
349 volatile uint32 fifoctrl;
350 uint32 reserved2[(0x0100-0x0058)/4];
351 struct
352 {
353 volatile uint32 winctrl0;
354 volatile uint32 winctrl1;
355 volatile uint32 winctrl2;
356 volatile uint32 winbuf0;
357 volatile uint32 winbuf1;
358 volatile uint32 winbufctrl;
359 uint32 winreserved0;
360 uint32 winreserved1;
361 } window[4];
362
363 uint32 reserved3[(0x0400-0x0180)/4];
364
365 volatile uint32 palette[(0x0800-0x0400)/4];
366
367 volatile uint8 cursorpattern[256];
368};
369
370/* lcd_screen */
371#define LCD_SCREEN_SEN (1<<31)
372#define LCD_SCREEN_SX (0x07FF<<19)
373#define LCD_SCREEN_SY (0x07FF<< 8)
374#define LCD_SCREEN_SWP (1<<7)
375#define LCD_SCREEN_SWD (1<<6)
376#define LCD_SCREEN_PT (7<<0)
377#define LCD_SCREEN_PT_TFT (0<<0)
378#define LCD_SCREEN_SX_N(WIDTH) ((WIDTH-1)<<19)
379#define LCD_SCREEN_SY_N(HEIGHT) ((HEIGHT-1)<<8)
380#define LCD_SCREEN_PT_CSTN (1<<0)
381#define LCD_SCREEN_PT_CDSTN (2<<0)
382#define LCD_SCREEN_PT_M8STN (3<<0)
383#define LCD_SCREEN_PT_M4STN (4<<0)
384
385/* lcd_backcolor */
386#define LCD_BACKCOLOR_SBGR (0xFF<<16)
387#define LCD_BACKCOLOR_SBGG (0xFF<<8)
388#define LCD_BACKCOLOR_SBGB (0xFF<<0)
389#define LCD_BACKCOLOR_SBGR_N(N) ((N)<<16)
390#define LCD_BACKCOLOR_SBGG_N(N) ((N)<<8)
391#define LCD_BACKCOLOR_SBGB_N(N) ((N)<<0)
392
393/* lcd_winenable */
394#define LCD_WINENABLE_WEN3 (1<<3)
395#define LCD_WINENABLE_WEN2 (1<<2)
396#define LCD_WINENABLE_WEN1 (1<<1)
397#define LCD_WINENABLE_WEN0 (1<<0)
398
399/* lcd_colorkey */
400#define LCD_COLORKEY_CKR (0xFF<<16)
401#define LCD_COLORKEY_CKG (0xFF<<8)
402#define LCD_COLORKEY_CKB (0xFF<<0)
403#define LCD_COLORKEY_CKR_N(N) ((N)<<16)
404#define LCD_COLORKEY_CKG_N(N) ((N)<<8)
405#define LCD_COLORKEY_CKB_N(N) ((N)<<0)
406
407/* lcd_colorkeymsk */
408#define LCD_COLORKEYMSK_CKMR (0xFF<<16)
409#define LCD_COLORKEYMSK_CKMG (0xFF<<8)
410#define LCD_COLORKEYMSK_CKMB (0xFF<<0)
411#define LCD_COLORKEYMSK_CKMR_N(N) ((N)<<16)
412#define LCD_COLORKEYMSK_CKMG_N(N) ((N)<<8)
413#define LCD_COLORKEYMSK_CKMB_N(N) ((N)<<0)
414
415/* lcd windows control 0 */
416#define LCD_WINCTRL0_OX (0x07FF<<21)
417#define LCD_WINCTRL0_OY (0x07FF<<10)
418#define LCD_WINCTRL0_A (0x00FF<<2)
419#define LCD_WINCTRL0_AEN (1<<1)
420#define LCD_WINCTRL0_OX_N(N) ((N)<<21)
421#define LCD_WINCTRL0_OY_N(N) ((N)<<10)
422#define LCD_WINCTRL0_A_N(N) ((N)<<2)
423
424/* lcd windows control 1 */
425#define LCD_WINCTRL1_PRI (3<<30)
426#define LCD_WINCTRL1_PIPE (1<<29)
427#define LCD_WINCTRL1_FRM (0xF<<25)
428#define LCD_WINCTRL1_CCO (1<<24)
429#define LCD_WINCTRL1_PO (3<<22)
430#define LCD_WINCTRL1_SZX (0x07FF<<11)
431#define LCD_WINCTRL1_SZY (0x07FF<<0)
432#define LCD_WINCTRL1_FRM_1BPP (0<<25)
433#define LCD_WINCTRL1_FRM_2BPP (1<<25)
434#define LCD_WINCTRL1_FRM_4BPP (2<<25)
435#define LCD_WINCTRL1_FRM_8BPP (3<<25)
436#define LCD_WINCTRL1_FRM_12BPP (4<<25)
437#define LCD_WINCTRL1_FRM_16BPP655 (5<<25)
438#define LCD_WINCTRL1_FRM_16BPP565 (6<<25)
439#define LCD_WINCTRL1_FRM_16BPP556 (7<<25)
440#define LCD_WINCTRL1_FRM_16BPPI1555 (8<<25)
441#define LCD_WINCTRL1_FRM_16BPPI5551 (9<<25)
442#define LCD_WINCTRL1_FRM_16BPPA1555 (10<<25)
443#define LCD_WINCTRL1_FRM_16BPPA5551 (11<<25)
444#define LCD_WINCTRL1_FRM_24BPP (12<<25)
445#define LCD_WINCTRL1_FRM_32BPP (13<<25)
446#define LCD_WINCTRL1_PRI_N(N) ((N)<<30)
447#define LCD_WINCTRL1_PO_00 (0<<22)
448#define LCD_WINCTRL1_PO_01 (1<<22)
449#define LCD_WINCTRL1_PO_10 (2<<22)
450#define LCD_WINCTRL1_PO_11 (3<<22)
451#define LCD_WINCTRL1_SZX_N(N) ((N-1)<<11)
452#define LCD_WINCTRL1_SZY_N(N) ((N-1)<<0)
453
454/* lcd windows control 2 */
455#define LCD_WINCTRL2_CKMODE (3<<24)
456#define LCD_WINCTRL2_DBM (1<<23)
457#define LCD_WINCTRL2_RAM (3<<21)
458#define LCD_WINCTRL2_BX (0x1FFF<<8)
459#define LCD_WINCTRL2_SCX (0xF<<4)
460#define LCD_WINCTRL2_SCY (0xF<<0)
461#define LCD_WINCTRL2_CKMODE_00 (0<<24)
462#define LCD_WINCTRL2_CKMODE_01 (1<<24)
463#define LCD_WINCTRL2_CKMODE_10 (2<<24)
464#define LCD_WINCTRL2_CKMODE_11 (3<<24)
465#define LCD_WINCTRL2_RAM_NONE (0<<21)
466#define LCD_WINCTRL2_RAM_PALETTE (1<<21)
467#define LCD_WINCTRL2_RAM_GAMMA (2<<21)
468#define LCD_WINCTRL2_RAM_BUFFER (3<<21)
469#define LCD_WINCTRL2_BX_N(N) ((N)<<8)
470#define LCD_WINCTRL2_SCX_1 (0<<4)
471#define LCD_WINCTRL2_SCX_2 (1<<4)
472#define LCD_WINCTRL2_SCX_4 (2<<4)
473#define LCD_WINCTRL2_SCY_1 (0<<0)
474#define LCD_WINCTRL2_SCY_2 (1<<0)
475#define LCD_WINCTRL2_SCY_4 (2<<0)
476
477/* lcd windows buffer control */
478#define LCD_WINBUFCTRL_DB (1<<1)
479#define LCD_WINBUFCTRL_DBN (1<<0)
480
481/* lcd_intstatus, lcd_intenable */
482#define LCD_INT_IFO (0xF<<14)
483#define LCD_INT_IFU (0xF<<10)
484#define LCD_INT_OFO (1<<9)
485#define LCD_INT_OFU (1<<8)
486#define LCD_INT_WAIT (1<<3)
487#define LCD_INT_SD (1<<2)
488#define LCD_INT_SA (1<<1)
489#define LCD_INT_SS (1<<0)
490
491/* lcd_horztiming */
492#define LCD_HORZTIMING_HND2 (0x1FF<<18)
493#define LCD_HORZTIMING_HND1 (0x1FF<<9)
494#define LCD_HORZTIMING_HPW (0x1FF<<0)
495#define LCD_HORZTIMING_HND2_N(N)(((N)-1)<<18)
496#define LCD_HORZTIMING_HND1_N(N)(((N)-1)<<9)
497#define LCD_HORZTIMING_HPW_N(N) (((N)-1)<<0)
498
499/* lcd_verttiming */
500#define LCD_VERTTIMING_VND2 (0x1FF<<18)
501#define LCD_VERTTIMING_VND1 (0x1FF<<9)
502#define LCD_VERTTIMING_VPW (0x1FF<<0)
503#define LCD_VERTTIMING_VND2_N(N)(((N)-1)<<18)
504#define LCD_VERTTIMING_VND1_N(N)(((N)-1)<<9)
505#define LCD_VERTTIMING_VPW_N(N) (((N)-1)<<0)
506
507/* lcd_clkcontrol */
508#define LCD_CLKCONTROL_EXT (1<<22)
509#define LCD_CLKCONTROL_DELAY (3<<20)
510#define LCD_CLKCONTROL_CDD (1<<19)
511#define LCD_CLKCONTROL_IB (1<<18)
512#define LCD_CLKCONTROL_IC (1<<17)
513#define LCD_CLKCONTROL_IH (1<<16)
514#define LCD_CLKCONTROL_IV (1<<15)
515#define LCD_CLKCONTROL_BF (0x1F<<10)
516#define LCD_CLKCONTROL_PCD (0x3FF<<0)
517#define LCD_CLKCONTROL_BF_N(N) (((N)-1)<<10)
518#define LCD_CLKCONTROL_PCD_N(N) ((N)<<0)
519
520/* lcd_pwmdiv */
521#define LCD_PWMDIV_EN (1<<31)
522#define LCD_PWMDIV_PWMDIV (0x1FFFF<<0)
523#define LCD_PWMDIV_PWMDIV_N(N) ((N)<<0)
524
525/* lcd_pwmhi */
526#define LCD_PWMHI_PWMHI1 (0xFFFF<<16)
527#define LCD_PWMHI_PWMHI0 (0xFFFF<<0)
528#define LCD_PWMHI_PWMHI1_N(N) ((N)<<16)
529#define LCD_PWMHI_PWMHI0_N(N) ((N)<<0)
530
531/* lcd_hwccon */
532#define LCD_HWCCON_EN (1<<0)
533
534/* lcd_cursorpos */
535#define LCD_CURSORPOS_HWCXOFF (0x1F<<27)
536#define LCD_CURSORPOS_HWCXPOS (0x07FF<<16)
537#define LCD_CURSORPOS_HWCYOFF (0x1F<<11)
538#define LCD_CURSORPOS_HWCYPOS (0x07FF<<0)
539#define LCD_CURSORPOS_HWCXOFF_N(N) ((N)<<27)
540#define LCD_CURSORPOS_HWCXPOS_N(N) ((N)<<16)
541#define LCD_CURSORPOS_HWCYOFF_N(N) ((N)<<11)
542#define LCD_CURSORPOS_HWCYPOS_N(N) ((N)<<0)
543
544/* lcd_cursorcolor */
545#define LCD_CURSORCOLOR_HWCA (0xFF<<24)
546#define LCD_CURSORCOLOR_HWCR (0xFF<<16)
547#define LCD_CURSORCOLOR_HWCG (0xFF<<8)
548#define LCD_CURSORCOLOR_HWCB (0xFF<<0)
549#define LCD_CURSORCOLOR_HWCA_N(N) ((N)<<24)
550#define LCD_CURSORCOLOR_HWCR_N(N) ((N)<<16)
551#define LCD_CURSORCOLOR_HWCG_N(N) ((N)<<8)
552#define LCD_CURSORCOLOR_HWCB_N(N) ((N)<<0)
553
554/* lcd_fifoctrl */
555#define LCD_FIFOCTRL_F3IF (1<<29)
556#define LCD_FIFOCTRL_F3REQ (0x1F<<24)
557#define LCD_FIFOCTRL_F2IF (1<<29)
558#define LCD_FIFOCTRL_F2REQ (0x1F<<16)
559#define LCD_FIFOCTRL_F1IF (1<<29)
560#define LCD_FIFOCTRL_F1REQ (0x1F<<8)
561#define LCD_FIFOCTRL_F0IF (1<<29)
562#define LCD_FIFOCTRL_F0REQ (0x1F<<0)
563#define LCD_FIFOCTRL_F3REQ_N(N) ((N-1)<<24)
564#define LCD_FIFOCTRL_F2REQ_N(N) ((N-1)<<16)
565#define LCD_FIFOCTRL_F1REQ_N(N) ((N-1)<<8)
566#define LCD_FIFOCTRL_F0REQ_N(N) ((N-1)<<0)
567
568/* lcd_outmask */
569#define LCD_OUTMASK_MASK (0x00FFFFFF)
570
571/********************************************************************/
572#endif /* _AU1200LCD_H */
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c
index bc061d4ec786..72ff6bf75e5e 100644
--- a/drivers/video/chipsfb.c
+++ b/drivers/video/chipsfb.c
@@ -178,8 +178,6 @@ struct chips_init_reg {
178 unsigned char data; 178 unsigned char data;
179}; 179};
180 180
181#define N_ELTS(x) (sizeof(x) / sizeof(x[0]))
182
183static struct chips_init_reg chips_init_sr[] = { 181static struct chips_init_reg chips_init_sr[] = {
184 { 0x00, 0x03 }, 182 { 0x00, 0x03 },
185 { 0x01, 0x01 }, 183 { 0x01, 0x01 },
@@ -287,18 +285,18 @@ static void __init chips_hw_init(void)
287{ 285{
288 int i; 286 int i;
289 287
290 for (i = 0; i < N_ELTS(chips_init_xr); ++i) 288 for (i = 0; i < ARRAY_SIZE(chips_init_xr); ++i)
291 write_xr(chips_init_xr[i].addr, chips_init_xr[i].data); 289 write_xr(chips_init_xr[i].addr, chips_init_xr[i].data);
292 outb(0x29, 0x3c2); /* set misc output reg */ 290 outb(0x29, 0x3c2); /* set misc output reg */
293 for (i = 0; i < N_ELTS(chips_init_sr); ++i) 291 for (i = 0; i < ARRAY_SIZE(chips_init_sr); ++i)
294 write_sr(chips_init_sr[i].addr, chips_init_sr[i].data); 292 write_sr(chips_init_sr[i].addr, chips_init_sr[i].data);
295 for (i = 0; i < N_ELTS(chips_init_gr); ++i) 293 for (i = 0; i < ARRAY_SIZE(chips_init_gr); ++i)
296 write_gr(chips_init_gr[i].addr, chips_init_gr[i].data); 294 write_gr(chips_init_gr[i].addr, chips_init_gr[i].data);
297 for (i = 0; i < N_ELTS(chips_init_ar); ++i) 295 for (i = 0; i < ARRAY_SIZE(chips_init_ar); ++i)
298 write_ar(chips_init_ar[i].addr, chips_init_ar[i].data); 296 write_ar(chips_init_ar[i].addr, chips_init_ar[i].data);
299 for (i = 0; i < N_ELTS(chips_init_cr); ++i) 297 for (i = 0; i < ARRAY_SIZE(chips_init_cr); ++i)
300 write_cr(chips_init_cr[i].addr, chips_init_cr[i].data); 298 write_cr(chips_init_cr[i].addr, chips_init_cr[i].data);
301 for (i = 0; i < N_ELTS(chips_init_fr); ++i) 299 for (i = 0; i < ARRAY_SIZE(chips_init_fr); ++i)
302 write_fr(chips_init_fr[i].addr, chips_init_fr[i].data); 300 write_fr(chips_init_fr[i].addr, chips_init_fr[i].data);
303} 301}
304 302
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 6ee449858a5c..4444bef68fba 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -26,6 +26,30 @@ config VGA_CONSOLE
26# fi 26# fi
27# fi 27# fi
28 28
29config VGACON_SOFT_SCROLLBACK
30 bool "Enable Scrollback Buffer in System RAM"
31 depends on VGA_CONSOLE
32 default n
33 help
34 The scrollback buffer of the standard VGA console is located in
35 the VGA RAM. The size of this RAM is fixed and is quite small.
36 If you require a larger scrollback buffer, this can be placed in
37 System RAM which is dynamically allocated during intialization.
38 Placing the scrollback buffer in System RAM will slightly slow
39 down the console.
40
41 If you want this feature, say 'Y' here and enter the amount of
42 RAM to allocate for this buffer. If unsure, say 'N'.
43
44config VGACON_SOFT_SCROLLBACK_SIZE
45 int "Scrollback Buffer Size (in KB)"
46 depends on VGACON_SOFT_SCROLLBACK
47 default "64"
48 help
49 Enter the amount of System RAM to allocate for the scrollback
50 buffer. Each 64KB will give you approximately 16 80x25
51 screenfuls of scrollback buffer
52
29config VIDEO_SELECT 53config VIDEO_SELECT
30 bool "Video mode selection support" 54 bool "Video mode selection support"
31 depends on X86 && VGA_CONSOLE 55 depends on X86 && VGA_CONSOLE
diff --git a/drivers/video/console/fonts.c b/drivers/video/console/fonts.c
index 4fd07d9eca03..0cc1bfda76a6 100644
--- a/drivers/video/console/fonts.c
+++ b/drivers/video/console/fonts.c
@@ -66,7 +66,7 @@ static const struct font_desc *fonts[] = {
66#endif 66#endif
67}; 67};
68 68
69#define num_fonts (sizeof(fonts)/sizeof(*fonts)) 69#define num_fonts ARRAY_SIZE(fonts)
70 70
71#ifdef NO_FONTS 71#ifdef NO_FONTS
72#error No fonts configured. 72#error No fonts configured.
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
index 762c7a593141..e99fe30e568c 100644
--- a/drivers/video/console/newport_con.c
+++ b/drivers/video/console/newport_con.c
@@ -149,7 +149,7 @@ static inline void newport_clear_lines(int ystart, int yend, int ci)
149 newport_clear_screen(0, ystart, 1280 + 63, yend, ci); 149 newport_clear_screen(0, ystart, 1280 + 63, yend, ci);
150} 150}
151 151
152void newport_reset(void) 152static void newport_reset(void)
153{ 153{
154 unsigned short treg; 154 unsigned short treg;
155 int i; 155 int i;
@@ -193,7 +193,7 @@ void newport_reset(void)
193 * calculate the actual screen size by reading 193 * calculate the actual screen size by reading
194 * the video timing out of the VC2 194 * the video timing out of the VC2
195 */ 195 */
196void newport_get_screensize(void) 196static void newport_get_screensize(void)
197{ 197{
198 int i, cols; 198 int i, cols;
199 unsigned short ventry, treg; 199 unsigned short ventry, treg;
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 5a86978537d2..d5a04b68c4d4 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -93,7 +93,6 @@ static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
93static void vgacon_invert_region(struct vc_data *c, u16 * p, int count); 93static void vgacon_invert_region(struct vc_data *c, u16 * p, int count);
94static unsigned long vgacon_uni_pagedir[2]; 94static unsigned long vgacon_uni_pagedir[2];
95 95
96
97/* Description of the hardware situation */ 96/* Description of the hardware situation */
98static unsigned long vga_vram_base; /* Base of video memory */ 97static unsigned long vga_vram_base; /* Base of video memory */
99static unsigned long vga_vram_end; /* End of video memory */ 98static unsigned long vga_vram_end; /* End of video memory */
@@ -161,6 +160,201 @@ static inline void write_vga(unsigned char reg, unsigned int val)
161 spin_unlock_irqrestore(&vga_lock, flags); 160 spin_unlock_irqrestore(&vga_lock, flags);
162} 161}
163 162
163static inline void vga_set_mem_top(struct vc_data *c)
164{
165 write_vga(12, (c->vc_visible_origin - vga_vram_base) / 2);
166}
167
168#ifdef CONFIG_VGACON_SOFT_SCROLLBACK
169#include <linux/bootmem.h>
170/* software scrollback */
171static void *vgacon_scrollback;
172static int vgacon_scrollback_tail;
173static int vgacon_scrollback_size;
174static int vgacon_scrollback_rows;
175static int vgacon_scrollback_cnt;
176static int vgacon_scrollback_cur;
177static int vgacon_scrollback_save;
178static int vgacon_scrollback_restore;
179
180static void vgacon_scrollback_init(int pitch)
181{
182 int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
183
184 if (vgacon_scrollback) {
185 vgacon_scrollback_cnt = 0;
186 vgacon_scrollback_tail = 0;
187 vgacon_scrollback_cur = 0;
188 vgacon_scrollback_rows = rows - 1;
189 vgacon_scrollback_size = rows * pitch;
190 }
191}
192
193static void __init vgacon_scrollback_startup(void)
194{
195 vgacon_scrollback = alloc_bootmem(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE
196 * 1024);
197 vgacon_scrollback_init(vga_video_num_columns * 2);
198}
199
200static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
201{
202 void *p;
203
204 if (!vgacon_scrollback_size || c->vc_num != fg_console)
205 return;
206
207 p = (void *) (c->vc_origin + t * c->vc_size_row);
208
209 while (count--) {
210 scr_memcpyw(vgacon_scrollback + vgacon_scrollback_tail,
211 p, c->vc_size_row);
212 vgacon_scrollback_cnt++;
213 p += c->vc_size_row;
214 vgacon_scrollback_tail += c->vc_size_row;
215
216 if (vgacon_scrollback_tail >= vgacon_scrollback_size)
217 vgacon_scrollback_tail = 0;
218
219 if (vgacon_scrollback_cnt > vgacon_scrollback_rows)
220 vgacon_scrollback_cnt = vgacon_scrollback_rows;
221
222 vgacon_scrollback_cur = vgacon_scrollback_cnt;
223 }
224}
225
226static void vgacon_restore_screen(struct vc_data *c)
227{
228 vgacon_scrollback_save = 0;
229
230 if (!vga_is_gfx && !vgacon_scrollback_restore) {
231 scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
232 c->vc_screenbuf_size > vga_vram_size ?
233 vga_vram_size : c->vc_screenbuf_size);
234 vgacon_scrollback_restore = 1;
235 vgacon_scrollback_cur = vgacon_scrollback_cnt;
236 }
237}
238
239static int vgacon_scrolldelta(struct vc_data *c, int lines)
240{
241 int start, end, count, soff, diff;
242 void *d, *s;
243
244 if (!lines) {
245 c->vc_visible_origin = c->vc_origin;
246 vga_set_mem_top(c);
247 return 1;
248 }
249
250 if (!vgacon_scrollback)
251 return 1;
252
253 if (!vgacon_scrollback_save) {
254 vgacon_cursor(c, CM_ERASE);
255 vgacon_save_screen(c);
256 vgacon_scrollback_save = 1;
257 }
258
259 vgacon_scrollback_restore = 0;
260 start = vgacon_scrollback_cur + lines;
261 end = start + abs(lines);
262
263 if (start < 0)
264 start = 0;
265
266 if (start > vgacon_scrollback_cnt)
267 start = vgacon_scrollback_cnt;
268
269 if (end < 0)
270 end = 0;
271
272 if (end > vgacon_scrollback_cnt)
273 end = vgacon_scrollback_cnt;
274
275 vgacon_scrollback_cur = start;
276 count = end - start;
277 soff = vgacon_scrollback_tail - ((vgacon_scrollback_cnt - end) *
278 c->vc_size_row);
279 soff -= count * c->vc_size_row;
280
281 if (soff < 0)
282 soff += vgacon_scrollback_size;
283
284 count = vgacon_scrollback_cnt - start;
285
286 if (count > c->vc_rows)
287 count = c->vc_rows;
288
289 diff = c->vc_rows - count;
290
291 d = (void *) c->vc_origin;
292 s = (void *) c->vc_screenbuf;
293
294 while (count--) {
295 scr_memcpyw(d, vgacon_scrollback + soff, c->vc_size_row);
296 d += c->vc_size_row;
297 soff += c->vc_size_row;
298
299 if (soff >= vgacon_scrollback_size)
300 soff = 0;
301 }
302
303 if (diff == c->vc_rows) {
304 vgacon_cursor(c, CM_MOVE);
305 } else {
306 while (diff--) {
307 scr_memcpyw(d, s, c->vc_size_row);
308 d += c->vc_size_row;
309 s += c->vc_size_row;
310 }
311 }
312
313 return 1;
314}
315#else
316#define vgacon_scrollback_startup(...) do { } while (0)
317#define vgacon_scrollback_init(...) do { } while (0)
318#define vgacon_scrollback_update(...) do { } while (0)
319
320static void vgacon_restore_screen(struct vc_data *c)
321{
322 if (c->vc_origin != c->vc_visible_origin)
323 vgacon_scrolldelta(c, 0);
324}
325
326static int vgacon_scrolldelta(struct vc_data *c, int lines)
327{
328 if (!lines) /* Turn scrollback off */
329 c->vc_visible_origin = c->vc_origin;
330 else {
331 int margin = c->vc_size_row * 4;
332 int ul, we, p, st;
333
334 if (vga_rolled_over >
335 (c->vc_scr_end - vga_vram_base) + margin) {
336 ul = c->vc_scr_end - vga_vram_base;
337 we = vga_rolled_over + c->vc_size_row;
338 } else {
339 ul = 0;
340 we = vga_vram_size;
341 }
342 p = (c->vc_visible_origin - vga_vram_base - ul + we) % we +
343 lines * c->vc_size_row;
344 st = (c->vc_origin - vga_vram_base - ul + we) % we;
345 if (st < 2 * margin)
346 margin = 0;
347 if (p < margin)
348 p = 0;
349 if (p > st - margin)
350 p = st;
351 c->vc_visible_origin = vga_vram_base + (p + ul) % we;
352 }
353 vga_set_mem_top(c);
354 return 1;
355}
356#endif /* CONFIG_VGACON_SOFT_SCROLLBACK */
357
164static const char __init *vgacon_startup(void) 358static const char __init *vgacon_startup(void)
165{ 359{
166 const char *display_desc = NULL; 360 const char *display_desc = NULL;
@@ -330,7 +524,7 @@ static const char __init *vgacon_startup(void)
330 524
331 vgacon_xres = ORIG_VIDEO_COLS * VGA_FONTWIDTH; 525 vgacon_xres = ORIG_VIDEO_COLS * VGA_FONTWIDTH;
332 vgacon_yres = vga_scan_lines; 526 vgacon_yres = vga_scan_lines;
333 527 vgacon_scrollback_startup();
334 return display_desc; 528 return display_desc;
335} 529}
336 530
@@ -357,11 +551,6 @@ static void vgacon_init(struct vc_data *c, int init)
357 con_set_default_unimap(c); 551 con_set_default_unimap(c);
358} 552}
359 553
360static inline void vga_set_mem_top(struct vc_data *c)
361{
362 write_vga(12, (c->vc_visible_origin - vga_vram_base) / 2);
363}
364
365static void vgacon_deinit(struct vc_data *c) 554static void vgacon_deinit(struct vc_data *c)
366{ 555{
367 /* When closing the last console, reset video origin */ 556 /* When closing the last console, reset video origin */
@@ -433,29 +622,37 @@ static void vgacon_set_cursor_size(int xpos, int from, int to)
433 cursor_size_lastto = to; 622 cursor_size_lastto = to;
434 623
435 spin_lock_irqsave(&vga_lock, flags); 624 spin_lock_irqsave(&vga_lock, flags);
436 outb_p(0x0a, vga_video_port_reg); /* Cursor start */ 625 if (vga_video_type >= VIDEO_TYPE_VGAC) {
437 curs = inb_p(vga_video_port_val); 626 outb_p(VGA_CRTC_CURSOR_START, vga_video_port_reg);
438 outb_p(0x0b, vga_video_port_reg); /* Cursor end */ 627 curs = inb_p(vga_video_port_val);
439 cure = inb_p(vga_video_port_val); 628 outb_p(VGA_CRTC_CURSOR_END, vga_video_port_reg);
629 cure = inb_p(vga_video_port_val);
630 } else {
631 curs = 0;
632 cure = 0;
633 }
440 634
441 curs = (curs & 0xc0) | from; 635 curs = (curs & 0xc0) | from;
442 cure = (cure & 0xe0) | to; 636 cure = (cure & 0xe0) | to;
443 637
444 outb_p(0x0a, vga_video_port_reg); /* Cursor start */ 638 outb_p(VGA_CRTC_CURSOR_START, vga_video_port_reg);
445 outb_p(curs, vga_video_port_val); 639 outb_p(curs, vga_video_port_val);
446 outb_p(0x0b, vga_video_port_reg); /* Cursor end */ 640 outb_p(VGA_CRTC_CURSOR_END, vga_video_port_reg);
447 outb_p(cure, vga_video_port_val); 641 outb_p(cure, vga_video_port_val);
448 spin_unlock_irqrestore(&vga_lock, flags); 642 spin_unlock_irqrestore(&vga_lock, flags);
449} 643}
450 644
451static void vgacon_cursor(struct vc_data *c, int mode) 645static void vgacon_cursor(struct vc_data *c, int mode)
452{ 646{
453 if (c->vc_origin != c->vc_visible_origin) 647 vgacon_restore_screen(c);
454 vgacon_scrolldelta(c, 0); 648
455 switch (mode) { 649 switch (mode) {
456 case CM_ERASE: 650 case CM_ERASE:
457 write_vga(14, (c->vc_pos - vga_vram_base) / 2); 651 write_vga(14, (c->vc_pos - vga_vram_base) / 2);
458 vgacon_set_cursor_size(c->vc_x, 31, 30); 652 if (vga_video_type >= VIDEO_TYPE_VGAC)
653 vgacon_set_cursor_size(c->vc_x, 31, 30);
654 else
655 vgacon_set_cursor_size(c->vc_x, 31, 31);
459 break; 656 break;
460 657
461 case CM_MOVE: 658 case CM_MOVE:
@@ -493,7 +690,10 @@ static void vgacon_cursor(struct vc_data *c, int mode)
493 10 ? 1 : 2)); 690 10 ? 1 : 2));
494 break; 691 break;
495 case CUR_NONE: 692 case CUR_NONE:
496 vgacon_set_cursor_size(c->vc_x, 31, 30); 693 if (vga_video_type >= VIDEO_TYPE_VGAC)
694 vgacon_set_cursor_size(c->vc_x, 31, 30);
695 else
696 vgacon_set_cursor_size(c->vc_x, 31, 31);
497 break; 697 break;
498 default: 698 default:
499 vgacon_set_cursor_size(c->vc_x, 1, 699 vgacon_set_cursor_size(c->vc_x, 1,
@@ -595,6 +795,7 @@ static int vgacon_switch(struct vc_data *c)
595 vgacon_doresize(c, c->vc_cols, c->vc_rows); 795 vgacon_doresize(c, c->vc_cols, c->vc_rows);
596 } 796 }
597 797
798 vgacon_scrollback_init(c->vc_size_row);
598 return 0; /* Redrawing not needed */ 799 return 0; /* Redrawing not needed */
599} 800}
600 801
@@ -1062,37 +1263,6 @@ static int vgacon_resize(struct vc_data *c, unsigned int width,
1062 return 0; 1263 return 0;
1063} 1264}
1064 1265
1065static int vgacon_scrolldelta(struct vc_data *c, int lines)
1066{
1067 if (!lines) /* Turn scrollback off */
1068 c->vc_visible_origin = c->vc_origin;
1069 else {
1070 int margin = c->vc_size_row * 4;
1071 int ul, we, p, st;
1072
1073 if (vga_rolled_over >
1074 (c->vc_scr_end - vga_vram_base) + margin) {
1075 ul = c->vc_scr_end - vga_vram_base;
1076 we = vga_rolled_over + c->vc_size_row;
1077 } else {
1078 ul = 0;
1079 we = vga_vram_size;
1080 }
1081 p = (c->vc_visible_origin - vga_vram_base - ul + we) % we +
1082 lines * c->vc_size_row;
1083 st = (c->vc_origin - vga_vram_base - ul + we) % we;
1084 if (st < 2 * margin)
1085 margin = 0;
1086 if (p < margin)
1087 p = 0;
1088 if (p > st - margin)
1089 p = st;
1090 c->vc_visible_origin = vga_vram_base + (p + ul) % we;
1091 }
1092 vga_set_mem_top(c);
1093 return 1;
1094}
1095
1096static int vgacon_set_origin(struct vc_data *c) 1266static int vgacon_set_origin(struct vc_data *c)
1097{ 1267{
1098 if (vga_is_gfx || /* We don't play origin tricks in graphic modes */ 1268 if (vga_is_gfx || /* We don't play origin tricks in graphic modes */
@@ -1135,15 +1305,14 @@ static int vgacon_scroll(struct vc_data *c, int t, int b, int dir,
1135 if (t || b != c->vc_rows || vga_is_gfx) 1305 if (t || b != c->vc_rows || vga_is_gfx)
1136 return 0; 1306 return 0;
1137 1307
1138 if (c->vc_origin != c->vc_visible_origin)
1139 vgacon_scrolldelta(c, 0);
1140
1141 if (!vga_hardscroll_enabled || lines >= c->vc_rows / 2) 1308 if (!vga_hardscroll_enabled || lines >= c->vc_rows / 2)
1142 return 0; 1309 return 0;
1143 1310
1311 vgacon_restore_screen(c);
1144 oldo = c->vc_origin; 1312 oldo = c->vc_origin;
1145 delta = lines * c->vc_size_row; 1313 delta = lines * c->vc_size_row;
1146 if (dir == SM_UP) { 1314 if (dir == SM_UP) {
1315 vgacon_scrollback_update(c, t, lines);
1147 if (c->vc_scr_end + delta >= vga_vram_end) { 1316 if (c->vc_scr_end + delta >= vga_vram_end) {
1148 scr_memcpyw((u16 *) vga_vram_base, 1317 scr_memcpyw((u16 *) vga_vram_base,
1149 (u16 *) (oldo + delta), 1318 (u16 *) (oldo + delta),
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index c32a2a50bfa2..1f98392a43b3 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -85,7 +85,7 @@ static struct fb_cmap default_16_colors = {
85 * Allocates memory for a colormap @cmap. @len is the 85 * Allocates memory for a colormap @cmap. @len is the
86 * number of entries in the palette. 86 * number of entries in the palette.
87 * 87 *
88 * Returns -1 errno on error, or zero on success. 88 * Returns negative errno on error, or zero on success.
89 * 89 *
90 */ 90 */
91 91
@@ -116,7 +116,7 @@ int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp)
116 116
117fail: 117fail:
118 fb_dealloc_cmap(cmap); 118 fb_dealloc_cmap(cmap);
119 return -1; 119 return -ENOMEM;
120} 120}
121 121
122/** 122/**
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 07d882b14396..b1a8dca76430 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -55,7 +55,7 @@
55 55
56#define FBPIXMAPSIZE (1024 * 8) 56#define FBPIXMAPSIZE (1024 * 8)
57 57
58static struct notifier_block *fb_notifier_list; 58static BLOCKING_NOTIFIER_HEAD(fb_notifier_list);
59struct fb_info *registered_fb[FB_MAX]; 59struct fb_info *registered_fb[FB_MAX];
60int num_registered_fb; 60int num_registered_fb;
61 61
@@ -784,7 +784,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
784 784
785 event.info = info; 785 event.info = info;
786 event.data = &mode1; 786 event.data = &mode1;
787 ret = notifier_call_chain(&fb_notifier_list, 787 ret = blocking_notifier_call_chain(&fb_notifier_list,
788 FB_EVENT_MODE_DELETE, &event); 788 FB_EVENT_MODE_DELETE, &event);
789 } 789 }
790 790
@@ -830,8 +830,8 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
830 830
831 info->flags &= ~FBINFO_MISC_USEREVENT; 831 info->flags &= ~FBINFO_MISC_USEREVENT;
832 event.info = info; 832 event.info = info;
833 notifier_call_chain(&fb_notifier_list, evnt, 833 blocking_notifier_call_chain(&fb_notifier_list,
834 &event); 834 evnt, &event);
835 } 835 }
836 } 836 }
837 } 837 }
@@ -854,7 +854,8 @@ fb_blank(struct fb_info *info, int blank)
854 854
855 event.info = info; 855 event.info = info;
856 event.data = &blank; 856 event.data = &blank;
857 notifier_call_chain(&fb_notifier_list, FB_EVENT_BLANK, &event); 857 blocking_notifier_call_chain(&fb_notifier_list,
858 FB_EVENT_BLANK, &event);
858 } 859 }
859 860
860 return ret; 861 return ret;
@@ -925,7 +926,7 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
925 con2fb.framebuffer = -1; 926 con2fb.framebuffer = -1;
926 event.info = info; 927 event.info = info;
927 event.data = &con2fb; 928 event.data = &con2fb;
928 notifier_call_chain(&fb_notifier_list, 929 blocking_notifier_call_chain(&fb_notifier_list,
929 FB_EVENT_GET_CONSOLE_MAP, &event); 930 FB_EVENT_GET_CONSOLE_MAP, &event);
930 return copy_to_user(argp, &con2fb, 931 return copy_to_user(argp, &con2fb,
931 sizeof(con2fb)) ? -EFAULT : 0; 932 sizeof(con2fb)) ? -EFAULT : 0;
@@ -944,7 +945,7 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
944 return -EINVAL; 945 return -EINVAL;
945 event.info = info; 946 event.info = info;
946 event.data = &con2fb; 947 event.data = &con2fb;
947 return notifier_call_chain(&fb_notifier_list, 948 return blocking_notifier_call_chain(&fb_notifier_list,
948 FB_EVENT_SET_CONSOLE_MAP, 949 FB_EVENT_SET_CONSOLE_MAP,
949 &event); 950 &event);
950 case FBIOBLANK: 951 case FBIOBLANK:
@@ -1324,7 +1325,7 @@ register_framebuffer(struct fb_info *fb_info)
1324 devfs_mk_cdev(MKDEV(FB_MAJOR, i), 1325 devfs_mk_cdev(MKDEV(FB_MAJOR, i),
1325 S_IFCHR | S_IRUGO | S_IWUGO, "fb/%d", i); 1326 S_IFCHR | S_IRUGO | S_IWUGO, "fb/%d", i);
1326 event.info = fb_info; 1327 event.info = fb_info;
1327 notifier_call_chain(&fb_notifier_list, 1328 blocking_notifier_call_chain(&fb_notifier_list,
1328 FB_EVENT_FB_REGISTERED, &event); 1329 FB_EVENT_FB_REGISTERED, &event);
1329 return 0; 1330 return 0;
1330} 1331}
@@ -1366,7 +1367,7 @@ unregister_framebuffer(struct fb_info *fb_info)
1366 */ 1367 */
1367int fb_register_client(struct notifier_block *nb) 1368int fb_register_client(struct notifier_block *nb)
1368{ 1369{
1369 return notifier_chain_register(&fb_notifier_list, nb); 1370 return blocking_notifier_chain_register(&fb_notifier_list, nb);
1370} 1371}
1371 1372
1372/** 1373/**
@@ -1375,7 +1376,7 @@ int fb_register_client(struct notifier_block *nb)
1375 */ 1376 */
1376int fb_unregister_client(struct notifier_block *nb) 1377int fb_unregister_client(struct notifier_block *nb)
1377{ 1378{
1378 return notifier_chain_unregister(&fb_notifier_list, nb); 1379 return blocking_notifier_chain_unregister(&fb_notifier_list, nb);
1379} 1380}
1380 1381
1381/** 1382/**
@@ -1393,11 +1394,13 @@ void fb_set_suspend(struct fb_info *info, int state)
1393 1394
1394 event.info = info; 1395 event.info = info;
1395 if (state) { 1396 if (state) {
1396 notifier_call_chain(&fb_notifier_list, FB_EVENT_SUSPEND, &event); 1397 blocking_notifier_call_chain(&fb_notifier_list,
1398 FB_EVENT_SUSPEND, &event);
1397 info->state = FBINFO_STATE_SUSPENDED; 1399 info->state = FBINFO_STATE_SUSPENDED;
1398 } else { 1400 } else {
1399 info->state = FBINFO_STATE_RUNNING; 1401 info->state = FBINFO_STATE_RUNNING;
1400 notifier_call_chain(&fb_notifier_list, FB_EVENT_RESUME, &event); 1402 blocking_notifier_call_chain(&fb_notifier_list,
1403 FB_EVENT_RESUME, &event);
1401 } 1404 }
1402} 1405}
1403 1406
@@ -1469,7 +1472,7 @@ int fb_new_modelist(struct fb_info *info)
1469 1472
1470 if (!list_empty(&info->modelist)) { 1473 if (!list_empty(&info->modelist)) {
1471 event.info = info; 1474 event.info = info;
1472 err = notifier_call_chain(&fb_notifier_list, 1475 err = blocking_notifier_call_chain(&fb_notifier_list,
1473 FB_EVENT_NEW_MODELIST, 1476 FB_EVENT_NEW_MODELIST,
1474 &event); 1477 &event);
1475 } 1478 }
@@ -1495,7 +1498,7 @@ int fb_con_duit(struct fb_info *info, int event, void *data)
1495 evnt.info = info; 1498 evnt.info = info;
1496 evnt.data = data; 1499 evnt.data = data;
1497 1500
1498 return notifier_call_chain(&fb_notifier_list, event, &evnt); 1501 return blocking_notifier_call_chain(&fb_notifier_list, event, &evnt);
1499} 1502}
1500EXPORT_SYMBOL(fb_con_duit); 1503EXPORT_SYMBOL(fb_con_duit);
1501 1504
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 7c74e7325d95..53beeb4a9998 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -1281,7 +1281,7 @@ int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info)
1281 -EINVAL : 0; 1281 -EINVAL : 0;
1282} 1282}
1283 1283
1284#if defined(__i386__) 1284#if defined(CONFIG_FB_FIRMWARE_EDID) && defined(__i386__)
1285#include <linux/pci.h> 1285#include <linux/pci.h>
1286 1286
1287/* 1287/*
@@ -1311,11 +1311,11 @@ const unsigned char *fb_firmware_edid(struct device *device)
1311{ 1311{
1312 return NULL; 1312 return NULL;
1313} 1313}
1314#endif /* _i386_ */ 1314#endif
1315EXPORT_SYMBOL(fb_firmware_edid);
1315 1316
1316EXPORT_SYMBOL(fb_parse_edid); 1317EXPORT_SYMBOL(fb_parse_edid);
1317EXPORT_SYMBOL(fb_edid_to_monspecs); 1318EXPORT_SYMBOL(fb_edid_to_monspecs);
1318EXPORT_SYMBOL(fb_firmware_edid);
1319EXPORT_SYMBOL(fb_get_mode); 1319EXPORT_SYMBOL(fb_get_mode);
1320EXPORT_SYMBOL(fb_validate_mode); 1320EXPORT_SYMBOL(fb_validate_mode);
1321EXPORT_SYMBOL(fb_destroy_modedb); 1321EXPORT_SYMBOL(fb_destroy_modedb);
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 6d26057337e2..b72b05250a9d 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -348,7 +348,7 @@ static ssize_t store_cmap(struct class_device *class_device, const char *buf,
348 fb_copy_cmap(&umap, &fb_info->cmap); 348 fb_copy_cmap(&umap, &fb_info->cmap);
349 fb_dealloc_cmap(&umap); 349 fb_dealloc_cmap(&umap);
350 350
351 return rc; 351 return rc ?: count;
352 } 352 }
353 for (i = 0; i < length; i++) { 353 for (i = 0; i < length; i++) {
354 u16 red, blue, green, tsp; 354 u16 red, blue, green, tsp;
@@ -367,7 +367,7 @@ static ssize_t store_cmap(struct class_device *class_device, const char *buf,
367 if (transp) 367 if (transp)
368 fb_info->cmap.transp[i] = tsp; 368 fb_info->cmap.transp[i] = tsp;
369 } 369 }
370 return 0; 370 return count;
371} 371}
372 372
373static ssize_t show_cmap(struct class_device *class_device, char *buf) 373static ssize_t show_cmap(struct class_device *class_device, char *buf)
diff --git a/drivers/video/geode/Kconfig b/drivers/video/geode/Kconfig
index 42fb9a89a792..4e173ef20a7d 100644
--- a/drivers/video/geode/Kconfig
+++ b/drivers/video/geode/Kconfig
@@ -8,9 +8,24 @@ config FB_GEODE
8 Say 'Y' here to allow you to select framebuffer drivers for 8 Say 'Y' here to allow you to select framebuffer drivers for
9 the AMD Geode family of processors. 9 the AMD Geode family of processors.
10 10
11config FB_GEODE_GX
12 tristate "AMD Geode GX framebuffer support (EXPERIMENTAL)"
13 depends on FB && FB_GEODE && EXPERIMENTAL
14 select FB_CFB_FILLRECT
15 select FB_CFB_COPYAREA
16 select FB_CFB_IMAGEBLIT
17 ---help---
18 Framebuffer driver for the display controller integrated into the
19 AMD Geode GX processors.
20
21 To compile this driver as a module, choose M here: the module will be
22 called gxfb.
23
24 If unsure, say N.
25
11config FB_GEODE_GX1 26config FB_GEODE_GX1
12 tristate "AMD Geode GX1 framebuffer support (EXPERIMENTAL)" 27 tristate "AMD Geode GX1 framebuffer support (EXPERIMENTAL)"
13 depends on FB_GEODE && EXPERIMENTAL 28 depends on FB && FB_GEODE && EXPERIMENTAL
14 select FB_CFB_FILLRECT 29 select FB_CFB_FILLRECT
15 select FB_CFB_COPYAREA 30 select FB_CFB_COPYAREA
16 select FB_CFB_IMAGEBLIT 31 select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/geode/Makefile b/drivers/video/geode/Makefile
index 13ad501ea990..f896565bc312 100644
--- a/drivers/video/geode/Makefile
+++ b/drivers/video/geode/Makefile
@@ -1,5 +1,7 @@
1# Makefile for the Geode family framebuffer drivers 1# Makefile for the Geode family framebuffer drivers
2 2
3obj-$(CONFIG_FB_GEODE_GX1) += gx1fb.o 3obj-$(CONFIG_FB_GEODE_GX1) += gx1fb.o
4obj-$(CONFIG_FB_GEODE_GX) += gxfb.o
4 5
5gx1fb-objs := gx1fb_core.o display_gx1.o video_cs5530.o 6gx1fb-objs := gx1fb_core.o display_gx1.o video_cs5530.o
7gxfb-objs := gxfb_core.o display_gx.o video_gx.o
diff --git a/drivers/video/geode/display_gx.c b/drivers/video/geode/display_gx.c
new file mode 100644
index 000000000000..825c3405f5c2
--- /dev/null
+++ b/drivers/video/geode/display_gx.c
@@ -0,0 +1,156 @@
1/*
2 * Geode GX display controller.
3 *
4 * Copyright (C) 2005 Arcom Control Systems Ltd.
5 *
6 * Portions from AMD's original 2.4 driver:
7 * Copyright (C) 2004 Advanced Micro Devices, Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by * the
11 * Free Software Foundation; either version 2 of the License, or * (at your
12 * option) any later version.
13 */
14#include <linux/spinlock.h>
15#include <linux/fb.h>
16#include <linux/delay.h>
17#include <asm/io.h>
18#include <asm/div64.h>
19#include <asm/delay.h>
20
21#include "geodefb.h"
22#include "display_gx.h"
23
24int gx_frame_buffer_size(void)
25{
26 /* Assuming 16 MiB. */
27 return 16*1024*1024;
28}
29
30int gx_line_delta(int xres, int bpp)
31{
32 /* Must be a multiple of 8 bytes. */
33 return (xres * (bpp >> 3) + 7) & ~0x7;
34}
35
36static void gx_set_mode(struct fb_info *info)
37{
38 struct geodefb_par *par = info->par;
39 u32 gcfg, dcfg;
40 int hactive, hblankstart, hsyncstart, hsyncend, hblankend, htotal;
41 int vactive, vblankstart, vsyncstart, vsyncend, vblankend, vtotal;
42
43 /* Unlock the display controller registers. */
44 readl(par->dc_regs + DC_UNLOCK);
45 writel(DC_UNLOCK_CODE, par->dc_regs + DC_UNLOCK);
46
47 gcfg = readl(par->dc_regs + DC_GENERAL_CFG);
48 dcfg = readl(par->dc_regs + DC_DISPLAY_CFG);
49
50 /* Disable the timing generator. */
51 dcfg &= ~(DC_DCFG_TGEN);
52 writel(dcfg, par->dc_regs + DC_DISPLAY_CFG);
53
54 /* Wait for pending memory requests before disabling the FIFO load. */
55 udelay(100);
56
57 /* Disable FIFO load and compression. */
58 gcfg &= ~(DC_GCFG_DFLE | DC_GCFG_CMPE | DC_GCFG_DECE);
59 writel(gcfg, par->dc_regs + DC_GENERAL_CFG);
60
61 /* Setup DCLK and its divisor. */
62 par->vid_ops->set_dclk(info);
63
64 /*
65 * Setup new mode.
66 */
67
68 /* Clear all unused feature bits. */
69 gcfg &= DC_GCFG_YUVM | DC_GCFG_VDSE;
70 dcfg = 0;
71
72 /* Set FIFO priority (default 6/5) and enable. */
73 /* FIXME: increase fifo priority for 1280x1024 and higher modes? */
74 gcfg |= (6 << DC_GCFG_DFHPEL_POS) | (5 << DC_GCFG_DFHPSL_POS) | DC_GCFG_DFLE;
75
76 /* Framebuffer start offset. */
77 writel(0, par->dc_regs + DC_FB_ST_OFFSET);
78
79 /* Line delta and line buffer length. */
80 writel(info->fix.line_length >> 3, par->dc_regs + DC_GFX_PITCH);
81 writel(((info->var.xres * info->var.bits_per_pixel/8) >> 3) + 2,
82 par->dc_regs + DC_LINE_SIZE);
83
84 /* Enable graphics and video data and unmask address lines. */
85 dcfg |= DC_DCFG_GDEN | DC_DCFG_VDEN | DC_DCFG_A20M | DC_DCFG_A18M;
86
87 /* Set pixel format. */
88 switch (info->var.bits_per_pixel) {
89 case 8:
90 dcfg |= DC_DCFG_DISP_MODE_8BPP;
91 break;
92 case 16:
93 dcfg |= DC_DCFG_DISP_MODE_16BPP;
94 dcfg |= DC_DCFG_16BPP_MODE_565;
95 break;
96 case 32:
97 dcfg |= DC_DCFG_DISP_MODE_24BPP;
98 dcfg |= DC_DCFG_PALB;
99 break;
100 }
101
102 /* Enable timing generator. */
103 dcfg |= DC_DCFG_TGEN;
104
105 /* Horizontal and vertical timings. */
106 hactive = info->var.xres;
107 hblankstart = hactive;
108 hsyncstart = hblankstart + info->var.right_margin;
109 hsyncend = hsyncstart + info->var.hsync_len;
110 hblankend = hsyncend + info->var.left_margin;
111 htotal = hblankend;
112
113 vactive = info->var.yres;
114 vblankstart = vactive;
115 vsyncstart = vblankstart + info->var.lower_margin;
116 vsyncend = vsyncstart + info->var.vsync_len;
117 vblankend = vsyncend + info->var.upper_margin;
118 vtotal = vblankend;
119
120 writel((hactive - 1) | ((htotal - 1) << 16), par->dc_regs + DC_H_ACTIVE_TIMING);
121 writel((hblankstart - 1) | ((hblankend - 1) << 16), par->dc_regs + DC_H_BLANK_TIMING);
122 writel((hsyncstart - 1) | ((hsyncend - 1) << 16), par->dc_regs + DC_H_SYNC_TIMING);
123
124 writel((vactive - 1) | ((vtotal - 1) << 16), par->dc_regs + DC_V_ACTIVE_TIMING);
125 writel((vblankstart - 1) | ((vblankend - 1) << 16), par->dc_regs + DC_V_BLANK_TIMING);
126 writel((vsyncstart - 1) | ((vsyncend - 1) << 16), par->dc_regs + DC_V_SYNC_TIMING);
127
128 /* Write final register values. */
129 writel(dcfg, par->dc_regs + DC_DISPLAY_CFG);
130 writel(gcfg, par->dc_regs + DC_GENERAL_CFG);
131
132 par->vid_ops->configure_display(info);
133
134 /* Relock display controller registers */
135 writel(0, par->dc_regs + DC_UNLOCK);
136}
137
138static void gx_set_hw_palette_reg(struct fb_info *info, unsigned regno,
139 unsigned red, unsigned green, unsigned blue)
140{
141 struct geodefb_par *par = info->par;
142 int val;
143
144 /* Hardware palette is in RGB 8-8-8 format. */
145 val = (red << 8) & 0xff0000;
146 val |= (green) & 0x00ff00;
147 val |= (blue >> 8) & 0x0000ff;
148
149 writel(regno, par->dc_regs + DC_PAL_ADDRESS);
150 writel(val, par->dc_regs + DC_PAL_DATA);
151}
152
153struct geode_dc_ops gx_dc_ops = {
154 .set_mode = gx_set_mode,
155 .set_palette_reg = gx_set_hw_palette_reg,
156};
diff --git a/drivers/video/geode/display_gx.h b/drivers/video/geode/display_gx.h
new file mode 100644
index 000000000000..86c623361305
--- /dev/null
+++ b/drivers/video/geode/display_gx.h
@@ -0,0 +1,96 @@
1/*
2 * Geode GX display controller
3 *
4 * Copyright (C) 2006 Arcom Control Systems Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11#ifndef __DISPLAY_GX_H__
12#define __DISPLAY_GX_H__
13
14int gx_frame_buffer_size(void);
15int gx_line_delta(int xres, int bpp);
16
17extern struct geode_dc_ops gx_dc_ops;
18
19/* Display controller registers */
20
21#define DC_UNLOCK 0x00
22# define DC_UNLOCK_CODE 0x00004758
23
24#define DC_GENERAL_CFG 0x04
25# define DC_GCFG_DFLE 0x00000001
26# define DC_GCFG_CURE 0x00000002
27# define DC_GCFG_ICNE 0x00000004
28# define DC_GCFG_VIDE 0x00000008
29# define DC_GCFG_CMPE 0x00000020
30# define DC_GCFG_DECE 0x00000040
31# define DC_GCFG_VGAE 0x00000080
32# define DC_GCFG_DFHPSL_MASK 0x00000F00
33# define DC_GCFG_DFHPSL_POS 8
34# define DC_GCFG_DFHPEL_MASK 0x0000F000
35# define DC_GCFG_DFHPEL_POS 12
36# define DC_GCFG_STFM 0x00010000
37# define DC_GCFG_FDTY 0x00020000
38# define DC_GCFG_VGAFT 0x00040000
39# define DC_GCFG_VDSE 0x00080000
40# define DC_GCFG_YUVM 0x00100000
41# define DC_GCFG_VFSL 0x00800000
42# define DC_GCFG_SIGE 0x01000000
43# define DC_GCFG_SGRE 0x02000000
44# define DC_GCFG_SGFR 0x04000000
45# define DC_GCFG_CRC_MODE 0x08000000
46# define DC_GCFG_DIAG 0x10000000
47# define DC_GCFG_CFRW 0x20000000
48
49#define DC_DISPLAY_CFG 0x08
50# define DC_DCFG_TGEN 0x00000001
51# define DC_DCFG_GDEN 0x00000008
52# define DC_DCFG_VDEN 0x00000010
53# define DC_DCFG_TRUP 0x00000040
54# define DC_DCFG_DISP_MODE_MASK 0x00000300
55# define DC_DCFG_DISP_MODE_8BPP 0x00000000
56# define DC_DCFG_DISP_MODE_16BPP 0x00000100
57# define DC_DCFG_DISP_MODE_24BPP 0x00000200
58# define DC_DCFG_16BPP_MODE_MASK 0x00000c00
59# define DC_DCFG_16BPP_MODE_565 0x00000000
60# define DC_DCFG_16BPP_MODE_555 0x00000100
61# define DC_DCFG_16BPP_MODE_444 0x00000200
62# define DC_DCFG_DCEN 0x00080000
63# define DC_DCFG_PALB 0x02000000
64# define DC_DCFG_FRLK 0x04000000
65# define DC_DCFG_VISL 0x08000000
66# define DC_DCFG_FRSL 0x20000000
67# define DC_DCFG_A18M 0x40000000
68# define DC_DCFG_A20M 0x80000000
69
70#define DC_FB_ST_OFFSET 0x10
71
72#define DC_LINE_SIZE 0x30
73# define DC_LINE_SIZE_FB_LINE_SIZE_MASK 0x000007ff
74# define DC_LINE_SIZE_FB_LINE_SIZE_POS 0
75# define DC_LINE_SIZE_CB_LINE_SIZE_MASK 0x007f0000
76# define DC_LINE_SIZE_CB_LINE_SIZE_POS 16
77# define DC_LINE_SIZE_VID_LINE_SIZE_MASK 0xff000000
78# define DC_LINE_SIZE_VID_LINE_SIZE_POS 24
79
80#define DC_GFX_PITCH 0x34
81# define DC_GFX_PITCH_FB_PITCH_MASK 0x0000ffff
82# define DC_GFX_PITCH_FB_PITCH_POS 0
83# define DC_GFX_PITCH_CB_PITCH_MASK 0xffff0000
84# define DC_GFX_PITCH_CB_PITCH_POS 16
85
86#define DC_H_ACTIVE_TIMING 0x40
87#define DC_H_BLANK_TIMING 0x44
88#define DC_H_SYNC_TIMING 0x48
89#define DC_V_ACTIVE_TIMING 0x50
90#define DC_V_BLANK_TIMING 0x54
91#define DC_V_SYNC_TIMING 0x58
92
93#define DC_PAL_ADDRESS 0x70
94#define DC_PAL_DATA 0x74
95
96#endif /* !__DISPLAY_GX1_H__ */
diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/geode/gxfb_core.c
new file mode 100644
index 000000000000..89c34b15f5d4
--- /dev/null
+++ b/drivers/video/geode/gxfb_core.c
@@ -0,0 +1,423 @@
1/*
2 * Geode GX framebuffer driver.
3 *
4 * Copyright (C) 2006 Arcom Control Systems Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 *
12 * This driver assumes that the BIOS has created a virtual PCI device header
13 * for the video device. The PCI header is assumed to contain the following
14 * BARs:
15 *
16 * BAR0 - framebuffer memory
17 * BAR1 - graphics processor registers
18 * BAR2 - display controller registers
19 * BAR3 - video processor and flat panel control registers.
20 *
21 * 16 MiB of framebuffer memory is assumed to be available.
22 */
23#include <linux/module.h>
24#include <linux/kernel.h>
25#include <linux/errno.h>
26#include <linux/string.h>
27#include <linux/mm.h>
28#include <linux/tty.h>
29#include <linux/slab.h>
30#include <linux/delay.h>
31#include <linux/fb.h>
32#include <linux/init.h>
33#include <linux/pci.h>
34
35#include "geodefb.h"
36#include "display_gx.h"
37#include "video_gx.h"
38
39static char mode_option[32] = "640x480-16@60";
40
41/* Modes relevant to the GX (taken from modedb.c) */
42static const struct fb_videomode __initdata gx_modedb[] = {
43 /* 640x480-60 VESA */
44 { NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2,
45 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
46 /* 640x480-75 VESA */
47 { NULL, 75, 640, 480, 31746, 120, 16, 16, 01, 64, 3,
48 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
49 /* 640x480-85 VESA */
50 { NULL, 85, 640, 480, 27777, 80, 56, 25, 01, 56, 3,
51 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
52 /* 800x600-60 VESA */
53 { NULL, 60, 800, 600, 25000, 88, 40, 23, 01, 128, 4,
54 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
55 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
56 /* 800x600-75 VESA */
57 { NULL, 75, 800, 600, 20202, 160, 16, 21, 01, 80, 3,
58 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
59 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
60 /* 800x600-85 VESA */
61 { NULL, 85, 800, 600, 17761, 152, 32, 27, 01, 64, 3,
62 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
63 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
64 /* 1024x768-60 VESA */
65 { NULL, 60, 1024, 768, 15384, 160, 24, 29, 3, 136, 6,
66 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
67 /* 1024x768-75 VESA */
68 { NULL, 75, 1024, 768, 12690, 176, 16, 28, 1, 96, 3,
69 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
70 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
71 /* 1024x768-85 VESA */
72 { NULL, 85, 1024, 768, 10582, 208, 48, 36, 1, 96, 3,
73 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
74 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
75 /* 1280x960-60 VESA */
76 { NULL, 60, 1280, 960, 9259, 312, 96, 36, 1, 112, 3,
77 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
78 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
79 /* 1280x960-85 VESA */
80 { NULL, 85, 1280, 960, 6734, 224, 64, 47, 1, 160, 3,
81 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
82 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
83 /* 1280x1024-60 VESA */
84 { NULL, 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3,
85 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
86 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
87 /* 1280x1024-75 VESA */
88 { NULL, 75, 1280, 1024, 7407, 248, 16, 38, 1, 144, 3,
89 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
90 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
91 /* 1280x1024-85 VESA */
92 { NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
93 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
94 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
95 /* 1600x1200-60 VESA */
96 { NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
97 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
98 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
99 /* 1600x1200-75 VESA */
100 { NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
101 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
102 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
103 /* 1600x1200-85 VESA */
104 { NULL, 85, 1600, 1200, 4357, 304, 64, 46, 1, 192, 3,
105 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
106 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
107};
108
109static int gxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
110{
111 if (var->xres > 1600 || var->yres > 1200)
112 return -EINVAL;
113 if ((var->xres > 1280 || var->yres > 1024) && var->bits_per_pixel > 16)
114 return -EINVAL;
115
116 if (var->bits_per_pixel == 32) {
117 var->red.offset = 16; var->red.length = 8;
118 var->green.offset = 8; var->green.length = 8;
119 var->blue.offset = 0; var->blue.length = 8;
120 } else if (var->bits_per_pixel == 16) {
121 var->red.offset = 11; var->red.length = 5;
122 var->green.offset = 5; var->green.length = 6;
123 var->blue.offset = 0; var->blue.length = 5;
124 } else if (var->bits_per_pixel == 8) {
125 var->red.offset = 0; var->red.length = 8;
126 var->green.offset = 0; var->green.length = 8;
127 var->blue.offset = 0; var->blue.length = 8;
128 } else
129 return -EINVAL;
130 var->transp.offset = 0; var->transp.length = 0;
131
132 /* Enough video memory? */
133 if (gx_line_delta(var->xres, var->bits_per_pixel) * var->yres > info->fix.smem_len)
134 return -EINVAL;
135
136 /* FIXME: Check timing parameters here? */
137
138 return 0;
139}
140
141static int gxfb_set_par(struct fb_info *info)
142{
143 struct geodefb_par *par = info->par;
144
145 if (info->var.bits_per_pixel > 8) {
146 info->fix.visual = FB_VISUAL_TRUECOLOR;
147 fb_dealloc_cmap(&info->cmap);
148 } else {
149 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
150 fb_alloc_cmap(&info->cmap, 1<<info->var.bits_per_pixel, 0);
151 }
152
153 info->fix.line_length = gx_line_delta(info->var.xres, info->var.bits_per_pixel);
154
155 par->dc_ops->set_mode(info);
156
157 return 0;
158}
159
160static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
161{
162 chan &= 0xffff;
163 chan >>= 16 - bf->length;
164 return chan << bf->offset;
165}
166
167static int gxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
168 unsigned blue, unsigned transp,
169 struct fb_info *info)
170{
171 struct geodefb_par *par = info->par;
172
173 if (info->var.grayscale) {
174 /* grayscale = 0.30*R + 0.59*G + 0.11*B */
175 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
176 }
177
178 /* Truecolor has hardware independent palette */
179 if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
180 u32 *pal = info->pseudo_palette;
181 u32 v;
182
183 if (regno >= 16)
184 return -EINVAL;
185
186 v = chan_to_field(red, &info->var.red);
187 v |= chan_to_field(green, &info->var.green);
188 v |= chan_to_field(blue, &info->var.blue);
189
190 pal[regno] = v;
191 } else {
192 if (regno >= 256)
193 return -EINVAL;
194
195 par->dc_ops->set_palette_reg(info, regno, red, green, blue);
196 }
197
198 return 0;
199}
200
201static int gxfb_blank(int blank_mode, struct fb_info *info)
202{
203 struct geodefb_par *par = info->par;
204
205 return par->vid_ops->blank_display(info, blank_mode);
206}
207
208static int __init gxfb_map_video_memory(struct fb_info *info, struct pci_dev *dev)
209{
210 struct geodefb_par *par = info->par;
211 int fb_len;
212 int ret;
213
214 ret = pci_enable_device(dev);
215 if (ret < 0)
216 return ret;
217
218 ret = pci_request_region(dev, 3, "gxfb (video processor)");
219 if (ret < 0)
220 return ret;
221 par->vid_regs = ioremap(pci_resource_start(dev, 3),
222 pci_resource_len(dev, 3));
223 if (!par->vid_regs)
224 return -ENOMEM;
225
226 ret = pci_request_region(dev, 2, "gxfb (display controller)");
227 if (ret < 0)
228 return ret;
229 par->dc_regs = ioremap(pci_resource_start(dev, 2), pci_resource_len(dev, 2));
230 if (!par->dc_regs)
231 return -ENOMEM;
232
233 ret = pci_request_region(dev, 0, "gxfb (framebuffer)");
234 if (ret < 0)
235 return ret;
236 if ((fb_len = gx_frame_buffer_size()) < 0)
237 return -ENOMEM;
238 info->fix.smem_start = pci_resource_start(dev, 0);
239 info->fix.smem_len = fb_len;
240 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
241 if (!info->screen_base)
242 return -ENOMEM;
243
244 dev_info(&dev->dev, "%d Kibyte of video memory at 0x%lx\n",
245 info->fix.smem_len / 1024, info->fix.smem_start);
246
247 return 0;
248}
249
250static struct fb_ops gxfb_ops = {
251 .owner = THIS_MODULE,
252 .fb_check_var = gxfb_check_var,
253 .fb_set_par = gxfb_set_par,
254 .fb_setcolreg = gxfb_setcolreg,
255 .fb_blank = gxfb_blank,
256 /* No HW acceleration for now. */
257 .fb_fillrect = cfb_fillrect,
258 .fb_copyarea = cfb_copyarea,
259 .fb_imageblit = cfb_imageblit,
260};
261
262static struct fb_info * __init gxfb_init_fbinfo(struct device *dev)
263{
264 struct geodefb_par *par;
265 struct fb_info *info;
266
267 /* Alloc enough space for the pseudo palette. */
268 info = framebuffer_alloc(sizeof(struct geodefb_par) + sizeof(u32) * 16, dev);
269 if (!info)
270 return NULL;
271
272 par = info->par;
273
274 strcpy(info->fix.id, "Geode GX");
275
276 info->fix.type = FB_TYPE_PACKED_PIXELS;
277 info->fix.type_aux = 0;
278 info->fix.xpanstep = 0;
279 info->fix.ypanstep = 0;
280 info->fix.ywrapstep = 0;
281 info->fix.accel = FB_ACCEL_NONE;
282
283 info->var.nonstd = 0;
284 info->var.activate = FB_ACTIVATE_NOW;
285 info->var.height = -1;
286 info->var.width = -1;
287 info->var.accel_flags = 0;
288 info->var.vmode = FB_VMODE_NONINTERLACED;
289
290 info->fbops = &gxfb_ops;
291 info->flags = FBINFO_DEFAULT;
292 info->node = -1;
293
294 info->pseudo_palette = (void *)par + sizeof(struct geodefb_par);
295
296 info->var.grayscale = 0;
297
298 return info;
299}
300
301static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
302{
303 struct geodefb_par *par;
304 struct fb_info *info;
305 int ret;
306
307 info = gxfb_init_fbinfo(&pdev->dev);
308 if (!info)
309 return -ENOMEM;
310 par = info->par;
311
312 /* GX display controller and GX video device. */
313 par->dc_ops = &gx_dc_ops;
314 par->vid_ops = &gx_vid_ops;
315
316 if ((ret = gxfb_map_video_memory(info, pdev)) < 0) {
317 dev_err(&pdev->dev, "failed to map frame buffer or controller registers\n");
318 goto err;
319 }
320
321 ret = fb_find_mode(&info->var, info, mode_option,
322 gx_modedb, ARRAY_SIZE(gx_modedb), NULL, 16);
323 if (ret == 0 || ret == 4) {
324 dev_err(&pdev->dev, "could not find valid video mode\n");
325 ret = -EINVAL;
326 goto err;
327 }
328
329 /* Clear the frame buffer of garbage. */
330 memset_io(info->screen_base, 0, info->fix.smem_len);
331
332 gxfb_check_var(&info->var, info);
333 gxfb_set_par(info);
334
335 if (register_framebuffer(info) < 0) {
336 ret = -EINVAL;
337 goto err;
338 }
339 pci_set_drvdata(pdev, info);
340 printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id);
341 return 0;
342
343 err:
344 if (info->screen_base) {
345 iounmap(info->screen_base);
346 pci_release_region(pdev, 0);
347 }
348 if (par->vid_regs) {
349 iounmap(par->vid_regs);
350 pci_release_region(pdev, 3);
351 }
352 if (par->dc_regs) {
353 iounmap(par->dc_regs);
354 pci_release_region(pdev, 2);
355 }
356
357 pci_disable_device(pdev);
358
359 if (info)
360 framebuffer_release(info);
361 return ret;
362}
363
364static void gxfb_remove(struct pci_dev *pdev)
365{
366 struct fb_info *info = pci_get_drvdata(pdev);
367 struct geodefb_par *par = info->par;
368
369 unregister_framebuffer(info);
370
371 iounmap((void __iomem *)info->screen_base);
372 pci_release_region(pdev, 0);
373
374 iounmap(par->vid_regs);
375 pci_release_region(pdev, 3);
376
377 iounmap(par->dc_regs);
378 pci_release_region(pdev, 2);
379
380 pci_disable_device(pdev);
381 pci_set_drvdata(pdev, NULL);
382
383 framebuffer_release(info);
384}
385
386static struct pci_device_id gxfb_id_table[] = {
387 { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_VIDEO,
388 PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
389 0xff0000, 0 },
390 { 0, }
391};
392
393MODULE_DEVICE_TABLE(pci, gxfb_id_table);
394
395static struct pci_driver gxfb_driver = {
396 .name = "gxfb",
397 .id_table = gxfb_id_table,
398 .probe = gxfb_probe,
399 .remove = gxfb_remove,
400};
401
402static int __init gxfb_init(void)
403{
404#ifndef MODULE
405 if (fb_get_options("gxfb", NULL))
406 return -ENODEV;
407#endif
408 return pci_register_driver(&gxfb_driver);
409}
410
411static void __exit gxfb_cleanup(void)
412{
413 pci_unregister_driver(&gxfb_driver);
414}
415
416module_init(gxfb_init);
417module_exit(gxfb_cleanup);
418
419module_param_string(mode, mode_option, sizeof(mode_option), 0444);
420MODULE_PARM_DESC(mode, "video mode (<x>x<y>[-<bpp>][@<refr>])");
421
422MODULE_DESCRIPTION("Framebuffer driver for the AMD Geode GX");
423MODULE_LICENSE("GPL");
diff --git a/drivers/video/geode/video_gx.c b/drivers/video/geode/video_gx.c
new file mode 100644
index 000000000000..2b2a7880ea75
--- /dev/null
+++ b/drivers/video/geode/video_gx.c
@@ -0,0 +1,262 @@
1/*
2 * Geode GX video processor device.
3 *
4 * Copyright (C) 2006 Arcom Control Systems Ltd.
5 *
6 * Portions from AMD's original 2.4 driver:
7 * Copyright (C) 2004 Advanced Micro Devices, Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14#include <linux/fb.h>
15#include <linux/delay.h>
16#include <asm/io.h>
17#include <asm/delay.h>
18#include <asm/msr.h>
19
20#include "geodefb.h"
21#include "video_gx.h"
22
23
24/*
25 * Tables of register settings for various DOTCLKs.
26 */
27struct gx_pll_entry {
28 long pixclock; /* ps */
29 u32 sys_rstpll_bits;
30 u32 dotpll_value;
31};
32
33#define POSTDIV3 ((u32)MSR_GLCP_SYS_RSTPLL_DOTPOSTDIV3)
34#define PREMULT2 ((u32)MSR_GLCP_SYS_RSTPLL_DOTPREMULT2)
35#define PREDIV2 ((u32)MSR_GLCP_SYS_RSTPLL_DOTPOSTDIV3)
36
37static const struct gx_pll_entry gx_pll_table_48MHz[] = {
38 { 40123, POSTDIV3, 0x00000BF2 }, /* 24.9230 */
39 { 39721, 0, 0x00000037 }, /* 25.1750 */
40 { 35308, POSTDIV3|PREMULT2, 0x00000B1A }, /* 28.3220 */
41 { 31746, POSTDIV3, 0x000002D2 }, /* 31.5000 */
42 { 27777, POSTDIV3|PREMULT2, 0x00000FE2 }, /* 36.0000 */
43 { 26666, POSTDIV3, 0x0000057A }, /* 37.5000 */
44 { 25000, POSTDIV3, 0x0000030A }, /* 40.0000 */
45 { 22271, 0, 0x00000063 }, /* 44.9000 */
46 { 20202, 0, 0x0000054B }, /* 49.5000 */
47 { 20000, 0, 0x0000026E }, /* 50.0000 */
48 { 19860, PREMULT2, 0x00000037 }, /* 50.3500 */
49 { 18518, POSTDIV3|PREMULT2, 0x00000B0D }, /* 54.0000 */
50 { 17777, 0, 0x00000577 }, /* 56.2500 */
51 { 17733, 0, 0x000007F7 }, /* 56.3916 */
52 { 17653, 0, 0x0000057B }, /* 56.6444 */
53 { 16949, PREMULT2, 0x00000707 }, /* 59.0000 */
54 { 15873, POSTDIV3|PREMULT2, 0x00000B39 }, /* 63.0000 */
55 { 15384, POSTDIV3|PREMULT2, 0x00000B45 }, /* 65.0000 */
56 { 14814, POSTDIV3|PREMULT2, 0x00000FC1 }, /* 67.5000 */
57 { 14124, POSTDIV3, 0x00000561 }, /* 70.8000 */
58 { 13888, POSTDIV3, 0x000007E1 }, /* 72.0000 */
59 { 13426, PREMULT2, 0x00000F4A }, /* 74.4810 */
60 { 13333, 0, 0x00000052 }, /* 75.0000 */
61 { 12698, 0, 0x00000056 }, /* 78.7500 */
62 { 12500, POSTDIV3|PREMULT2, 0x00000709 }, /* 80.0000 */
63 { 11135, PREMULT2, 0x00000262 }, /* 89.8000 */
64 { 10582, 0, 0x000002D2 }, /* 94.5000 */
65 { 10101, PREMULT2, 0x00000B4A }, /* 99.0000 */
66 { 10000, PREMULT2, 0x00000036 }, /* 100.0000 */
67 { 9259, 0, 0x000007E2 }, /* 108.0000 */
68 { 8888, 0, 0x000007F6 }, /* 112.5000 */
69 { 7692, POSTDIV3|PREMULT2, 0x00000FB0 }, /* 130.0000 */
70 { 7407, POSTDIV3|PREMULT2, 0x00000B50 }, /* 135.0000 */
71 { 6349, 0, 0x00000055 }, /* 157.5000 */
72 { 6172, 0, 0x000009C1 }, /* 162.0000 */
73 { 5787, PREMULT2, 0x0000002D }, /* 172.798 */
74 { 5698, 0, 0x000002C1 }, /* 175.5000 */
75 { 5291, 0, 0x000002D1 }, /* 189.0000 */
76 { 4938, 0, 0x00000551 }, /* 202.5000 */
77 { 4357, 0, 0x0000057D }, /* 229.5000 */
78};
79
80static const struct gx_pll_entry gx_pll_table_14MHz[] = {
81 { 39721, 0, 0x00000037 }, /* 25.1750 */
82 { 35308, 0, 0x00000B7B }, /* 28.3220 */
83 { 31746, 0, 0x000004D3 }, /* 31.5000 */
84 { 27777, 0, 0x00000BE3 }, /* 36.0000 */
85 { 26666, 0, 0x0000074F }, /* 37.5000 */
86 { 25000, 0, 0x0000050B }, /* 40.0000 */
87 { 22271, 0, 0x00000063 }, /* 44.9000 */
88 { 20202, 0, 0x0000054B }, /* 49.5000 */
89 { 20000, 0, 0x0000026E }, /* 50.0000 */
90 { 19860, 0, 0x000007C3 }, /* 50.3500 */
91 { 18518, 0, 0x000007E3 }, /* 54.0000 */
92 { 17777, 0, 0x00000577 }, /* 56.2500 */
93 { 17733, 0, 0x000002FB }, /* 56.3916 */
94 { 17653, 0, 0x0000057B }, /* 56.6444 */
95 { 16949, 0, 0x0000058B }, /* 59.0000 */
96 { 15873, 0, 0x0000095E }, /* 63.0000 */
97 { 15384, 0, 0x0000096A }, /* 65.0000 */
98 { 14814, 0, 0x00000BC2 }, /* 67.5000 */
99 { 14124, 0, 0x0000098A }, /* 70.8000 */
100 { 13888, 0, 0x00000BE2 }, /* 72.0000 */
101 { 13333, 0, 0x00000052 }, /* 75.0000 */
102 { 12698, 0, 0x00000056 }, /* 78.7500 */
103 { 12500, 0, 0x0000050A }, /* 80.0000 */
104 { 11135, 0, 0x0000078E }, /* 89.8000 */
105 { 10582, 0, 0x000002D2 }, /* 94.5000 */
106 { 10101, 0, 0x000011F6 }, /* 99.0000 */
107 { 10000, 0, 0x0000054E }, /* 100.0000 */
108 { 9259, 0, 0x000007E2 }, /* 108.0000 */
109 { 8888, 0, 0x000002FA }, /* 112.5000 */
110 { 7692, 0, 0x00000BB1 }, /* 130.0000 */
111 { 7407, 0, 0x00000975 }, /* 135.0000 */
112 { 6349, 0, 0x00000055 }, /* 157.5000 */
113 { 6172, 0, 0x000009C1 }, /* 162.0000 */
114 { 5698, 0, 0x000002C1 }, /* 175.5000 */
115 { 5291, 0, 0x00000539 }, /* 189.0000 */
116 { 4938, 0, 0x00000551 }, /* 202.5000 */
117 { 4357, 0, 0x0000057D }, /* 229.5000 */
118};
119
120static void gx_set_dclk_frequency(struct fb_info *info)
121{
122 const struct gx_pll_entry *pll_table;
123 int pll_table_len;
124 int i, best_i;
125 long min, diff;
126 u64 dotpll, sys_rstpll;
127 int timeout = 1000;
128
129 /* Rev. 1 Geode GXs use a 14 MHz reference clock instead of 48 MHz. */
130 if (cpu_data->x86_mask == 1) {
131 pll_table = gx_pll_table_14MHz;
132 pll_table_len = ARRAY_SIZE(gx_pll_table_14MHz);
133 } else {
134 pll_table = gx_pll_table_48MHz;
135 pll_table_len = ARRAY_SIZE(gx_pll_table_48MHz);
136 }
137
138 /* Search the table for the closest pixclock. */
139 best_i = 0;
140 min = abs(pll_table[0].pixclock - info->var.pixclock);
141 for (i = 1; i < pll_table_len; i++) {
142 diff = abs(pll_table[i].pixclock - info->var.pixclock);
143 if (diff < min) {
144 min = diff;
145 best_i = i;
146 }
147 }
148
149 rdmsrl(MSR_GLCP_SYS_RSTPLL, sys_rstpll);
150 rdmsrl(MSR_GLCP_DOTPLL, dotpll);
151
152 /* Program new M, N and P. */
153 dotpll &= 0x00000000ffffffffull;
154 dotpll |= (u64)pll_table[best_i].dotpll_value << 32;
155 dotpll |= MSR_GLCP_DOTPLL_DOTRESET;
156 dotpll &= ~MSR_GLCP_DOTPLL_BYPASS;
157
158 wrmsrl(MSR_GLCP_DOTPLL, dotpll);
159
160 /* Program dividers. */
161 sys_rstpll &= ~( MSR_GLCP_SYS_RSTPLL_DOTPREDIV2
162 | MSR_GLCP_SYS_RSTPLL_DOTPREMULT2
163 | MSR_GLCP_SYS_RSTPLL_DOTPOSTDIV3 );
164 sys_rstpll |= pll_table[best_i].sys_rstpll_bits;
165
166 wrmsrl(MSR_GLCP_SYS_RSTPLL, sys_rstpll);
167
168 /* Clear reset bit to start PLL. */
169 dotpll &= ~(MSR_GLCP_DOTPLL_DOTRESET);
170 wrmsrl(MSR_GLCP_DOTPLL, dotpll);
171
172 /* Wait for LOCK bit. */
173 do {
174 rdmsrl(MSR_GLCP_DOTPLL, dotpll);
175 } while (timeout-- && !(dotpll & MSR_GLCP_DOTPLL_LOCK));
176}
177
178static void gx_configure_display(struct fb_info *info)
179{
180 struct geodefb_par *par = info->par;
181 u32 dcfg, fp_pm;
182
183 dcfg = readl(par->vid_regs + GX_DCFG);
184
185 /* Clear bits from existing mode. */
186 dcfg &= ~(GX_DCFG_CRT_SYNC_SKW_MASK
187 | GX_DCFG_CRT_HSYNC_POL | GX_DCFG_CRT_VSYNC_POL
188 | GX_DCFG_VSYNC_EN | GX_DCFG_HSYNC_EN);
189
190 /* Set default sync skew. */
191 dcfg |= GX_DCFG_CRT_SYNC_SKW_DFLT;
192
193 /* Enable hsync and vsync. */
194 dcfg |= GX_DCFG_HSYNC_EN | GX_DCFG_VSYNC_EN;
195
196 /* Sync polarities. */
197 if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
198 dcfg |= GX_DCFG_CRT_HSYNC_POL;
199 if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
200 dcfg |= GX_DCFG_CRT_VSYNC_POL;
201
202 writel(dcfg, par->vid_regs + GX_DCFG);
203
204 /* Power on flat panel. */
205 fp_pm = readl(par->vid_regs + GX_FP_PM);
206 fp_pm |= GX_FP_PM_P;
207 writel(fp_pm, par->vid_regs + GX_FP_PM);
208}
209
210static int gx_blank_display(struct fb_info *info, int blank_mode)
211{
212 struct geodefb_par *par = info->par;
213 u32 dcfg, fp_pm;
214 int blank, hsync, vsync;
215
216 /* CRT power saving modes. */
217 switch (blank_mode) {
218 case FB_BLANK_UNBLANK:
219 blank = 0; hsync = 1; vsync = 1;
220 break;
221 case FB_BLANK_NORMAL:
222 blank = 1; hsync = 1; vsync = 1;
223 break;
224 case FB_BLANK_VSYNC_SUSPEND:
225 blank = 1; hsync = 1; vsync = 0;
226 break;
227 case FB_BLANK_HSYNC_SUSPEND:
228 blank = 1; hsync = 0; vsync = 1;
229 break;
230 case FB_BLANK_POWERDOWN:
231 blank = 1; hsync = 0; vsync = 0;
232 break;
233 default:
234 return -EINVAL;
235 }
236 dcfg = readl(par->vid_regs + GX_DCFG);
237 dcfg &= ~(GX_DCFG_DAC_BL_EN
238 | GX_DCFG_HSYNC_EN | GX_DCFG_VSYNC_EN);
239 if (!blank)
240 dcfg |= GX_DCFG_DAC_BL_EN;
241 if (hsync)
242 dcfg |= GX_DCFG_HSYNC_EN;
243 if (vsync)
244 dcfg |= GX_DCFG_VSYNC_EN;
245 writel(dcfg, par->vid_regs + GX_DCFG);
246
247 /* Power on/off flat panel. */
248 fp_pm = readl(par->vid_regs + GX_FP_PM);
249 if (blank_mode == FB_BLANK_POWERDOWN)
250 fp_pm &= ~GX_FP_PM_P;
251 else
252 fp_pm |= GX_FP_PM_P;
253 writel(fp_pm, par->vid_regs + GX_FP_PM);
254
255 return 0;
256}
257
258struct geode_vid_ops gx_vid_ops = {
259 .set_dclk = gx_set_dclk_frequency,
260 .configure_display = gx_configure_display,
261 .blank_display = gx_blank_display,
262};
diff --git a/drivers/video/geode/video_gx.h b/drivers/video/geode/video_gx.h
new file mode 100644
index 000000000000..2d9211f3ed84
--- /dev/null
+++ b/drivers/video/geode/video_gx.h
@@ -0,0 +1,47 @@
1/*
2 * Geode GX video device
3 *
4 * Copyright (C) 2006 Arcom Control Systems Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11#ifndef __VIDEO_GX_H__
12#define __VIDEO_GX_H__
13
14extern struct geode_vid_ops gx_vid_ops;
15
16/* Geode GX video processor registers */
17
18#define GX_DCFG 0x0008
19# define GX_DCFG_CRT_EN 0x00000001
20# define GX_DCFG_HSYNC_EN 0x00000002
21# define GX_DCFG_VSYNC_EN 0x00000004
22# define GX_DCFG_DAC_BL_EN 0x00000008
23# define GX_DCFG_CRT_HSYNC_POL 0x00000100
24# define GX_DCFG_CRT_VSYNC_POL 0x00000200
25# define GX_DCFG_CRT_SYNC_SKW_MASK 0x0001C000
26# define GX_DCFG_CRT_SYNC_SKW_DFLT 0x00010000
27# define GX_DCFG_VG_CK 0x00100000
28# define GX_DCFG_GV_GAM 0x00200000
29# define GX_DCFG_DAC_VREF 0x04000000
30
31/* Geode GX flat panel display control registers */
32#define GX_FP_PM 0x410
33# define GX_FP_PM_P 0x01000000
34
35/* Geode GX clock control MSRs */
36
37#define MSR_GLCP_SYS_RSTPLL 0x4c000014
38# define MSR_GLCP_SYS_RSTPLL_DOTPREDIV2 (0x0000000000000002ull)
39# define MSR_GLCP_SYS_RSTPLL_DOTPREMULT2 (0x0000000000000004ull)
40# define MSR_GLCP_SYS_RSTPLL_DOTPOSTDIV3 (0x0000000000000008ull)
41
42#define MSR_GLCP_DOTPLL 0x4c000015
43# define MSR_GLCP_DOTPLL_DOTRESET (0x0000000000000001ull)
44# define MSR_GLCP_DOTPLL_BYPASS (0x0000000000008000ull)
45# define MSR_GLCP_DOTPLL_LOCK (0x0000000002000000ull)
46
47#endif /* !__VIDEO_GX_H__ */
diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c
index e3c8b5f1ca76..3fe3ae1aff12 100644
--- a/drivers/video/i810/i810-i2c.c
+++ b/drivers/video/i810/i810-i2c.c
@@ -210,8 +210,7 @@ int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn)
210 } 210 }
211 } 211 }
212 212
213 if (out_edid) 213 *out_edid = edid;
214 *out_edid = edid;
215 214
216 return (edid) ? 0 : 1; 215 return (edid) ? 0 : 1;
217} 216}
diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c
index 7db42542eb19..f73c642b50c2 100644
--- a/drivers/video/imsttfb.c
+++ b/drivers/video/imsttfb.c
@@ -440,9 +440,9 @@ getclkMHz(struct imstt_par *par)
440static void 440static void
441setclkMHz(struct imstt_par *par, __u32 MHz) 441setclkMHz(struct imstt_par *par, __u32 MHz)
442{ 442{
443 __u32 clk_m, clk_n, clk_p, x, stage, spilled; 443 __u32 clk_m, clk_n, x, stage, spilled;
444 444
445 clk_m = clk_n = clk_p = 0; 445 clk_m = clk_n = 0;
446 stage = spilled = 0; 446 stage = spilled = 0;
447 for (;;) { 447 for (;;) {
448 switch (stage) { 448 switch (stage) {
@@ -453,7 +453,7 @@ setclkMHz(struct imstt_par *par, __u32 MHz)
453 clk_n++; 453 clk_n++;
454 break; 454 break;
455 } 455 }
456 x = 20 * (clk_m + 1) / ((clk_n + 1) * (clk_p ? 2 * clk_p : 1)); 456 x = 20 * (clk_m + 1) / (clk_n + 1);
457 if (x == MHz) 457 if (x == MHz)
458 break; 458 break;
459 if (x > MHz) { 459 if (x > MHz) {
@@ -466,7 +466,7 @@ setclkMHz(struct imstt_par *par, __u32 MHz)
466 466
467 par->init.pclk_m = clk_m; 467 par->init.pclk_m = clk_m;
468 par->init.pclk_n = clk_n; 468 par->init.pclk_n = clk_n;
469 par->init.pclk_p = clk_p; 469 par->init.pclk_p = 0;
470} 470}
471 471
472static struct imstt_regvals * 472static struct imstt_regvals *
@@ -1372,18 +1372,24 @@ init_imstt(struct fb_info *info)
1372 write_reg_le32(par->dc_regs, STGCTL, tmp & ~0x1); 1372 write_reg_le32(par->dc_regs, STGCTL, tmp & ~0x1);
1373 write_reg_le32(par->dc_regs, SSR, 0); 1373 write_reg_le32(par->dc_regs, SSR, 0);
1374 1374
1375 /* set default values for DAC registers */ 1375 /* set default values for DAC registers */
1376 if (par->ramdac == IBM) { 1376 if (par->ramdac == IBM) {
1377 par->cmap_regs[PPMASK] = 0xff; eieio(); 1377 par->cmap_regs[PPMASK] = 0xff;
1378 par->cmap_regs[PIDXHI] = 0; eieio(); 1378 eieio();
1379 for (i = 0; i < sizeof(ibm_initregs) / sizeof(*ibm_initregs); i++) { 1379 par->cmap_regs[PIDXHI] = 0;
1380 par->cmap_regs[PIDXLO] = ibm_initregs[i].addr; eieio(); 1380 eieio();
1381 par->cmap_regs[PIDXDATA] = ibm_initregs[i].value; eieio(); 1381 for (i = 0; i < ARRAY_SIZE(ibm_initregs); i++) {
1382 par->cmap_regs[PIDXLO] = ibm_initregs[i].addr;
1383 eieio();
1384 par->cmap_regs[PIDXDATA] = ibm_initregs[i].value;
1385 eieio();
1382 } 1386 }
1383 } else { 1387 } else {
1384 for (i = 0; i < sizeof(tvp_initregs) / sizeof(*tvp_initregs); i++) { 1388 for (i = 0; i < ARRAY_SIZE(tvp_initregs); i++) {
1385 par->cmap_regs[TVPADDRW] = tvp_initregs[i].addr; eieio(); 1389 par->cmap_regs[TVPADDRW] = tvp_initregs[i].addr;
1386 par->cmap_regs[TVPIDATA] = tvp_initregs[i].value; eieio(); 1390 eieio();
1391 par->cmap_regs[TVPIDATA] = tvp_initregs[i].value;
1392 eieio();
1387 } 1393 }
1388 } 1394 }
1389 1395
diff --git a/drivers/video/macmodes.c b/drivers/video/macmodes.c
index 2fc71081f7e7..c0385c6f7db5 100644
--- a/drivers/video/macmodes.c
+++ b/drivers/video/macmodes.c
@@ -380,7 +380,7 @@ int __init mac_find_mode(struct fb_var_screeninfo *var, struct fb_info *info,
380 if (mode_option && !strncmp(mode_option, "mac", 3)) { 380 if (mode_option && !strncmp(mode_option, "mac", 3)) {
381 mode_option += 3; 381 mode_option += 3;
382 db = mac_modedb; 382 db = mac_modedb;
383 dbsize = sizeof(mac_modedb)/sizeof(*mac_modedb); 383 dbsize = ARRAY_SIZE(mac_modedb);
384 } 384 }
385 return fb_find_mode(var, info, mode_option, db, dbsize, 385 return fb_find_mode(var, info, mode_option, db, dbsize,
386 &mac_modedb[DEFAULT_MODEDB_INDEX], default_bpp); 386 &mac_modedb[DEFAULT_MODEDB_INDEX], default_bpp);
diff --git a/drivers/video/matrox/matroxfb_g450.c b/drivers/video/matrox/matroxfb_g450.c
index c122d8743dd2..4d610b405d45 100644
--- a/drivers/video/matrox/matroxfb_g450.c
+++ b/drivers/video/matrox/matroxfb_g450.c
@@ -59,7 +59,7 @@ static const struct mctl g450_controls[] =
59 }, offsetof(struct matrox_fb_info, altout.tvo_params.testout) }, 59 }, offsetof(struct matrox_fb_info, altout.tvo_params.testout) },
60}; 60};
61 61
62#define G450CTRLS (sizeof(g450_controls)/sizeof(g450_controls[0])) 62#define G450CTRLS ARRAY_SIZE(g450_controls)
63 63
64/* Return: positive number: id found 64/* Return: positive number: id found
65 -EINVAL: id not found, return failure 65 -EINVAL: id not found, return failure
diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c
index 6019710dc298..5d29a26b8cdf 100644
--- a/drivers/video/matrox/matroxfb_maven.c
+++ b/drivers/video/matrox/matroxfb_maven.c
@@ -89,12 +89,12 @@ static const struct mctl maven_controls[] =
89 }, offsetof(struct matrox_fb_info, altout.tvo_params.hue) }, 89 }, offsetof(struct matrox_fb_info, altout.tvo_params.hue) },
90 { { V4L2_CID_GAMMA, V4L2_CTRL_TYPE_INTEGER, 90 { { V4L2_CID_GAMMA, V4L2_CTRL_TYPE_INTEGER,
91 "gamma", 91 "gamma",
92 0, sizeof(maven_gamma)/sizeof(maven_gamma[0])-1, 1, 3, 92 0, ARRAY_SIZE(maven_gamma) - 1, 1, 3,
93 0, 93 0,
94 }, offsetof(struct matrox_fb_info, altout.tvo_params.gamma) }, 94 }, offsetof(struct matrox_fb_info, altout.tvo_params.gamma) },
95 { { MATROXFB_CID_TESTOUT, V4L2_CTRL_TYPE_BOOLEAN, 95 { { MATROXFB_CID_TESTOUT, V4L2_CTRL_TYPE_BOOLEAN,
96 "test output", 96 "test output",
97 0, 1, 1, 0, 97 0, 1, 1, 0,
98 0, 98 0,
99 }, offsetof(struct matrox_fb_info, altout.tvo_params.testout) }, 99 }, offsetof(struct matrox_fb_info, altout.tvo_params.testout) },
100 { { MATROXFB_CID_DEFLICKER, V4L2_CTRL_TYPE_INTEGER, 100 { { MATROXFB_CID_DEFLICKER, V4L2_CTRL_TYPE_INTEGER,
@@ -105,7 +105,7 @@ static const struct mctl maven_controls[] =
105 105
106}; 106};
107 107
108#define MAVCTRLS (sizeof(maven_controls)/sizeof(maven_controls[0])) 108#define MAVCTRLS ARRAY_SIZE(maven_controls)
109 109
110/* Return: positive number: id found 110/* Return: positive number: id found
111 -EINVAL: id not found, return failure 111 -EINVAL: id not found, return failure
@@ -129,7 +129,7 @@ static int get_ctrl_id(__u32 v4l2_id) {
129 129
130struct maven_data { 130struct maven_data {
131 struct matrox_fb_info* primary_head; 131 struct matrox_fb_info* primary_head;
132 struct i2c_client* client; 132 struct i2c_client client;
133 int version; 133 int version;
134}; 134};
135 135
@@ -970,7 +970,7 @@ static inline int maven_compute_timming(struct maven_data* md,
970 970
971static int maven_program_timming(struct maven_data* md, 971static int maven_program_timming(struct maven_data* md,
972 const struct mavenregs* m) { 972 const struct mavenregs* m) {
973 struct i2c_client* c = md->client; 973 struct i2c_client* c = &md->client;
974 974
975 if (m->mode == MATROXFB_OUTPUT_MODE_MONITOR) { 975 if (m->mode == MATROXFB_OUTPUT_MODE_MONITOR) {
976 LR(0x80); 976 LR(0x80);
@@ -1007,7 +1007,7 @@ static int maven_program_timming(struct maven_data* md,
1007} 1007}
1008 1008
1009static inline int maven_resync(struct maven_data* md) { 1009static inline int maven_resync(struct maven_data* md) {
1010 struct i2c_client* c = md->client; 1010 struct i2c_client* c = &md->client;
1011 maven_set_reg(c, 0x95, 0x20); /* start whole thing */ 1011 maven_set_reg(c, 0x95, 0x20); /* start whole thing */
1012 return 0; 1012 return 0;
1013} 1013}
@@ -1065,48 +1065,48 @@ static int maven_set_control (struct maven_data* md,
1065 maven_compute_bwlevel(md, &blacklevel, &whitelevel); 1065 maven_compute_bwlevel(md, &blacklevel, &whitelevel);
1066 blacklevel = (blacklevel >> 2) | ((blacklevel & 3) << 8); 1066 blacklevel = (blacklevel >> 2) | ((blacklevel & 3) << 8);
1067 whitelevel = (whitelevel >> 2) | ((whitelevel & 3) << 8); 1067 whitelevel = (whitelevel >> 2) | ((whitelevel & 3) << 8);
1068 maven_set_reg_pair(md->client, 0x0e, blacklevel); 1068 maven_set_reg_pair(&md->client, 0x0e, blacklevel);
1069 maven_set_reg_pair(md->client, 0x1e, whitelevel); 1069 maven_set_reg_pair(&md->client, 0x1e, whitelevel);
1070 } 1070 }
1071 break; 1071 break;
1072 case V4L2_CID_SATURATION: 1072 case V4L2_CID_SATURATION:
1073 { 1073 {
1074 maven_set_reg(md->client, 0x20, p->value); 1074 maven_set_reg(&md->client, 0x20, p->value);
1075 maven_set_reg(md->client, 0x22, p->value); 1075 maven_set_reg(&md->client, 0x22, p->value);
1076 } 1076 }
1077 break; 1077 break;
1078 case V4L2_CID_HUE: 1078 case V4L2_CID_HUE:
1079 { 1079 {
1080 maven_set_reg(md->client, 0x25, p->value); 1080 maven_set_reg(&md->client, 0x25, p->value);
1081 } 1081 }
1082 break; 1082 break;
1083 case V4L2_CID_GAMMA: 1083 case V4L2_CID_GAMMA:
1084 { 1084 {
1085 const struct maven_gamma* g; 1085 const struct maven_gamma* g;
1086 g = maven_compute_gamma(md); 1086 g = maven_compute_gamma(md);
1087 maven_set_reg(md->client, 0x83, g->reg83); 1087 maven_set_reg(&md->client, 0x83, g->reg83);
1088 maven_set_reg(md->client, 0x84, g->reg84); 1088 maven_set_reg(&md->client, 0x84, g->reg84);
1089 maven_set_reg(md->client, 0x85, g->reg85); 1089 maven_set_reg(&md->client, 0x85, g->reg85);
1090 maven_set_reg(md->client, 0x86, g->reg86); 1090 maven_set_reg(&md->client, 0x86, g->reg86);
1091 maven_set_reg(md->client, 0x87, g->reg87); 1091 maven_set_reg(&md->client, 0x87, g->reg87);
1092 maven_set_reg(md->client, 0x88, g->reg88); 1092 maven_set_reg(&md->client, 0x88, g->reg88);
1093 maven_set_reg(md->client, 0x89, g->reg89); 1093 maven_set_reg(&md->client, 0x89, g->reg89);
1094 maven_set_reg(md->client, 0x8a, g->reg8a); 1094 maven_set_reg(&md->client, 0x8a, g->reg8a);
1095 maven_set_reg(md->client, 0x8b, g->reg8b); 1095 maven_set_reg(&md->client, 0x8b, g->reg8b);
1096 } 1096 }
1097 break; 1097 break;
1098 case MATROXFB_CID_TESTOUT: 1098 case MATROXFB_CID_TESTOUT:
1099 { 1099 {
1100 unsigned char val 1100 unsigned char val
1101 = maven_get_reg (md->client,0x8d); 1101 = maven_get_reg(&md->client,0x8d);
1102 if (p->value) val |= 0x10; 1102 if (p->value) val |= 0x10;
1103 else val &= ~0x10; 1103 else val &= ~0x10;
1104 maven_set_reg (md->client, 0x8d, val); 1104 maven_set_reg(&md->client, 0x8d, val);
1105 } 1105 }
1106 break; 1106 break;
1107 case MATROXFB_CID_DEFLICKER: 1107 case MATROXFB_CID_DEFLICKER:
1108 { 1108 {
1109 maven_set_reg(md->client, 0x93, maven_compute_deflicker(md)); 1109 maven_set_reg(&md->client, 0x93, maven_compute_deflicker(md));
1110 } 1110 }
1111 break; 1111 break;
1112 } 1112 }
@@ -1185,7 +1185,6 @@ static int maven_init_client(struct i2c_client* clnt) {
1185 MINFO_FROM(container_of(clnt->adapter, struct i2c_bit_adapter, adapter)->minfo); 1185 MINFO_FROM(container_of(clnt->adapter, struct i2c_bit_adapter, adapter)->minfo);
1186 1186
1187 md->primary_head = MINFO; 1187 md->primary_head = MINFO;
1188 md->client = clnt;
1189 down_write(&ACCESS_FBINFO(altout.lock)); 1188 down_write(&ACCESS_FBINFO(altout.lock));
1190 ACCESS_FBINFO(outputs[1]).output = &maven_altout; 1189 ACCESS_FBINFO(outputs[1]).output = &maven_altout;
1191 ACCESS_FBINFO(outputs[1]).src = ACCESS_FBINFO(outputs[1]).default_src; 1190 ACCESS_FBINFO(outputs[1]).src = ACCESS_FBINFO(outputs[1]).default_src;
@@ -1243,19 +1242,17 @@ static int maven_detect_client(struct i2c_adapter* adapter, int address, int kin
1243 I2C_FUNC_SMBUS_BYTE_DATA | 1242 I2C_FUNC_SMBUS_BYTE_DATA |
1244 I2C_FUNC_PROTOCOL_MANGLING)) 1243 I2C_FUNC_PROTOCOL_MANGLING))
1245 goto ERROR0; 1244 goto ERROR0;
1246 if (!(new_client = (struct i2c_client*)kmalloc(sizeof(*new_client) + sizeof(*data), 1245 if (!(data = kzalloc(sizeof(*data), GFP_KERNEL))) {
1247 GFP_KERNEL))) {
1248 err = -ENOMEM; 1246 err = -ENOMEM;
1249 goto ERROR0; 1247 goto ERROR0;
1250 } 1248 }
1251 memset(new_client, 0, sizeof(*new_client) + sizeof(*data)); 1249 new_client = &data->client;
1252 data = (struct maven_data*)(new_client + 1);
1253 i2c_set_clientdata(new_client, data); 1250 i2c_set_clientdata(new_client, data);
1254 new_client->addr = address; 1251 new_client->addr = address;
1255 new_client->adapter = adapter; 1252 new_client->adapter = adapter;
1256 new_client->driver = &maven_driver; 1253 new_client->driver = &maven_driver;
1257 new_client->flags = 0; 1254 new_client->flags = 0;
1258 strcpy(new_client->name, "maven client"); 1255 strlcpy(new_client->name, "maven", I2C_NAME_SIZE);
1259 if ((err = i2c_attach_client(new_client))) 1256 if ((err = i2c_attach_client(new_client)))
1260 goto ERROR3; 1257 goto ERROR3;
1261 err = maven_init_client(new_client); 1258 err = maven_init_client(new_client);
@@ -1279,12 +1276,10 @@ static int maven_attach_adapter(struct i2c_adapter* adapter) {
1279static int maven_detach_client(struct i2c_client* client) { 1276static int maven_detach_client(struct i2c_client* client) {
1280 int err; 1277 int err;
1281 1278
1282 if ((err = i2c_detach_client(client))) { 1279 if ((err = i2c_detach_client(client)))
1283 printk(KERN_ERR "maven: Cannot deregister client\n");
1284 return err; 1280 return err;
1285 }
1286 maven_shutdown_client(client); 1281 maven_shutdown_client(client);
1287 kfree(client); 1282 kfree(i2c_get_clientdata(client));
1288 return 0; 1283 return 0;
1289} 1284}
1290 1285
@@ -1297,20 +1292,13 @@ static struct i2c_driver maven_driver={
1297 .detach_client = maven_detach_client, 1292 .detach_client = maven_detach_client,
1298}; 1293};
1299 1294
1300/* ************************** */ 1295static int __init matroxfb_maven_init(void)
1301 1296{
1302static int matroxfb_maven_init(void) { 1297 return i2c_add_driver(&maven_driver);
1303 int err;
1304
1305 err = i2c_add_driver(&maven_driver);
1306 if (err) {
1307 printk(KERN_ERR "maven: Maven driver failed to register (%d).\n", err);
1308 return err;
1309 }
1310 return 0;
1311} 1298}
1312 1299
1313static void matroxfb_maven_exit(void) { 1300static void __exit matroxfb_maven_exit(void)
1301{
1314 i2c_del_driver(&maven_driver); 1302 i2c_del_driver(&maven_driver);
1315} 1303}
1316 1304
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 1da2f84bdc25..26a1c618a205 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -183,6 +183,10 @@ static const struct fb_videomode modedb[] = {
183 NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3, 183 NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
184 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 184 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
185 }, { 185 }, {
186 /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
187 NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
188 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
189 }, {
186 /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */ 190 /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
187 NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3, 191 NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
188 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 192 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
@@ -496,7 +500,7 @@ int fb_find_mode(struct fb_var_screeninfo *var,
496 /* Set up defaults */ 500 /* Set up defaults */
497 if (!db) { 501 if (!db) {
498 db = modedb; 502 db = modedb;
499 dbsize = sizeof(modedb)/sizeof(*modedb); 503 dbsize = ARRAY_SIZE(modedb);
500 } 504 }
501 if (!default_mode) 505 if (!default_mode)
502 default_mode = &modedb[DEFAULT_MODEDB_INDEX]; 506 default_mode = &modedb[DEFAULT_MODEDB_INDEX];
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index b961d5601bd9..24b12f71d5a8 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -165,20 +165,20 @@ static int neoFindMode(int xres, int yres, int depth)
165 165
166 switch (depth) { 166 switch (depth) {
167 case 8: 167 case 8:
168 size = sizeof(bios8) / sizeof(biosMode); 168 size = ARRAY_SIZE(bios8);
169 mode = bios8; 169 mode = bios8;
170 break; 170 break;
171 case 16: 171 case 16:
172 size = sizeof(bios16) / sizeof(biosMode); 172 size = ARRAY_SIZE(bios16);
173 mode = bios16; 173 mode = bios16;
174 break; 174 break;
175 case 24: 175 case 24:
176 size = sizeof(bios24) / sizeof(biosMode); 176 size = ARRAY_SIZE(bios24);
177 mode = bios24; 177 mode = bios24;
178 break; 178 break;
179#ifdef NO_32BIT_SUPPORT_YET 179#ifdef NO_32BIT_SUPPORT_YET
180 case 32: 180 case 32:
181 size = sizeof(bios32) / sizeof(biosMode); 181 size = ARRAY_SIZE(bios32);
182 mode = bios32; 182 mode = bios32;
183 break; 183 break;
184#endif 184#endif
diff --git a/drivers/video/nvidia/nv_accel.c b/drivers/video/nvidia/nv_accel.c
index f377a29ec97a..4aefb8f41637 100644
--- a/drivers/video/nvidia/nv_accel.c
+++ b/drivers/video/nvidia/nv_accel.c
@@ -300,6 +300,9 @@ int nvidiafb_sync(struct fb_info *info)
300{ 300{
301 struct nvidia_par *par = info->par; 301 struct nvidia_par *par = info->par;
302 302
303 if (info->state != FBINFO_STATE_RUNNING)
304 return 0;
305
303 if (!par->lockup) 306 if (!par->lockup)
304 NVFlush(par); 307 NVFlush(par);
305 308
@@ -313,6 +316,9 @@ void nvidiafb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
313{ 316{
314 struct nvidia_par *par = info->par; 317 struct nvidia_par *par = info->par;
315 318
319 if (info->state != FBINFO_STATE_RUNNING)
320 return;
321
316 if (par->lockup) 322 if (par->lockup)
317 return cfb_copyarea(info, region); 323 return cfb_copyarea(info, region);
318 324
@@ -329,6 +335,9 @@ void nvidiafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
329 struct nvidia_par *par = info->par; 335 struct nvidia_par *par = info->par;
330 u32 color; 336 u32 color;
331 337
338 if (info->state != FBINFO_STATE_RUNNING)
339 return;
340
332 if (par->lockup) 341 if (par->lockup)
333 return cfb_fillrect(info, rect); 342 return cfb_fillrect(info, rect);
334 343
@@ -412,6 +421,9 @@ void nvidiafb_imageblit(struct fb_info *info, const struct fb_image *image)
412{ 421{
413 struct nvidia_par *par = info->par; 422 struct nvidia_par *par = info->par;
414 423
424 if (info->state != FBINFO_STATE_RUNNING)
425 return;
426
415 if (image->depth == 1 && !par->lockup) 427 if (image->depth == 1 && !par->lockup)
416 nvidiafb_mono_color_expand(info, image); 428 nvidiafb_mono_color_expand(info, image);
417 else 429 else
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c
index bd9eca05e146..1edb1c432b75 100644
--- a/drivers/video/nvidia/nv_i2c.c
+++ b/drivers/video/nvidia/nv_i2c.c
@@ -218,8 +218,7 @@ int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid)
218 } 218 }
219 } 219 }
220 220
221 if (out_edid) 221 *out_edid = edid;
222 *out_edid = edid;
223 222
224 return (edid) ? 0 : 1; 223 return (edid) ? 0 : 1;
225} 224}
diff --git a/drivers/video/nvidia/nv_type.h b/drivers/video/nvidia/nv_type.h
index e4a5b1da71c4..acdc26693402 100644
--- a/drivers/video/nvidia/nv_type.h
+++ b/drivers/video/nvidia/nv_type.h
@@ -129,6 +129,7 @@ struct nvidia_par {
129 int fpHeight; 129 int fpHeight;
130 int PanelTweak; 130 int PanelTweak;
131 int paneltweak; 131 int paneltweak;
132 int pm_state;
132 u32 crtcSync_read; 133 u32 crtcSync_read;
133 u32 fpSyncs; 134 u32 fpSyncs;
134 u32 dmaPut; 135 u32 dmaPut;
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index a7c4e5e8ead6..6d3e4890cb43 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -21,6 +21,7 @@
21#include <linux/fb.h> 21#include <linux/fb.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/pci.h> 23#include <linux/pci.h>
24#include <linux/console.h>
24#ifdef CONFIG_MTRR 25#ifdef CONFIG_MTRR
25#include <asm/mtrr.h> 26#include <asm/mtrr.h>
26#endif 27#endif
@@ -296,6 +297,8 @@ static struct pci_device_id nvidiafb_pci_tbl[] = {
296 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 297 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
297 {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_GT, 298 {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_GT,
298 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 299 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
300 {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_QUADRO_NVS280,
301 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
299 {PCI_VENDOR_ID_NVIDIA, 0x0252, 302 {PCI_VENDOR_ID_NVIDIA, 0x0252,
300 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 303 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
301 {PCI_VENDOR_ID_NVIDIA, 0x0313, 304 {PCI_VENDOR_ID_NVIDIA, 0x0313,
@@ -615,6 +618,30 @@ static int nvidia_panel_tweak(struct nvidia_par *par,
615 return tweak; 618 return tweak;
616} 619}
617 620
621static void nvidia_vga_protect(struct nvidia_par *par, int on)
622{
623 unsigned char tmp;
624
625 if (on) {
626 /*
627 * Turn off screen and disable sequencer.
628 */
629 tmp = NVReadSeq(par, 0x01);
630
631 NVWriteSeq(par, 0x00, 0x01); /* Synchronous Reset */
632 NVWriteSeq(par, 0x01, tmp | 0x20); /* disable the display */
633 } else {
634 /*
635 * Reenable sequencer, then turn on screen.
636 */
637
638 tmp = NVReadSeq(par, 0x01);
639
640 NVWriteSeq(par, 0x01, tmp & ~0x20); /* reenable display */
641 NVWriteSeq(par, 0x00, 0x03); /* End Reset */
642 }
643}
644
618static void nvidia_save_vga(struct nvidia_par *par, 645static void nvidia_save_vga(struct nvidia_par *par,
619 struct _riva_hw_state *state) 646 struct _riva_hw_state *state)
620{ 647{
@@ -643,9 +670,9 @@ static void nvidia_save_vga(struct nvidia_par *par,
643 670
644#undef DUMP_REG 671#undef DUMP_REG
645 672
646static void nvidia_write_regs(struct nvidia_par *par) 673static void nvidia_write_regs(struct nvidia_par *par,
674 struct _riva_hw_state *state)
647{ 675{
648 struct _riva_hw_state *state = &par->ModeReg;
649 int i; 676 int i;
650 677
651 NVTRACE_ENTER(); 678 NVTRACE_ENTER();
@@ -694,32 +721,6 @@ static void nvidia_write_regs(struct nvidia_par *par)
694 NVTRACE_LEAVE(); 721 NVTRACE_LEAVE();
695} 722}
696 723
697static void nvidia_vga_protect(struct nvidia_par *par, int on)
698{
699 unsigned char tmp;
700
701 if (on) {
702 /*
703 * Turn off screen and disable sequencer.
704 */
705 tmp = NVReadSeq(par, 0x01);
706
707 NVWriteSeq(par, 0x00, 0x01); /* Synchronous Reset */
708 NVWriteSeq(par, 0x01, tmp | 0x20); /* disable the display */
709 } else {
710 /*
711 * Reenable sequencer, then turn on screen.
712 */
713
714 tmp = NVReadSeq(par, 0x01);
715
716 NVWriteSeq(par, 0x01, tmp & ~0x20); /* reenable display */
717 NVWriteSeq(par, 0x00, 0x03); /* End Reset */
718 }
719}
720
721
722
723static int nvidia_calc_regs(struct fb_info *info) 724static int nvidia_calc_regs(struct fb_info *info)
724{ 725{
725 struct nvidia_par *par = info->par; 726 struct nvidia_par *par = info->par;
@@ -1068,7 +1069,8 @@ static int nvidiafb_set_par(struct fb_info *info)
1068 1069
1069 nvidia_vga_protect(par, 1); 1070 nvidia_vga_protect(par, 1);
1070 1071
1071 nvidia_write_regs(par); 1072 nvidia_write_regs(par, &par->ModeReg);
1073 NVSetStartAddress(par, 0);
1072 1074
1073#if defined (__BIG_ENDIAN) 1075#if defined (__BIG_ENDIAN)
1074 /* turn on LFB swapping */ 1076 /* turn on LFB swapping */
@@ -1377,6 +1379,57 @@ static struct fb_ops nvidia_fb_ops = {
1377 .fb_sync = nvidiafb_sync, 1379 .fb_sync = nvidiafb_sync,
1378}; 1380};
1379 1381
1382#ifdef CONFIG_PM
1383static int nvidiafb_suspend(struct pci_dev *dev, pm_message_t state)
1384{
1385 struct fb_info *info = pci_get_drvdata(dev);
1386 struct nvidia_par *par = info->par;
1387
1388 acquire_console_sem();
1389 par->pm_state = state.event;
1390
1391 if (state.event == PM_EVENT_FREEZE) {
1392 dev->dev.power.power_state = state;
1393 } else {
1394 fb_set_suspend(info, 1);
1395 nvidiafb_blank(FB_BLANK_POWERDOWN, info);
1396 nvidia_write_regs(par, &par->SavedReg);
1397 pci_save_state(dev);
1398 pci_disable_device(dev);
1399 pci_set_power_state(dev, pci_choose_state(dev, state));
1400 }
1401
1402 release_console_sem();
1403 return 0;
1404}
1405
1406static int nvidiafb_resume(struct pci_dev *dev)
1407{
1408 struct fb_info *info = pci_get_drvdata(dev);
1409 struct nvidia_par *par = info->par;
1410
1411 acquire_console_sem();
1412 pci_set_power_state(dev, PCI_D0);
1413
1414 if (par->pm_state != PM_EVENT_FREEZE) {
1415 pci_restore_state(dev);
1416 pci_enable_device(dev);
1417 pci_set_master(dev);
1418 }
1419
1420 par->pm_state = PM_EVENT_ON;
1421 nvidiafb_set_par(info);
1422 fb_set_suspend (info, 0);
1423 nvidiafb_blank(FB_BLANK_UNBLANK, info);
1424
1425 release_console_sem();
1426 return 0;
1427}
1428#else
1429#define nvidiafb_suspend NULL
1430#define nvidiafb_resume NULL
1431#endif
1432
1380static int __devinit nvidia_set_fbinfo(struct fb_info *info) 1433static int __devinit nvidia_set_fbinfo(struct fb_info *info)
1381{ 1434{
1382 struct fb_monspecs *specs = &info->monspecs; 1435 struct fb_monspecs *specs = &info->monspecs;
@@ -1720,8 +1773,6 @@ static void __exit nvidiafb_remove(struct pci_dev *pd)
1720 struct nvidia_par *par = info->par; 1773 struct nvidia_par *par = info->par;
1721 1774
1722 NVTRACE_ENTER(); 1775 NVTRACE_ENTER();
1723 if (!info)
1724 return;
1725 1776
1726 unregister_framebuffer(info); 1777 unregister_framebuffer(info);
1727#ifdef CONFIG_MTRR 1778#ifdef CONFIG_MTRR
@@ -1798,8 +1849,10 @@ static int __devinit nvidiafb_setup(char *options)
1798static struct pci_driver nvidiafb_driver = { 1849static struct pci_driver nvidiafb_driver = {
1799 .name = "nvidiafb", 1850 .name = "nvidiafb",
1800 .id_table = nvidiafb_pci_tbl, 1851 .id_table = nvidiafb_pci_tbl,
1801 .probe = nvidiafb_probe, 1852 .probe = nvidiafb_probe,
1802 .remove = __exit_p(nvidiafb_remove), 1853 .suspend = nvidiafb_suspend,
1854 .resume = nvidiafb_resume,
1855 .remove = __exit_p(nvidiafb_remove),
1803}; 1856};
1804 1857
1805/* ------------------------------------------------------------------------- * 1858/* ------------------------------------------------------------------------- *
diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c
index eeeac924b500..73e2d7d16608 100644
--- a/drivers/video/pmagb-b-fb.c
+++ b/drivers/video/pmagb-b-fb.c
@@ -228,7 +228,7 @@ static void __init pmagbbfb_osc_setup(struct fb_info *info)
228 228
229 freq1 = (par->osc0 * count1 + count0 / 2) / count0; 229 freq1 = (par->osc0 * count1 + count0 / 2) / count0;
230 par->osc1 = freq1; 230 par->osc1 = freq1;
231 for (i = 0; i < sizeof(pmagbbfb_freqs) / sizeof(*pmagbbfb_freqs); i++) 231 for (i = 0; i < ARRAY_SIZE(pmagbbfb_freqs); i++)
232 if (freq1 >= pmagbbfb_freqs[i] - 232 if (freq1 >= pmagbbfb_freqs[i] -
233 (pmagbbfb_freqs[i] + 128) / 256 && 233 (pmagbbfb_freqs[i] + 128) / 256 &&
234 freq1 <= pmagbbfb_freqs[i] + 234 freq1 <= pmagbbfb_freqs[i] +
diff --git a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c
index db9fb9074dbc..24982adb3aa2 100644
--- a/drivers/video/radeonfb.c
+++ b/drivers/video/radeonfb.c
@@ -759,7 +759,7 @@ static void __iomem *radeon_find_rom(struct radeonfb_info *rinfo)
759 rom = rom_base; 759 rom = rom_base;
760 760
761 for (i = 0; (i < 512) && (stage != 4); i++) { 761 for (i = 0; (i < 512) && (stage != 4); i++) {
762 for(j = 0;j < sizeof(radeon_sig)/sizeof(char *);j++) { 762 for (j = 0; j < ARRAY_SIZE(radeon_sig); j++) {
763 if (radeon_sig[j][0] == *rom) 763 if (radeon_sig[j][0] == *rom)
764 if (strncmp(radeon_sig[j], rom, 764 if (strncmp(radeon_sig[j], rom,
765 strlen(radeon_sig[j])) == 0) { 765 strlen(radeon_sig[j])) == 0) {
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index 6c19ab6afb01..f841f013b96f 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -2072,8 +2072,6 @@ static void __exit rivafb_remove(struct pci_dev *pd)
2072 struct riva_par *par = info->par; 2072 struct riva_par *par = info->par;
2073 2073
2074 NVTRACE_ENTER(); 2074 NVTRACE_ENTER();
2075 if (!info)
2076 return;
2077 2075
2078#ifdef CONFIG_FB_RIVA_I2C 2076#ifdef CONFIG_FB_RIVA_I2C
2079 riva_delete_i2c_busses(par); 2077 riva_delete_i2c_busses(par);
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c
index 00719a91479f..21debed863ac 100644
--- a/drivers/video/savage/savagefb-i2c.c
+++ b/drivers/video/savage/savagefb-i2c.c
@@ -273,8 +273,7 @@ int savagefb_probe_i2c_connector(struct fb_info *info, u8 **out_edid)
273 } 273 }
274 } 274 }
275 275
276 if (out_edid) 276 *out_edid = edid;
277 *out_edid = edid;
278 277
279 return (edid) ? 0 : 1; 278 return (edid) ? 0 : 1;
280} 279}
diff --git a/drivers/video/sis/init301.c b/drivers/video/sis/init301.c
index 2d88f908170a..c3e070a6effd 100644
--- a/drivers/video/sis/init301.c
+++ b/drivers/video/sis/init301.c
@@ -8564,11 +8564,9 @@ SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8564static void 8564static void
8565SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr) 8565SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
8566{ 8566{
8567 unsigned short temp,tempcl,tempch; 8567 unsigned short temp;
8568 8568
8569 SiS_LongDelay(SiS_Pr, 1); 8569 SiS_LongDelay(SiS_Pr, 1);
8570 tempcl = 3;
8571 tempch = 0;
8572 8570
8573 do { 8571 do {
8574 temp = SiS_GetCH701x(SiS_Pr,0x66); 8572 temp = SiS_GetCH701x(SiS_Pr,0x66);
@@ -8582,13 +8580,6 @@ SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
8582 8580
8583 SiS_SetCH701xForLCD(SiS_Pr); 8581 SiS_SetCH701xForLCD(SiS_Pr);
8584 8582
8585 if(tempcl == 0) {
8586 if(tempch == 3) break;
8587 SiS_ChrontelResetDB(SiS_Pr);
8588 tempcl = 3;
8589 tempch++;
8590 }
8591 tempcl--;
8592 temp = SiS_GetCH701x(SiS_Pr,0x76); 8583 temp = SiS_GetCH701x(SiS_Pr,0x76);
8593 temp &= 0xfb; /* Reset PLL */ 8584 temp &= 0xfb; /* Reset PLL */
8594 SiS_SetCH701x(SiS_Pr,0x76,temp); 8585 SiS_SetCH701x(SiS_Pr,0x76,temp);
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
index 8c1a8b5135c6..c44de90ca12e 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/sstfb.c
@@ -1194,10 +1194,11 @@ static struct dac_switch dacs[] __devinitdata = {
1194static int __devinit sst_detect_dactype(struct fb_info *info, struct sstfb_par *par) 1194static int __devinit sst_detect_dactype(struct fb_info *info, struct sstfb_par *par)
1195{ 1195{
1196 int i, ret = 0; 1196 int i, ret = 0;
1197 1197
1198 for (i=0; i<sizeof(dacs)/sizeof(dacs[0]); i++) { 1198 for (i = 0; i < ARRAY_SIZE(dacs); i++) {
1199 ret = dacs[i].detect(info); 1199 ret = dacs[i].detect(info);
1200 if (ret) break; 1200 if (ret)
1201 break;
1201 } 1202 }
1202 if (!ret) 1203 if (!ret)
1203 return 0; 1204 return 0;
@@ -1604,8 +1605,8 @@ static int sstfb_dump_regs(struct fb_info *info)
1604 {FBZMODE,"fbzmode"}, 1605 {FBZMODE,"fbzmode"},
1605 }; 1606 };
1606 1607
1607 const int pci_s = sizeof(pci_regs)/sizeof(pci_regs[0]); 1608 const int pci_s = ARRAY_SIZE(pci_regs);
1608 const int sst_s = sizeof(sst_regs)/sizeof(sst_regs[0]); 1609 const int sst_s = ARRAY_SIZE(sst_regs);
1609 struct sstfb_par *par = info->par; 1610 struct sstfb_par *par = info->par;
1610 struct pci_dev *dev = par->dev; 1611 struct pci_dev *dev = par->dev;
1611 u32 pci_res[pci_s]; 1612 u32 pci_res[pci_s];
diff --git a/drivers/video/virgefb.c b/drivers/video/virgefb.c
index ed78747487e2..5ea2345dab99 100644
--- a/drivers/video/virgefb.c
+++ b/drivers/video/virgefb.c
@@ -616,8 +616,7 @@ static struct {
616#endif 616#endif
617}; 617};
618 618
619#define arraysize(x) (sizeof(x)/sizeof(*(x))) 619#define NUM_TOTAL_MODES ARRAY_SIZE(virgefb_predefined)
620#define NUM_TOTAL_MODES arraysize(virgefb_predefined)
621 620
622/* 621/*
623 * Default to 800x600 for video=virge8:, virge16: or virge32: 622 * Default to 800x600 for video=virge8:, virge16: or virge32:
diff --git a/fs/autofs/dirhash.c b/fs/autofs/dirhash.c
index 5ccfcf26310d..3fded389d06b 100644
--- a/fs/autofs/dirhash.c
+++ b/fs/autofs/dirhash.c
@@ -92,7 +92,7 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb,
92 ; 92 ;
93 dput(dentry); 93 dput(dentry);
94 94
95 if ( may_umount(mnt) == 0 ) { 95 if ( may_umount(mnt) ) {
96 mntput(mnt); 96 mntput(mnt);
97 DPRINTK(("autofs: signaling expire on %s\n", ent->name)); 97 DPRINTK(("autofs: signaling expire on %s\n", ent->name));
98 return ent; /* Expirable! */ 98 return ent; /* Expirable! */
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index f54c5b21f876..617fd7b37447 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -3,6 +3,7 @@
3 * linux/fs/autofs/autofs_i.h 3 * linux/fs/autofs/autofs_i.h
4 * 4 *
5 * Copyright 1997-1998 Transmeta Corporation - All Rights Reserved 5 * Copyright 1997-1998 Transmeta Corporation - All Rights Reserved
6 * Copyright 2005-2006 Ian Kent <raven@themaw.net>
6 * 7 *
7 * This file is part of the Linux kernel and is made available under 8 * This file is part of the Linux kernel and is made available under
8 * the terms of the GNU General Public License, version 2, or at your 9 * the terms of the GNU General Public License, version 2, or at your
@@ -41,14 +42,6 @@
41 42
42#define AUTOFS_SUPER_MAGIC 0x0187 43#define AUTOFS_SUPER_MAGIC 0x0187
43 44
44/*
45 * If the daemon returns a negative response (AUTOFS_IOC_FAIL) then the
46 * kernel will keep the negative response cached for up to the time given
47 * here, although the time can be shorter if the kernel throws the dcache
48 * entry away. This probably should be settable from user space.
49 */
50#define AUTOFS_NEGATIVE_TIMEOUT (60*HZ) /* 1 minute */
51
52/* Unified info structure. This is pointed to by both the dentry and 45/* Unified info structure. This is pointed to by both the dentry and
53 inode structures. Each file in the filesystem has an instance of this 46 inode structures. Each file in the filesystem has an instance of this
54 structure. It holds a reference to the dentry, so dentries are never 47 structure. It holds a reference to the dentry, so dentries are never
@@ -63,6 +56,7 @@ struct autofs_info {
63 56
64 struct autofs_sb_info *sbi; 57 struct autofs_sb_info *sbi;
65 unsigned long last_used; 58 unsigned long last_used;
59 atomic_t count;
66 60
67 mode_t mode; 61 mode_t mode;
68 size_t size; 62 size_t size;
@@ -83,23 +77,37 @@ struct autofs_wait_queue {
83 int hash; 77 int hash;
84 int len; 78 int len;
85 char *name; 79 char *name;
80 u32 dev;
81 u64 ino;
82 uid_t uid;
83 gid_t gid;
84 pid_t pid;
85 pid_t tgid;
86 /* This is for status reporting upon return */ 86 /* This is for status reporting upon return */
87 int status; 87 int status;
88 atomic_t notified; 88 atomic_t notify;
89 atomic_t wait_ctr; 89 atomic_t wait_ctr;
90}; 90};
91 91
92#define AUTOFS_SBI_MAGIC 0x6d4a556d 92#define AUTOFS_SBI_MAGIC 0x6d4a556d
93 93
94#define AUTOFS_TYPE_INDIRECT 0x0001
95#define AUTOFS_TYPE_DIRECT 0x0002
96#define AUTOFS_TYPE_OFFSET 0x0004
97
94struct autofs_sb_info { 98struct autofs_sb_info {
95 u32 magic; 99 u32 magic;
96 struct dentry *root; 100 struct dentry *root;
101 int pipefd;
97 struct file *pipe; 102 struct file *pipe;
98 pid_t oz_pgrp; 103 pid_t oz_pgrp;
99 int catatonic; 104 int catatonic;
100 int version; 105 int version;
101 int sub_version; 106 int sub_version;
107 int min_proto;
108 int max_proto;
102 unsigned long exp_timeout; 109 unsigned long exp_timeout;
110 unsigned int type;
103 int reghost_enabled; 111 int reghost_enabled;
104 int needs_reghost; 112 int needs_reghost;
105 struct super_block *sb; 113 struct super_block *sb;
@@ -166,6 +174,8 @@ int autofs4_expire_multi(struct super_block *, struct vfsmount *,
166extern struct inode_operations autofs4_symlink_inode_operations; 174extern struct inode_operations autofs4_symlink_inode_operations;
167extern struct inode_operations autofs4_dir_inode_operations; 175extern struct inode_operations autofs4_dir_inode_operations;
168extern struct inode_operations autofs4_root_inode_operations; 176extern struct inode_operations autofs4_root_inode_operations;
177extern struct inode_operations autofs4_indirect_root_inode_operations;
178extern struct inode_operations autofs4_direct_root_inode_operations;
169extern struct file_operations autofs4_dir_operations; 179extern struct file_operations autofs4_dir_operations;
170extern struct file_operations autofs4_root_operations; 180extern struct file_operations autofs4_root_operations;
171 181
@@ -176,13 +186,6 @@ struct autofs_info *autofs4_init_ino(struct autofs_info *, struct autofs_sb_info
176 186
177/* Queue management functions */ 187/* Queue management functions */
178 188
179enum autofs_notify
180{
181 NFY_NONE,
182 NFY_MOUNT,
183 NFY_EXPIRE
184};
185
186int autofs4_wait(struct autofs_sb_info *,struct dentry *, enum autofs_notify); 189int autofs4_wait(struct autofs_sb_info *,struct dentry *, enum autofs_notify);
187int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int); 190int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int);
188void autofs4_catatonic_mode(struct autofs_sb_info *); 191void autofs4_catatonic_mode(struct autofs_sb_info *);
@@ -200,12 +203,22 @@ static inline int autofs4_follow_mount(struct vfsmount **mnt, struct dentry **de
200 return res; 203 return res;
201} 204}
202 205
206static inline u32 autofs4_get_dev(struct autofs_sb_info *sbi)
207{
208 return new_encode_dev(sbi->sb->s_dev);
209}
210
211static inline u64 autofs4_get_ino(struct autofs_sb_info *sbi)
212{
213 return sbi->sb->s_root->d_inode->i_ino;
214}
215
203static inline int simple_positive(struct dentry *dentry) 216static inline int simple_positive(struct dentry *dentry)
204{ 217{
205 return dentry->d_inode && !d_unhashed(dentry); 218 return dentry->d_inode && !d_unhashed(dentry);
206} 219}
207 220
208static inline int simple_empty_nolock(struct dentry *dentry) 221static inline int __simple_empty(struct dentry *dentry)
209{ 222{
210 struct dentry *child; 223 struct dentry *child;
211 int ret = 0; 224 int ret = 0;
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index dc39589df165..b8ce02607d66 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -4,7 +4,7 @@
4 * 4 *
5 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved 5 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
6 * Copyright 1999-2000 Jeremy Fitzhardinge <jeremy@goop.org> 6 * Copyright 1999-2000 Jeremy Fitzhardinge <jeremy@goop.org>
7 * Copyright 2001-2003 Ian Kent <raven@themaw.net> 7 * Copyright 2001-2006 Ian Kent <raven@themaw.net>
8 * 8 *
9 * This file is part of the Linux kernel and is made available under 9 * This file is part of the Linux kernel and is made available under
10 * the terms of the GNU General Public License, version 2, or at your 10 * the terms of the GNU General Public License, version 2, or at your
@@ -16,7 +16,7 @@
16 16
17static unsigned long now; 17static unsigned long now;
18 18
19/* Check if a dentry can be expired return 1 if it can else return 0 */ 19/* Check if a dentry can be expired */
20static inline int autofs4_can_expire(struct dentry *dentry, 20static inline int autofs4_can_expire(struct dentry *dentry,
21 unsigned long timeout, int do_now) 21 unsigned long timeout, int do_now)
22{ 22{
@@ -41,14 +41,14 @@ static inline int autofs4_can_expire(struct dentry *dentry,
41 attempts if expire fails the first time */ 41 attempts if expire fails the first time */
42 ino->last_used = now; 42 ino->last_used = now;
43 } 43 }
44
45 return 1; 44 return 1;
46} 45}
47 46
48/* Check a mount point for busyness return 1 if not busy, otherwise */ 47/* Check a mount point for busyness */
49static int autofs4_check_mount(struct vfsmount *mnt, struct dentry *dentry) 48static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry)
50{ 49{
51 int status = 0; 50 struct dentry *top = dentry;
51 int status = 1;
52 52
53 DPRINTK("dentry %p %.*s", 53 DPRINTK("dentry %p %.*s",
54 dentry, (int)dentry->d_name.len, dentry->d_name.name); 54 dentry, (int)dentry->d_name.len, dentry->d_name.name);
@@ -63,9 +63,14 @@ static int autofs4_check_mount(struct vfsmount *mnt, struct dentry *dentry)
63 if (is_autofs4_dentry(dentry)) 63 if (is_autofs4_dentry(dentry))
64 goto done; 64 goto done;
65 65
66 /* The big question */ 66 /* Update the expiry counter if fs is busy */
67 if (may_umount_tree(mnt) == 0) 67 if (!may_umount_tree(mnt)) {
68 status = 1; 68 struct autofs_info *ino = autofs4_dentry_ino(top);
69 ino->last_used = jiffies;
70 goto done;
71 }
72
73 status = 0;
69done: 74done:
70 DPRINTK("returning = %d", status); 75 DPRINTK("returning = %d", status);
71 mntput(mnt); 76 mntput(mnt);
@@ -73,78 +78,124 @@ done:
73 return status; 78 return status;
74} 79}
75 80
81/*
82 * Calculate next entry in top down tree traversal.
83 * From next_mnt in namespace.c - elegant.
84 */
85static struct dentry *next_dentry(struct dentry *p, struct dentry *root)
86{
87 struct list_head *next = p->d_subdirs.next;
88
89 if (next == &p->d_subdirs) {
90 while (1) {
91 if (p == root)
92 return NULL;
93 next = p->d_u.d_child.next;
94 if (next != &p->d_parent->d_subdirs)
95 break;
96 p = p->d_parent;
97 }
98 }
99 return list_entry(next, struct dentry, d_u.d_child);
100}
101
102/*
103 * Check a direct mount point for busyness.
104 * Direct mounts have similar expiry semantics to tree mounts.
105 * The tree is not busy iff no mountpoints are busy and there are no
106 * autofs submounts.
107 */
108static int autofs4_direct_busy(struct vfsmount *mnt,
109 struct dentry *top,
110 unsigned long timeout,
111 int do_now)
112{
113 DPRINTK("top %p %.*s",
114 top, (int) top->d_name.len, top->d_name.name);
115
116 /* If it's busy update the expiry counters */
117 if (!may_umount_tree(mnt)) {
118 struct autofs_info *ino = autofs4_dentry_ino(top);
119 if (ino)
120 ino->last_used = jiffies;
121 return 1;
122 }
123
124 /* Timeout of a direct mount is determined by its top dentry */
125 if (!autofs4_can_expire(top, timeout, do_now))
126 return 1;
127
128 return 0;
129}
130
76/* Check a directory tree of mount points for busyness 131/* Check a directory tree of mount points for busyness
77 * The tree is not busy iff no mountpoints are busy 132 * The tree is not busy iff no mountpoints are busy
78 * Return 1 if the tree is busy or 0 otherwise
79 */ 133 */
80static int autofs4_check_tree(struct vfsmount *mnt, 134static int autofs4_tree_busy(struct vfsmount *mnt,
81 struct dentry *top, 135 struct dentry *top,
82 unsigned long timeout, 136 unsigned long timeout,
83 int do_now) 137 int do_now)
84{ 138{
85 struct dentry *this_parent = top; 139 struct autofs_info *top_ino = autofs4_dentry_ino(top);
86 struct list_head *next; 140 struct dentry *p;
87 141
88 DPRINTK("parent %p %.*s", 142 DPRINTK("top %p %.*s",
89 top, (int)top->d_name.len, top->d_name.name); 143 top, (int)top->d_name.len, top->d_name.name);
90 144
91 /* Negative dentry - give up */ 145 /* Negative dentry - give up */
92 if (!simple_positive(top)) 146 if (!simple_positive(top))
93 return 0; 147 return 1;
94
95 /* Timeout of a tree mount is determined by its top dentry */
96 if (!autofs4_can_expire(top, timeout, do_now))
97 return 0;
98
99 /* Is someone visiting anywhere in the tree ? */
100 if (may_umount_tree(mnt))
101 return 0;
102 148
103 spin_lock(&dcache_lock); 149 spin_lock(&dcache_lock);
104repeat: 150 for (p = top; p; p = next_dentry(p, top)) {
105 next = this_parent->d_subdirs.next;
106resume:
107 while (next != &this_parent->d_subdirs) {
108 struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
109
110 /* Negative dentry - give up */ 151 /* Negative dentry - give up */
111 if (!simple_positive(dentry)) { 152 if (!simple_positive(p))
112 next = next->next;
113 continue; 153 continue;
114 }
115 154
116 DPRINTK("dentry %p %.*s", 155 DPRINTK("dentry %p %.*s",
117 dentry, (int)dentry->d_name.len, dentry->d_name.name); 156 p, (int) p->d_name.len, p->d_name.name);
118
119 if (!simple_empty_nolock(dentry)) {
120 this_parent = dentry;
121 goto repeat;
122 }
123 157
124 dentry = dget(dentry); 158 p = dget(p);
125 spin_unlock(&dcache_lock); 159 spin_unlock(&dcache_lock);
126 160
127 if (d_mountpoint(dentry)) { 161 /*
128 /* First busy => tree busy */ 162 * Is someone visiting anywhere in the subtree ?
129 if (!autofs4_check_mount(mnt, dentry)) { 163 * If there's no mount we need to check the usage
130 dput(dentry); 164 * count for the autofs dentry.
131 return 0; 165 * If the fs is busy update the expiry counter.
166 */
167 if (d_mountpoint(p)) {
168 if (autofs4_mount_busy(mnt, p)) {
169 top_ino->last_used = jiffies;
170 dput(p);
171 return 1;
172 }
173 } else {
174 struct autofs_info *ino = autofs4_dentry_ino(p);
175 unsigned int ino_count = atomic_read(&ino->count);
176
177 /* allow for dget above and top is already dgot */
178 if (p == top)
179 ino_count += 2;
180 else
181 ino_count++;
182
183 if (atomic_read(&p->d_count) > ino_count) {
184 top_ino->last_used = jiffies;
185 dput(p);
186 return 1;
132 } 187 }
133 } 188 }
134 189 dput(p);
135 dput(dentry);
136 spin_lock(&dcache_lock); 190 spin_lock(&dcache_lock);
137 next = next->next;
138 }
139
140 if (this_parent != top) {
141 next = this_parent->d_u.d_child.next;
142 this_parent = this_parent->d_parent;
143 goto resume;
144 } 191 }
145 spin_unlock(&dcache_lock); 192 spin_unlock(&dcache_lock);
146 193
147 return 1; 194 /* Timeout of a tree mount is ultimately determined by its top dentry */
195 if (!autofs4_can_expire(top, timeout, do_now))
196 return 1;
197
198 return 0;
148} 199}
149 200
150static struct dentry *autofs4_check_leaves(struct vfsmount *mnt, 201static struct dentry *autofs4_check_leaves(struct vfsmount *mnt,
@@ -152,58 +203,68 @@ static struct dentry *autofs4_check_leaves(struct vfsmount *mnt,
152 unsigned long timeout, 203 unsigned long timeout,
153 int do_now) 204 int do_now)
154{ 205{
155 struct dentry *this_parent = parent; 206 struct dentry *p;
156 struct list_head *next;
157 207
158 DPRINTK("parent %p %.*s", 208 DPRINTK("parent %p %.*s",
159 parent, (int)parent->d_name.len, parent->d_name.name); 209 parent, (int)parent->d_name.len, parent->d_name.name);
160 210
161 spin_lock(&dcache_lock); 211 spin_lock(&dcache_lock);
162repeat: 212 for (p = parent; p; p = next_dentry(p, parent)) {
163 next = this_parent->d_subdirs.next;
164resume:
165 while (next != &this_parent->d_subdirs) {
166 struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
167
168 /* Negative dentry - give up */ 213 /* Negative dentry - give up */
169 if (!simple_positive(dentry)) { 214 if (!simple_positive(p))
170 next = next->next;
171 continue; 215 continue;
172 }
173 216
174 DPRINTK("dentry %p %.*s", 217 DPRINTK("dentry %p %.*s",
175 dentry, (int)dentry->d_name.len, dentry->d_name.name); 218 p, (int) p->d_name.len, p->d_name.name);
176
177 if (!list_empty(&dentry->d_subdirs)) {
178 this_parent = dentry;
179 goto repeat;
180 }
181 219
182 dentry = dget(dentry); 220 p = dget(p);
183 spin_unlock(&dcache_lock); 221 spin_unlock(&dcache_lock);
184 222
185 if (d_mountpoint(dentry)) { 223 if (d_mountpoint(p)) {
186 /* Can we expire this guy */
187 if (!autofs4_can_expire(dentry, timeout, do_now))
188 goto cont;
189
190 /* Can we umount this guy */ 224 /* Can we umount this guy */
191 if (autofs4_check_mount(mnt, dentry)) 225 if (autofs4_mount_busy(mnt, p))
192 return dentry; 226 goto cont;
193 227
228 /* Can we expire this guy */
229 if (autofs4_can_expire(p, timeout, do_now))
230 return p;
194 } 231 }
195cont: 232cont:
196 dput(dentry); 233 dput(p);
197 spin_lock(&dcache_lock); 234 spin_lock(&dcache_lock);
198 next = next->next;
199 } 235 }
236 spin_unlock(&dcache_lock);
237 return NULL;
238}
239
240/* Check if we can expire a direct mount (possibly a tree) */
241static struct dentry *autofs4_expire_direct(struct super_block *sb,
242 struct vfsmount *mnt,
243 struct autofs_sb_info *sbi,
244 int how)
245{
246 unsigned long timeout;
247 struct dentry *root = dget(sb->s_root);
248 int do_now = how & AUTOFS_EXP_IMMEDIATE;
249
250 if (!sbi->exp_timeout || !root)
251 return NULL;
252
253 now = jiffies;
254 timeout = sbi->exp_timeout;
255
256 /* Lock the tree as we must expire as a whole */
257 spin_lock(&sbi->fs_lock);
258 if (!autofs4_direct_busy(mnt, root, timeout, do_now)) {
259 struct autofs_info *ino = autofs4_dentry_ino(root);
200 260
201 if (this_parent != parent) { 261 /* Set this flag early to catch sys_chdir and the like */
202 next = this_parent->d_u.d_child.next; 262 ino->flags |= AUTOFS_INF_EXPIRING;
203 this_parent = this_parent->d_parent; 263 spin_unlock(&sbi->fs_lock);
204 goto resume; 264 return root;
205 } 265 }
206 spin_unlock(&dcache_lock); 266 spin_unlock(&sbi->fs_lock);
267 dput(root);
207 268
208 return NULL; 269 return NULL;
209} 270}
@@ -214,10 +275,10 @@ cont:
214 * - it is unused by any user process 275 * - it is unused by any user process
215 * - it has been unused for exp_timeout time 276 * - it has been unused for exp_timeout time
216 */ 277 */
217static struct dentry *autofs4_expire(struct super_block *sb, 278static struct dentry *autofs4_expire_indirect(struct super_block *sb,
218 struct vfsmount *mnt, 279 struct vfsmount *mnt,
219 struct autofs_sb_info *sbi, 280 struct autofs_sb_info *sbi,
220 int how) 281 int how)
221{ 282{
222 unsigned long timeout; 283 unsigned long timeout;
223 struct dentry *root = sb->s_root; 284 struct dentry *root = sb->s_root;
@@ -241,7 +302,7 @@ static struct dentry *autofs4_expire(struct super_block *sb,
241 struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child); 302 struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
242 303
243 /* Negative dentry - give up */ 304 /* Negative dentry - give up */
244 if ( !simple_positive(dentry) ) { 305 if (!simple_positive(dentry)) {
245 next = next->next; 306 next = next->next;
246 continue; 307 continue;
247 } 308 }
@@ -249,31 +310,36 @@ static struct dentry *autofs4_expire(struct super_block *sb,
249 dentry = dget(dentry); 310 dentry = dget(dentry);
250 spin_unlock(&dcache_lock); 311 spin_unlock(&dcache_lock);
251 312
252 /* Case 1: indirect mount or top level direct mount */ 313 /*
314 * Case 1: (i) indirect mount or top level pseudo direct mount
315 * (autofs-4.1).
316 * (ii) indirect mount with offset mount, check the "/"
317 * offset (autofs-5.0+).
318 */
253 if (d_mountpoint(dentry)) { 319 if (d_mountpoint(dentry)) {
254 DPRINTK("checking mountpoint %p %.*s", 320 DPRINTK("checking mountpoint %p %.*s",
255 dentry, (int)dentry->d_name.len, dentry->d_name.name); 321 dentry, (int)dentry->d_name.len, dentry->d_name.name);
256 322
257 /* Can we expire this guy */ 323 /* Can we umount this guy */
258 if (!autofs4_can_expire(dentry, timeout, do_now)) 324 if (autofs4_mount_busy(mnt, dentry))
259 goto next; 325 goto next;
260 326
261 /* Can we umount this guy */ 327 /* Can we expire this guy */
262 if (autofs4_check_mount(mnt, dentry)) { 328 if (autofs4_can_expire(dentry, timeout, do_now)) {
263 expired = dentry; 329 expired = dentry;
264 break; 330 break;
265 } 331 }
266 goto next; 332 goto next;
267 } 333 }
268 334
269 if ( simple_empty(dentry) ) 335 if (simple_empty(dentry))
270 goto next; 336 goto next;
271 337
272 /* Case 2: tree mount, expire iff entire tree is not busy */ 338 /* Case 2: tree mount, expire iff entire tree is not busy */
273 if (!exp_leaves) { 339 if (!exp_leaves) {
274 /* Lock the tree as we must expire as a whole */ 340 /* Lock the tree as we must expire as a whole */
275 spin_lock(&sbi->fs_lock); 341 spin_lock(&sbi->fs_lock);
276 if (autofs4_check_tree(mnt, dentry, timeout, do_now)) { 342 if (!autofs4_tree_busy(mnt, dentry, timeout, do_now)) {
277 struct autofs_info *inf = autofs4_dentry_ino(dentry); 343 struct autofs_info *inf = autofs4_dentry_ino(dentry);
278 344
279 /* Set this flag early to catch sys_chdir and the like */ 345 /* Set this flag early to catch sys_chdir and the like */
@@ -283,7 +349,10 @@ static struct dentry *autofs4_expire(struct super_block *sb,
283 break; 349 break;
284 } 350 }
285 spin_unlock(&sbi->fs_lock); 351 spin_unlock(&sbi->fs_lock);
286 /* Case 3: direct mount, expire individual leaves */ 352 /*
353 * Case 3: pseudo direct mount, expire individual leaves
354 * (autofs-4.1).
355 */
287 } else { 356 } else {
288 expired = autofs4_check_leaves(mnt, dentry, timeout, do_now); 357 expired = autofs4_check_leaves(mnt, dentry, timeout, do_now);
289 if (expired) { 358 if (expired) {
@@ -297,7 +366,7 @@ next:
297 next = next->next; 366 next = next->next;
298 } 367 }
299 368
300 if ( expired ) { 369 if (expired) {
301 DPRINTK("returning %p %.*s", 370 DPRINTK("returning %p %.*s",
302 expired, (int)expired->d_name.len, expired->d_name.name); 371 expired, (int)expired->d_name.len, expired->d_name.name);
303 spin_lock(&dcache_lock); 372 spin_lock(&dcache_lock);
@@ -325,7 +394,7 @@ int autofs4_expire_run(struct super_block *sb,
325 pkt.hdr.proto_version = sbi->version; 394 pkt.hdr.proto_version = sbi->version;
326 pkt.hdr.type = autofs_ptype_expire; 395 pkt.hdr.type = autofs_ptype_expire;
327 396
328 if ((dentry = autofs4_expire(sb, mnt, sbi, 0)) == NULL) 397 if ((dentry = autofs4_expire_indirect(sb, mnt, sbi, 0)) == NULL)
329 return -EAGAIN; 398 return -EAGAIN;
330 399
331 pkt.len = dentry->d_name.len; 400 pkt.len = dentry->d_name.len;
@@ -351,17 +420,22 @@ int autofs4_expire_multi(struct super_block *sb, struct vfsmount *mnt,
351 if (arg && get_user(do_now, arg)) 420 if (arg && get_user(do_now, arg))
352 return -EFAULT; 421 return -EFAULT;
353 422
354 if ((dentry = autofs4_expire(sb, mnt, sbi, do_now)) != NULL) { 423 if (sbi->type & AUTOFS_TYPE_DIRECT)
355 struct autofs_info *de_info = autofs4_dentry_ino(dentry); 424 dentry = autofs4_expire_direct(sb, mnt, sbi, do_now);
425 else
426 dentry = autofs4_expire_indirect(sb, mnt, sbi, do_now);
427
428 if (dentry) {
429 struct autofs_info *ino = autofs4_dentry_ino(dentry);
356 430
357 /* This is synchronous because it makes the daemon a 431 /* This is synchronous because it makes the daemon a
358 little easier */ 432 little easier */
359 de_info->flags |= AUTOFS_INF_EXPIRING; 433 ino->flags |= AUTOFS_INF_EXPIRING;
360 ret = autofs4_wait(sbi, dentry, NFY_EXPIRE); 434 ret = autofs4_wait(sbi, dentry, NFY_EXPIRE);
361 de_info->flags &= ~AUTOFS_INF_EXPIRING; 435 ino->flags &= ~AUTOFS_INF_EXPIRING;
362 dput(dentry); 436 dput(dentry);
363 } 437 }
364 438
365 return ret; 439 return ret;
366} 440}
367 441
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 1ad98d48e550..4eddee4e76fc 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -3,6 +3,7 @@
3 * linux/fs/autofs/inode.c 3 * linux/fs/autofs/inode.c
4 * 4 *
5 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved 5 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
6 * Copyright 2005-2006 Ian Kent <raven@themaw.net>
6 * 7 *
7 * This file is part of the Linux kernel and is made available under 8 * This file is part of the Linux kernel and is made available under
8 * the terms of the GNU General Public License, version 2, or at your 9 * the terms of the GNU General Public License, version 2, or at your
@@ -13,6 +14,7 @@
13#include <linux/kernel.h> 14#include <linux/kernel.h>
14#include <linux/slab.h> 15#include <linux/slab.h>
15#include <linux/file.h> 16#include <linux/file.h>
17#include <linux/seq_file.h>
16#include <linux/pagemap.h> 18#include <linux/pagemap.h>
17#include <linux/parser.h> 19#include <linux/parser.h>
18#include <linux/bitops.h> 20#include <linux/bitops.h>
@@ -46,6 +48,7 @@ struct autofs_info *autofs4_init_ino(struct autofs_info *ino,
46 ino->size = 0; 48 ino->size = 0;
47 49
48 ino->last_used = jiffies; 50 ino->last_used = jiffies;
51 atomic_set(&ino->count, 0);
49 52
50 ino->sbi = sbi; 53 ino->sbi = sbi;
51 54
@@ -64,10 +67,19 @@ struct autofs_info *autofs4_init_ino(struct autofs_info *ino,
64 67
65void autofs4_free_ino(struct autofs_info *ino) 68void autofs4_free_ino(struct autofs_info *ino)
66{ 69{
70 struct autofs_info *p_ino;
71
67 if (ino->dentry) { 72 if (ino->dentry) {
68 ino->dentry->d_fsdata = NULL; 73 ino->dentry->d_fsdata = NULL;
69 if (ino->dentry->d_inode) 74 if (ino->dentry->d_inode) {
75 struct dentry *parent = ino->dentry->d_parent;
76 if (atomic_dec_and_test(&ino->count)) {
77 p_ino = autofs4_dentry_ino(parent);
78 if (p_ino && parent != ino->dentry)
79 atomic_dec(&p_ino->count);
80 }
70 dput(ino->dentry); 81 dput(ino->dentry);
82 }
71 ino->dentry = NULL; 83 ino->dentry = NULL;
72 } 84 }
73 if (ino->free) 85 if (ino->free)
@@ -145,20 +157,44 @@ static void autofs4_put_super(struct super_block *sb)
145 autofs4_catatonic_mode(sbi); /* Free wait queues, close pipe */ 157 autofs4_catatonic_mode(sbi); /* Free wait queues, close pipe */
146 158
147 /* Clean up and release dangling references */ 159 /* Clean up and release dangling references */
148 if (sbi) 160 autofs4_force_release(sbi);
149 autofs4_force_release(sbi);
150 161
151 kfree(sbi); 162 kfree(sbi);
152 163
153 DPRINTK("shutting down"); 164 DPRINTK("shutting down");
154} 165}
155 166
167static int autofs4_show_options(struct seq_file *m, struct vfsmount *mnt)
168{
169 struct autofs_sb_info *sbi = autofs4_sbi(mnt->mnt_sb);
170
171 if (!sbi)
172 return 0;
173
174 seq_printf(m, ",fd=%d", sbi->pipefd);
175 seq_printf(m, ",pgrp=%d", sbi->oz_pgrp);
176 seq_printf(m, ",timeout=%lu", sbi->exp_timeout/HZ);
177 seq_printf(m, ",minproto=%d", sbi->min_proto);
178 seq_printf(m, ",maxproto=%d", sbi->max_proto);
179
180 if (sbi->type & AUTOFS_TYPE_OFFSET)
181 seq_printf(m, ",offset");
182 else if (sbi->type & AUTOFS_TYPE_DIRECT)
183 seq_printf(m, ",direct");
184 else
185 seq_printf(m, ",indirect");
186
187 return 0;
188}
189
156static struct super_operations autofs4_sops = { 190static struct super_operations autofs4_sops = {
157 .put_super = autofs4_put_super, 191 .put_super = autofs4_put_super,
158 .statfs = simple_statfs, 192 .statfs = simple_statfs,
193 .show_options = autofs4_show_options,
159}; 194};
160 195
161enum {Opt_err, Opt_fd, Opt_uid, Opt_gid, Opt_pgrp, Opt_minproto, Opt_maxproto}; 196enum {Opt_err, Opt_fd, Opt_uid, Opt_gid, Opt_pgrp, Opt_minproto, Opt_maxproto,
197 Opt_indirect, Opt_direct, Opt_offset};
162 198
163static match_table_t tokens = { 199static match_table_t tokens = {
164 {Opt_fd, "fd=%u"}, 200 {Opt_fd, "fd=%u"},
@@ -167,11 +203,15 @@ static match_table_t tokens = {
167 {Opt_pgrp, "pgrp=%u"}, 203 {Opt_pgrp, "pgrp=%u"},
168 {Opt_minproto, "minproto=%u"}, 204 {Opt_minproto, "minproto=%u"},
169 {Opt_maxproto, "maxproto=%u"}, 205 {Opt_maxproto, "maxproto=%u"},
206 {Opt_indirect, "indirect"},
207 {Opt_direct, "direct"},
208 {Opt_offset, "offset"},
170 {Opt_err, NULL} 209 {Opt_err, NULL}
171}; 210};
172 211
173static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, 212static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
174 pid_t *pgrp, int *minproto, int *maxproto) 213 pid_t *pgrp, unsigned int *type,
214 int *minproto, int *maxproto)
175{ 215{
176 char *p; 216 char *p;
177 substring_t args[MAX_OPT_ARGS]; 217 substring_t args[MAX_OPT_ARGS];
@@ -225,6 +265,15 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
225 return 1; 265 return 1;
226 *maxproto = option; 266 *maxproto = option;
227 break; 267 break;
268 case Opt_indirect:
269 *type = AUTOFS_TYPE_INDIRECT;
270 break;
271 case Opt_direct:
272 *type = AUTOFS_TYPE_DIRECT;
273 break;
274 case Opt_offset:
275 *type = AUTOFS_TYPE_DIRECT | AUTOFS_TYPE_OFFSET;
276 break;
228 default: 277 default:
229 return 1; 278 return 1;
230 } 279 }
@@ -243,6 +292,11 @@ static struct autofs_info *autofs4_mkroot(struct autofs_sb_info *sbi)
243 return ino; 292 return ino;
244} 293}
245 294
295void autofs4_dentry_release(struct dentry *);
296static struct dentry_operations autofs4_sb_dentry_operations = {
297 .d_release = autofs4_dentry_release,
298};
299
246int autofs4_fill_super(struct super_block *s, void *data, int silent) 300int autofs4_fill_super(struct super_block *s, void *data, int silent)
247{ 301{
248 struct inode * root_inode; 302 struct inode * root_inode;
@@ -251,7 +305,6 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
251 int pipefd; 305 int pipefd;
252 struct autofs_sb_info *sbi; 306 struct autofs_sb_info *sbi;
253 struct autofs_info *ino; 307 struct autofs_info *ino;
254 int minproto, maxproto;
255 308
256 sbi = (struct autofs_sb_info *) kmalloc(sizeof(*sbi), GFP_KERNEL); 309 sbi = (struct autofs_sb_info *) kmalloc(sizeof(*sbi), GFP_KERNEL);
257 if ( !sbi ) 310 if ( !sbi )
@@ -263,12 +316,16 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
263 s->s_fs_info = sbi; 316 s->s_fs_info = sbi;
264 sbi->magic = AUTOFS_SBI_MAGIC; 317 sbi->magic = AUTOFS_SBI_MAGIC;
265 sbi->root = NULL; 318 sbi->root = NULL;
319 sbi->pipefd = -1;
266 sbi->catatonic = 0; 320 sbi->catatonic = 0;
267 sbi->exp_timeout = 0; 321 sbi->exp_timeout = 0;
268 sbi->oz_pgrp = process_group(current); 322 sbi->oz_pgrp = process_group(current);
269 sbi->sb = s; 323 sbi->sb = s;
270 sbi->version = 0; 324 sbi->version = 0;
271 sbi->sub_version = 0; 325 sbi->sub_version = 0;
326 sbi->type = 0;
327 sbi->min_proto = 0;
328 sbi->max_proto = 0;
272 mutex_init(&sbi->wq_mutex); 329 mutex_init(&sbi->wq_mutex);
273 spin_lock_init(&sbi->fs_lock); 330 spin_lock_init(&sbi->fs_lock);
274 sbi->queues = NULL; 331 sbi->queues = NULL;
@@ -285,38 +342,46 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
285 if (!ino) 342 if (!ino)
286 goto fail_free; 343 goto fail_free;
287 root_inode = autofs4_get_inode(s, ino); 344 root_inode = autofs4_get_inode(s, ino);
288 kfree(ino);
289 if (!root_inode) 345 if (!root_inode)
290 goto fail_free; 346 goto fail_ino;
291 347
292 root_inode->i_op = &autofs4_root_inode_operations;
293 root_inode->i_fop = &autofs4_root_operations;
294 root = d_alloc_root(root_inode); 348 root = d_alloc_root(root_inode);
295 pipe = NULL;
296
297 if (!root) 349 if (!root)
298 goto fail_iput; 350 goto fail_iput;
351 pipe = NULL;
352
353 root->d_op = &autofs4_sb_dentry_operations;
354 root->d_fsdata = ino;
299 355
300 /* Can this call block? */ 356 /* Can this call block? */
301 if (parse_options(data, &pipefd, 357 if (parse_options(data, &pipefd,
302 &root_inode->i_uid, &root_inode->i_gid, 358 &root_inode->i_uid, &root_inode->i_gid,
303 &sbi->oz_pgrp, 359 &sbi->oz_pgrp, &sbi->type,
304 &minproto, &maxproto)) { 360 &sbi->min_proto, &sbi->max_proto)) {
305 printk("autofs: called with bogus options\n"); 361 printk("autofs: called with bogus options\n");
306 goto fail_dput; 362 goto fail_dput;
307 } 363 }
308 364
365 root_inode->i_fop = &autofs4_root_operations;
366 root_inode->i_op = sbi->type & AUTOFS_TYPE_DIRECT ?
367 &autofs4_direct_root_inode_operations :
368 &autofs4_indirect_root_inode_operations;
369
309 /* Couldn't this be tested earlier? */ 370 /* Couldn't this be tested earlier? */
310 if (maxproto < AUTOFS_MIN_PROTO_VERSION || 371 if (sbi->max_proto < AUTOFS_MIN_PROTO_VERSION ||
311 minproto > AUTOFS_MAX_PROTO_VERSION) { 372 sbi->min_proto > AUTOFS_MAX_PROTO_VERSION) {
312 printk("autofs: kernel does not match daemon version " 373 printk("autofs: kernel does not match daemon version "
313 "daemon (%d, %d) kernel (%d, %d)\n", 374 "daemon (%d, %d) kernel (%d, %d)\n",
314 minproto, maxproto, 375 sbi->min_proto, sbi->max_proto,
315 AUTOFS_MIN_PROTO_VERSION, AUTOFS_MAX_PROTO_VERSION); 376 AUTOFS_MIN_PROTO_VERSION, AUTOFS_MAX_PROTO_VERSION);
316 goto fail_dput; 377 goto fail_dput;
317 } 378 }
318 379
319 sbi->version = maxproto > AUTOFS_MAX_PROTO_VERSION ? AUTOFS_MAX_PROTO_VERSION : maxproto; 380 /* Establish highest kernel protocol version */
381 if (sbi->max_proto > AUTOFS_MAX_PROTO_VERSION)
382 sbi->version = AUTOFS_MAX_PROTO_VERSION;
383 else
384 sbi->version = sbi->max_proto;
320 sbi->sub_version = AUTOFS_PROTO_SUBVERSION; 385 sbi->sub_version = AUTOFS_PROTO_SUBVERSION;
321 386
322 DPRINTK("pipe fd = %d, pgrp = %u", pipefd, sbi->oz_pgrp); 387 DPRINTK("pipe fd = %d, pgrp = %u", pipefd, sbi->oz_pgrp);
@@ -329,6 +394,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
329 if ( !pipe->f_op || !pipe->f_op->write ) 394 if ( !pipe->f_op || !pipe->f_op->write )
330 goto fail_fput; 395 goto fail_fput;
331 sbi->pipe = pipe; 396 sbi->pipe = pipe;
397 sbi->pipefd = pipefd;
332 398
333 /* 399 /*
334 * Take a reference to the root dentry so we get a chance to 400 * Take a reference to the root dentry so we get a chance to
@@ -356,6 +422,8 @@ fail_dput:
356fail_iput: 422fail_iput:
357 printk("autofs: get root dentry failed\n"); 423 printk("autofs: get root dentry failed\n");
358 iput(root_inode); 424 iput(root_inode);
425fail_ino:
426 kfree(ino);
359fail_free: 427fail_free:
360 kfree(sbi); 428 kfree(sbi);
361fail_unlock: 429fail_unlock:
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index 62d8d4acb8bb..c8fe43a475e2 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -4,7 +4,7 @@
4 * 4 *
5 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved 5 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
6 * Copyright 1999-2000 Jeremy Fitzhardinge <jeremy@goop.org> 6 * Copyright 1999-2000 Jeremy Fitzhardinge <jeremy@goop.org>
7 * Copyright 2001-2003 Ian Kent <raven@themaw.net> 7 * Copyright 2001-2006 Ian Kent <raven@themaw.net>
8 * 8 *
9 * This file is part of the Linux kernel and is made available under 9 * This file is part of the Linux kernel and is made available under
10 * the terms of the GNU General Public License, version 2, or at your 10 * the terms of the GNU General Public License, version 2, or at your
@@ -30,7 +30,7 @@ static int autofs4_dir_close(struct inode *inode, struct file *file);
30static int autofs4_dir_readdir(struct file * filp, void * dirent, filldir_t filldir); 30static int autofs4_dir_readdir(struct file * filp, void * dirent, filldir_t filldir);
31static int autofs4_root_readdir(struct file * filp, void * dirent, filldir_t filldir); 31static int autofs4_root_readdir(struct file * filp, void * dirent, filldir_t filldir);
32static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *); 32static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *);
33static int autofs4_dcache_readdir(struct file *, void *, filldir_t); 33static void *autofs4_follow_link(struct dentry *, struct nameidata *);
34 34
35struct file_operations autofs4_root_operations = { 35struct file_operations autofs4_root_operations = {
36 .open = dcache_dir_open, 36 .open = dcache_dir_open,
@@ -47,7 +47,7 @@ struct file_operations autofs4_dir_operations = {
47 .readdir = autofs4_dir_readdir, 47 .readdir = autofs4_dir_readdir,
48}; 48};
49 49
50struct inode_operations autofs4_root_inode_operations = { 50struct inode_operations autofs4_indirect_root_inode_operations = {
51 .lookup = autofs4_lookup, 51 .lookup = autofs4_lookup,
52 .unlink = autofs4_dir_unlink, 52 .unlink = autofs4_dir_unlink,
53 .symlink = autofs4_dir_symlink, 53 .symlink = autofs4_dir_symlink,
@@ -55,6 +55,14 @@ struct inode_operations autofs4_root_inode_operations = {
55 .rmdir = autofs4_dir_rmdir, 55 .rmdir = autofs4_dir_rmdir,
56}; 56};
57 57
58struct inode_operations autofs4_direct_root_inode_operations = {
59 .lookup = autofs4_lookup,
60 .unlink = autofs4_dir_unlink,
61 .mkdir = autofs4_dir_mkdir,
62 .rmdir = autofs4_dir_rmdir,
63 .follow_link = autofs4_follow_link,
64};
65
58struct inode_operations autofs4_dir_inode_operations = { 66struct inode_operations autofs4_dir_inode_operations = {
59 .lookup = autofs4_lookup, 67 .lookup = autofs4_lookup,
60 .unlink = autofs4_dir_unlink, 68 .unlink = autofs4_dir_unlink,
@@ -82,87 +90,7 @@ static int autofs4_root_readdir(struct file *file, void *dirent,
82 90
83 DPRINTK("needs_reghost = %d", sbi->needs_reghost); 91 DPRINTK("needs_reghost = %d", sbi->needs_reghost);
84 92
85 return autofs4_dcache_readdir(file, dirent, filldir); 93 return dcache_readdir(file, dirent, filldir);
86}
87
88/* Update usage from here to top of tree, so that scan of
89 top-level directories will give a useful result */
90static void autofs4_update_usage(struct vfsmount *mnt, struct dentry *dentry)
91{
92 struct dentry *top = dentry->d_sb->s_root;
93
94 spin_lock(&dcache_lock);
95 for(; dentry != top; dentry = dentry->d_parent) {
96 struct autofs_info *ino = autofs4_dentry_ino(dentry);
97
98 if (ino) {
99 touch_atime(mnt, dentry);
100 ino->last_used = jiffies;
101 }
102 }
103 spin_unlock(&dcache_lock);
104}
105
106/*
107 * From 2.4 kernel readdir.c
108 */
109static int autofs4_dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
110{
111 int i;
112 struct dentry *dentry = filp->f_dentry;
113
114 i = filp->f_pos;
115 switch (i) {
116 case 0:
117 if (filldir(dirent, ".", 1, i, dentry->d_inode->i_ino, DT_DIR) < 0)
118 break;
119 i++;
120 filp->f_pos++;
121 /* fallthrough */
122 case 1:
123 if (filldir(dirent, "..", 2, i, dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
124 break;
125 i++;
126 filp->f_pos++;
127 /* fallthrough */
128 default: {
129 struct list_head *list;
130 int j = i-2;
131
132 spin_lock(&dcache_lock);
133 list = dentry->d_subdirs.next;
134
135 for (;;) {
136 if (list == &dentry->d_subdirs) {
137 spin_unlock(&dcache_lock);
138 return 0;
139 }
140 if (!j)
141 break;
142 j--;
143 list = list->next;
144 }
145
146 while(1) {
147 struct dentry *de = list_entry(list,
148 struct dentry, d_u.d_child);
149
150 if (!d_unhashed(de) && de->d_inode) {
151 spin_unlock(&dcache_lock);
152 if (filldir(dirent, de->d_name.name, de->d_name.len, filp->f_pos, de->d_inode->i_ino, DT_UNKNOWN) < 0)
153 break;
154 spin_lock(&dcache_lock);
155 }
156 filp->f_pos++;
157 list = list->next;
158 if (list != &dentry->d_subdirs)
159 continue;
160 spin_unlock(&dcache_lock);
161 break;
162 }
163 }
164 }
165 return 0;
166} 94}
167 95
168static int autofs4_dir_open(struct inode *inode, struct file *file) 96static int autofs4_dir_open(struct inode *inode, struct file *file)
@@ -170,8 +98,16 @@ static int autofs4_dir_open(struct inode *inode, struct file *file)
170 struct dentry *dentry = file->f_dentry; 98 struct dentry *dentry = file->f_dentry;
171 struct vfsmount *mnt = file->f_vfsmnt; 99 struct vfsmount *mnt = file->f_vfsmnt;
172 struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); 100 struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
101 struct dentry *cursor;
173 int status; 102 int status;
174 103
104 status = dcache_dir_open(inode, file);
105 if (status)
106 goto out;
107
108 cursor = file->private_data;
109 cursor->d_fsdata = NULL;
110
175 DPRINTK("file=%p dentry=%p %.*s", 111 DPRINTK("file=%p dentry=%p %.*s",
176 file, dentry, dentry->d_name.len, dentry->d_name.name); 112 file, dentry, dentry->d_name.len, dentry->d_name.name);
177 113
@@ -180,12 +116,15 @@ static int autofs4_dir_open(struct inode *inode, struct file *file)
180 116
181 if (autofs4_ispending(dentry)) { 117 if (autofs4_ispending(dentry)) {
182 DPRINTK("dentry busy"); 118 DPRINTK("dentry busy");
183 return -EBUSY; 119 dcache_dir_close(inode, file);
120 status = -EBUSY;
121 goto out;
184 } 122 }
185 123
124 status = -ENOENT;
186 if (!d_mountpoint(dentry) && dentry->d_op && dentry->d_op->d_revalidate) { 125 if (!d_mountpoint(dentry) && dentry->d_op && dentry->d_op->d_revalidate) {
187 struct nameidata nd; 126 struct nameidata nd;
188 int empty; 127 int empty, ret;
189 128
190 /* In case there are stale directory dentrys from a failed mount */ 129 /* In case there are stale directory dentrys from a failed mount */
191 spin_lock(&dcache_lock); 130 spin_lock(&dcache_lock);
@@ -195,13 +134,13 @@ static int autofs4_dir_open(struct inode *inode, struct file *file)
195 if (!empty) 134 if (!empty)
196 d_invalidate(dentry); 135 d_invalidate(dentry);
197 136
198 nd.dentry = dentry;
199 nd.mnt = mnt;
200 nd.flags = LOOKUP_DIRECTORY; 137 nd.flags = LOOKUP_DIRECTORY;
201 status = (dentry->d_op->d_revalidate)(dentry, &nd); 138 ret = (dentry->d_op->d_revalidate)(dentry, &nd);
202 139
203 if (!status) 140 if (!ret) {
204 return -ENOENT; 141 dcache_dir_close(inode, file);
142 goto out;
143 }
205 } 144 }
206 145
207 if (d_mountpoint(dentry)) { 146 if (d_mountpoint(dentry)) {
@@ -212,25 +151,29 @@ static int autofs4_dir_open(struct inode *inode, struct file *file)
212 if (!autofs4_follow_mount(&fp_mnt, &fp_dentry)) { 151 if (!autofs4_follow_mount(&fp_mnt, &fp_dentry)) {
213 dput(fp_dentry); 152 dput(fp_dentry);
214 mntput(fp_mnt); 153 mntput(fp_mnt);
215 return -ENOENT; 154 dcache_dir_close(inode, file);
155 goto out;
216 } 156 }
217 157
218 fp = dentry_open(fp_dentry, fp_mnt, file->f_flags); 158 fp = dentry_open(fp_dentry, fp_mnt, file->f_flags);
219 status = PTR_ERR(fp); 159 status = PTR_ERR(fp);
220 if (IS_ERR(fp)) { 160 if (IS_ERR(fp)) {
221 file->private_data = NULL; 161 dcache_dir_close(inode, file);
222 return status; 162 goto out;
223 } 163 }
224 file->private_data = fp; 164 cursor->d_fsdata = fp;
225 } 165 }
226out:
227 return 0; 166 return 0;
167out:
168 return status;
228} 169}
229 170
230static int autofs4_dir_close(struct inode *inode, struct file *file) 171static int autofs4_dir_close(struct inode *inode, struct file *file)
231{ 172{
232 struct dentry *dentry = file->f_dentry; 173 struct dentry *dentry = file->f_dentry;
233 struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); 174 struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
175 struct dentry *cursor = file->private_data;
176 int status = 0;
234 177
235 DPRINTK("file=%p dentry=%p %.*s", 178 DPRINTK("file=%p dentry=%p %.*s",
236 file, dentry, dentry->d_name.len, dentry->d_name.name); 179 file, dentry, dentry->d_name.len, dentry->d_name.name);
@@ -240,26 +183,28 @@ static int autofs4_dir_close(struct inode *inode, struct file *file)
240 183
241 if (autofs4_ispending(dentry)) { 184 if (autofs4_ispending(dentry)) {
242 DPRINTK("dentry busy"); 185 DPRINTK("dentry busy");
243 return -EBUSY; 186 status = -EBUSY;
187 goto out;
244 } 188 }
245 189
246 if (d_mountpoint(dentry)) { 190 if (d_mountpoint(dentry)) {
247 struct file *fp = file->private_data; 191 struct file *fp = cursor->d_fsdata;
248 192 if (!fp) {
249 if (!fp) 193 status = -ENOENT;
250 return -ENOENT; 194 goto out;
251 195 }
252 filp_close(fp, current->files); 196 filp_close(fp, current->files);
253 file->private_data = NULL;
254 } 197 }
255out: 198out:
256 return 0; 199 dcache_dir_close(inode, file);
200 return status;
257} 201}
258 202
259static int autofs4_dir_readdir(struct file *file, void *dirent, filldir_t filldir) 203static int autofs4_dir_readdir(struct file *file, void *dirent, filldir_t filldir)
260{ 204{
261 struct dentry *dentry = file->f_dentry; 205 struct dentry *dentry = file->f_dentry;
262 struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); 206 struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
207 struct dentry *cursor = file->private_data;
263 int status; 208 int status;
264 209
265 DPRINTK("file=%p dentry=%p %.*s", 210 DPRINTK("file=%p dentry=%p %.*s",
@@ -274,7 +219,7 @@ static int autofs4_dir_readdir(struct file *file, void *dirent, filldir_t filldi
274 } 219 }
275 220
276 if (d_mountpoint(dentry)) { 221 if (d_mountpoint(dentry)) {
277 struct file *fp = file->private_data; 222 struct file *fp = cursor->d_fsdata;
278 223
279 if (!fp) 224 if (!fp)
280 return -ENOENT; 225 return -ENOENT;
@@ -289,27 +234,26 @@ static int autofs4_dir_readdir(struct file *file, void *dirent, filldir_t filldi
289 return status; 234 return status;
290 } 235 }
291out: 236out:
292 return autofs4_dcache_readdir(file, dirent, filldir); 237 return dcache_readdir(file, dirent, filldir);
293} 238}
294 239
295static int try_to_fill_dentry(struct vfsmount *mnt, struct dentry *dentry, int flags) 240static int try_to_fill_dentry(struct dentry *dentry, int flags)
296{ 241{
297 struct super_block *sb = mnt->mnt_sb; 242 struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
298 struct autofs_sb_info *sbi = autofs4_sbi(sb); 243 struct autofs_info *ino = autofs4_dentry_ino(dentry);
299 struct autofs_info *de_info = autofs4_dentry_ino(dentry);
300 int status = 0; 244 int status = 0;
301 245
302 /* Block on any pending expiry here; invalidate the dentry 246 /* Block on any pending expiry here; invalidate the dentry
303 when expiration is done to trigger mount request with a new 247 when expiration is done to trigger mount request with a new
304 dentry */ 248 dentry */
305 if (de_info && (de_info->flags & AUTOFS_INF_EXPIRING)) { 249 if (ino && (ino->flags & AUTOFS_INF_EXPIRING)) {
306 DPRINTK("waiting for expire %p name=%.*s", 250 DPRINTK("waiting for expire %p name=%.*s",
307 dentry, dentry->d_name.len, dentry->d_name.name); 251 dentry, dentry->d_name.len, dentry->d_name.name);
308 252
309 status = autofs4_wait(sbi, dentry, NFY_NONE); 253 status = autofs4_wait(sbi, dentry, NFY_NONE);
310 254
311 DPRINTK("expire done status=%d", status); 255 DPRINTK("expire done status=%d", status);
312 256
313 /* 257 /*
314 * If the directory still exists the mount request must 258 * If the directory still exists the mount request must
315 * continue otherwise it can't be followed at the right 259 * continue otherwise it can't be followed at the right
@@ -317,34 +261,36 @@ static int try_to_fill_dentry(struct vfsmount *mnt, struct dentry *dentry, int f
317 */ 261 */
318 status = d_invalidate(dentry); 262 status = d_invalidate(dentry);
319 if (status != -EBUSY) 263 if (status != -EBUSY)
320 return 0; 264 return -ENOENT;
321 } 265 }
322 266
323 DPRINTK("dentry=%p %.*s ino=%p", 267 DPRINTK("dentry=%p %.*s ino=%p",
324 dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode); 268 dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode);
325 269
326 /* Wait for a pending mount, triggering one if there isn't one already */ 270 /*
271 * Wait for a pending mount, triggering one if there
272 * isn't one already
273 */
327 if (dentry->d_inode == NULL) { 274 if (dentry->d_inode == NULL) {
328 DPRINTK("waiting for mount name=%.*s", 275 DPRINTK("waiting for mount name=%.*s",
329 dentry->d_name.len, dentry->d_name.name); 276 dentry->d_name.len, dentry->d_name.name);
330 277
331 status = autofs4_wait(sbi, dentry, NFY_MOUNT); 278 status = autofs4_wait(sbi, dentry, NFY_MOUNT);
332 279
333 DPRINTK("mount done status=%d", status); 280 DPRINTK("mount done status=%d", status);
334 281
335 if (status && dentry->d_inode) 282 if (status && dentry->d_inode)
336 return 0; /* Try to get the kernel to invalidate this dentry */ 283 return status; /* Try to get the kernel to invalidate this dentry */
337 284
338 /* Turn this into a real negative dentry? */ 285 /* Turn this into a real negative dentry? */
339 if (status == -ENOENT) { 286 if (status == -ENOENT) {
340 dentry->d_time = jiffies + AUTOFS_NEGATIVE_TIMEOUT;
341 spin_lock(&dentry->d_lock); 287 spin_lock(&dentry->d_lock);
342 dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; 288 dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
343 spin_unlock(&dentry->d_lock); 289 spin_unlock(&dentry->d_lock);
344 return 1; 290 return status;
345 } else if (status) { 291 } else if (status) {
346 /* Return a negative dentry, but leave it "pending" */ 292 /* Return a negative dentry, but leave it "pending" */
347 return 1; 293 return status;
348 } 294 }
349 /* Trigger mount for path component or follow link */ 295 /* Trigger mount for path component or follow link */
350 } else if (flags & (LOOKUP_CONTINUE | LOOKUP_DIRECTORY) || 296 } else if (flags & (LOOKUP_CONTINUE | LOOKUP_DIRECTORY) ||
@@ -363,19 +309,87 @@ static int try_to_fill_dentry(struct vfsmount *mnt, struct dentry *dentry, int f
363 spin_lock(&dentry->d_lock); 309 spin_lock(&dentry->d_lock);
364 dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; 310 dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
365 spin_unlock(&dentry->d_lock); 311 spin_unlock(&dentry->d_lock);
366 return 0; 312 return status;
367 } 313 }
368 } 314 }
369 315
370 /* We don't update the usages for the autofs daemon itself, this 316 /* Initialize expiry counter after successful mount */
371 is necessary for recursive autofs mounts */ 317 if (ino)
372 if (!autofs4_oz_mode(sbi)) 318 ino->last_used = jiffies;
373 autofs4_update_usage(mnt, dentry);
374 319
375 spin_lock(&dentry->d_lock); 320 spin_lock(&dentry->d_lock);
376 dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; 321 dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
377 spin_unlock(&dentry->d_lock); 322 spin_unlock(&dentry->d_lock);
378 return 1; 323 return status;
324}
325
326/* For autofs direct mounts the follow link triggers the mount */
327static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
328{
329 struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
330 int oz_mode = autofs4_oz_mode(sbi);
331 unsigned int lookup_type;
332 int status;
333
334 DPRINTK("dentry=%p %.*s oz_mode=%d nd->flags=%d",
335 dentry, dentry->d_name.len, dentry->d_name.name, oz_mode,
336 nd->flags);
337
338 /* If it's our master or we shouldn't trigger a mount we're done */
339 lookup_type = nd->flags & (LOOKUP_CONTINUE | LOOKUP_DIRECTORY);
340 if (oz_mode || !lookup_type)
341 goto done;
342
343 /*
344 * If a request is pending wait for it.
345 * If it's a mount then it won't be expired till at least
346 * a liitle later and if it's an expire then we might need
347 * to mount it again.
348 */
349 if (autofs4_ispending(dentry)) {
350 DPRINTK("waiting for active request %p name=%.*s",
351 dentry, dentry->d_name.len, dentry->d_name.name);
352
353 status = autofs4_wait(sbi, dentry, NFY_NONE);
354
355 DPRINTK("request done status=%d", status);
356 }
357
358 /*
359 * If the dentry contains directories then it is an
360 * autofs multi-mount with no root mount offset. So
361 * don't try to mount it again.
362 */
363 spin_lock(&dcache_lock);
364 if (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) {
365 spin_unlock(&dcache_lock);
366
367 status = try_to_fill_dentry(dentry, 0);
368 if (status)
369 goto out_error;
370
371 /*
372 * The mount succeeded but if there is no root mount
373 * it must be an autofs multi-mount with no root offset
374 * so we don't need to follow the mount.
375 */
376 if (d_mountpoint(dentry)) {
377 if (!autofs4_follow_mount(&nd->mnt, &nd->dentry)) {
378 status = -ENOENT;
379 goto out_error;
380 }
381 }
382
383 goto done;
384 }
385 spin_unlock(&dcache_lock);
386
387done:
388 return NULL;
389
390out_error:
391 path_release(nd);
392 return ERR_PTR(status);
379} 393}
380 394
381/* 395/*
@@ -384,47 +398,43 @@ static int try_to_fill_dentry(struct vfsmount *mnt, struct dentry *dentry, int f
384 * yet completely filled in, and revalidate has to delay such 398 * yet completely filled in, and revalidate has to delay such
385 * lookups.. 399 * lookups..
386 */ 400 */
387static int autofs4_revalidate(struct dentry * dentry, struct nameidata *nd) 401static int autofs4_revalidate(struct dentry *dentry, struct nameidata *nd)
388{ 402{
389 struct inode * dir = dentry->d_parent->d_inode; 403 struct inode *dir = dentry->d_parent->d_inode;
390 struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb); 404 struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
391 int oz_mode = autofs4_oz_mode(sbi); 405 int oz_mode = autofs4_oz_mode(sbi);
392 int flags = nd ? nd->flags : 0; 406 int flags = nd ? nd->flags : 0;
393 int status = 1; 407 int status = 0;
394 408
395 /* Pending dentry */ 409 /* Pending dentry */
396 if (autofs4_ispending(dentry)) { 410 if (autofs4_ispending(dentry)) {
397 if (!oz_mode) 411 if (!oz_mode)
398 status = try_to_fill_dentry(nd->mnt, dentry, flags); 412 status = try_to_fill_dentry(dentry, flags);
399 return status; 413 return !status;
400 } 414 }
401 415
402 /* Negative dentry.. invalidate if "old" */ 416 /* Negative dentry.. invalidate if "old" */
403 if (dentry->d_inode == NULL) 417 if (dentry->d_inode == NULL)
404 return (dentry->d_time - jiffies <= AUTOFS_NEGATIVE_TIMEOUT); 418 return 0;
405 419
406 /* Check for a non-mountpoint directory with no contents */ 420 /* Check for a non-mountpoint directory with no contents */
407 spin_lock(&dcache_lock); 421 spin_lock(&dcache_lock);
408 if (S_ISDIR(dentry->d_inode->i_mode) && 422 if (S_ISDIR(dentry->d_inode->i_mode) &&
409 !d_mountpoint(dentry) && 423 !d_mountpoint(dentry) &&
410 list_empty(&dentry->d_subdirs)) { 424 __simple_empty(dentry)) {
411 DPRINTK("dentry=%p %.*s, emptydir", 425 DPRINTK("dentry=%p %.*s, emptydir",
412 dentry, dentry->d_name.len, dentry->d_name.name); 426 dentry, dentry->d_name.len, dentry->d_name.name);
413 spin_unlock(&dcache_lock); 427 spin_unlock(&dcache_lock);
414 if (!oz_mode) 428 if (!oz_mode)
415 status = try_to_fill_dentry(nd->mnt, dentry, flags); 429 status = try_to_fill_dentry(dentry, flags);
416 return status; 430 return !status;
417 } 431 }
418 spin_unlock(&dcache_lock); 432 spin_unlock(&dcache_lock);
419 433
420 /* Update the usage list */
421 if (!oz_mode)
422 autofs4_update_usage(nd->mnt, dentry);
423
424 return 1; 434 return 1;
425} 435}
426 436
427static void autofs4_dentry_release(struct dentry *de) 437void autofs4_dentry_release(struct dentry *de)
428{ 438{
429 struct autofs_info *inf; 439 struct autofs_info *inf;
430 440
@@ -462,12 +472,13 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s
462 DPRINTK("name = %.*s", 472 DPRINTK("name = %.*s",
463 dentry->d_name.len, dentry->d_name.name); 473 dentry->d_name.len, dentry->d_name.name);
464 474
475 /* File name too long to exist */
465 if (dentry->d_name.len > NAME_MAX) 476 if (dentry->d_name.len > NAME_MAX)
466 return ERR_PTR(-ENAMETOOLONG);/* File name too long to exist */ 477 return ERR_PTR(-ENAMETOOLONG);
467 478
468 sbi = autofs4_sbi(dir->i_sb); 479 sbi = autofs4_sbi(dir->i_sb);
469
470 oz_mode = autofs4_oz_mode(sbi); 480 oz_mode = autofs4_oz_mode(sbi);
481
471 DPRINTK("pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d", 482 DPRINTK("pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d",
472 current->pid, process_group(current), sbi->catatonic, oz_mode); 483 current->pid, process_group(current), sbi->catatonic, oz_mode);
473 484
@@ -519,7 +530,7 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s
519 * doesn't do the right thing for all system calls, but it should 530 * doesn't do the right thing for all system calls, but it should
520 * be OK for the operations we permit from an autofs. 531 * be OK for the operations we permit from an autofs.
521 */ 532 */
522 if ( dentry->d_inode && d_unhashed(dentry) ) 533 if (dentry->d_inode && d_unhashed(dentry))
523 return ERR_PTR(-ENOENT); 534 return ERR_PTR(-ENOENT);
524 535
525 return NULL; 536 return NULL;
@@ -531,6 +542,7 @@ static int autofs4_dir_symlink(struct inode *dir,
531{ 542{
532 struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb); 543 struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
533 struct autofs_info *ino = autofs4_dentry_ino(dentry); 544 struct autofs_info *ino = autofs4_dentry_ino(dentry);
545 struct autofs_info *p_ino;
534 struct inode *inode; 546 struct inode *inode;
535 char *cp; 547 char *cp;
536 548
@@ -564,6 +576,10 @@ static int autofs4_dir_symlink(struct inode *dir,
564 576
565 dentry->d_fsdata = ino; 577 dentry->d_fsdata = ino;
566 ino->dentry = dget(dentry); 578 ino->dentry = dget(dentry);
579 atomic_inc(&ino->count);
580 p_ino = autofs4_dentry_ino(dentry->d_parent);
581 if (p_ino && dentry->d_parent != dentry)
582 atomic_inc(&p_ino->count);
567 ino->inode = inode; 583 ino->inode = inode;
568 584
569 dir->i_mtime = CURRENT_TIME; 585 dir->i_mtime = CURRENT_TIME;
@@ -590,11 +606,17 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry)
590{ 606{
591 struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb); 607 struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
592 struct autofs_info *ino = autofs4_dentry_ino(dentry); 608 struct autofs_info *ino = autofs4_dentry_ino(dentry);
609 struct autofs_info *p_ino;
593 610
594 /* This allows root to remove symlinks */ 611 /* This allows root to remove symlinks */
595 if ( !autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN) ) 612 if ( !autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN) )
596 return -EACCES; 613 return -EACCES;
597 614
615 if (atomic_dec_and_test(&ino->count)) {
616 p_ino = autofs4_dentry_ino(dentry->d_parent);
617 if (p_ino && dentry->d_parent != dentry)
618 atomic_dec(&p_ino->count);
619 }
598 dput(ino->dentry); 620 dput(ino->dentry);
599 621
600 dentry->d_inode->i_size = 0; 622 dentry->d_inode->i_size = 0;
@@ -611,6 +633,7 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry)
611{ 633{
612 struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb); 634 struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
613 struct autofs_info *ino = autofs4_dentry_ino(dentry); 635 struct autofs_info *ino = autofs4_dentry_ino(dentry);
636 struct autofs_info *p_ino;
614 637
615 if (!autofs4_oz_mode(sbi)) 638 if (!autofs4_oz_mode(sbi))
616 return -EACCES; 639 return -EACCES;
@@ -625,8 +648,12 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry)
625 spin_unlock(&dentry->d_lock); 648 spin_unlock(&dentry->d_lock);
626 spin_unlock(&dcache_lock); 649 spin_unlock(&dcache_lock);
627 650
651 if (atomic_dec_and_test(&ino->count)) {
652 p_ino = autofs4_dentry_ino(dentry->d_parent);
653 if (p_ino && dentry->d_parent != dentry)
654 atomic_dec(&p_ino->count);
655 }
628 dput(ino->dentry); 656 dput(ino->dentry);
629
630 dentry->d_inode->i_size = 0; 657 dentry->d_inode->i_size = 0;
631 dentry->d_inode->i_nlink = 0; 658 dentry->d_inode->i_nlink = 0;
632 659
@@ -640,6 +667,7 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode)
640{ 667{
641 struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb); 668 struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
642 struct autofs_info *ino = autofs4_dentry_ino(dentry); 669 struct autofs_info *ino = autofs4_dentry_ino(dentry);
670 struct autofs_info *p_ino;
643 struct inode *inode; 671 struct inode *inode;
644 672
645 if ( !autofs4_oz_mode(sbi) ) 673 if ( !autofs4_oz_mode(sbi) )
@@ -662,6 +690,10 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode)
662 690
663 dentry->d_fsdata = ino; 691 dentry->d_fsdata = ino;
664 ino->dentry = dget(dentry); 692 ino->dentry = dget(dentry);
693 atomic_inc(&ino->count);
694 p_ino = autofs4_dentry_ino(dentry->d_parent);
695 if (p_ino && dentry->d_parent != dentry)
696 atomic_inc(&p_ino->count);
665 ino->inode = inode; 697 ino->inode = inode;
666 dir->i_nlink++; 698 dir->i_nlink++;
667 dir->i_mtime = CURRENT_TIME; 699 dir->i_mtime = CURRENT_TIME;
@@ -745,7 +777,7 @@ static inline int autofs4_ask_umount(struct vfsmount *mnt, int __user *p)
745{ 777{
746 int status = 0; 778 int status = 0;
747 779
748 if (may_umount(mnt) == 0) 780 if (may_umount(mnt))
749 status = 1; 781 status = 1;
750 782
751 DPRINTK("returning %d", status); 783 DPRINTK("returning %d", status);
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index be78e9378c03..142ab6aa2aa1 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -3,7 +3,7 @@
3 * linux/fs/autofs/waitq.c 3 * linux/fs/autofs/waitq.c
4 * 4 *
5 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved 5 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
6 * Copyright 2001-2003 Ian Kent <raven@themaw.net> 6 * Copyright 2001-2006 Ian Kent <raven@themaw.net>
7 * 7 *
8 * This file is part of the Linux kernel and is made available under 8 * This file is part of the Linux kernel and is made available under
9 * the terms of the GNU General Public License, version 2, or at your 9 * the terms of the GNU General Public License, version 2, or at your
@@ -33,7 +33,7 @@ void autofs4_catatonic_mode(struct autofs_sb_info *sbi)
33 sbi->catatonic = 1; 33 sbi->catatonic = 1;
34 wq = sbi->queues; 34 wq = sbi->queues;
35 sbi->queues = NULL; /* Erase all wait queues */ 35 sbi->queues = NULL; /* Erase all wait queues */
36 while ( wq ) { 36 while (wq) {
37 nwq = wq->next; 37 nwq = wq->next;
38 wq->status = -ENOENT; /* Magic is gone - report failure */ 38 wq->status = -ENOENT; /* Magic is gone - report failure */
39 kfree(wq->name); 39 kfree(wq->name);
@@ -45,7 +45,6 @@ void autofs4_catatonic_mode(struct autofs_sb_info *sbi)
45 fput(sbi->pipe); /* Close the pipe */ 45 fput(sbi->pipe); /* Close the pipe */
46 sbi->pipe = NULL; 46 sbi->pipe = NULL;
47 } 47 }
48
49 shrink_dcache_sb(sbi->sb); 48 shrink_dcache_sb(sbi->sb);
50} 49}
51 50
@@ -98,7 +97,10 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
98 97
99 pkt.hdr.proto_version = sbi->version; 98 pkt.hdr.proto_version = sbi->version;
100 pkt.hdr.type = type; 99 pkt.hdr.type = type;
101 if (type == autofs_ptype_missing) { 100 switch (type) {
101 /* Kernel protocol v4 missing and expire packets */
102 case autofs_ptype_missing:
103 {
102 struct autofs_packet_missing *mp = &pkt.missing; 104 struct autofs_packet_missing *mp = &pkt.missing;
103 105
104 pktsz = sizeof(*mp); 106 pktsz = sizeof(*mp);
@@ -107,7 +109,10 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
107 mp->len = wq->len; 109 mp->len = wq->len;
108 memcpy(mp->name, wq->name, wq->len); 110 memcpy(mp->name, wq->name, wq->len);
109 mp->name[wq->len] = '\0'; 111 mp->name[wq->len] = '\0';
110 } else if (type == autofs_ptype_expire_multi) { 112 break;
113 }
114 case autofs_ptype_expire_multi:
115 {
111 struct autofs_packet_expire_multi *ep = &pkt.expire_multi; 116 struct autofs_packet_expire_multi *ep = &pkt.expire_multi;
112 117
113 pktsz = sizeof(*ep); 118 pktsz = sizeof(*ep);
@@ -116,7 +121,34 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
116 ep->len = wq->len; 121 ep->len = wq->len;
117 memcpy(ep->name, wq->name, wq->len); 122 memcpy(ep->name, wq->name, wq->len);
118 ep->name[wq->len] = '\0'; 123 ep->name[wq->len] = '\0';
119 } else { 124 break;
125 }
126 /*
127 * Kernel protocol v5 packet for handling indirect and direct
128 * mount missing and expire requests
129 */
130 case autofs_ptype_missing_indirect:
131 case autofs_ptype_expire_indirect:
132 case autofs_ptype_missing_direct:
133 case autofs_ptype_expire_direct:
134 {
135 struct autofs_v5_packet *packet = &pkt.v5_packet;
136
137 pktsz = sizeof(*packet);
138
139 packet->wait_queue_token = wq->wait_queue_token;
140 packet->len = wq->len;
141 memcpy(packet->name, wq->name, wq->len);
142 packet->name[wq->len] = '\0';
143 packet->dev = wq->dev;
144 packet->ino = wq->ino;
145 packet->uid = wq->uid;
146 packet->gid = wq->gid;
147 packet->pid = wq->pid;
148 packet->tgid = wq->tgid;
149 break;
150 }
151 default:
120 printk("autofs4_notify_daemon: bad type %d!\n", type); 152 printk("autofs4_notify_daemon: bad type %d!\n", type);
121 return; 153 return;
122 } 154 }
@@ -162,21 +194,29 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
162{ 194{
163 struct autofs_wait_queue *wq; 195 struct autofs_wait_queue *wq;
164 char *name; 196 char *name;
165 int len, status; 197 unsigned int len = 0;
198 unsigned int hash = 0;
199 int status;
166 200
167 /* In catatonic mode, we don't wait for nobody */ 201 /* In catatonic mode, we don't wait for nobody */
168 if ( sbi->catatonic ) 202 if (sbi->catatonic)
169 return -ENOENT; 203 return -ENOENT;
170 204
171 name = kmalloc(NAME_MAX + 1, GFP_KERNEL); 205 name = kmalloc(NAME_MAX + 1, GFP_KERNEL);
172 if (!name) 206 if (!name)
173 return -ENOMEM; 207 return -ENOMEM;
174 208
175 len = autofs4_getpath(sbi, dentry, &name); 209 /* If this is a direct mount request create a dummy name */
176 if (!len) { 210 if (IS_ROOT(dentry) && (sbi->type & AUTOFS_TYPE_DIRECT))
177 kfree(name); 211 len = sprintf(name, "%p", dentry);
178 return -ENOENT; 212 else {
213 len = autofs4_getpath(sbi, dentry, &name);
214 if (!len) {
215 kfree(name);
216 return -ENOENT;
217 }
179 } 218 }
219 hash = full_name_hash(name, len);
180 220
181 if (mutex_lock_interruptible(&sbi->wq_mutex)) { 221 if (mutex_lock_interruptible(&sbi->wq_mutex)) {
182 kfree(name); 222 kfree(name);
@@ -190,7 +230,7 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
190 break; 230 break;
191 } 231 }
192 232
193 if ( !wq ) { 233 if (!wq) {
194 /* Can't wait for an expire if there's no mount */ 234 /* Can't wait for an expire if there's no mount */
195 if (notify == NFY_NONE && !d_mountpoint(dentry)) { 235 if (notify == NFY_NONE && !d_mountpoint(dentry)) {
196 kfree(name); 236 kfree(name);
@@ -200,7 +240,7 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
200 240
201 /* Create a new wait queue */ 241 /* Create a new wait queue */
202 wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL); 242 wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL);
203 if ( !wq ) { 243 if (!wq) {
204 kfree(name); 244 kfree(name);
205 mutex_unlock(&sbi->wq_mutex); 245 mutex_unlock(&sbi->wq_mutex);
206 return -ENOMEM; 246 return -ENOMEM;
@@ -212,12 +252,18 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
212 wq->next = sbi->queues; 252 wq->next = sbi->queues;
213 sbi->queues = wq; 253 sbi->queues = wq;
214 init_waitqueue_head(&wq->queue); 254 init_waitqueue_head(&wq->queue);
215 wq->hash = dentry->d_name.hash; 255 wq->hash = hash;
216 wq->name = name; 256 wq->name = name;
217 wq->len = len; 257 wq->len = len;
258 wq->dev = autofs4_get_dev(sbi);
259 wq->ino = autofs4_get_ino(sbi);
260 wq->uid = current->uid;
261 wq->gid = current->gid;
262 wq->pid = current->pid;
263 wq->tgid = current->tgid;
218 wq->status = -EINTR; /* Status return if interrupted */ 264 wq->status = -EINTR; /* Status return if interrupted */
219 atomic_set(&wq->wait_ctr, 2); 265 atomic_set(&wq->wait_ctr, 2);
220 atomic_set(&wq->notified, 1); 266 atomic_set(&wq->notify, 1);
221 mutex_unlock(&sbi->wq_mutex); 267 mutex_unlock(&sbi->wq_mutex);
222 } else { 268 } else {
223 atomic_inc(&wq->wait_ctr); 269 atomic_inc(&wq->wait_ctr);
@@ -227,9 +273,26 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
227 (unsigned long) wq->wait_queue_token, wq->len, wq->name, notify); 273 (unsigned long) wq->wait_queue_token, wq->len, wq->name, notify);
228 } 274 }
229 275
230 if (notify != NFY_NONE && atomic_dec_and_test(&wq->notified)) { 276 if (notify != NFY_NONE && atomic_read(&wq->notify)) {
231 int type = (notify == NFY_MOUNT ? 277 int type;
232 autofs_ptype_missing : autofs_ptype_expire_multi); 278
279 atomic_dec(&wq->notify);
280
281 if (sbi->version < 5) {
282 if (notify == NFY_MOUNT)
283 type = autofs_ptype_missing;
284 else
285 type = autofs_ptype_expire_multi;
286 } else {
287 if (notify == NFY_MOUNT)
288 type = (sbi->type & AUTOFS_TYPE_DIRECT) ?
289 autofs_ptype_missing_direct :
290 autofs_ptype_missing_indirect;
291 else
292 type = (sbi->type & AUTOFS_TYPE_DIRECT) ?
293 autofs_ptype_expire_direct :
294 autofs_ptype_expire_indirect;
295 }
233 296
234 DPRINTK("new wait id = 0x%08lx, name = %.*s, nfy=%d\n", 297 DPRINTK("new wait id = 0x%08lx, name = %.*s, nfy=%d\n",
235 (unsigned long) wq->wait_queue_token, wq->len, wq->name, notify); 298 (unsigned long) wq->wait_queue_token, wq->len, wq->name, notify);
@@ -240,14 +303,14 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
240 303
241 /* wq->name is NULL if and only if the lock is already released */ 304 /* wq->name is NULL if and only if the lock is already released */
242 305
243 if ( sbi->catatonic ) { 306 if (sbi->catatonic) {
244 /* We might have slept, so check again for catatonic mode */ 307 /* We might have slept, so check again for catatonic mode */
245 wq->status = -ENOENT; 308 wq->status = -ENOENT;
246 kfree(wq->name); 309 kfree(wq->name);
247 wq->name = NULL; 310 wq->name = NULL;
248 } 311 }
249 312
250 if ( wq->name ) { 313 if (wq->name) {
251 /* Block all but "shutdown" signals while waiting */ 314 /* Block all but "shutdown" signals while waiting */
252 sigset_t oldset; 315 sigset_t oldset;
253 unsigned long irqflags; 316 unsigned long irqflags;
@@ -283,12 +346,12 @@ int autofs4_wait_release(struct autofs_sb_info *sbi, autofs_wqt_t wait_queue_tok
283 struct autofs_wait_queue *wq, **wql; 346 struct autofs_wait_queue *wq, **wql;
284 347
285 mutex_lock(&sbi->wq_mutex); 348 mutex_lock(&sbi->wq_mutex);
286 for ( wql = &sbi->queues ; (wq = *wql) != 0 ; wql = &wq->next ) { 349 for (wql = &sbi->queues ; (wq = *wql) != 0 ; wql = &wq->next) {
287 if ( wq->wait_queue_token == wait_queue_token ) 350 if (wq->wait_queue_token == wait_queue_token)
288 break; 351 break;
289 } 352 }
290 353
291 if ( !wq ) { 354 if (!wq) {
292 mutex_unlock(&sbi->wq_mutex); 355 mutex_unlock(&sbi->wq_mutex);
293 return -EINVAL; 356 return -EINVAL;
294 } 357 }
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 5983d42df015..17c76182f389 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -266,6 +266,9 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
266 mutex_init(&bdev->bd_mount_mutex); 266 mutex_init(&bdev->bd_mount_mutex);
267 INIT_LIST_HEAD(&bdev->bd_inodes); 267 INIT_LIST_HEAD(&bdev->bd_inodes);
268 INIT_LIST_HEAD(&bdev->bd_list); 268 INIT_LIST_HEAD(&bdev->bd_list);
269#ifdef CONFIG_SYSFS
270 INIT_LIST_HEAD(&bdev->bd_holder_list);
271#endif
269 inode_init_once(&ei->vfs_inode); 272 inode_init_once(&ei->vfs_inode);
270 } 273 }
271} 274}
@@ -490,6 +493,300 @@ void bd_release(struct block_device *bdev)
490 493
491EXPORT_SYMBOL(bd_release); 494EXPORT_SYMBOL(bd_release);
492 495
496#ifdef CONFIG_SYSFS
497/*
498 * Functions for bd_claim_by_kobject / bd_release_from_kobject
499 *
500 * If a kobject is passed to bd_claim_by_kobject()
501 * and the kobject has a parent directory,
502 * following symlinks are created:
503 * o from the kobject to the claimed bdev
504 * o from "holders" directory of the bdev to the parent of the kobject
505 * bd_release_from_kobject() removes these symlinks.
506 *
507 * Example:
508 * If /dev/dm-0 maps to /dev/sda, kobject corresponding to
509 * /sys/block/dm-0/slaves is passed to bd_claim_by_kobject(), then:
510 * /sys/block/dm-0/slaves/sda --> /sys/block/sda
511 * /sys/block/sda/holders/dm-0 --> /sys/block/dm-0
512 */
513
514static struct kobject *bdev_get_kobj(struct block_device *bdev)
515{
516 if (bdev->bd_contains != bdev)
517 return kobject_get(&bdev->bd_part->kobj);
518 else
519 return kobject_get(&bdev->bd_disk->kobj);
520}
521
522static struct kobject *bdev_get_holder(struct block_device *bdev)
523{
524 if (bdev->bd_contains != bdev)
525 return kobject_get(bdev->bd_part->holder_dir);
526 else
527 return kobject_get(bdev->bd_disk->holder_dir);
528}
529
530static void add_symlink(struct kobject *from, struct kobject *to)
531{
532 if (!from || !to)
533 return;
534 sysfs_create_link(from, to, kobject_name(to));
535}
536
537static void del_symlink(struct kobject *from, struct kobject *to)
538{
539 if (!from || !to)
540 return;
541 sysfs_remove_link(from, kobject_name(to));
542}
543
544/*
545 * 'struct bd_holder' contains pointers to kobjects symlinked by
546 * bd_claim_by_kobject.
547 * It's connected to bd_holder_list which is protected by bdev->bd_sem.
548 */
549struct bd_holder {
550 struct list_head list; /* chain of holders of the bdev */
551 int count; /* references from the holder */
552 struct kobject *sdir; /* holder object, e.g. "/block/dm-0/slaves" */
553 struct kobject *hdev; /* e.g. "/block/dm-0" */
554 struct kobject *hdir; /* e.g. "/block/sda/holders" */
555 struct kobject *sdev; /* e.g. "/block/sda" */
556};
557
558/*
559 * Get references of related kobjects at once.
560 * Returns 1 on success. 0 on failure.
561 *
562 * Should call bd_holder_release_dirs() after successful use.
563 */
564static int bd_holder_grab_dirs(struct block_device *bdev,
565 struct bd_holder *bo)
566{
567 if (!bdev || !bo)
568 return 0;
569
570 bo->sdir = kobject_get(bo->sdir);
571 if (!bo->sdir)
572 return 0;
573
574 bo->hdev = kobject_get(bo->sdir->parent);
575 if (!bo->hdev)
576 goto fail_put_sdir;
577
578 bo->sdev = bdev_get_kobj(bdev);
579 if (!bo->sdev)
580 goto fail_put_hdev;
581
582 bo->hdir = bdev_get_holder(bdev);
583 if (!bo->hdir)
584 goto fail_put_sdev;
585
586 return 1;
587
588fail_put_sdev:
589 kobject_put(bo->sdev);
590fail_put_hdev:
591 kobject_put(bo->hdev);
592fail_put_sdir:
593 kobject_put(bo->sdir);
594
595 return 0;
596}
597
598/* Put references of related kobjects at once. */
599static void bd_holder_release_dirs(struct bd_holder *bo)
600{
601 kobject_put(bo->hdir);
602 kobject_put(bo->sdev);
603 kobject_put(bo->hdev);
604 kobject_put(bo->sdir);
605}
606
607static struct bd_holder *alloc_bd_holder(struct kobject *kobj)
608{
609 struct bd_holder *bo;
610
611 bo = kzalloc(sizeof(*bo), GFP_KERNEL);
612 if (!bo)
613 return NULL;
614
615 bo->count = 1;
616 bo->sdir = kobj;
617
618 return bo;
619}
620
621static void free_bd_holder(struct bd_holder *bo)
622{
623 kfree(bo);
624}
625
626/**
627 * add_bd_holder - create sysfs symlinks for bd_claim() relationship
628 *
629 * @bdev: block device to be bd_claimed
630 * @bo: preallocated and initialized by alloc_bd_holder()
631 *
632 * If there is no matching entry with @bo in @bdev->bd_holder_list,
633 * add @bo to the list, create symlinks.
634 *
635 * Returns 1 if @bo was added to the list.
636 * Returns 0 if @bo wasn't used by any reason and should be freed.
637 */
638static int add_bd_holder(struct block_device *bdev, struct bd_holder *bo)
639{
640 struct bd_holder *tmp;
641
642 if (!bo)
643 return 0;
644
645 list_for_each_entry(tmp, &bdev->bd_holder_list, list) {
646 if (tmp->sdir == bo->sdir) {
647 tmp->count++;
648 return 0;
649 }
650 }
651
652 if (!bd_holder_grab_dirs(bdev, bo))
653 return 0;
654
655 add_symlink(bo->sdir, bo->sdev);
656 add_symlink(bo->hdir, bo->hdev);
657 list_add_tail(&bo->list, &bdev->bd_holder_list);
658 return 1;
659}
660
661/**
662 * del_bd_holder - delete sysfs symlinks for bd_claim() relationship
663 *
664 * @bdev: block device to be bd_claimed
665 * @kobj: holder's kobject
666 *
667 * If there is matching entry with @kobj in @bdev->bd_holder_list
668 * and no other bd_claim() from the same kobject,
669 * remove the struct bd_holder from the list, delete symlinks for it.
670 *
671 * Returns a pointer to the struct bd_holder when it's removed from the list
672 * and ready to be freed.
673 * Returns NULL if matching claim isn't found or there is other bd_claim()
674 * by the same kobject.
675 */
676static struct bd_holder *del_bd_holder(struct block_device *bdev,
677 struct kobject *kobj)
678{
679 struct bd_holder *bo;
680
681 list_for_each_entry(bo, &bdev->bd_holder_list, list) {
682 if (bo->sdir == kobj) {
683 bo->count--;
684 BUG_ON(bo->count < 0);
685 if (!bo->count) {
686 list_del(&bo->list);
687 del_symlink(bo->sdir, bo->sdev);
688 del_symlink(bo->hdir, bo->hdev);
689 bd_holder_release_dirs(bo);
690 return bo;
691 }
692 break;
693 }
694 }
695
696 return NULL;
697}
698
699/**
700 * bd_claim_by_kobject - bd_claim() with additional kobject signature
701 *
702 * @bdev: block device to be claimed
703 * @holder: holder's signature
704 * @kobj: holder's kobject
705 *
706 * Do bd_claim() and if it succeeds, create sysfs symlinks between
707 * the bdev and the holder's kobject.
708 * Use bd_release_from_kobject() when relesing the claimed bdev.
709 *
710 * Returns 0 on success. (same as bd_claim())
711 * Returns errno on failure.
712 */
713static int bd_claim_by_kobject(struct block_device *bdev, void *holder,
714 struct kobject *kobj)
715{
716 int res;
717 struct bd_holder *bo;
718
719 if (!kobj)
720 return -EINVAL;
721
722 bo = alloc_bd_holder(kobj);
723 if (!bo)
724 return -ENOMEM;
725
726 mutex_lock(&bdev->bd_mutex);
727 res = bd_claim(bdev, holder);
728 if (res || !add_bd_holder(bdev, bo))
729 free_bd_holder(bo);
730 mutex_unlock(&bdev->bd_mutex);
731
732 return res;
733}
734
735/**
736 * bd_release_from_kobject - bd_release() with additional kobject signature
737 *
738 * @bdev: block device to be released
739 * @kobj: holder's kobject
740 *
741 * Do bd_release() and remove sysfs symlinks created by bd_claim_by_kobject().
742 */
743static void bd_release_from_kobject(struct block_device *bdev,
744 struct kobject *kobj)
745{
746 struct bd_holder *bo;
747
748 if (!kobj)
749 return;
750
751 mutex_lock(&bdev->bd_mutex);
752 bd_release(bdev);
753 if ((bo = del_bd_holder(bdev, kobj)))
754 free_bd_holder(bo);
755 mutex_unlock(&bdev->bd_mutex);
756}
757
758/**
759 * bd_claim_by_disk - wrapper function for bd_claim_by_kobject()
760 *
761 * @bdev: block device to be claimed
762 * @holder: holder's signature
763 * @disk: holder's gendisk
764 *
765 * Call bd_claim_by_kobject() with getting @disk->slave_dir.
766 */
767int bd_claim_by_disk(struct block_device *bdev, void *holder,
768 struct gendisk *disk)
769{
770 return bd_claim_by_kobject(bdev, holder, kobject_get(disk->slave_dir));
771}
772EXPORT_SYMBOL_GPL(bd_claim_by_disk);
773
774/**
775 * bd_release_from_disk - wrapper function for bd_release_from_kobject()
776 *
777 * @bdev: block device to be claimed
778 * @disk: holder's gendisk
779 *
780 * Call bd_release_from_kobject() and put @disk->slave_dir.
781 */
782void bd_release_from_disk(struct block_device *bdev, struct gendisk *disk)
783{
784 bd_release_from_kobject(bdev, disk->slave_dir);
785 kobject_put(disk->slave_dir);
786}
787EXPORT_SYMBOL_GPL(bd_release_from_disk);
788#endif
789
493/* 790/*
494 * Tries to open block device by device number. Use it ONLY if you 791 * Tries to open block device by device number. Use it ONLY if you
495 * really do not have anything better - i.e. when you are behind a 792 * really do not have anything better - i.e. when you are behind a
diff --git a/fs/buffer.c b/fs/buffer.c
index d597758dd129..23f1f3a68077 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -493,7 +493,7 @@ static void free_more_memory(void)
493 wakeup_pdflush(1024); 493 wakeup_pdflush(1024);
494 yield(); 494 yield();
495 495
496 for_each_pgdat(pgdat) { 496 for_each_online_pgdat(pgdat) {
497 zones = pgdat->node_zonelists[gfp_zone(GFP_NOFS)].zones; 497 zones = pgdat->node_zonelists[gfp_zone(GFP_NOFS)].zones;
498 if (*zones) 498 if (*zones)
499 try_to_free_pages(zones, GFP_NOFS); 499 try_to_free_pages(zones, GFP_NOFS);
diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c
index b97809deba66..23b7cee72123 100644
--- a/fs/hostfs/hostfs_user.c
+++ b/fs/hostfs/hostfs_user.c
@@ -360,7 +360,6 @@ int do_statfs(char *root, long *bsize_out, long long *blocks_out,
360 spare_out[2] = buf.f_spare[2]; 360 spare_out[2] = buf.f_spare[2];
361 spare_out[3] = buf.f_spare[3]; 361 spare_out[3] = buf.f_spare[3];
362 spare_out[4] = buf.f_spare[4]; 362 spare_out[4] = buf.f_spare[4];
363 spare_out[5] = buf.f_spare[5];
364 return(0); 363 return(0);
365} 364}
366 365
diff --git a/fs/namei.c b/fs/namei.c
index 98dc2e134362..22f6e8d16aa8 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -546,6 +546,22 @@ struct path {
546 struct dentry *dentry; 546 struct dentry *dentry;
547}; 547};
548 548
549static inline void dput_path(struct path *path, struct nameidata *nd)
550{
551 dput(path->dentry);
552 if (path->mnt != nd->mnt)
553 mntput(path->mnt);
554}
555
556static inline void path_to_nameidata(struct path *path, struct nameidata *nd)
557{
558 dput(nd->dentry);
559 if (nd->mnt != path->mnt)
560 mntput(nd->mnt);
561 nd->mnt = path->mnt;
562 nd->dentry = path->dentry;
563}
564
549static __always_inline int __do_follow_link(struct path *path, struct nameidata *nd) 565static __always_inline int __do_follow_link(struct path *path, struct nameidata *nd)
550{ 566{
551 int error; 567 int error;
@@ -555,8 +571,11 @@ static __always_inline int __do_follow_link(struct path *path, struct nameidata
555 touch_atime(path->mnt, dentry); 571 touch_atime(path->mnt, dentry);
556 nd_set_link(nd, NULL); 572 nd_set_link(nd, NULL);
557 573
558 if (path->mnt == nd->mnt) 574 if (path->mnt != nd->mnt) {
559 mntget(path->mnt); 575 path_to_nameidata(path, nd);
576 dget(dentry);
577 }
578 mntget(path->mnt);
560 cookie = dentry->d_inode->i_op->follow_link(dentry, nd); 579 cookie = dentry->d_inode->i_op->follow_link(dentry, nd);
561 error = PTR_ERR(cookie); 580 error = PTR_ERR(cookie);
562 if (!IS_ERR(cookie)) { 581 if (!IS_ERR(cookie)) {
@@ -573,22 +592,6 @@ static __always_inline int __do_follow_link(struct path *path, struct nameidata
573 return error; 592 return error;
574} 593}
575 594
576static inline void dput_path(struct path *path, struct nameidata *nd)
577{
578 dput(path->dentry);
579 if (path->mnt != nd->mnt)
580 mntput(path->mnt);
581}
582
583static inline void path_to_nameidata(struct path *path, struct nameidata *nd)
584{
585 dput(nd->dentry);
586 if (nd->mnt != path->mnt)
587 mntput(nd->mnt);
588 nd->mnt = path->mnt;
589 nd->dentry = path->dentry;
590}
591
592/* 595/*
593 * This limits recursive symlink follows to 8, while 596 * This limits recursive symlink follows to 8, while
594 * limiting consecutive symlinks to 40. 597 * limiting consecutive symlinks to 40.
diff --git a/fs/namespace.c b/fs/namespace.c
index e069a4c5e389..bf478addb852 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -459,9 +459,9 @@ int may_umount_tree(struct vfsmount *mnt)
459 spin_unlock(&vfsmount_lock); 459 spin_unlock(&vfsmount_lock);
460 460
461 if (actual_refs > minimum_refs) 461 if (actual_refs > minimum_refs)
462 return -EBUSY; 462 return 0;
463 463
464 return 0; 464 return 1;
465} 465}
466 466
467EXPORT_SYMBOL(may_umount_tree); 467EXPORT_SYMBOL(may_umount_tree);
@@ -481,10 +481,10 @@ EXPORT_SYMBOL(may_umount_tree);
481 */ 481 */
482int may_umount(struct vfsmount *mnt) 482int may_umount(struct vfsmount *mnt)
483{ 483{
484 int ret = 0; 484 int ret = 1;
485 spin_lock(&vfsmount_lock); 485 spin_lock(&vfsmount_lock);
486 if (propagate_mount_busy(mnt, 2)) 486 if (propagate_mount_busy(mnt, 2))
487 ret = -EBUSY; 487 ret = 0;
488 spin_unlock(&vfsmount_lock); 488 spin_unlock(&vfsmount_lock);
489 return ret; 489 return ret;
490} 490}
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 417ec02df44f..c340be0a3f59 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -57,27 +57,17 @@ static int exp_verify_string(char *cp, int max);
57#define EXPKEY_HASHMASK (EXPKEY_HASHMAX -1) 57#define EXPKEY_HASHMASK (EXPKEY_HASHMAX -1)
58static struct cache_head *expkey_table[EXPKEY_HASHMAX]; 58static struct cache_head *expkey_table[EXPKEY_HASHMAX];
59 59
60static inline int svc_expkey_hash(struct svc_expkey *item) 60static void expkey_put(struct kref *ref)
61{ 61{
62 int hash = item->ek_fsidtype; 62 struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref);
63 char * cp = (char*)item->ek_fsid;
64 int len = key_len(item->ek_fsidtype);
65 63
66 hash ^= hash_mem(cp, len, EXPKEY_HASHBITS); 64 if (test_bit(CACHE_VALID, &key->h.flags) &&
67 hash ^= hash_ptr(item->ek_client, EXPKEY_HASHBITS); 65 !test_bit(CACHE_NEGATIVE, &key->h.flags)) {
68 return hash & EXPKEY_HASHMASK; 66 dput(key->ek_dentry);
69} 67 mntput(key->ek_mnt);
70
71void expkey_put(struct cache_head *item, struct cache_detail *cd)
72{
73 if (cache_put(item, cd)) {
74 struct svc_expkey *key = container_of(item, struct svc_expkey, h);
75 if (test_bit(CACHE_VALID, &item->flags) &&
76 !test_bit(CACHE_NEGATIVE, &item->flags))
77 exp_put(key->ek_export);
78 auth_domain_put(key->ek_client);
79 kfree(key);
80 } 68 }
69 auth_domain_put(key->ek_client);
70 kfree(key);
81} 71}
82 72
83static void expkey_request(struct cache_detail *cd, 73static void expkey_request(struct cache_detail *cd,
@@ -95,7 +85,10 @@ static void expkey_request(struct cache_detail *cd,
95 (*bpp)[-1] = '\n'; 85 (*bpp)[-1] = '\n';
96} 86}
97 87
98static struct svc_expkey *svc_expkey_lookup(struct svc_expkey *, int); 88static struct svc_expkey *svc_expkey_update(struct svc_expkey *new, struct svc_expkey *old);
89static struct svc_expkey *svc_expkey_lookup(struct svc_expkey *);
90static struct cache_detail svc_expkey_cache;
91
99static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen) 92static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
100{ 93{
101 /* client fsidtype fsid [path] */ 94 /* client fsidtype fsid [path] */
@@ -106,6 +99,7 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
106 int fsidtype; 99 int fsidtype;
107 char *ep; 100 char *ep;
108 struct svc_expkey key; 101 struct svc_expkey key;
102 struct svc_expkey *ek;
109 103
110 if (mesg[mlen-1] != '\n') 104 if (mesg[mlen-1] != '\n')
111 return -EINVAL; 105 return -EINVAL;
@@ -150,40 +144,38 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
150 key.ek_fsidtype = fsidtype; 144 key.ek_fsidtype = fsidtype;
151 memcpy(key.ek_fsid, buf, len); 145 memcpy(key.ek_fsid, buf, len);
152 146
147 ek = svc_expkey_lookup(&key);
148 err = -ENOMEM;
149 if (!ek)
150 goto out;
151
153 /* now we want a pathname, or empty meaning NEGATIVE */ 152 /* now we want a pathname, or empty meaning NEGATIVE */
153 err = -EINVAL;
154 if ((len=qword_get(&mesg, buf, PAGE_SIZE)) < 0) 154 if ((len=qword_get(&mesg, buf, PAGE_SIZE)) < 0)
155 goto out; 155 goto out;
156 dprintk("Path seems to be <%s>\n", buf); 156 dprintk("Path seems to be <%s>\n", buf);
157 err = 0; 157 err = 0;
158 if (len == 0) { 158 if (len == 0) {
159 struct svc_expkey *ek;
160 set_bit(CACHE_NEGATIVE, &key.h.flags); 159 set_bit(CACHE_NEGATIVE, &key.h.flags);
161 ek = svc_expkey_lookup(&key, 1); 160 ek = svc_expkey_update(&key, ek);
162 if (ek) 161 if (ek)
163 expkey_put(&ek->h, &svc_expkey_cache); 162 cache_put(&ek->h, &svc_expkey_cache);
163 else err = -ENOMEM;
164 } else { 164 } else {
165 struct nameidata nd; 165 struct nameidata nd;
166 struct svc_expkey *ek;
167 struct svc_export *exp;
168 err = path_lookup(buf, 0, &nd); 166 err = path_lookup(buf, 0, &nd);
169 if (err) 167 if (err)
170 goto out; 168 goto out;
171 169
172 dprintk("Found the path %s\n", buf); 170 dprintk("Found the path %s\n", buf);
173 exp = exp_get_by_name(dom, nd.mnt, nd.dentry, NULL); 171 key.ek_mnt = nd.mnt;
174 172 key.ek_dentry = nd.dentry;
175 err = -ENOENT;
176 if (!exp)
177 goto out_nd;
178 key.ek_export = exp;
179 dprintk("And found export\n");
180 173
181 ek = svc_expkey_lookup(&key, 1); 174 ek = svc_expkey_update(&key, ek);
182 if (ek) 175 if (ek)
183 expkey_put(&ek->h, &svc_expkey_cache); 176 cache_put(&ek->h, &svc_expkey_cache);
184 exp_put(exp); 177 else
185 err = 0; 178 err = -ENOMEM;
186 out_nd:
187 path_release(&nd); 179 path_release(&nd);
188 } 180 }
189 cache_flush(); 181 cache_flush();
@@ -214,35 +206,31 @@ static int expkey_show(struct seq_file *m,
214 if (test_bit(CACHE_VALID, &h->flags) && 206 if (test_bit(CACHE_VALID, &h->flags) &&
215 !test_bit(CACHE_NEGATIVE, &h->flags)) { 207 !test_bit(CACHE_NEGATIVE, &h->flags)) {
216 seq_printf(m, " "); 208 seq_printf(m, " ");
217 seq_path(m, ek->ek_export->ex_mnt, ek->ek_export->ex_dentry, "\\ \t\n"); 209 seq_path(m, ek->ek_mnt, ek->ek_dentry, "\\ \t\n");
218 } 210 }
219 seq_printf(m, "\n"); 211 seq_printf(m, "\n");
220 return 0; 212 return 0;
221} 213}
222
223struct cache_detail svc_expkey_cache = {
224 .owner = THIS_MODULE,
225 .hash_size = EXPKEY_HASHMAX,
226 .hash_table = expkey_table,
227 .name = "nfsd.fh",
228 .cache_put = expkey_put,
229 .cache_request = expkey_request,
230 .cache_parse = expkey_parse,
231 .cache_show = expkey_show,
232};
233 214
234static inline int svc_expkey_match (struct svc_expkey *a, struct svc_expkey *b) 215static inline int expkey_match (struct cache_head *a, struct cache_head *b)
235{ 216{
236 if (a->ek_fsidtype != b->ek_fsidtype || 217 struct svc_expkey *orig = container_of(a, struct svc_expkey, h);
237 a->ek_client != b->ek_client || 218 struct svc_expkey *new = container_of(b, struct svc_expkey, h);
238 memcmp(a->ek_fsid, b->ek_fsid, key_len(a->ek_fsidtype)) != 0) 219
220 if (orig->ek_fsidtype != new->ek_fsidtype ||
221 orig->ek_client != new->ek_client ||
222 memcmp(orig->ek_fsid, new->ek_fsid, key_len(orig->ek_fsidtype)) != 0)
239 return 0; 223 return 0;
240 return 1; 224 return 1;
241} 225}
242 226
243static inline void svc_expkey_init(struct svc_expkey *new, struct svc_expkey *item) 227static inline void expkey_init(struct cache_head *cnew,
228 struct cache_head *citem)
244{ 229{
245 cache_get(&item->ek_client->h); 230 struct svc_expkey *new = container_of(cnew, struct svc_expkey, h);
231 struct svc_expkey *item = container_of(citem, struct svc_expkey, h);
232
233 kref_get(&item->ek_client->ref);
246 new->ek_client = item->ek_client; 234 new->ek_client = item->ek_client;
247 new->ek_fsidtype = item->ek_fsidtype; 235 new->ek_fsidtype = item->ek_fsidtype;
248 new->ek_fsid[0] = item->ek_fsid[0]; 236 new->ek_fsid[0] = item->ek_fsid[0];
@@ -250,39 +238,94 @@ static inline void svc_expkey_init(struct svc_expkey *new, struct svc_expkey *it
250 new->ek_fsid[2] = item->ek_fsid[2]; 238 new->ek_fsid[2] = item->ek_fsid[2];
251} 239}
252 240
253static inline void svc_expkey_update(struct svc_expkey *new, struct svc_expkey *item) 241static inline void expkey_update(struct cache_head *cnew,
242 struct cache_head *citem)
243{
244 struct svc_expkey *new = container_of(cnew, struct svc_expkey, h);
245 struct svc_expkey *item = container_of(citem, struct svc_expkey, h);
246
247 new->ek_mnt = mntget(item->ek_mnt);
248 new->ek_dentry = dget(item->ek_dentry);
249}
250
251static struct cache_head *expkey_alloc(void)
254{ 252{
255 cache_get(&item->ek_export->h); 253 struct svc_expkey *i = kmalloc(sizeof(*i), GFP_KERNEL);
256 new->ek_export = item->ek_export; 254 if (i)
255 return &i->h;
256 else
257 return NULL;
257} 258}
258 259
259static DefineSimpleCacheLookup(svc_expkey,0) /* no inplace updates */ 260static struct cache_detail svc_expkey_cache = {
261 .owner = THIS_MODULE,
262 .hash_size = EXPKEY_HASHMAX,
263 .hash_table = expkey_table,
264 .name = "nfsd.fh",
265 .cache_put = expkey_put,
266 .cache_request = expkey_request,
267 .cache_parse = expkey_parse,
268 .cache_show = expkey_show,
269 .match = expkey_match,
270 .init = expkey_init,
271 .update = expkey_update,
272 .alloc = expkey_alloc,
273};
260 274
261#define EXPORT_HASHBITS 8 275static struct svc_expkey *
262#define EXPORT_HASHMAX (1<< EXPORT_HASHBITS) 276svc_expkey_lookup(struct svc_expkey *item)
263#define EXPORT_HASHMASK (EXPORT_HASHMAX -1) 277{
278 struct cache_head *ch;
279 int hash = item->ek_fsidtype;
280 char * cp = (char*)item->ek_fsid;
281 int len = key_len(item->ek_fsidtype);
264 282
265static struct cache_head *export_table[EXPORT_HASHMAX]; 283 hash ^= hash_mem(cp, len, EXPKEY_HASHBITS);
284 hash ^= hash_ptr(item->ek_client, EXPKEY_HASHBITS);
285 hash &= EXPKEY_HASHMASK;
266 286
267static inline int svc_export_hash(struct svc_export *item) 287 ch = sunrpc_cache_lookup(&svc_expkey_cache, &item->h,
288 hash);
289 if (ch)
290 return container_of(ch, struct svc_expkey, h);
291 else
292 return NULL;
293}
294
295static struct svc_expkey *
296svc_expkey_update(struct svc_expkey *new, struct svc_expkey *old)
268{ 297{
269 int rv; 298 struct cache_head *ch;
299 int hash = new->ek_fsidtype;
300 char * cp = (char*)new->ek_fsid;
301 int len = key_len(new->ek_fsidtype);
270 302
271 rv = hash_ptr(item->ex_client, EXPORT_HASHBITS); 303 hash ^= hash_mem(cp, len, EXPKEY_HASHBITS);
272 rv ^= hash_ptr(item->ex_dentry, EXPORT_HASHBITS); 304 hash ^= hash_ptr(new->ek_client, EXPKEY_HASHBITS);
273 rv ^= hash_ptr(item->ex_mnt, EXPORT_HASHBITS); 305 hash &= EXPKEY_HASHMASK;
274 return rv; 306
307 ch = sunrpc_cache_update(&svc_expkey_cache, &new->h,
308 &old->h, hash);
309 if (ch)
310 return container_of(ch, struct svc_expkey, h);
311 else
312 return NULL;
275} 313}
276 314
277void svc_export_put(struct cache_head *item, struct cache_detail *cd) 315
316#define EXPORT_HASHBITS 8
317#define EXPORT_HASHMAX (1<< EXPORT_HASHBITS)
318#define EXPORT_HASHMASK (EXPORT_HASHMAX -1)
319
320static struct cache_head *export_table[EXPORT_HASHMAX];
321
322static void svc_export_put(struct kref *ref)
278{ 323{
279 if (cache_put(item, cd)) { 324 struct svc_export *exp = container_of(ref, struct svc_export, h.ref);
280 struct svc_export *exp = container_of(item, struct svc_export, h); 325 dput(exp->ex_dentry);
281 dput(exp->ex_dentry); 326 mntput(exp->ex_mnt);
282 mntput(exp->ex_mnt); 327 auth_domain_put(exp->ex_client);
283 auth_domain_put(exp->ex_client); 328 kfree(exp);
284 kfree(exp);
285 }
286} 329}
287 330
288static void svc_export_request(struct cache_detail *cd, 331static void svc_export_request(struct cache_detail *cd,
@@ -304,7 +347,9 @@ static void svc_export_request(struct cache_detail *cd,
304 (*bpp)[-1] = '\n'; 347 (*bpp)[-1] = '\n';
305} 348}
306 349
307static struct svc_export *svc_export_lookup(struct svc_export *, int); 350static struct svc_export *svc_export_update(struct svc_export *new,
351 struct svc_export *old);
352static struct svc_export *svc_export_lookup(struct svc_export *);
308 353
309static int check_export(struct inode *inode, int flags) 354static int check_export(struct inode *inode, int flags)
310{ 355{
@@ -417,11 +462,16 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
417 if (err) goto out; 462 if (err) goto out;
418 } 463 }
419 464
420 expp = svc_export_lookup(&exp, 1); 465 expp = svc_export_lookup(&exp);
421 if (expp) 466 if (expp)
422 exp_put(expp); 467 expp = svc_export_update(&exp, expp);
423 err = 0; 468 else
469 err = -ENOMEM;
424 cache_flush(); 470 cache_flush();
471 if (expp == NULL)
472 err = -ENOMEM;
473 else
474 exp_put(expp);
425 out: 475 out:
426 if (nd.dentry) 476 if (nd.dentry)
427 path_release(&nd); 477 path_release(&nd);
@@ -455,6 +505,46 @@ static int svc_export_show(struct seq_file *m,
455 seq_puts(m, ")\n"); 505 seq_puts(m, ")\n");
456 return 0; 506 return 0;
457} 507}
508static int svc_export_match(struct cache_head *a, struct cache_head *b)
509{
510 struct svc_export *orig = container_of(a, struct svc_export, h);
511 struct svc_export *new = container_of(b, struct svc_export, h);
512 return orig->ex_client == new->ex_client &&
513 orig->ex_dentry == new->ex_dentry &&
514 orig->ex_mnt == new->ex_mnt;
515}
516
517static void svc_export_init(struct cache_head *cnew, struct cache_head *citem)
518{
519 struct svc_export *new = container_of(cnew, struct svc_export, h);
520 struct svc_export *item = container_of(citem, struct svc_export, h);
521
522 kref_get(&item->ex_client->ref);
523 new->ex_client = item->ex_client;
524 new->ex_dentry = dget(item->ex_dentry);
525 new->ex_mnt = mntget(item->ex_mnt);
526}
527
528static void export_update(struct cache_head *cnew, struct cache_head *citem)
529{
530 struct svc_export *new = container_of(cnew, struct svc_export, h);
531 struct svc_export *item = container_of(citem, struct svc_export, h);
532
533 new->ex_flags = item->ex_flags;
534 new->ex_anon_uid = item->ex_anon_uid;
535 new->ex_anon_gid = item->ex_anon_gid;
536 new->ex_fsid = item->ex_fsid;
537}
538
539static struct cache_head *svc_export_alloc(void)
540{
541 struct svc_export *i = kmalloc(sizeof(*i), GFP_KERNEL);
542 if (i)
543 return &i->h;
544 else
545 return NULL;
546}
547
458struct cache_detail svc_export_cache = { 548struct cache_detail svc_export_cache = {
459 .owner = THIS_MODULE, 549 .owner = THIS_MODULE,
460 .hash_size = EXPORT_HASHMAX, 550 .hash_size = EXPORT_HASHMAX,
@@ -464,34 +554,49 @@ struct cache_detail svc_export_cache = {
464 .cache_request = svc_export_request, 554 .cache_request = svc_export_request,
465 .cache_parse = svc_export_parse, 555 .cache_parse = svc_export_parse,
466 .cache_show = svc_export_show, 556 .cache_show = svc_export_show,
557 .match = svc_export_match,
558 .init = svc_export_init,
559 .update = export_update,
560 .alloc = svc_export_alloc,
467}; 561};
468 562
469static inline int svc_export_match(struct svc_export *a, struct svc_export *b) 563static struct svc_export *
564svc_export_lookup(struct svc_export *exp)
470{ 565{
471 return a->ex_client == b->ex_client && 566 struct cache_head *ch;
472 a->ex_dentry == b->ex_dentry && 567 int hash;
473 a->ex_mnt == b->ex_mnt; 568 hash = hash_ptr(exp->ex_client, EXPORT_HASHBITS);
474} 569 hash ^= hash_ptr(exp->ex_dentry, EXPORT_HASHBITS);
475static inline void svc_export_init(struct svc_export *new, struct svc_export *item) 570 hash ^= hash_ptr(exp->ex_mnt, EXPORT_HASHBITS);
476{ 571
477 cache_get(&item->ex_client->h); 572 ch = sunrpc_cache_lookup(&svc_export_cache, &exp->h,
478 new->ex_client = item->ex_client; 573 hash);
479 new->ex_dentry = dget(item->ex_dentry); 574 if (ch)
480 new->ex_mnt = mntget(item->ex_mnt); 575 return container_of(ch, struct svc_export, h);
576 else
577 return NULL;
481} 578}
482 579
483static inline void svc_export_update(struct svc_export *new, struct svc_export *item) 580static struct svc_export *
581svc_export_update(struct svc_export *new, struct svc_export *old)
484{ 582{
485 new->ex_flags = item->ex_flags; 583 struct cache_head *ch;
486 new->ex_anon_uid = item->ex_anon_uid; 584 int hash;
487 new->ex_anon_gid = item->ex_anon_gid; 585 hash = hash_ptr(old->ex_client, EXPORT_HASHBITS);
488 new->ex_fsid = item->ex_fsid; 586 hash ^= hash_ptr(old->ex_dentry, EXPORT_HASHBITS);
587 hash ^= hash_ptr(old->ex_mnt, EXPORT_HASHBITS);
588
589 ch = sunrpc_cache_update(&svc_export_cache, &new->h,
590 &old->h,
591 hash);
592 if (ch)
593 return container_of(ch, struct svc_export, h);
594 else
595 return NULL;
489} 596}
490 597
491static DefineSimpleCacheLookup(svc_export,1) /* allow inplace updates */
492 598
493 599static struct svc_expkey *
494struct svc_expkey *
495exp_find_key(svc_client *clp, int fsid_type, u32 *fsidv, struct cache_req *reqp) 600exp_find_key(svc_client *clp, int fsid_type, u32 *fsidv, struct cache_req *reqp)
496{ 601{
497 struct svc_expkey key, *ek; 602 struct svc_expkey key, *ek;
@@ -504,7 +609,7 @@ exp_find_key(svc_client *clp, int fsid_type, u32 *fsidv, struct cache_req *reqp)
504 key.ek_fsidtype = fsid_type; 609 key.ek_fsidtype = fsid_type;
505 memcpy(key.ek_fsid, fsidv, key_len(fsid_type)); 610 memcpy(key.ek_fsid, fsidv, key_len(fsid_type));
506 611
507 ek = svc_expkey_lookup(&key, 0); 612 ek = svc_expkey_lookup(&key);
508 if (ek != NULL) 613 if (ek != NULL)
509 if ((err = cache_check(&svc_expkey_cache, &ek->h, reqp))) 614 if ((err = cache_check(&svc_expkey_cache, &ek->h, reqp)))
510 ek = ERR_PTR(err); 615 ek = ERR_PTR(err);
@@ -519,13 +624,16 @@ static int exp_set_key(svc_client *clp, int fsid_type, u32 *fsidv,
519 key.ek_client = clp; 624 key.ek_client = clp;
520 key.ek_fsidtype = fsid_type; 625 key.ek_fsidtype = fsid_type;
521 memcpy(key.ek_fsid, fsidv, key_len(fsid_type)); 626 memcpy(key.ek_fsid, fsidv, key_len(fsid_type));
522 key.ek_export = exp; 627 key.ek_mnt = exp->ex_mnt;
628 key.ek_dentry = exp->ex_dentry;
523 key.h.expiry_time = NEVER; 629 key.h.expiry_time = NEVER;
524 key.h.flags = 0; 630 key.h.flags = 0;
525 631
526 ek = svc_expkey_lookup(&key, 1); 632 ek = svc_expkey_lookup(&key);
633 if (ek)
634 ek = svc_expkey_update(&key,ek);
527 if (ek) { 635 if (ek) {
528 expkey_put(&ek->h, &svc_expkey_cache); 636 cache_put(&ek->h, &svc_expkey_cache);
529 return 0; 637 return 0;
530 } 638 }
531 return -ENOMEM; 639 return -ENOMEM;
@@ -573,7 +681,7 @@ exp_get_by_name(svc_client *clp, struct vfsmount *mnt, struct dentry *dentry,
573 key.ex_mnt = mnt; 681 key.ex_mnt = mnt;
574 key.ex_dentry = dentry; 682 key.ex_dentry = dentry;
575 683
576 exp = svc_export_lookup(&key, 0); 684 exp = svc_export_lookup(&key);
577 if (exp != NULL) 685 if (exp != NULL)
578 switch (cache_check(&svc_export_cache, &exp->h, reqp)) { 686 switch (cache_check(&svc_export_cache, &exp->h, reqp)) {
579 case 0: break; 687 case 0: break;
@@ -654,7 +762,7 @@ static void exp_fsid_unhash(struct svc_export *exp)
654 ek = exp_get_fsid_key(exp->ex_client, exp->ex_fsid); 762 ek = exp_get_fsid_key(exp->ex_client, exp->ex_fsid);
655 if (ek && !IS_ERR(ek)) { 763 if (ek && !IS_ERR(ek)) {
656 ek->h.expiry_time = get_seconds()-1; 764 ek->h.expiry_time = get_seconds()-1;
657 expkey_put(&ek->h, &svc_expkey_cache); 765 cache_put(&ek->h, &svc_expkey_cache);
658 } 766 }
659 svc_expkey_cache.nextcheck = get_seconds(); 767 svc_expkey_cache.nextcheck = get_seconds();
660} 768}
@@ -692,7 +800,7 @@ static void exp_unhash(struct svc_export *exp)
692 ek = exp_get_key(exp->ex_client, inode->i_sb->s_dev, inode->i_ino); 800 ek = exp_get_key(exp->ex_client, inode->i_sb->s_dev, inode->i_ino);
693 if (ek && !IS_ERR(ek)) { 801 if (ek && !IS_ERR(ek)) {
694 ek->h.expiry_time = get_seconds()-1; 802 ek->h.expiry_time = get_seconds()-1;
695 expkey_put(&ek->h, &svc_expkey_cache); 803 cache_put(&ek->h, &svc_expkey_cache);
696 } 804 }
697 svc_expkey_cache.nextcheck = get_seconds(); 805 svc_expkey_cache.nextcheck = get_seconds();
698} 806}
@@ -741,8 +849,8 @@ exp_export(struct nfsctl_export *nxp)
741 if ((nxp->ex_flags & NFSEXP_FSID) && 849 if ((nxp->ex_flags & NFSEXP_FSID) &&
742 (fsid_key = exp_get_fsid_key(clp, nxp->ex_dev)) && 850 (fsid_key = exp_get_fsid_key(clp, nxp->ex_dev)) &&
743 !IS_ERR(fsid_key) && 851 !IS_ERR(fsid_key) &&
744 fsid_key->ek_export && 852 fsid_key->ek_mnt &&
745 fsid_key->ek_export != exp) 853 (fsid_key->ek_mnt != nd.mnt || fsid_key->ek_dentry != nd.dentry) )
746 goto finish; 854 goto finish;
747 855
748 if (exp) { 856 if (exp) {
@@ -775,13 +883,13 @@ exp_export(struct nfsctl_export *nxp)
775 new.ex_anon_gid = nxp->ex_anon_gid; 883 new.ex_anon_gid = nxp->ex_anon_gid;
776 new.ex_fsid = nxp->ex_dev; 884 new.ex_fsid = nxp->ex_dev;
777 885
778 exp = svc_export_lookup(&new, 1); 886 exp = svc_export_lookup(&new);
887 if (exp)
888 exp = svc_export_update(&new, exp);
779 889
780 if (exp == NULL) 890 if (!exp)
781 goto finish; 891 goto finish;
782 892
783 err = 0;
784
785 if (exp_hash(clp, exp) || 893 if (exp_hash(clp, exp) ||
786 exp_fsid_hash(clp, exp)) { 894 exp_fsid_hash(clp, exp)) {
787 /* failed to create at least one index */ 895 /* failed to create at least one index */
@@ -794,7 +902,7 @@ finish:
794 if (exp) 902 if (exp)
795 exp_put(exp); 903 exp_put(exp);
796 if (fsid_key && !IS_ERR(fsid_key)) 904 if (fsid_key && !IS_ERR(fsid_key))
797 expkey_put(&fsid_key->h, &svc_expkey_cache); 905 cache_put(&fsid_key->h, &svc_expkey_cache);
798 if (clp) 906 if (clp)
799 auth_domain_put(clp); 907 auth_domain_put(clp);
800 path_release(&nd); 908 path_release(&nd);
@@ -912,6 +1020,24 @@ out:
912 return err; 1020 return err;
913} 1021}
914 1022
1023struct svc_export *
1024exp_find(struct auth_domain *clp, int fsid_type, u32 *fsidv,
1025 struct cache_req *reqp)
1026{
1027 struct svc_export *exp;
1028 struct svc_expkey *ek = exp_find_key(clp, fsid_type, fsidv, reqp);
1029 if (!ek || IS_ERR(ek))
1030 return ERR_PTR(PTR_ERR(ek));
1031
1032 exp = exp_get_by_name(clp, ek->ek_mnt, ek->ek_dentry, reqp);
1033 cache_put(&ek->h, &svc_expkey_cache);
1034
1035 if (!exp || IS_ERR(exp))
1036 return ERR_PTR(PTR_ERR(exp));
1037 return exp;
1038}
1039
1040
915/* 1041/*
916 * Called when we need the filehandle for the root of the pseudofs, 1042 * Called when we need the filehandle for the root of the pseudofs,
917 * for a given NFSv4 client. The root is defined to be the 1043 * for a given NFSv4 client. The root is defined to be the
@@ -922,6 +1048,7 @@ exp_pseudoroot(struct auth_domain *clp, struct svc_fh *fhp,
922 struct cache_req *creq) 1048 struct cache_req *creq)
923{ 1049{
924 struct svc_expkey *fsid_key; 1050 struct svc_expkey *fsid_key;
1051 struct svc_export *exp;
925 int rv; 1052 int rv;
926 u32 fsidv[2]; 1053 u32 fsidv[2];
927 1054
@@ -933,9 +1060,15 @@ exp_pseudoroot(struct auth_domain *clp, struct svc_fh *fhp,
933 if (!fsid_key || IS_ERR(fsid_key)) 1060 if (!fsid_key || IS_ERR(fsid_key))
934 return nfserr_perm; 1061 return nfserr_perm;
935 1062
936 rv = fh_compose(fhp, fsid_key->ek_export, 1063 exp = exp_get_by_name(clp, fsid_key->ek_mnt, fsid_key->ek_dentry, creq);
937 fsid_key->ek_export->ex_dentry, NULL); 1064 if (exp == NULL)
938 expkey_put(&fsid_key->h, &svc_expkey_cache); 1065 rv = nfserr_perm;
1066 else if (IS_ERR(exp))
1067 rv = nfserrno(PTR_ERR(exp));
1068 else
1069 rv = fh_compose(fhp, exp,
1070 fsid_key->ek_dentry, NULL);
1071 cache_put(&fsid_key->h, &svc_expkey_cache);
939 return rv; 1072 return rv;
940} 1073}
941 1074
@@ -1054,7 +1187,7 @@ static int e_show(struct seq_file *m, void *p)
1054 cache_get(&exp->h); 1187 cache_get(&exp->h);
1055 if (cache_check(&svc_export_cache, &exp->h, NULL)) 1188 if (cache_check(&svc_export_cache, &exp->h, NULL))
1056 return 0; 1189 return 0;
1057 if (cache_put(&exp->h, &svc_export_cache)) BUG(); 1190 cache_put(&exp->h, &svc_export_cache);
1058 return svc_export_show(m, &svc_export_cache, cp); 1191 return svc_export_show(m, &svc_export_cache, cp);
1059} 1192}
1060 1193
@@ -1129,7 +1262,6 @@ exp_delclient(struct nfsctl_client *ncp)
1129 */ 1262 */
1130 if (dom) { 1263 if (dom) {
1131 err = auth_unix_forget_old(dom); 1264 err = auth_unix_forget_old(dom);
1132 dom->h.expiry_time = get_seconds();
1133 auth_domain_put(dom); 1265 auth_domain_put(dom);
1134 } 1266 }
1135 1267
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index 13369650cdf9..4b6aa60dfceb 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -76,21 +76,18 @@ struct ent {
76 char authname[IDMAP_NAMESZ]; 76 char authname[IDMAP_NAMESZ];
77}; 77};
78 78
79#define DefineSimpleCacheLookupMap(STRUCT, FUNC) \
80 DefineCacheLookup(struct STRUCT, h, FUNC##_lookup, \
81 (struct STRUCT *item, int set), /*no setup */, \
82 & FUNC##_cache, FUNC##_hash(item), FUNC##_match(item, tmp), \
83 STRUCT##_init(new, item), STRUCT##_update(tmp, item), 0)
84
85/* Common entry handling */ 79/* Common entry handling */
86 80
87#define ENT_HASHBITS 8 81#define ENT_HASHBITS 8
88#define ENT_HASHMAX (1 << ENT_HASHBITS) 82#define ENT_HASHMAX (1 << ENT_HASHBITS)
89#define ENT_HASHMASK (ENT_HASHMAX - 1) 83#define ENT_HASHMASK (ENT_HASHMAX - 1)
90 84
91static inline void 85static void
92ent_init(struct ent *new, struct ent *itm) 86ent_init(struct cache_head *cnew, struct cache_head *citm)
93{ 87{
88 struct ent *new = container_of(cnew, struct ent, h);
89 struct ent *itm = container_of(citm, struct ent, h);
90
94 new->id = itm->id; 91 new->id = itm->id;
95 new->type = itm->type; 92 new->type = itm->type;
96 93
@@ -98,19 +95,21 @@ ent_init(struct ent *new, struct ent *itm)
98 strlcpy(new->authname, itm->authname, sizeof(new->name)); 95 strlcpy(new->authname, itm->authname, sizeof(new->name));
99} 96}
100 97
101static inline void 98static void
102ent_update(struct ent *new, struct ent *itm) 99ent_put(struct kref *ref)
103{ 100{
104 ent_init(new, itm); 101 struct ent *map = container_of(ref, struct ent, h.ref);
102 kfree(map);
105} 103}
106 104
107static void 105static struct cache_head *
108ent_put(struct cache_head *ch, struct cache_detail *cd) 106ent_alloc(void)
109{ 107{
110 if (cache_put(ch, cd)) { 108 struct ent *e = kmalloc(sizeof(*e), GFP_KERNEL);
111 struct ent *map = container_of(ch, struct ent, h); 109 if (e)
112 kfree(map); 110 return &e->h;
113 } 111 else
112 return NULL;
114} 113}
115 114
116/* 115/*
@@ -149,9 +148,12 @@ idtoname_request(struct cache_detail *cd, struct cache_head *ch, char **bpp,
149 (*bpp)[-1] = '\n'; 148 (*bpp)[-1] = '\n';
150} 149}
151 150
152static inline int 151static int
153idtoname_match(struct ent *a, struct ent *b) 152idtoname_match(struct cache_head *ca, struct cache_head *cb)
154{ 153{
154 struct ent *a = container_of(ca, struct ent, h);
155 struct ent *b = container_of(cb, struct ent, h);
156
155 return (a->id == b->id && a->type == b->type && 157 return (a->id == b->id && a->type == b->type &&
156 strcmp(a->authname, b->authname) == 0); 158 strcmp(a->authname, b->authname) == 0);
157} 159}
@@ -184,7 +186,8 @@ warn_no_idmapd(struct cache_detail *detail)
184 186
185 187
186static int idtoname_parse(struct cache_detail *, char *, int); 188static int idtoname_parse(struct cache_detail *, char *, int);
187static struct ent *idtoname_lookup(struct ent *, int); 189static struct ent *idtoname_lookup(struct ent *);
190static struct ent *idtoname_update(struct ent *, struct ent *);
188 191
189static struct cache_detail idtoname_cache = { 192static struct cache_detail idtoname_cache = {
190 .owner = THIS_MODULE, 193 .owner = THIS_MODULE,
@@ -196,6 +199,10 @@ static struct cache_detail idtoname_cache = {
196 .cache_parse = idtoname_parse, 199 .cache_parse = idtoname_parse,
197 .cache_show = idtoname_show, 200 .cache_show = idtoname_show,
198 .warn_no_listener = warn_no_idmapd, 201 .warn_no_listener = warn_no_idmapd,
202 .match = idtoname_match,
203 .init = ent_init,
204 .update = ent_init,
205 .alloc = ent_alloc,
199}; 206};
200 207
201int 208int
@@ -238,6 +245,11 @@ idtoname_parse(struct cache_detail *cd, char *buf, int buflen)
238 if (ent.h.expiry_time == 0) 245 if (ent.h.expiry_time == 0)
239 goto out; 246 goto out;
240 247
248 error = -ENOMEM;
249 res = idtoname_lookup(&ent);
250 if (!res)
251 goto out;
252
241 /* Name */ 253 /* Name */
242 error = qword_get(&buf, buf1, PAGE_SIZE); 254 error = qword_get(&buf, buf1, PAGE_SIZE);
243 if (error == -EINVAL) 255 if (error == -EINVAL)
@@ -252,10 +264,11 @@ idtoname_parse(struct cache_detail *cd, char *buf, int buflen)
252 memcpy(ent.name, buf1, sizeof(ent.name)); 264 memcpy(ent.name, buf1, sizeof(ent.name));
253 } 265 }
254 error = -ENOMEM; 266 error = -ENOMEM;
255 if ((res = idtoname_lookup(&ent, 1)) == NULL) 267 res = idtoname_update(&ent, res);
268 if (res == NULL)
256 goto out; 269 goto out;
257 270
258 ent_put(&res->h, &idtoname_cache); 271 cache_put(&res->h, &idtoname_cache);
259 272
260 error = 0; 273 error = 0;
261out: 274out:
@@ -264,7 +277,31 @@ out:
264 return error; 277 return error;
265} 278}
266 279
267static DefineSimpleCacheLookupMap(ent, idtoname); 280
281static struct ent *
282idtoname_lookup(struct ent *item)
283{
284 struct cache_head *ch = sunrpc_cache_lookup(&idtoname_cache,
285 &item->h,
286 idtoname_hash(item));
287 if (ch)
288 return container_of(ch, struct ent, h);
289 else
290 return NULL;
291}
292
293static struct ent *
294idtoname_update(struct ent *new, struct ent *old)
295{
296 struct cache_head *ch = sunrpc_cache_update(&idtoname_cache,
297 &new->h, &old->h,
298 idtoname_hash(new));
299 if (ch)
300 return container_of(ch, struct ent, h);
301 else
302 return NULL;
303}
304
268 305
269/* 306/*
270 * Name -> ID cache 307 * Name -> ID cache
@@ -291,9 +328,12 @@ nametoid_request(struct cache_detail *cd, struct cache_head *ch, char **bpp,
291 (*bpp)[-1] = '\n'; 328 (*bpp)[-1] = '\n';
292} 329}
293 330
294static inline int 331static int
295nametoid_match(struct ent *a, struct ent *b) 332nametoid_match(struct cache_head *ca, struct cache_head *cb)
296{ 333{
334 struct ent *a = container_of(ca, struct ent, h);
335 struct ent *b = container_of(cb, struct ent, h);
336
297 return (a->type == b->type && strcmp(a->name, b->name) == 0 && 337 return (a->type == b->type && strcmp(a->name, b->name) == 0 &&
298 strcmp(a->authname, b->authname) == 0); 338 strcmp(a->authname, b->authname) == 0);
299} 339}
@@ -317,7 +357,8 @@ nametoid_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h)
317 return 0; 357 return 0;
318} 358}
319 359
320static struct ent *nametoid_lookup(struct ent *, int); 360static struct ent *nametoid_lookup(struct ent *);
361static struct ent *nametoid_update(struct ent *, struct ent *);
321static int nametoid_parse(struct cache_detail *, char *, int); 362static int nametoid_parse(struct cache_detail *, char *, int);
322 363
323static struct cache_detail nametoid_cache = { 364static struct cache_detail nametoid_cache = {
@@ -330,6 +371,10 @@ static struct cache_detail nametoid_cache = {
330 .cache_parse = nametoid_parse, 371 .cache_parse = nametoid_parse,
331 .cache_show = nametoid_show, 372 .cache_show = nametoid_show,
332 .warn_no_listener = warn_no_idmapd, 373 .warn_no_listener = warn_no_idmapd,
374 .match = nametoid_match,
375 .init = ent_init,
376 .update = ent_init,
377 .alloc = ent_alloc,
333}; 378};
334 379
335static int 380static int
@@ -379,10 +424,14 @@ nametoid_parse(struct cache_detail *cd, char *buf, int buflen)
379 set_bit(CACHE_NEGATIVE, &ent.h.flags); 424 set_bit(CACHE_NEGATIVE, &ent.h.flags);
380 425
381 error = -ENOMEM; 426 error = -ENOMEM;
382 if ((res = nametoid_lookup(&ent, 1)) == NULL) 427 res = nametoid_lookup(&ent);
428 if (res == NULL)
429 goto out;
430 res = nametoid_update(&ent, res);
431 if (res == NULL)
383 goto out; 432 goto out;
384 433
385 ent_put(&res->h, &nametoid_cache); 434 cache_put(&res->h, &nametoid_cache);
386 error = 0; 435 error = 0;
387out: 436out:
388 kfree(buf1); 437 kfree(buf1);
@@ -390,7 +439,30 @@ out:
390 return (error); 439 return (error);
391} 440}
392 441
393static DefineSimpleCacheLookupMap(ent, nametoid); 442
443static struct ent *
444nametoid_lookup(struct ent *item)
445{
446 struct cache_head *ch = sunrpc_cache_lookup(&nametoid_cache,
447 &item->h,
448 nametoid_hash(item));
449 if (ch)
450 return container_of(ch, struct ent, h);
451 else
452 return NULL;
453}
454
455static struct ent *
456nametoid_update(struct ent *new, struct ent *old)
457{
458 struct cache_head *ch = sunrpc_cache_update(&nametoid_cache,
459 &new->h, &old->h,
460 nametoid_hash(new));
461 if (ch)
462 return container_of(ch, struct ent, h);
463 else
464 return NULL;
465}
394 466
395/* 467/*
396 * Exported API 468 * Exported API
@@ -458,24 +530,24 @@ idmap_defer(struct cache_req *req)
458} 530}
459 531
460static inline int 532static inline int
461do_idmap_lookup(struct ent *(*lookup_fn)(struct ent *, int), struct ent *key, 533do_idmap_lookup(struct ent *(*lookup_fn)(struct ent *), struct ent *key,
462 struct cache_detail *detail, struct ent **item, 534 struct cache_detail *detail, struct ent **item,
463 struct idmap_defer_req *mdr) 535 struct idmap_defer_req *mdr)
464{ 536{
465 *item = lookup_fn(key, 0); 537 *item = lookup_fn(key);
466 if (!*item) 538 if (!*item)
467 return -ENOMEM; 539 return -ENOMEM;
468 return cache_check(detail, &(*item)->h, &mdr->req); 540 return cache_check(detail, &(*item)->h, &mdr->req);
469} 541}
470 542
471static inline int 543static inline int
472do_idmap_lookup_nowait(struct ent *(*lookup_fn)(struct ent *, int), 544do_idmap_lookup_nowait(struct ent *(*lookup_fn)(struct ent *),
473 struct ent *key, struct cache_detail *detail, 545 struct ent *key, struct cache_detail *detail,
474 struct ent **item) 546 struct ent **item)
475{ 547{
476 int ret = -ENOMEM; 548 int ret = -ENOMEM;
477 549
478 *item = lookup_fn(key, 0); 550 *item = lookup_fn(key);
479 if (!*item) 551 if (!*item)
480 goto out_err; 552 goto out_err;
481 ret = -ETIMEDOUT; 553 ret = -ETIMEDOUT;
@@ -488,7 +560,7 @@ do_idmap_lookup_nowait(struct ent *(*lookup_fn)(struct ent *, int),
488 goto out_put; 560 goto out_put;
489 return 0; 561 return 0;
490out_put: 562out_put:
491 ent_put(&(*item)->h, detail); 563 cache_put(&(*item)->h, detail);
492out_err: 564out_err:
493 *item = NULL; 565 *item = NULL;
494 return ret; 566 return ret;
@@ -496,7 +568,7 @@ out_err:
496 568
497static int 569static int
498idmap_lookup(struct svc_rqst *rqstp, 570idmap_lookup(struct svc_rqst *rqstp,
499 struct ent *(*lookup_fn)(struct ent *, int), struct ent *key, 571 struct ent *(*lookup_fn)(struct ent *), struct ent *key,
500 struct cache_detail *detail, struct ent **item) 572 struct cache_detail *detail, struct ent **item)
501{ 573{
502 struct idmap_defer_req *mdr; 574 struct idmap_defer_req *mdr;
@@ -539,7 +611,7 @@ idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen
539 if (ret) 611 if (ret)
540 return ret; 612 return ret;
541 *id = item->id; 613 *id = item->id;
542 ent_put(&item->h, &nametoid_cache); 614 cache_put(&item->h, &nametoid_cache);
543 return 0; 615 return 0;
544} 616}
545 617
@@ -561,7 +633,7 @@ idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name)
561 ret = strlen(item->name); 633 ret = strlen(item->name);
562 BUG_ON(ret > IDMAP_NAMESZ); 634 BUG_ON(ret > IDMAP_NAMESZ);
563 memcpy(name, item->name, ret); 635 memcpy(name, item->name, ret);
564 ent_put(&item->h, &idtoname_cache); 636 cache_put(&item->h, &idtoname_cache);
565 return ret; 637 return ret;
566} 638}
567 639
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 7a3e397b4ed3..3f2ec2e6d06c 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -506,7 +506,7 @@ fh_put(struct svc_fh *fhp)
506 nfsd_nr_put++; 506 nfsd_nr_put++;
507 } 507 }
508 if (exp) { 508 if (exp) {
509 svc_export_put(&exp->h, &svc_export_cache); 509 cache_put(&exp->h, &svc_export_cache);
510 fhp->fh_export = NULL; 510 fhp->fh_export = NULL;
511 } 511 }
512 return; 512 return;
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index f924f459bdb8..af0cb4b9e784 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -297,6 +297,25 @@ struct kobj_type ktype_part = {
297 .sysfs_ops = &part_sysfs_ops, 297 .sysfs_ops = &part_sysfs_ops,
298}; 298};
299 299
300static inline void partition_sysfs_add_subdir(struct hd_struct *p)
301{
302 struct kobject *k;
303
304 k = kobject_get(&p->kobj);
305 p->holder_dir = kobject_add_dir(k, "holders");
306 kobject_put(k);
307}
308
309static inline void disk_sysfs_add_subdirs(struct gendisk *disk)
310{
311 struct kobject *k;
312
313 k = kobject_get(&disk->kobj);
314 disk->holder_dir = kobject_add_dir(k, "holders");
315 disk->slave_dir = kobject_add_dir(k, "slaves");
316 kobject_put(k);
317}
318
300void delete_partition(struct gendisk *disk, int part) 319void delete_partition(struct gendisk *disk, int part)
301{ 320{
302 struct hd_struct *p = disk->part[part-1]; 321 struct hd_struct *p = disk->part[part-1];
@@ -310,6 +329,8 @@ void delete_partition(struct gendisk *disk, int part)
310 p->ios[0] = p->ios[1] = 0; 329 p->ios[0] = p->ios[1] = 0;
311 p->sectors[0] = p->sectors[1] = 0; 330 p->sectors[0] = p->sectors[1] = 0;
312 devfs_remove("%s/part%d", disk->devfs_name, part); 331 devfs_remove("%s/part%d", disk->devfs_name, part);
332 if (p->holder_dir)
333 kobject_unregister(p->holder_dir);
313 kobject_unregister(&p->kobj); 334 kobject_unregister(&p->kobj);
314} 335}
315 336
@@ -337,6 +358,7 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len)
337 p->kobj.parent = &disk->kobj; 358 p->kobj.parent = &disk->kobj;
338 p->kobj.ktype = &ktype_part; 359 p->kobj.ktype = &ktype_part;
339 kobject_register(&p->kobj); 360 kobject_register(&p->kobj);
361 partition_sysfs_add_subdir(p);
340 disk->part[part-1] = p; 362 disk->part[part-1] = p;
341} 363}
342 364
@@ -383,6 +405,7 @@ void register_disk(struct gendisk *disk)
383 if ((err = kobject_add(&disk->kobj))) 405 if ((err = kobject_add(&disk->kobj)))
384 return; 406 return;
385 disk_sysfs_symlinks(disk); 407 disk_sysfs_symlinks(disk);
408 disk_sysfs_add_subdirs(disk);
386 kobject_uevent(&disk->kobj, KOBJ_ADD); 409 kobject_uevent(&disk->kobj, KOBJ_ADD);
387 410
388 /* No minors to use for partitions */ 411 /* No minors to use for partitions */
@@ -483,6 +506,10 @@ void del_gendisk(struct gendisk *disk)
483 506
484 devfs_remove_disk(disk); 507 devfs_remove_disk(disk);
485 508
509 if (disk->holder_dir)
510 kobject_unregister(disk->holder_dir);
511 if (disk->slave_dir)
512 kobject_unregister(disk->slave_dir);
486 if (disk->driverfs_dev) { 513 if (disk->driverfs_dev) {
487 char *disk_name = make_block_name(disk); 514 char *disk_name = make_block_name(disk);
488 sysfs_remove_link(&disk->kobj, "device"); 515 sysfs_remove_link(&disk->kobj, "device");
diff --git a/include/asm-alpha/mmzone.h b/include/asm-alpha/mmzone.h
index a011ef4cf3d3..192d80c875b0 100644
--- a/include/asm-alpha/mmzone.h
+++ b/include/asm-alpha/mmzone.h
@@ -59,9 +59,6 @@ PLAT_NODE_DATA_LOCALNR(unsigned long p, int n)
59#define kvaddr_to_nid(kaddr) pa_to_nid(__pa(kaddr)) 59#define kvaddr_to_nid(kaddr) pa_to_nid(__pa(kaddr))
60#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn) 60#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn)
61 61
62#define local_mapnr(kvaddr) \
63 ((__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr)))
64
65/* 62/*
66 * Given a kaddr, LOCAL_BASE_ADDR finds the owning node of the memory 63 * Given a kaddr, LOCAL_BASE_ADDR finds the owning node of the memory
67 * and returns the kaddr corresponding to first physical page in the 64 * and returns the kaddr corresponding to first physical page in the
@@ -86,8 +83,7 @@ PLAT_NODE_DATA_LOCALNR(unsigned long p, int n)
86 pte_t pte; \ 83 pte_t pte; \
87 unsigned long pfn; \ 84 unsigned long pfn; \
88 \ 85 \
89 pfn = ((unsigned long)((page)-page_zone(page)->zone_mem_map)) << 32; \ 86 pfn = page_to_pfn(page) << 32; \
90 pfn += page_zone(page)->zone_start_pfn << 32; \
91 pte_val(pte) = pfn | pgprot_val(pgprot); \ 87 pte_val(pte) = pfn | pgprot_val(pgprot); \
92 \ 88 \
93 pte; \ 89 pte; \
@@ -104,19 +100,8 @@ PLAT_NODE_DATA_LOCALNR(unsigned long p, int n)
104 __xx; \ 100 __xx; \
105}) 101})
106 102
107#define pfn_to_page(pfn) \
108({ \
109 unsigned long kaddr = (unsigned long)__va((pfn) << PAGE_SHIFT); \
110 (NODE_DATA(kvaddr_to_nid(kaddr))->node_mem_map + local_mapnr(kaddr)); \
111})
112
113#define page_to_pfn(page) \
114 ((page) - page_zone(page)->zone_mem_map + \
115 (page_zone(page)->zone_start_pfn))
116
117#define page_to_pa(page) \ 103#define page_to_pa(page) \
118 ((( (page) - page_zone(page)->zone_mem_map ) \ 104 (page_to_pfn(page) << PAGE_SHIFT)
119 + page_zone(page)->zone_start_pfn) << PAGE_SHIFT)
120 105
121#define pfn_to_nid(pfn) pa_to_nid(((u64)(pfn) << PAGE_SHIFT)) 106#define pfn_to_nid(pfn) pa_to_nid(((u64)(pfn) << PAGE_SHIFT))
122#define pfn_valid(pfn) \ 107#define pfn_valid(pfn) \
diff --git a/include/asm-alpha/page.h b/include/asm-alpha/page.h
index fa0b41b164a7..61bcf70b5eac 100644
--- a/include/asm-alpha/page.h
+++ b/include/asm-alpha/page.h
@@ -85,8 +85,6 @@ typedef unsigned long pgprot_t;
85#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) 85#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET)
86#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) 86#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET))
87#ifndef CONFIG_DISCONTIGMEM 87#ifndef CONFIG_DISCONTIGMEM
88#define pfn_to_page(pfn) (mem_map + (pfn))
89#define page_to_pfn(page) ((unsigned long)((page) - mem_map))
90#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) 88#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
91 89
92#define pfn_valid(pfn) ((pfn) < max_mapnr) 90#define pfn_valid(pfn) ((pfn) < max_mapnr)
@@ -95,9 +93,9 @@ typedef unsigned long pgprot_t;
95 93
96#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ 94#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
97 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) 95 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
98
99#endif /* __KERNEL__ */ 96#endif /* __KERNEL__ */
100 97
98#include <asm-generic/memory_model.h>
101#include <asm-generic/page.h> 99#include <asm-generic/page.h>
102 100
103#endif /* _ALPHA_PAGE_H */ 101#endif /* _ALPHA_PAGE_H */
diff --git a/include/asm-arm/memory.h b/include/asm-arm/memory.h
index b4e1146ab682..afa5c3ea077c 100644
--- a/include/asm-arm/memory.h
+++ b/include/asm-arm/memory.h
@@ -172,9 +172,7 @@ static inline __deprecated void *bus_to_virt(unsigned long x)
172 * virt_addr_valid(k) indicates whether a virtual address is valid 172 * virt_addr_valid(k) indicates whether a virtual address is valid
173 */ 173 */
174#ifndef CONFIG_DISCONTIGMEM 174#ifndef CONFIG_DISCONTIGMEM
175 175#define ARCH_PFN_OFFSET (PHYS_PFN_OFFSET)
176#define page_to_pfn(page) (((page) - mem_map) + PHYS_PFN_OFFSET)
177#define pfn_to_page(pfn) ((mem_map + (pfn)) - PHYS_PFN_OFFSET)
178#define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr)) 176#define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr))
179 177
180#define virt_to_page(kaddr) (pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)) 178#define virt_to_page(kaddr) (pfn_to_page(__pa(kaddr) >> PAGE_SHIFT))
@@ -189,13 +187,8 @@ static inline __deprecated void *bus_to_virt(unsigned long x)
189 * around in memory. 187 * around in memory.
190 */ 188 */
191#include <linux/numa.h> 189#include <linux/numa.h>
192 190#define arch_pfn_to_nid(pfn) (PFN_TO_NID(pfn))
193#define page_to_pfn(page) \ 191#define arch_local_page_offset(pfn, nid) (LOCAL_MAP_NR((pfn) << PAGE_OFFSET))
194 (( (page) - page_zone(page)->zone_mem_map) \
195 + page_zone(page)->zone_start_pfn)
196
197#define pfn_to_page(pfn) \
198 (PFN_TO_MAPBASE(pfn) + LOCAL_MAP_NR((pfn) << PAGE_SHIFT))
199 192
200#define pfn_valid(pfn) \ 193#define pfn_valid(pfn) \
201 ({ \ 194 ({ \
@@ -243,4 +236,6 @@ static inline __deprecated void *bus_to_virt(unsigned long x)
243 236
244#endif 237#endif
245 238
239#include <asm-generic/memory_model.h>
240
246#endif 241#endif
diff --git a/include/asm-arm/rtc.h b/include/asm-arm/rtc.h
index 370dfe77589d..1a5c9232a91e 100644
--- a/include/asm-arm/rtc.h
+++ b/include/asm-arm/rtc.h
@@ -25,9 +25,6 @@ struct rtc_ops {
25 int (*proc)(char *buf); 25 int (*proc)(char *buf);
26}; 26};
27 27
28void rtc_time_to_tm(unsigned long, struct rtc_time *);
29int rtc_tm_to_time(struct rtc_time *, unsigned long *);
30int rtc_valid_tm(struct rtc_time *);
31void rtc_next_alarm_time(struct rtc_time *, struct rtc_time *, struct rtc_time *); 28void rtc_next_alarm_time(struct rtc_time *, struct rtc_time *, struct rtc_time *);
32void rtc_update(unsigned long, unsigned long); 29void rtc_update(unsigned long, unsigned long);
33int register_rtc(struct rtc_ops *); 30int register_rtc(struct rtc_ops *);
diff --git a/include/asm-arm26/memory.h b/include/asm-arm26/memory.h
index 20d78616f650..a65f10b80dfb 100644
--- a/include/asm-arm26/memory.h
+++ b/include/asm-arm26/memory.h
@@ -81,8 +81,7 @@ static inline void *phys_to_virt(unsigned long x)
81 * virt_to_page(k) convert a _valid_ virtual address to struct page * 81 * virt_to_page(k) convert a _valid_ virtual address to struct page *
82 * virt_addr_valid(k) indicates whether a virtual address is valid 82 * virt_addr_valid(k) indicates whether a virtual address is valid
83 */ 83 */
84#define page_to_pfn(page) (((page) - mem_map) + PHYS_PFN_OFFSET) 84#define ARCH_PFN_OFFSET (PHYS_PFN_OFFSET)
85#define pfn_to_page(pfn) ((mem_map + (pfn)) - PHYS_PFN_OFFSET)
86#define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr)) 85#define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr))
87 86
88#define virt_to_page(kaddr) (pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)) 87#define virt_to_page(kaddr) (pfn_to_page(__pa(kaddr) >> PAGE_SHIFT))
@@ -98,4 +97,5 @@ static inline void *phys_to_virt(unsigned long x)
98 */ 97 */
99#define page_to_bus(page) (page_address(page)) 98#define page_to_bus(page) (page_address(page))
100 99
100#include <asm-generic/memory_model.h>
101#endif 101#endif
diff --git a/include/asm-cris/page.h b/include/asm-cris/page.h
index c99c478c482f..3787633e6209 100644
--- a/include/asm-cris/page.h
+++ b/include/asm-cris/page.h
@@ -43,8 +43,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
43 43
44/* On CRIS the PFN numbers doesn't start at 0 so we have to compensate */ 44/* On CRIS the PFN numbers doesn't start at 0 so we have to compensate */
45/* for that before indexing into the page table starting at mem_map */ 45/* for that before indexing into the page table starting at mem_map */
46#define pfn_to_page(pfn) (mem_map + ((pfn) - (PAGE_OFFSET >> PAGE_SHIFT))) 46#define ARCH_PFN_OFFSET (PAGE_OFFSET >> PAGE_SHIFT)
47#define page_to_pfn(page) ((unsigned long)((page) - mem_map) + (PAGE_OFFSET >> PAGE_SHIFT))
48#define pfn_valid(pfn) (((pfn) - (PAGE_OFFSET >> PAGE_SHIFT)) < max_mapnr) 47#define pfn_valid(pfn) (((pfn) - (PAGE_OFFSET >> PAGE_SHIFT)) < max_mapnr)
49 48
50/* to index into the page map. our pages all start at physical addr PAGE_OFFSET so 49/* to index into the page map. our pages all start at physical addr PAGE_OFFSET so
@@ -77,6 +76,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
77 76
78#endif /* __KERNEL__ */ 77#endif /* __KERNEL__ */
79 78
79#include <asm-generic/memory_model.h>
80#include <asm-generic/page.h> 80#include <asm-generic/page.h>
81 81
82#endif /* _CRIS_PAGE_H */ 82#endif /* _CRIS_PAGE_H */
diff --git a/include/asm-frv/futex.h b/include/asm-frv/futex.h
index fca9d90e32c9..08b3d1da3583 100644
--- a/include/asm-frv/futex.h
+++ b/include/asm-frv/futex.h
@@ -9,5 +9,11 @@
9 9
10extern int futex_atomic_op_inuser(int encoded_op, int __user *uaddr); 10extern int futex_atomic_op_inuser(int encoded_op, int __user *uaddr);
11 11
12static inline int
13futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
14{
15 return -ENOSYS;
16}
17
12#endif 18#endif
13#endif 19#endif
diff --git a/include/asm-frv/page.h b/include/asm-frv/page.h
index b8221b611b5c..dc0f7e08a4c2 100644
--- a/include/asm-frv/page.h
+++ b/include/asm-frv/page.h
@@ -57,13 +57,9 @@ extern unsigned long min_low_pfn;
57extern unsigned long max_pfn; 57extern unsigned long max_pfn;
58 58
59#ifdef CONFIG_MMU 59#ifdef CONFIG_MMU
60#define pfn_to_page(pfn) (mem_map + (pfn))
61#define page_to_pfn(page) ((unsigned long) ((page) - mem_map))
62#define pfn_valid(pfn) ((pfn) < max_mapnr) 60#define pfn_valid(pfn) ((pfn) < max_mapnr)
63
64#else 61#else
65#define pfn_to_page(pfn) (&mem_map[(pfn) - (PAGE_OFFSET >> PAGE_SHIFT)]) 62#define ARCH_PFN_OFFSET (PAGE_OFFSET >> PAGE_SHIFT)
66#define page_to_pfn(page) ((PAGE_OFFSET >> PAGE_SHIFT) + (unsigned long) ((page) - mem_map))
67#define pfn_valid(pfn) ((pfn) >= min_low_pfn && (pfn) < max_low_pfn) 63#define pfn_valid(pfn) ((pfn) >= min_low_pfn && (pfn) < max_low_pfn)
68 64
69#endif 65#endif
@@ -87,6 +83,7 @@ extern unsigned long max_pfn;
87#define WANT_PAGE_VIRTUAL 1 83#define WANT_PAGE_VIRTUAL 1
88#endif 84#endif
89 85
86#include <asm-generic/memory_model.h>
90#include <asm-generic/page.h> 87#include <asm-generic/page.h>
91 88
92#endif /* _ASM_PAGE_H */ 89#endif /* _ASM_PAGE_H */
diff --git a/include/asm-generic/futex.h b/include/asm-generic/futex.h
index 3ae2c7347549..df893c160318 100644
--- a/include/asm-generic/futex.h
+++ b/include/asm-generic/futex.h
@@ -49,5 +49,11 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
49 return ret; 49 return ret;
50} 50}
51 51
52static inline int
53futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
54{
55 return -ENOSYS;
56}
57
52#endif 58#endif
53#endif 59#endif
diff --git a/include/asm-generic/memory_model.h b/include/asm-generic/memory_model.h
new file mode 100644
index 000000000000..0cfb086dd373
--- /dev/null
+++ b/include/asm-generic/memory_model.h
@@ -0,0 +1,77 @@
1#ifndef __ASM_MEMORY_MODEL_H
2#define __ASM_MEMORY_MODEL_H
3
4#ifdef __KERNEL__
5#ifndef __ASSEMBLY__
6
7#if defined(CONFIG_FLATMEM)
8
9#ifndef ARCH_PFN_OFFSET
10#define ARCH_PFN_OFFSET (0UL)
11#endif
12
13#elif defined(CONFIG_DISCONTIGMEM)
14
15#ifndef arch_pfn_to_nid
16#define arch_pfn_to_nid(pfn) pfn_to_nid(pfn)
17#endif
18
19#ifndef arch_local_page_offset
20#define arch_local_page_offset(pfn, nid) \
21 ((pfn) - NODE_DATA(nid)->node_start_pfn)
22#endif
23
24#endif /* CONFIG_DISCONTIGMEM */
25
26#ifdef CONFIG_OUT_OF_LINE_PFN_TO_PAGE
27struct page;
28/* this is useful when inlined pfn_to_page is too big */
29extern struct page *pfn_to_page(unsigned long pfn);
30extern unsigned long page_to_pfn(struct page *page);
31#else
32/*
33 * supports 3 memory models.
34 */
35#if defined(CONFIG_FLATMEM)
36
37#define pfn_to_page(pfn) (mem_map + ((pfn) - ARCH_PFN_OFFSET))
38#define page_to_pfn(page) ((unsigned long)((page) - mem_map) + \
39 ARCH_PFN_OFFSET)
40#elif defined(CONFIG_DISCONTIGMEM)
41
42#define pfn_to_page(pfn) \
43({ unsigned long __pfn = (pfn); \
44 unsigned long __nid = arch_pfn_to_nid(pfn); \
45 NODE_DATA(__nid)->node_mem_map + arch_local_page_offset(__pfn, __nid);\
46})
47
48#define page_to_pfn(pg) \
49({ struct page *__pg = (pg); \
50 struct pglist_data *__pgdat = NODE_DATA(page_to_nid(__pg)); \
51 (unsigned long)(__pg - __pgdat->node_mem_map) + \
52 __pgdat->node_start_pfn; \
53})
54
55#elif defined(CONFIG_SPARSEMEM)
56/*
57 * Note: section's mem_map is encorded to reflect its start_pfn.
58 * section[i].section_mem_map == mem_map's address - start_pfn;
59 */
60#define page_to_pfn(pg) \
61({ struct page *__pg = (pg); \
62 int __sec = page_to_section(__pg); \
63 __pg - __section_mem_map_addr(__nr_to_section(__sec)); \
64})
65
66#define pfn_to_page(pfn) \
67({ unsigned long __pfn = (pfn); \
68 struct mem_section *__sec = __pfn_to_section(__pfn); \
69 __section_mem_map_addr(__sec) + __pfn; \
70})
71#endif /* CONFIG_FLATMEM/DISCONTIGMEM/SPARSEMEM */
72#endif /* CONFIG_OUT_OF_LINE_PFN_TO_PAGE */
73
74#endif /* __ASSEMBLY__ */
75#endif /* __KERNEL__ */
76
77#endif
diff --git a/include/asm-h8300/page.h b/include/asm-h8300/page.h
index cd35b1cc6cde..6472c9f88227 100644
--- a/include/asm-h8300/page.h
+++ b/include/asm-h8300/page.h
@@ -71,8 +71,7 @@ extern unsigned long memory_end;
71#define page_to_virt(page) ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET) 71#define page_to_virt(page) ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)
72#define pfn_valid(page) (page < max_mapnr) 72#define pfn_valid(page) (page < max_mapnr)
73 73
74#define pfn_to_page(pfn) virt_to_page(pfn_to_virt(pfn)) 74#define ARCH_PFN_OFFSET (PAGE_OFFSET >> PAGE_SHIFT)
75#define page_to_pfn(page) virt_to_pfn(page_to_virt(page))
76 75
77#define virt_addr_valid(kaddr) (((void *)(kaddr) >= (void *)PAGE_OFFSET) && \ 76#define virt_addr_valid(kaddr) (((void *)(kaddr) >= (void *)PAGE_OFFSET) && \
78 ((void *)(kaddr) < (void *)memory_end)) 77 ((void *)(kaddr) < (void *)memory_end))
@@ -81,6 +80,7 @@ extern unsigned long memory_end;
81 80
82#endif /* __KERNEL__ */ 81#endif /* __KERNEL__ */
83 82
83#include <asm-generic/memory_model.h>
84#include <asm-generic/page.h> 84#include <asm-generic/page.h>
85 85
86#endif /* _H8300_PAGE_H */ 86#endif /* _H8300_PAGE_H */
diff --git a/include/asm-i386/futex.h b/include/asm-i386/futex.h
index 44b9db806474..7b8ceefd010f 100644
--- a/include/asm-i386/futex.h
+++ b/include/asm-i386/futex.h
@@ -104,5 +104,32 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
104 return ret; 104 return ret;
105} 105}
106 106
107static inline int
108futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
109{
110 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
111 return -EFAULT;
112
113 __asm__ __volatile__(
114 "1: " LOCK_PREFIX "cmpxchgl %3, %1 \n"
115
116 "2: .section .fixup, \"ax\" \n"
117 "3: mov %2, %0 \n"
118 " jmp 2b \n"
119 " .previous \n"
120
121 " .section __ex_table, \"a\" \n"
122 " .align 8 \n"
123 " .long 1b,3b \n"
124 " .previous \n"
125
126 : "=a" (oldval), "=m" (*uaddr)
127 : "i" (-EFAULT), "r" (newval), "0" (oldval)
128 : "memory"
129 );
130
131 return oldval;
132}
133
107#endif 134#endif
108#endif 135#endif
diff --git a/include/asm-i386/kdebug.h b/include/asm-i386/kdebug.h
index 316138e89910..96d0828ce096 100644
--- a/include/asm-i386/kdebug.h
+++ b/include/asm-i386/kdebug.h
@@ -17,11 +17,9 @@ struct die_args {
17 int signr; 17 int signr;
18}; 18};
19 19
20/* Note - you should never unregister because that can race with NMIs. 20extern int register_die_notifier(struct notifier_block *);
21 If you really want to do it first unregister - then synchronize_sched - then free. 21extern int unregister_die_notifier(struct notifier_block *);
22 */ 22extern struct atomic_notifier_head i386die_chain;
23int register_die_notifier(struct notifier_block *nb);
24extern struct notifier_block *i386die_chain;
25 23
26 24
27/* Grossly misnamed. */ 25/* Grossly misnamed. */
@@ -51,7 +49,7 @@ static inline int notify_die(enum die_val val, const char *str,
51 .trapnr = trap, 49 .trapnr = trap,
52 .signr = sig 50 .signr = sig
53 }; 51 };
54 return notifier_call_chain(&i386die_chain, val, &args); 52 return atomic_notifier_call_chain(&i386die_chain, val, &args);
55} 53}
56 54
57#endif 55#endif
diff --git a/include/asm-i386/mmzone.h b/include/asm-i386/mmzone.h
index 74f595d80579..e33e9f9e4c66 100644
--- a/include/asm-i386/mmzone.h
+++ b/include/asm-i386/mmzone.h
@@ -70,8 +70,6 @@ static inline int pfn_to_nid(unsigned long pfn)
70#endif 70#endif
71} 71}
72 72
73#define node_localnr(pfn, nid) ((pfn) - node_data[nid]->node_start_pfn)
74
75/* 73/*
76 * Following are macros that each numa implmentation must define. 74 * Following are macros that each numa implmentation must define.
77 */ 75 */
@@ -86,21 +84,6 @@ static inline int pfn_to_nid(unsigned long pfn)
86/* XXX: FIXME -- wli */ 84/* XXX: FIXME -- wli */
87#define kern_addr_valid(kaddr) (0) 85#define kern_addr_valid(kaddr) (0)
88 86
89#define pfn_to_page(pfn) \
90({ \
91 unsigned long __pfn = pfn; \
92 int __node = pfn_to_nid(__pfn); \
93 &NODE_DATA(__node)->node_mem_map[node_localnr(__pfn,__node)]; \
94})
95
96#define page_to_pfn(pg) \
97({ \
98 struct page *__page = pg; \
99 struct zone *__zone = page_zone(__page); \
100 (unsigned long)(__page - __zone->zone_mem_map) \
101 + __zone->zone_start_pfn; \
102})
103
104#ifdef CONFIG_X86_NUMAQ /* we have contiguous memory on NUMA-Q */ 87#ifdef CONFIG_X86_NUMAQ /* we have contiguous memory on NUMA-Q */
105#define pfn_valid(pfn) ((pfn) < num_physpages) 88#define pfn_valid(pfn) ((pfn) < num_physpages)
106#else 89#else
diff --git a/include/asm-i386/page.h b/include/asm-i386/page.h
index 997ca5d17876..30f52a2263ba 100644
--- a/include/asm-i386/page.h
+++ b/include/asm-i386/page.h
@@ -126,8 +126,6 @@ extern int page_is_ram(unsigned long pagenr);
126#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) 126#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
127#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) 127#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
128#ifdef CONFIG_FLATMEM 128#ifdef CONFIG_FLATMEM
129#define pfn_to_page(pfn) (mem_map + (pfn))
130#define page_to_pfn(page) ((unsigned long)((page) - mem_map))
131#define pfn_valid(pfn) ((pfn) < max_mapnr) 129#define pfn_valid(pfn) ((pfn) < max_mapnr)
132#endif /* CONFIG_FLATMEM */ 130#endif /* CONFIG_FLATMEM */
133#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) 131#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
@@ -141,6 +139,7 @@ extern int page_is_ram(unsigned long pagenr);
141 139
142#endif /* __KERNEL__ */ 140#endif /* __KERNEL__ */
143 141
142#include <asm-generic/memory_model.h>
144#include <asm-generic/page.h> 143#include <asm-generic/page.h>
145 144
146#endif /* _I386_PAGE_H */ 145#endif /* _I386_PAGE_H */
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index feca5d961e2b..af4bfd012475 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -20,6 +20,7 @@
20#include <linux/config.h> 20#include <linux/config.h>
21#include <linux/threads.h> 21#include <linux/threads.h>
22#include <asm/percpu.h> 22#include <asm/percpu.h>
23#include <linux/cpumask.h>
23 24
24/* flag for disabling the tsc */ 25/* flag for disabling the tsc */
25extern int tsc_disable; 26extern int tsc_disable;
@@ -67,6 +68,9 @@ struct cpuinfo_x86 {
67 char pad0; 68 char pad0;
68 int x86_power; 69 int x86_power;
69 unsigned long loops_per_jiffy; 70 unsigned long loops_per_jiffy;
71#ifdef CONFIG_SMP
72 cpumask_t llc_shared_map; /* cpus sharing the last level cache */
73#endif
70 unsigned char x86_max_cores; /* cpuid returned max cores value */ 74 unsigned char x86_max_cores; /* cpuid returned max cores value */
71 unsigned char booted_cores; /* number of cores as seen by OS */ 75 unsigned char booted_cores; /* number of cores as seen by OS */
72 unsigned char apicid; 76 unsigned char apicid;
@@ -103,6 +107,7 @@ extern struct cpuinfo_x86 cpu_data[];
103 107
104extern int phys_proc_id[NR_CPUS]; 108extern int phys_proc_id[NR_CPUS];
105extern int cpu_core_id[NR_CPUS]; 109extern int cpu_core_id[NR_CPUS];
110extern int cpu_llc_id[NR_CPUS];
106extern char ignore_fpu_irq; 111extern char ignore_fpu_irq;
107 112
108extern void identify_cpu(struct cpuinfo_x86 *); 113extern void identify_cpu(struct cpuinfo_x86 *);
diff --git a/include/asm-i386/setup.h b/include/asm-i386/setup.h
index 826a8ca50ac8..ee941457b55d 100644
--- a/include/asm-i386/setup.h
+++ b/include/asm-i386/setup.h
@@ -6,9 +6,7 @@
6#ifndef _i386_SETUP_H 6#ifndef _i386_SETUP_H
7#define _i386_SETUP_H 7#define _i386_SETUP_H
8 8
9#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) 9#include <linux/pfn.h>
10#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
11#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
12 10
13/* 11/*
14 * Reserved space for vmalloc and iomap - defined in asm/page.h 12 * Reserved space for vmalloc and iomap - defined in asm/page.h
diff --git a/include/asm-i386/topology.h b/include/asm-i386/topology.h
index aa958c6ee83e..b94e5eeef917 100644
--- a/include/asm-i386/topology.h
+++ b/include/asm-i386/topology.h
@@ -112,4 +112,6 @@ extern unsigned long node_remap_size[];
112 112
113#endif /* CONFIG_NUMA */ 113#endif /* CONFIG_NUMA */
114 114
115extern cpumask_t cpu_coregroup_map(int cpu);
116
115#endif /* _ASM_I386_TOPOLOGY_H */ 117#endif /* _ASM_I386_TOPOLOGY_H */
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
index d8afd0e3b81a..014e3562895b 100644
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -316,8 +316,10 @@
316#define __NR_pselect6 308 316#define __NR_pselect6 308
317#define __NR_ppoll 309 317#define __NR_ppoll 309
318#define __NR_unshare 310 318#define __NR_unshare 310
319#define __NR_set_robust_list 311
320#define __NR_get_robust_list 312
319 321
320#define NR_syscalls 311 322#define NR_syscalls 313
321 323
322/* 324/*
323 * user-visible error numbers are in the range -1 - -128: see 325 * user-visible error numbers are in the range -1 - -128: see
diff --git a/include/asm-ia64/compat.h b/include/asm-ia64/compat.h
index c0b19106665c..40d01d80610d 100644
--- a/include/asm-ia64/compat.h
+++ b/include/asm-ia64/compat.h
@@ -189,6 +189,12 @@ compat_ptr (compat_uptr_t uptr)
189 return (void __user *) (unsigned long) uptr; 189 return (void __user *) (unsigned long) uptr;
190} 190}
191 191
192static inline compat_uptr_t
193ptr_to_compat(void __user *uptr)
194{
195 return (u32)(unsigned long)uptr;
196}
197
192static __inline__ void __user * 198static __inline__ void __user *
193compat_alloc_user_space (long len) 199compat_alloc_user_space (long len)
194{ 200{
diff --git a/include/asm-ia64/kdebug.h b/include/asm-ia64/kdebug.h
index 8b01a083dde6..218c458ab60c 100644
--- a/include/asm-ia64/kdebug.h
+++ b/include/asm-ia64/kdebug.h
@@ -40,7 +40,7 @@ struct die_args {
40 40
41extern int register_die_notifier(struct notifier_block *); 41extern int register_die_notifier(struct notifier_block *);
42extern int unregister_die_notifier(struct notifier_block *); 42extern int unregister_die_notifier(struct notifier_block *);
43extern struct notifier_block *ia64die_chain; 43extern struct atomic_notifier_head ia64die_chain;
44 44
45enum die_val { 45enum die_val {
46 DIE_BREAK = 1, 46 DIE_BREAK = 1,
@@ -81,7 +81,7 @@ static inline int notify_die(enum die_val val, char *str, struct pt_regs *regs,
81 .signr = sig 81 .signr = sig
82 }; 82 };
83 83
84 return notifier_call_chain(&ia64die_chain, val, &args); 84 return atomic_notifier_call_chain(&ia64die_chain, val, &args);
85} 85}
86 86
87#endif 87#endif
diff --git a/include/asm-ia64/page.h b/include/asm-ia64/page.h
index 6e9aa23250c4..2087825eefa4 100644
--- a/include/asm-ia64/page.h
+++ b/include/asm-ia64/page.h
@@ -106,17 +106,25 @@ extern int ia64_pfn_valid (unsigned long pfn);
106# define ia64_pfn_valid(pfn) 1 106# define ia64_pfn_valid(pfn) 1
107#endif 107#endif
108 108
109#ifdef CONFIG_VIRTUAL_MEM_MAP
110extern struct page *vmem_map;
111#ifdef CONFIG_DISCONTIGMEM
112# define page_to_pfn(page) ((unsigned long) (page - vmem_map))
113# define pfn_to_page(pfn) (vmem_map + (pfn))
114#endif
115#endif
116
117#if defined(CONFIG_FLATMEM) || defined(CONFIG_SPARSEMEM)
118/* FLATMEM always configures mem_map (mem_map = vmem_map if necessary) */
119#include <asm-generic/memory_model.h>
120#endif
121
109#ifdef CONFIG_FLATMEM 122#ifdef CONFIG_FLATMEM
110# define pfn_valid(pfn) (((pfn) < max_mapnr) && ia64_pfn_valid(pfn)) 123# define pfn_valid(pfn) (((pfn) < max_mapnr) && ia64_pfn_valid(pfn))
111# define page_to_pfn(page) ((unsigned long) (page - mem_map))
112# define pfn_to_page(pfn) (mem_map + (pfn))
113#elif defined(CONFIG_DISCONTIGMEM) 124#elif defined(CONFIG_DISCONTIGMEM)
114extern struct page *vmem_map;
115extern unsigned long min_low_pfn; 125extern unsigned long min_low_pfn;
116extern unsigned long max_low_pfn; 126extern unsigned long max_low_pfn;
117# define pfn_valid(pfn) (((pfn) >= min_low_pfn) && ((pfn) < max_low_pfn) && ia64_pfn_valid(pfn)) 127# define pfn_valid(pfn) (((pfn) >= min_low_pfn) && ((pfn) < max_low_pfn) && ia64_pfn_valid(pfn))
118# define page_to_pfn(page) ((unsigned long) (page - vmem_map))
119# define pfn_to_page(pfn) (vmem_map + (pfn))
120#endif 128#endif
121 129
122#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) 130#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
diff --git a/include/asm-m32r/mmzone.h b/include/asm-m32r/mmzone.h
index adc7970a77ec..9f3b5accda88 100644
--- a/include/asm-m32r/mmzone.h
+++ b/include/asm-m32r/mmzone.h
@@ -21,20 +21,6 @@ extern struct pglist_data *node_data[];
21 __pgdat->node_start_pfn + __pgdat->node_spanned_pages - 1; \ 21 __pgdat->node_start_pfn + __pgdat->node_spanned_pages - 1; \
22}) 22})
23 23
24#define pfn_to_page(pfn) \
25({ \
26 unsigned long __pfn = pfn; \
27 int __node = pfn_to_nid(__pfn); \
28 &NODE_DATA(__node)->node_mem_map[node_localnr(__pfn,__node)]; \
29})
30
31#define page_to_pfn(pg) \
32({ \
33 struct page *__page = pg; \
34 struct zone *__zone = page_zone(__page); \
35 (unsigned long)(__page - __zone->zone_mem_map) \
36 + __zone->zone_start_pfn; \
37})
38#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)) 24#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
39/* 25/*
40 * pfn_valid should be made as fast as possible, and the current definition 26 * pfn_valid should be made as fast as possible, and the current definition
diff --git a/include/asm-m32r/page.h b/include/asm-m32r/page.h
index 4ab578876361..9ddbc087dbc5 100644
--- a/include/asm-m32r/page.h
+++ b/include/asm-m32r/page.h
@@ -76,9 +76,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
76 76
77#ifndef CONFIG_DISCONTIGMEM 77#ifndef CONFIG_DISCONTIGMEM
78#define PFN_BASE (CONFIG_MEMORY_START >> PAGE_SHIFT) 78#define PFN_BASE (CONFIG_MEMORY_START >> PAGE_SHIFT)
79#define pfn_to_page(pfn) (mem_map + ((pfn) - PFN_BASE)) 79#define ARCH_PFN_OFFSET PFN_BASE
80#define page_to_pfn(page) \
81 ((unsigned long)((page) - mem_map) + PFN_BASE)
82#define pfn_valid(pfn) (((pfn) - PFN_BASE) < max_mapnr) 80#define pfn_valid(pfn) (((pfn) - PFN_BASE) < max_mapnr)
83#endif /* !CONFIG_DISCONTIGMEM */ 81#endif /* !CONFIG_DISCONTIGMEM */
84 82
@@ -92,6 +90,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
92 90
93#endif /* __KERNEL__ */ 91#endif /* __KERNEL__ */
94 92
93#include <asm-generic/memory_model.h>
95#include <asm-generic/page.h> 94#include <asm-generic/page.h>
96 95
97#endif /* _ASM_M32R_PAGE_H */ 96#endif /* _ASM_M32R_PAGE_H */
diff --git a/include/asm-m32r/setup.h b/include/asm-m32r/setup.h
index 5f028dc26a9b..52f4fa29abfc 100644
--- a/include/asm-m32r/setup.h
+++ b/include/asm-m32r/setup.h
@@ -24,10 +24,6 @@
24#define RAMDISK_PROMPT_FLAG (0x8000) 24#define RAMDISK_PROMPT_FLAG (0x8000)
25#define RAMDISK_LOAD_FLAG (0x4000) 25#define RAMDISK_LOAD_FLAG (0x4000)
26 26
27#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
28#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
29#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
30
31extern unsigned long memory_start; 27extern unsigned long memory_start;
32extern unsigned long memory_end; 28extern unsigned long memory_end;
33 29
diff --git a/include/asm-mips/compat.h b/include/asm-mips/compat.h
index 0012bd804d2d..986511db54a6 100644
--- a/include/asm-mips/compat.h
+++ b/include/asm-mips/compat.h
@@ -133,6 +133,11 @@ static inline void __user *compat_ptr(compat_uptr_t uptr)
133 return (void __user *)(long)uptr; 133 return (void __user *)(long)uptr;
134} 134}
135 135
136static inline compat_uptr_t ptr_to_compat(void __user *uptr)
137{
138 return (u32)(unsigned long)uptr;
139}
140
136static inline void __user *compat_alloc_user_space(long len) 141static inline void __user *compat_alloc_user_space(long len)
137{ 142{
138 struct pt_regs *regs = (struct pt_regs *) 143 struct pt_regs *regs = (struct pt_regs *)
diff --git a/include/asm-mips/futex.h b/include/asm-mips/futex.h
index 2454c44a8f54..a554089991f2 100644
--- a/include/asm-mips/futex.h
+++ b/include/asm-mips/futex.h
@@ -99,5 +99,11 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
99 return ret; 99 return ret;
100} 100}
101 101
102static inline int
103futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
104{
105 return -ENOSYS;
106}
107
102#endif 108#endif
103#endif 109#endif
diff --git a/include/asm-mips/mmzone.h b/include/asm-mips/mmzone.h
index 011caebac369..7bde4432092b 100644
--- a/include/asm-mips/mmzone.h
+++ b/include/asm-mips/mmzone.h
@@ -22,20 +22,6 @@
22 NODE_DATA(__n)->node_spanned_pages) : 0);\ 22 NODE_DATA(__n)->node_spanned_pages) : 0);\
23}) 23})
24 24
25#define pfn_to_page(pfn) \
26({ \
27 unsigned long __pfn = (pfn); \
28 pg_data_t *__pg = NODE_DATA(pfn_to_nid(__pfn)); \
29 __pg->node_mem_map + (__pfn - __pg->node_start_pfn); \
30})
31
32#define page_to_pfn(p) \
33({ \
34 struct page *__p = (p); \
35 struct zone *__z = page_zone(__p); \
36 ((__p - __z->zone_mem_map) + __z->zone_start_pfn); \
37})
38
39/* XXX: FIXME -- wli */ 25/* XXX: FIXME -- wli */
40#define kern_addr_valid(addr) (0) 26#define kern_addr_valid(addr) (0)
41 27
diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h
index ee25a779bf49..a1eab136ff6c 100644
--- a/include/asm-mips/page.h
+++ b/include/asm-mips/page.h
@@ -140,8 +140,6 @@ typedef struct { unsigned long pgprot; } pgprot_t;
140#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) 140#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
141 141
142#ifndef CONFIG_NEED_MULTIPLE_NODES 142#ifndef CONFIG_NEED_MULTIPLE_NODES
143#define pfn_to_page(pfn) (mem_map + (pfn))
144#define page_to_pfn(page) ((unsigned long)((page) - mem_map))
145#define pfn_valid(pfn) ((pfn) < max_mapnr) 143#define pfn_valid(pfn) ((pfn) < max_mapnr)
146#endif 144#endif
147 145
@@ -160,6 +158,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
160#define WANT_PAGE_VIRTUAL 158#define WANT_PAGE_VIRTUAL
161#endif 159#endif
162 160
161#include <asm-generic/memory_model.h>
163#include <asm-generic/page.h> 162#include <asm-generic/page.h>
164 163
165#endif /* _ASM_PAGE_H */ 164#endif /* _ASM_PAGE_H */
diff --git a/include/asm-mips/time.h b/include/asm-mips/time.h
index 9cc3564cc2c9..d897c8bb554d 100644
--- a/include/asm-mips/time.h
+++ b/include/asm-mips/time.h
@@ -26,14 +26,14 @@ extern spinlock_t rtc_lock;
26 26
27/* 27/*
28 * RTC ops. By default, they point to no-RTC functions. 28 * RTC ops. By default, they point to no-RTC functions.
29 * rtc_get_time - mktime(year, mon, day, hour, min, sec) in seconds. 29 * rtc_mips_get_time - mktime(year, mon, day, hour, min, sec) in seconds.
30 * rtc_set_time - reverse the above translation and set time to RTC. 30 * rtc_mips_set_time - reverse the above translation and set time to RTC.
31 * rtc_set_mmss - similar to rtc_set_time, but only min and sec need 31 * rtc_mips_set_mmss - similar to rtc_set_time, but only min and sec need
32 * to be set. Used by RTC sync-up. 32 * to be set. Used by RTC sync-up.
33 */ 33 */
34extern unsigned long (*rtc_get_time)(void); 34extern unsigned long (*rtc_mips_get_time)(void);
35extern int (*rtc_set_time)(unsigned long); 35extern int (*rtc_mips_set_time)(unsigned long);
36extern int (*rtc_set_mmss)(unsigned long); 36extern int (*rtc_mips_set_mmss)(unsigned long);
37 37
38/* 38/*
39 * Timer interrupt functions. 39 * Timer interrupt functions.
diff --git a/include/asm-parisc/compat.h b/include/asm-parisc/compat.h
index 38b918feead9..289624d8b2d4 100644
--- a/include/asm-parisc/compat.h
+++ b/include/asm-parisc/compat.h
@@ -138,6 +138,11 @@ static inline void __user *compat_ptr(compat_uptr_t uptr)
138 return (void __user *)(unsigned long)uptr; 138 return (void __user *)(unsigned long)uptr;
139} 139}
140 140
141static inline compat_uptr_t ptr_to_compat(void __user *uptr)
142{
143 return (u32)(unsigned long)uptr;
144}
145
141static __inline__ void __user *compat_alloc_user_space(long len) 146static __inline__ void __user *compat_alloc_user_space(long len)
142{ 147{
143 struct pt_regs *regs = &current->thread.regs; 148 struct pt_regs *regs = &current->thread.regs;
diff --git a/include/asm-parisc/mmzone.h b/include/asm-parisc/mmzone.h
index ae039f4fd711..ceb9b73199d1 100644
--- a/include/asm-parisc/mmzone.h
+++ b/include/asm-parisc/mmzone.h
@@ -25,23 +25,6 @@ extern struct node_map_data node_data[];
25 pg_data_t *__pgdat = NODE_DATA(nid); \ 25 pg_data_t *__pgdat = NODE_DATA(nid); \
26 __pgdat->node_start_pfn + __pgdat->node_spanned_pages; \ 26 __pgdat->node_start_pfn + __pgdat->node_spanned_pages; \
27}) 27})
28#define node_localnr(pfn, nid) ((pfn) - node_start_pfn(nid))
29
30#define pfn_to_page(pfn) \
31({ \
32 unsigned long __pfn = (pfn); \
33 int __node = pfn_to_nid(__pfn); \
34 &NODE_DATA(__node)->node_mem_map[node_localnr(__pfn,__node)]; \
35})
36
37#define page_to_pfn(pg) \
38({ \
39 struct page *__page = pg; \
40 struct zone *__zone = page_zone(__page); \
41 BUG_ON(__zone == NULL); \
42 (unsigned long)(__page - __zone->zone_mem_map) \
43 + __zone->zone_start_pfn; \
44})
45 28
46/* We have these possible memory map layouts: 29/* We have these possible memory map layouts:
47 * Astro: 0-3.75, 67.75-68, 4-64 30 * Astro: 0-3.75, 67.75-68, 4-64
diff --git a/include/asm-parisc/page.h b/include/asm-parisc/page.h
index 4a6752b0afed..9f303c0c3cd7 100644
--- a/include/asm-parisc/page.h
+++ b/include/asm-parisc/page.h
@@ -130,8 +130,6 @@ extern int npmem_ranges;
130#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) 130#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
131 131
132#ifndef CONFIG_DISCONTIGMEM 132#ifndef CONFIG_DISCONTIGMEM
133#define pfn_to_page(pfn) (mem_map + (pfn))
134#define page_to_pfn(page) ((unsigned long)((page) - mem_map))
135#define pfn_valid(pfn) ((pfn) < max_mapnr) 133#define pfn_valid(pfn) ((pfn) < max_mapnr)
136#endif /* CONFIG_DISCONTIGMEM */ 134#endif /* CONFIG_DISCONTIGMEM */
137 135
@@ -152,6 +150,7 @@ extern int npmem_ranges;
152 150
153#endif /* __KERNEL__ */ 151#endif /* __KERNEL__ */
154 152
153#include <asm-generic/memory_model.h>
155#include <asm-generic/page.h> 154#include <asm-generic/page.h>
156 155
157#endif /* _PARISC_PAGE_H */ 156#endif /* _PARISC_PAGE_H */
diff --git a/include/asm-powerpc/futex.h b/include/asm-powerpc/futex.h
index 39e85f320a76..f1b3c00bc1ce 100644
--- a/include/asm-powerpc/futex.h
+++ b/include/asm-powerpc/futex.h
@@ -81,5 +81,11 @@ static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
81 return ret; 81 return ret;
82} 82}
83 83
84static inline int
85futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
86{
87 return -ENOSYS;
88}
89
84#endif /* __KERNEL__ */ 90#endif /* __KERNEL__ */
85#endif /* _ASM_POWERPC_FUTEX_H */ 91#endif /* _ASM_POWERPC_FUTEX_H */
diff --git a/include/asm-powerpc/kdebug.h b/include/asm-powerpc/kdebug.h
index 7c16265568e0..c01786ab5fa6 100644
--- a/include/asm-powerpc/kdebug.h
+++ b/include/asm-powerpc/kdebug.h
@@ -16,13 +16,9 @@ struct die_args {
16 int signr; 16 int signr;
17}; 17};
18 18
19/* 19extern int register_die_notifier(struct notifier_block *);
20 Note - you should never unregister because that can race with NMIs. 20extern int unregister_die_notifier(struct notifier_block *);
21 If you really want to do it first unregister - then synchronize_sched - 21extern struct atomic_notifier_head powerpc_die_chain;
22 then free.
23 */
24int register_die_notifier(struct notifier_block *nb);
25extern struct notifier_block *powerpc_die_chain;
26 22
27/* Grossly misnamed. */ 23/* Grossly misnamed. */
28enum die_val { 24enum die_val {
@@ -37,7 +33,7 @@ enum die_val {
37static inline int notify_die(enum die_val val,char *str,struct pt_regs *regs,long err,int trap, int sig) 33static inline int notify_die(enum die_val val,char *str,struct pt_regs *regs,long err,int trap, int sig)
38{ 34{
39 struct die_args args = { .regs=regs, .str=str, .err=err, .trapnr=trap,.signr=sig }; 35 struct die_args args = { .regs=regs, .str=str, .err=err, .trapnr=trap,.signr=sig };
40 return notifier_call_chain(&powerpc_die_chain, val, &args); 36 return atomic_notifier_call_chain(&powerpc_die_chain, val, &args);
41} 37}
42 38
43#endif /* __KERNEL__ */ 39#endif /* __KERNEL__ */
diff --git a/include/asm-powerpc/page.h b/include/asm-powerpc/page.h
index 0b82df483f7f..2fbecebe1c92 100644
--- a/include/asm-powerpc/page.h
+++ b/include/asm-powerpc/page.h
@@ -69,8 +69,6 @@
69#endif 69#endif
70 70
71#ifdef CONFIG_FLATMEM 71#ifdef CONFIG_FLATMEM
72#define pfn_to_page(pfn) (mem_map + (pfn))
73#define page_to_pfn(page) ((unsigned long)((page) - mem_map))
74#define pfn_valid(pfn) ((pfn) < max_mapnr) 72#define pfn_valid(pfn) ((pfn) < max_mapnr)
75#endif 73#endif
76 74
@@ -200,6 +198,7 @@ extern void copy_user_page(void *to, void *from, unsigned long vaddr,
200 struct page *p); 198 struct page *p);
201extern int page_is_ram(unsigned long pfn); 199extern int page_is_ram(unsigned long pfn);
202 200
201#include <asm-generic/memory_model.h>
203#endif /* __ASSEMBLY__ */ 202#endif /* __ASSEMBLY__ */
204 203
205#endif /* __KERNEL__ */ 204#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/page.h b/include/asm-ppc/page.h
index 538e0c8ab243..a70ba2ee552d 100644
--- a/include/asm-ppc/page.h
+++ b/include/asm-ppc/page.h
@@ -149,8 +149,7 @@ extern int page_is_ram(unsigned long pfn);
149#define __pa(x) ___pa((unsigned long)(x)) 149#define __pa(x) ___pa((unsigned long)(x))
150#define __va(x) ((void *)(___va((unsigned long)(x)))) 150#define __va(x) ((void *)(___va((unsigned long)(x))))
151 151
152#define pfn_to_page(pfn) (mem_map + ((pfn) - PPC_PGSTART)) 152#define ARCH_PFN_OFFSET (PPC_PGSTART)
153#define page_to_pfn(page) ((unsigned long)((page) - mem_map) + PPC_PGSTART)
154#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) 153#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
155#define page_to_virt(page) __va(page_to_pfn(page) << PAGE_SHIFT) 154#define page_to_virt(page) __va(page_to_pfn(page) << PAGE_SHIFT)
156 155
@@ -175,5 +174,6 @@ extern __inline__ int get_order(unsigned long size)
175/* We do define AT_SYSINFO_EHDR but don't use the gate mecanism */ 174/* We do define AT_SYSINFO_EHDR but don't use the gate mecanism */
176#define __HAVE_ARCH_GATE_AREA 1 175#define __HAVE_ARCH_GATE_AREA 1
177 176
177#include <asm-generic/memory_model.h>
178#endif /* __KERNEL__ */ 178#endif /* __KERNEL__ */
179#endif /* _PPC_PAGE_H */ 179#endif /* _PPC_PAGE_H */
diff --git a/include/asm-s390/compat.h b/include/asm-s390/compat.h
index a007715f4aea..356a0b183539 100644
--- a/include/asm-s390/compat.h
+++ b/include/asm-s390/compat.h
@@ -128,6 +128,11 @@ static inline void __user *compat_ptr(compat_uptr_t uptr)
128 return (void __user *)(unsigned long)(uptr & 0x7fffffffUL); 128 return (void __user *)(unsigned long)(uptr & 0x7fffffffUL);
129} 129}
130 130
131static inline compat_uptr_t ptr_to_compat(void __user *uptr)
132{
133 return (u32)(unsigned long)uptr;
134}
135
131static inline void __user *compat_alloc_user_space(long len) 136static inline void __user *compat_alloc_user_space(long len)
132{ 137{
133 unsigned long stack; 138 unsigned long stack;
diff --git a/include/asm-s390/page.h b/include/asm-s390/page.h
index 2430c561e021..3b1138ac7e79 100644
--- a/include/asm-s390/page.h
+++ b/include/asm-s390/page.h
@@ -181,8 +181,6 @@ page_get_storage_key(unsigned long addr)
181#define PAGE_OFFSET 0x0UL 181#define PAGE_OFFSET 0x0UL
182#define __pa(x) (unsigned long)(x) 182#define __pa(x) (unsigned long)(x)
183#define __va(x) (void *)(unsigned long)(x) 183#define __va(x) (void *)(unsigned long)(x)
184#define pfn_to_page(pfn) (mem_map + (pfn))
185#define page_to_pfn(page) ((unsigned long)((page) - mem_map))
186#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) 184#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
187 185
188#define pfn_valid(pfn) ((pfn) < max_mapnr) 186#define pfn_valid(pfn) ((pfn) < max_mapnr)
@@ -193,6 +191,7 @@ page_get_storage_key(unsigned long addr)
193 191
194#endif /* __KERNEL__ */ 192#endif /* __KERNEL__ */
195 193
194#include <asm-generic/memory_model.h>
196#include <asm-generic/page.h> 195#include <asm-generic/page.h>
197 196
198#endif /* _S390_PAGE_H */ 197#endif /* _S390_PAGE_H */
diff --git a/include/asm-sh/page.h b/include/asm-sh/page.h
index 972c3f655b2a..9c89287c3e56 100644
--- a/include/asm-sh/page.h
+++ b/include/asm-sh/page.h
@@ -105,9 +105,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
105 105
106/* PFN start number, because of __MEMORY_START */ 106/* PFN start number, because of __MEMORY_START */
107#define PFN_START (__MEMORY_START >> PAGE_SHIFT) 107#define PFN_START (__MEMORY_START >> PAGE_SHIFT)
108 108#define ARCH_PFN_OFFSET (FPN_START)
109#define pfn_to_page(pfn) (mem_map + (pfn) - PFN_START)
110#define page_to_pfn(page) ((unsigned long)((page) - mem_map) + PFN_START)
111#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) 109#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
112#define pfn_valid(pfn) (((pfn) - PFN_START) < max_mapnr) 110#define pfn_valid(pfn) (((pfn) - PFN_START) < max_mapnr)
113#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) 111#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
@@ -117,6 +115,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
117 115
118#endif /* __KERNEL__ */ 116#endif /* __KERNEL__ */
119 117
118#include <asm-generic/memory_model.h>
120#include <asm-generic/page.h> 119#include <asm-generic/page.h>
121 120
122#endif /* __ASM_SH_PAGE_H */ 121#endif /* __ASM_SH_PAGE_H */
diff --git a/include/asm-sh64/page.h b/include/asm-sh64/page.h
index c86df90f7cbd..e4937cdabebd 100644
--- a/include/asm-sh64/page.h
+++ b/include/asm-sh64/page.h
@@ -105,9 +105,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
105 105
106/* PFN start number, because of __MEMORY_START */ 106/* PFN start number, because of __MEMORY_START */
107#define PFN_START (__MEMORY_START >> PAGE_SHIFT) 107#define PFN_START (__MEMORY_START >> PAGE_SHIFT)
108 108#define ARCH_PFN_OFFSET (PFN_START)
109#define pfn_to_page(pfn) (mem_map + (pfn) - PFN_START)
110#define page_to_pfn(page) ((unsigned long)((page) - mem_map) + PFN_START)
111#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) 109#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
112#define pfn_valid(pfn) (((pfn) - PFN_START) < max_mapnr) 110#define pfn_valid(pfn) (((pfn) - PFN_START) < max_mapnr)
113#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) 111#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
@@ -117,6 +115,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
117 115
118#endif /* __KERNEL__ */ 116#endif /* __KERNEL__ */
119 117
118#include <asm-generic/memory_model.h>
120#include <asm-generic/page.h> 119#include <asm-generic/page.h>
121 120
122#endif /* __ASM_SH64_PAGE_H */ 121#endif /* __ASM_SH64_PAGE_H */
diff --git a/include/asm-sh64/platform.h b/include/asm-sh64/platform.h
index 7046a9014027..bd0d9c405a80 100644
--- a/include/asm-sh64/platform.h
+++ b/include/asm-sh64/platform.h
@@ -61,9 +61,4 @@ extern int platform_int_priority[NR_INTC_IRQS];
61#define code_resource (platform_parms.kram_res_p[STANDARD_KRAM_RESOURCES - 2]) 61#define code_resource (platform_parms.kram_res_p[STANDARD_KRAM_RESOURCES - 2])
62#define data_resource (platform_parms.kram_res_p[STANDARD_KRAM_RESOURCES - 1]) 62#define data_resource (platform_parms.kram_res_p[STANDARD_KRAM_RESOURCES - 1])
63 63
64/* Be prepared to 64-bit sign extensions */
65#define PFN_UP(x) ((((x) + PAGE_SIZE-1) >> PAGE_SHIFT) & 0x000fffff)
66#define PFN_DOWN(x) (((x) >> PAGE_SHIFT) & 0x000fffff)
67#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
68
69#endif /* __ASM_SH64_PLATFORM_H */ 64#endif /* __ASM_SH64_PLATFORM_H */
diff --git a/include/asm-sparc/page.h b/include/asm-sparc/page.h
index 9122684f6c1e..ec3274b7ddf4 100644
--- a/include/asm-sparc/page.h
+++ b/include/asm-sparc/page.h
@@ -152,8 +152,7 @@ extern unsigned long pfn_base;
152#define virt_to_phys __pa 152#define virt_to_phys __pa
153#define phys_to_virt __va 153#define phys_to_virt __va
154 154
155#define pfn_to_page(pfn) (mem_map + ((pfn)-(pfn_base))) 155#define ARCH_PFN_OFFSET (pfn_base)
156#define page_to_pfn(page) ((unsigned long)(((page) - mem_map) + pfn_base))
157#define virt_to_page(kaddr) (mem_map + ((((unsigned long)(kaddr)-PAGE_OFFSET)>>PAGE_SHIFT))) 156#define virt_to_page(kaddr) (mem_map + ((((unsigned long)(kaddr)-PAGE_OFFSET)>>PAGE_SHIFT)))
158 157
159#define pfn_valid(pfn) (((pfn) >= (pfn_base)) && (((pfn)-(pfn_base)) < max_mapnr)) 158#define pfn_valid(pfn) (((pfn) >= (pfn_base)) && (((pfn)-(pfn_base)) < max_mapnr))
@@ -164,6 +163,7 @@ extern unsigned long pfn_base;
164 163
165#endif /* __KERNEL__ */ 164#endif /* __KERNEL__ */
166 165
166#include <asm-generic/memory_model.h>
167#include <asm-generic/page.h> 167#include <asm-generic/page.h>
168 168
169#endif /* _SPARC_PAGE_H */ 169#endif /* _SPARC_PAGE_H */
diff --git a/include/asm-sparc64/futex.h b/include/asm-sparc64/futex.h
index 34c4b43d3f98..cd340a233156 100644
--- a/include/asm-sparc64/futex.h
+++ b/include/asm-sparc64/futex.h
@@ -83,4 +83,10 @@ static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
83 return ret; 83 return ret;
84} 84}
85 85
86static inline int
87futex_atomic_cmpxchg_inuser(int __user *uaddr, int oldval, int newval)
88{
89 return -ENOSYS;
90}
91
86#endif /* !(_SPARC64_FUTEX_H) */ 92#endif /* !(_SPARC64_FUTEX_H) */
diff --git a/include/asm-sparc64/kdebug.h b/include/asm-sparc64/kdebug.h
index 6321f5a0198d..4040d127ac3e 100644
--- a/include/asm-sparc64/kdebug.h
+++ b/include/asm-sparc64/kdebug.h
@@ -15,12 +15,9 @@ struct die_args {
15 int signr; 15 int signr;
16}; 16};
17 17
18/* Note - you should never unregister because that can race with NMIs. 18extern int register_die_notifier(struct notifier_block *);
19 * If you really want to do it first unregister - then synchronize_sched 19extern int unregister_die_notifier(struct notifier_block *);
20 * - then free. 20extern struct atomic_notifier_head sparc64die_chain;
21 */
22int register_die_notifier(struct notifier_block *nb);
23extern struct notifier_block *sparc64die_chain;
24 21
25extern void bad_trap(struct pt_regs *, long); 22extern void bad_trap(struct pt_regs *, long);
26 23
@@ -46,7 +43,7 @@ static inline int notify_die(enum die_val val,char *str, struct pt_regs *regs,
46 .trapnr = trap, 43 .trapnr = trap,
47 .signr = sig }; 44 .signr = sig };
48 45
49 return notifier_call_chain(&sparc64die_chain, val, &args); 46 return atomic_notifier_call_chain(&sparc64die_chain, val, &args);
50} 47}
51 48
52#endif 49#endif
diff --git a/include/asm-sparc64/page.h b/include/asm-sparc64/page.h
index 66fe4ac59fd6..aabb21906724 100644
--- a/include/asm-sparc64/page.h
+++ b/include/asm-sparc64/page.h
@@ -111,6 +111,8 @@ typedef unsigned long pgprot_t;
111 (_AC(0x0000000070000000,UL)) : \ 111 (_AC(0x0000000070000000,UL)) : \
112 (_AC(0xfffff80000000000,UL) + (1UL << 32UL))) 112 (_AC(0xfffff80000000000,UL) + (1UL << 32UL)))
113 113
114#include <asm-generic/memory_model.h>
115
114#endif /* !(__ASSEMBLY__) */ 116#endif /* !(__ASSEMBLY__) */
115 117
116/* to align the pointer to the (next) page boundary */ 118/* to align the pointer to the (next) page boundary */
diff --git a/include/asm-um/page.h b/include/asm-um/page.h
index 0229814af31e..41364330aff1 100644
--- a/include/asm-um/page.h
+++ b/include/asm-um/page.h
@@ -106,9 +106,6 @@ extern unsigned long uml_physmem;
106#define __pa(virt) to_phys((void *) (unsigned long) (virt)) 106#define __pa(virt) to_phys((void *) (unsigned long) (virt))
107#define __va(phys) to_virt((unsigned long) (phys)) 107#define __va(phys) to_virt((unsigned long) (phys))
108 108
109#define page_to_pfn(page) ((page) - mem_map)
110#define pfn_to_page(pfn) (mem_map + (pfn))
111
112#define phys_to_pfn(p) ((p) >> PAGE_SHIFT) 109#define phys_to_pfn(p) ((p) >> PAGE_SHIFT)
113#define pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT) 110#define pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT)
114 111
@@ -121,6 +118,7 @@ extern struct page *arch_validate(struct page *page, gfp_t mask, int order);
121extern void arch_free_page(struct page *page, int order); 118extern void arch_free_page(struct page *page, int order);
122#define HAVE_ARCH_FREE_PAGE 119#define HAVE_ARCH_FREE_PAGE
123 120
121#include <asm-generic/memory_model.h>
124#include <asm-generic/page.h> 122#include <asm-generic/page.h>
125 123
126#endif 124#endif
diff --git a/include/asm-um/uaccess.h b/include/asm-um/uaccess.h
index 2ee028b8de9d..4e460d6f5ac8 100644
--- a/include/asm-um/uaccess.h
+++ b/include/asm-um/uaccess.h
@@ -41,16 +41,16 @@
41 41
42#define __get_user(x, ptr) \ 42#define __get_user(x, ptr) \
43({ \ 43({ \
44 const __typeof__(ptr) __private_ptr = ptr; \ 44 const __typeof__(ptr) __private_ptr = ptr; \
45 __typeof__(*(__private_ptr)) __private_val; \ 45 __typeof__(x) __private_val; \
46 int __private_ret = -EFAULT; \ 46 int __private_ret = -EFAULT; \
47 (x) = (__typeof__(*(__private_ptr)))0; \ 47 (x) = (__typeof__(*(__private_ptr)))0; \
48 if (__copy_from_user(&__private_val, (__private_ptr), \ 48 if (__copy_from_user((void *) &__private_val, (__private_ptr), \
49 sizeof(*(__private_ptr))) == 0) {\ 49 sizeof(*(__private_ptr))) == 0) { \
50 (x) = (__typeof__(*(__private_ptr))) __private_val; \ 50 (x) = (__typeof__(*(__private_ptr))) __private_val; \
51 __private_ret = 0; \ 51 __private_ret = 0; \
52 } \ 52 } \
53 __private_ret; \ 53 __private_ret; \
54}) 54})
55 55
56#define get_user(x, ptr) \ 56#define get_user(x, ptr) \
@@ -89,14 +89,3 @@ struct exception_table_entry
89}; 89};
90 90
91#endif 91#endif
92
93/*
94 * Overrides for Emacs so that we follow Linus's tabbing style.
95 * Emacs will notice this stuff at the end of the file and automatically
96 * adjust the settings for this buffer only. This must remain at the end
97 * of the file.
98 * ---------------------------------------------------------------------------
99 * Local variables:
100 * c-file-style: "linux"
101 * End:
102 */
diff --git a/include/asm-v850/page.h b/include/asm-v850/page.h
index b4bc85e7b91a..ad03c46a1f92 100644
--- a/include/asm-v850/page.h
+++ b/include/asm-v850/page.h
@@ -111,8 +111,7 @@ typedef unsigned long pgprot_t;
111#define page_to_virt(page) \ 111#define page_to_virt(page) \
112 ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET) 112 ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)
113 113
114#define pfn_to_page(pfn) virt_to_page (pfn_to_virt (pfn)) 114#define ARCH_PFN_OFFSET (PAGE_OFFSET >> PAGE_SHIFT)
115#define page_to_pfn(page) virt_to_pfn (page_to_virt (page))
116#define pfn_valid(pfn) ((pfn) < max_mapnr) 115#define pfn_valid(pfn) ((pfn) < max_mapnr)
117 116
118#define virt_addr_valid(kaddr) \ 117#define virt_addr_valid(kaddr) \
@@ -125,6 +124,7 @@ typedef unsigned long pgprot_t;
125 124
126#endif /* KERNEL */ 125#endif /* KERNEL */
127 126
127#include <asm-generic/memory_model.h>
128#include <asm-generic/page.h> 128#include <asm-generic/page.h>
129 129
130#endif /* __V850_PAGE_H__ */ 130#endif /* __V850_PAGE_H__ */
diff --git a/include/asm-x86_64/futex.h b/include/asm-x86_64/futex.h
index 8602c09bf89e..9804bf07b092 100644
--- a/include/asm-x86_64/futex.h
+++ b/include/asm-x86_64/futex.h
@@ -94,5 +94,32 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
94 return ret; 94 return ret;
95} 95}
96 96
97static inline int
98futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
99{
100 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
101 return -EFAULT;
102
103 __asm__ __volatile__(
104 "1: " LOCK_PREFIX "cmpxchgl %3, %1 \n"
105
106 "2: .section .fixup, \"ax\" \n"
107 "3: mov %2, %0 \n"
108 " jmp 2b \n"
109 " .previous \n"
110
111 " .section __ex_table, \"a\" \n"
112 " .align 8 \n"
113 " .quad 1b,3b \n"
114 " .previous \n"
115
116 : "=a" (oldval), "=m" (*uaddr)
117 : "i" (-EFAULT), "r" (newval), "0" (oldval)
118 : "memory"
119 );
120
121 return oldval;
122}
123
97#endif 124#endif
98#endif 125#endif
diff --git a/include/asm-x86_64/kdebug.h b/include/asm-x86_64/kdebug.h
index b9ed4c0c8783..cf795631d9b4 100644
--- a/include/asm-x86_64/kdebug.h
+++ b/include/asm-x86_64/kdebug.h
@@ -5,21 +5,20 @@
5 5
6struct pt_regs; 6struct pt_regs;
7 7
8struct die_args { 8struct die_args {
9 struct pt_regs *regs; 9 struct pt_regs *regs;
10 const char *str; 10 const char *str;
11 long err; 11 long err;
12 int trapnr; 12 int trapnr;
13 int signr; 13 int signr;
14}; 14};
15
16extern int register_die_notifier(struct notifier_block *);
17extern int unregister_die_notifier(struct notifier_block *);
18extern struct atomic_notifier_head die_chain;
15 19
16/* Note - you should never unregister because that can race with NMIs.
17 If you really want to do it first unregister - then synchronize_sched - then free.
18 */
19int register_die_notifier(struct notifier_block *nb);
20extern struct notifier_block *die_chain;
21/* Grossly misnamed. */ 20/* Grossly misnamed. */
22enum die_val { 21enum die_val {
23 DIE_OOPS = 1, 22 DIE_OOPS = 1,
24 DIE_INT3, 23 DIE_INT3,
25 DIE_DEBUG, 24 DIE_DEBUG,
@@ -33,8 +32,8 @@ enum die_val {
33 DIE_CALL, 32 DIE_CALL,
34 DIE_NMI_IPI, 33 DIE_NMI_IPI,
35 DIE_PAGE_FAULT, 34 DIE_PAGE_FAULT,
36}; 35};
37 36
38static inline int notify_die(enum die_val val, const char *str, 37static inline int notify_die(enum die_val val, const char *str,
39 struct pt_regs *regs, long err, int trap, int sig) 38 struct pt_regs *regs, long err, int trap, int sig)
40{ 39{
@@ -45,7 +44,7 @@ static inline int notify_die(enum die_val val, const char *str,
45 .trapnr = trap, 44 .trapnr = trap,
46 .signr = sig 45 .signr = sig
47 }; 46 };
48 return notifier_call_chain(&die_chain, val, &args); 47 return atomic_notifier_call_chain(&die_chain, val, &args);
49} 48}
50 49
51extern int printk_address(unsigned long address); 50extern int printk_address(unsigned long address);
diff --git a/include/asm-x86_64/mmzone.h b/include/asm-x86_64/mmzone.h
index 937f99b26883..6b18cd8f293d 100644
--- a/include/asm-x86_64/mmzone.h
+++ b/include/asm-x86_64/mmzone.h
@@ -44,12 +44,8 @@ static inline __attribute__((pure)) int phys_to_nid(unsigned long addr)
44#define pfn_to_nid(pfn) phys_to_nid((unsigned long)(pfn) << PAGE_SHIFT) 44#define pfn_to_nid(pfn) phys_to_nid((unsigned long)(pfn) << PAGE_SHIFT)
45#define kvaddr_to_nid(kaddr) phys_to_nid(__pa(kaddr)) 45#define kvaddr_to_nid(kaddr) phys_to_nid(__pa(kaddr))
46 46
47extern struct page *pfn_to_page(unsigned long pfn);
48extern unsigned long page_to_pfn(struct page *page);
49extern int pfn_valid(unsigned long pfn); 47extern int pfn_valid(unsigned long pfn);
50#endif 48#endif
51 49
52#define local_mapnr(kvaddr) \
53 ( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr)) )
54#endif 50#endif
55#endif 51#endif
diff --git a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h
index 615e3e494929..408185bac351 100644
--- a/include/asm-x86_64/page.h
+++ b/include/asm-x86_64/page.h
@@ -123,8 +123,6 @@ typedef struct { unsigned long pgprot; } pgprot_t;
123#define __boot_va(x) __va(x) 123#define __boot_va(x) __va(x)
124#define __boot_pa(x) __pa(x) 124#define __boot_pa(x) __pa(x)
125#ifdef CONFIG_FLATMEM 125#ifdef CONFIG_FLATMEM
126#define pfn_to_page(pfn) (mem_map + (pfn))
127#define page_to_pfn(page) ((unsigned long)((page) - mem_map))
128#define pfn_valid(pfn) ((pfn) < end_pfn) 126#define pfn_valid(pfn) ((pfn) < end_pfn)
129#endif 127#endif
130 128
@@ -140,6 +138,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
140 138
141#endif /* __KERNEL__ */ 139#endif /* __KERNEL__ */
142 140
141#include <asm-generic/memory_model.h>
143#include <asm-generic/page.h> 142#include <asm-generic/page.h>
144 143
145#endif /* _X86_64_PAGE_H */ 144#endif /* _X86_64_PAGE_H */
diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h
index 8c8d88c036ed..1aa2cee43344 100644
--- a/include/asm-x86_64/processor.h
+++ b/include/asm-x86_64/processor.h
@@ -20,6 +20,7 @@
20#include <asm/mmsegment.h> 20#include <asm/mmsegment.h>
21#include <asm/percpu.h> 21#include <asm/percpu.h>
22#include <linux/personality.h> 22#include <linux/personality.h>
23#include <linux/cpumask.h>
23 24
24#define TF_MASK 0x00000100 25#define TF_MASK 0x00000100
25#define IF_MASK 0x00000200 26#define IF_MASK 0x00000200
@@ -65,6 +66,9 @@ struct cpuinfo_x86 {
65 __u32 x86_power; 66 __u32 x86_power;
66 __u32 extended_cpuid_level; /* Max extended CPUID function supported */ 67 __u32 extended_cpuid_level; /* Max extended CPUID function supported */
67 unsigned long loops_per_jiffy; 68 unsigned long loops_per_jiffy;
69#ifdef CONFIG_SMP
70 cpumask_t llc_shared_map; /* cpus sharing the last level cache */
71#endif
68 __u8 apicid; 72 __u8 apicid;
69 __u8 booted_cores; /* number of cores as seen by OS */ 73 __u8 booted_cores; /* number of cores as seen by OS */
70} ____cacheline_aligned; 74} ____cacheline_aligned;
diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h
index 9ccbb2cfd5c0..a4fdaeb5c397 100644
--- a/include/asm-x86_64/smp.h
+++ b/include/asm-x86_64/smp.h
@@ -56,6 +56,7 @@ extern cpumask_t cpu_sibling_map[NR_CPUS];
56extern cpumask_t cpu_core_map[NR_CPUS]; 56extern cpumask_t cpu_core_map[NR_CPUS];
57extern u8 phys_proc_id[NR_CPUS]; 57extern u8 phys_proc_id[NR_CPUS];
58extern u8 cpu_core_id[NR_CPUS]; 58extern u8 cpu_core_id[NR_CPUS];
59extern u8 cpu_llc_id[NR_CPUS];
59 60
60#define SMP_TRAMPOLINE_BASE 0x6000 61#define SMP_TRAMPOLINE_BASE 0x6000
61 62
diff --git a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h
index c642f5d9882d..9db54e9d17bb 100644
--- a/include/asm-x86_64/topology.h
+++ b/include/asm-x86_64/topology.h
@@ -68,4 +68,6 @@ extern int __node_distance(int, int);
68 68
69#include <asm-generic/topology.h> 69#include <asm-generic/topology.h>
70 70
71extern cpumask_t cpu_coregroup_map(int cpu);
72
71#endif 73#endif
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h
index da0341c57949..fcc516353087 100644
--- a/include/asm-x86_64/unistd.h
+++ b/include/asm-x86_64/unistd.h
@@ -605,8 +605,12 @@ __SYSCALL(__NR_pselect6, sys_ni_syscall) /* for now */
605__SYSCALL(__NR_ppoll, sys_ni_syscall) /* for now */ 605__SYSCALL(__NR_ppoll, sys_ni_syscall) /* for now */
606#define __NR_unshare 272 606#define __NR_unshare 272
607__SYSCALL(__NR_unshare, sys_unshare) 607__SYSCALL(__NR_unshare, sys_unshare)
608#define __NR_set_robust_list 273
609__SYSCALL(__NR_set_robust_list, sys_set_robust_list)
610#define __NR_get_robust_list 274
611__SYSCALL(__NR_get_robust_list, sys_get_robust_list)
608 612
609#define __NR_syscall_max __NR_unshare 613#define __NR_syscall_max __NR_get_robust_list
610 614
611#ifndef __NO_STUBS 615#ifndef __NO_STUBS
612 616
diff --git a/include/asm-xtensa/page.h b/include/asm-xtensa/page.h
index 8ded36f255a2..992bac5c1258 100644
--- a/include/asm-xtensa/page.h
+++ b/include/asm-xtensa/page.h
@@ -109,10 +109,7 @@ void copy_user_page(void *to,void* from,unsigned long vaddr,struct page* page);
109#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) 109#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET)
110#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) 110#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET))
111#define pfn_valid(pfn) ((unsigned long)pfn < max_mapnr) 111#define pfn_valid(pfn) ((unsigned long)pfn < max_mapnr)
112#ifndef CONFIG_DISCONTIGMEM 112#ifdef CONFIG_DISCONTIGMEM
113# define pfn_to_page(pfn) (mem_map + (pfn))
114# define page_to_pfn(page) ((unsigned long)((page) - mem_map))
115#else
116# error CONFIG_DISCONTIGMEM not supported 113# error CONFIG_DISCONTIGMEM not supported
117#endif 114#endif
118 115
@@ -130,4 +127,5 @@ void copy_user_page(void *to,void* from,unsigned long vaddr,struct page* page);
130 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) 127 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
131 128
132#endif /* __KERNEL__ */ 129#endif /* __KERNEL__ */
130#include <asm-generic/memory_model.h>
133#endif /* _XTENSA_PAGE_H */ 131#endif /* _XTENSA_PAGE_H */
diff --git a/include/linux/adb.h b/include/linux/adb.h
index e9fdc63483c7..b7305b178279 100644
--- a/include/linux/adb.h
+++ b/include/linux/adb.h
@@ -85,7 +85,7 @@ enum adb_message {
85 ADB_MSG_POST_RESET /* Called after resetting the bus (re-do init & register) */ 85 ADB_MSG_POST_RESET /* Called after resetting the bus (re-do init & register) */
86}; 86};
87extern struct adb_driver *adb_controller; 87extern struct adb_driver *adb_controller;
88extern struct notifier_block *adb_client_list; 88extern struct blocking_notifier_head adb_client_list;
89 89
90int adb_request(struct adb_request *req, void (*done)(struct adb_request *), 90int adb_request(struct adb_request *req, void (*done)(struct adb_request *),
91 int flags, int nbytes, ...); 91 int flags, int nbytes, ...);
diff --git a/include/linux/auto_fs4.h b/include/linux/auto_fs4.h
index 9343c89d843c..0a6bc52ffe88 100644
--- a/include/linux/auto_fs4.h
+++ b/include/linux/auto_fs4.h
@@ -19,18 +19,37 @@
19#undef AUTOFS_MIN_PROTO_VERSION 19#undef AUTOFS_MIN_PROTO_VERSION
20#undef AUTOFS_MAX_PROTO_VERSION 20#undef AUTOFS_MAX_PROTO_VERSION
21 21
22#define AUTOFS_PROTO_VERSION 4 22#define AUTOFS_PROTO_VERSION 5
23#define AUTOFS_MIN_PROTO_VERSION 3 23#define AUTOFS_MIN_PROTO_VERSION 3
24#define AUTOFS_MAX_PROTO_VERSION 4 24#define AUTOFS_MAX_PROTO_VERSION 5
25 25
26#define AUTOFS_PROTO_SUBVERSION 7 26#define AUTOFS_PROTO_SUBVERSION 0
27 27
28/* Mask for expire behaviour */ 28/* Mask for expire behaviour */
29#define AUTOFS_EXP_IMMEDIATE 1 29#define AUTOFS_EXP_IMMEDIATE 1
30#define AUTOFS_EXP_LEAVES 2 30#define AUTOFS_EXP_LEAVES 2
31 31
32/* New message type */ 32/* Daemon notification packet types */
33#define autofs_ptype_expire_multi 2 /* Expire entry (umount request) */ 33enum autofs_notify {
34 NFY_NONE,
35 NFY_MOUNT,
36 NFY_EXPIRE
37};
38
39/* Kernel protocol version 4 packet types */
40
41/* Expire entry (umount request) */
42#define autofs_ptype_expire_multi 2
43
44/* Kernel protocol version 5 packet types */
45
46/* Indirect mount missing and expire requests. */
47#define autofs_ptype_missing_indirect 3
48#define autofs_ptype_expire_indirect 4
49
50/* Direct mount missing and expire requests */
51#define autofs_ptype_missing_direct 5
52#define autofs_ptype_expire_direct 6
34 53
35/* v4 multi expire (via pipe) */ 54/* v4 multi expire (via pipe) */
36struct autofs_packet_expire_multi { 55struct autofs_packet_expire_multi {
@@ -40,14 +59,36 @@ struct autofs_packet_expire_multi {
40 char name[NAME_MAX+1]; 59 char name[NAME_MAX+1];
41}; 60};
42 61
62/* autofs v5 common packet struct */
63struct autofs_v5_packet {
64 struct autofs_packet_hdr hdr;
65 autofs_wqt_t wait_queue_token;
66 __u32 dev;
67 __u64 ino;
68 __u32 uid;
69 __u32 gid;
70 __u32 pid;
71 __u32 tgid;
72 __u32 len;
73 char name[NAME_MAX+1];
74};
75
76typedef struct autofs_v5_packet autofs_packet_missing_indirect_t;
77typedef struct autofs_v5_packet autofs_packet_expire_indirect_t;
78typedef struct autofs_v5_packet autofs_packet_missing_direct_t;
79typedef struct autofs_v5_packet autofs_packet_expire_direct_t;
80
43union autofs_packet_union { 81union autofs_packet_union {
44 struct autofs_packet_hdr hdr; 82 struct autofs_packet_hdr hdr;
45 struct autofs_packet_missing missing; 83 struct autofs_packet_missing missing;
46 struct autofs_packet_expire expire; 84 struct autofs_packet_expire expire;
47 struct autofs_packet_expire_multi expire_multi; 85 struct autofs_packet_expire_multi expire_multi;
86 struct autofs_v5_packet v5_packet;
48}; 87};
49 88
50#define AUTOFS_IOC_EXPIRE_MULTI _IOW(0x93,0x66,int) 89#define AUTOFS_IOC_EXPIRE_MULTI _IOW(0x93,0x66,int)
90#define AUTOFS_IOC_EXPIRE_INDIRECT AUTOFS_IOC_EXPIRE_MULTI
91#define AUTOFS_IOC_EXPIRE_DIRECT AUTOFS_IOC_EXPIRE_MULTI
51#define AUTOFS_IOC_PROTOSUBVER _IOR(0x93,0x67,int) 92#define AUTOFS_IOC_PROTOSUBVER _IOR(0x93,0x67,int)
52#define AUTOFS_IOC_ASKREGHOST _IOR(0x93,0x68,int) 93#define AUTOFS_IOC_ASKREGHOST _IOR(0x93,0x68,int)
53#define AUTOFS_IOC_TOGGLEREGHOST _IOR(0x93,0x69,int) 94#define AUTOFS_IOC_TOGGLEREGHOST _IOR(0x93,0x69,int)
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h
index 7155452fb4a8..de3eb8d8ae26 100644
--- a/include/linux/bootmem.h
+++ b/include/linux/bootmem.h
@@ -38,6 +38,7 @@ typedef struct bootmem_data {
38 unsigned long last_pos; 38 unsigned long last_pos;
39 unsigned long last_success; /* Previous allocation point. To speed 39 unsigned long last_success; /* Previous allocation point. To speed
40 * up searching */ 40 * up searching */
41 struct list_head list;
41} bootmem_data_t; 42} bootmem_data_t;
42 43
43extern unsigned long __init bootmem_bootmap_pages (unsigned long); 44extern unsigned long __init bootmem_bootmap_pages (unsigned long);
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 24d659cdbafe..6d3a654be1ae 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -147,6 +147,24 @@ typedef struct compat_sigevent {
147 } _sigev_un; 147 } _sigev_un;
148} compat_sigevent_t; 148} compat_sigevent_t;
149 149
150struct compat_robust_list {
151 compat_uptr_t next;
152};
153
154struct compat_robust_list_head {
155 struct compat_robust_list list;
156 compat_long_t futex_offset;
157 compat_uptr_t list_op_pending;
158};
159
160extern void compat_exit_robust_list(struct task_struct *curr);
161
162asmlinkage long
163compat_sys_set_robust_list(struct compat_robust_list_head __user *head,
164 compat_size_t len);
165asmlinkage long
166compat_sys_get_robust_list(int pid, compat_uptr_t *head_ptr,
167 compat_size_t __user *len_ptr);
150 168
151long compat_sys_semctl(int first, int second, int third, void __user *uptr); 169long compat_sys_semctl(int first, int second, int third, void __user *uptr);
152long compat_sys_msgsnd(int first, int second, int third, void __user *uptr); 170long compat_sys_msgsnd(int first, int second, int third, void __user *uptr);
diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h
index efb518f16bb3..89ab677cb993 100644
--- a/include/linux/compat_ioctl.h
+++ b/include/linux/compat_ioctl.h
@@ -140,6 +140,7 @@ COMPATIBLE_IOCTL(DM_TABLE_DEPS_32)
140COMPATIBLE_IOCTL(DM_TABLE_STATUS_32) 140COMPATIBLE_IOCTL(DM_TABLE_STATUS_32)
141COMPATIBLE_IOCTL(DM_LIST_VERSIONS_32) 141COMPATIBLE_IOCTL(DM_LIST_VERSIONS_32)
142COMPATIBLE_IOCTL(DM_TARGET_MSG_32) 142COMPATIBLE_IOCTL(DM_TARGET_MSG_32)
143COMPATIBLE_IOCTL(DM_DEV_SET_GEOMETRY_32)
143COMPATIBLE_IOCTL(DM_VERSION) 144COMPATIBLE_IOCTL(DM_VERSION)
144COMPATIBLE_IOCTL(DM_REMOVE_ALL) 145COMPATIBLE_IOCTL(DM_REMOVE_ALL)
145COMPATIBLE_IOCTL(DM_LIST_DEVICES) 146COMPATIBLE_IOCTL(DM_LIST_DEVICES)
@@ -155,6 +156,7 @@ COMPATIBLE_IOCTL(DM_TABLE_DEPS)
155COMPATIBLE_IOCTL(DM_TABLE_STATUS) 156COMPATIBLE_IOCTL(DM_TABLE_STATUS)
156COMPATIBLE_IOCTL(DM_LIST_VERSIONS) 157COMPATIBLE_IOCTL(DM_LIST_VERSIONS)
157COMPATIBLE_IOCTL(DM_TARGET_MSG) 158COMPATIBLE_IOCTL(DM_TARGET_MSG)
159COMPATIBLE_IOCTL(DM_DEV_SET_GEOMETRY)
158/* Big K */ 160/* Big K */
159COMPATIBLE_IOCTL(PIO_FONT) 161COMPATIBLE_IOCTL(PIO_FONT)
160COMPATIBLE_IOCTL(GIO_FONT) 162COMPATIBLE_IOCTL(GIO_FONT)
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index 51e0e95a421a..aee10b2ea4c6 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -97,6 +97,7 @@ struct io_restrictions {
97 unsigned short hardsect_size; 97 unsigned short hardsect_size;
98 unsigned int max_segment_size; 98 unsigned int max_segment_size;
99 unsigned long seg_boundary_mask; 99 unsigned long seg_boundary_mask;
100 unsigned char no_cluster; /* inverted so that 0 is default */
100}; 101};
101 102
102struct dm_target { 103struct dm_target {
diff --git a/include/linux/dm-ioctl.h b/include/linux/dm-ioctl.h
index fa75ba0d635e..c67c6786612a 100644
--- a/include/linux/dm-ioctl.h
+++ b/include/linux/dm-ioctl.h
@@ -80,6 +80,16 @@
80 * 80 *
81 * DM_TARGET_MSG: 81 * DM_TARGET_MSG:
82 * Pass a message string to the target at a specific offset of a device. 82 * Pass a message string to the target at a specific offset of a device.
83 *
84 * DM_DEV_SET_GEOMETRY:
85 * Set the geometry of a device by passing in a string in this format:
86 *
87 * "cylinders heads sectors_per_track start_sector"
88 *
89 * Beware that CHS geometry is nearly obsolete and only provided
90 * for compatibility with dm devices that can be booted by a PC
91 * BIOS. See struct hd_geometry for range limits. Also note that
92 * the geometry is erased if the device size changes.
83 */ 93 */
84 94
85/* 95/*
@@ -218,6 +228,7 @@ enum {
218 /* Added later */ 228 /* Added later */
219 DM_LIST_VERSIONS_CMD, 229 DM_LIST_VERSIONS_CMD,
220 DM_TARGET_MSG_CMD, 230 DM_TARGET_MSG_CMD,
231 DM_DEV_SET_GEOMETRY_CMD
221}; 232};
222 233
223/* 234/*
@@ -247,6 +258,7 @@ typedef char ioctl_struct[308];
247#define DM_TABLE_STATUS_32 _IOWR(DM_IOCTL, DM_TABLE_STATUS_CMD, ioctl_struct) 258#define DM_TABLE_STATUS_32 _IOWR(DM_IOCTL, DM_TABLE_STATUS_CMD, ioctl_struct)
248#define DM_LIST_VERSIONS_32 _IOWR(DM_IOCTL, DM_LIST_VERSIONS_CMD, ioctl_struct) 259#define DM_LIST_VERSIONS_32 _IOWR(DM_IOCTL, DM_LIST_VERSIONS_CMD, ioctl_struct)
249#define DM_TARGET_MSG_32 _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, ioctl_struct) 260#define DM_TARGET_MSG_32 _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, ioctl_struct)
261#define DM_DEV_SET_GEOMETRY_32 _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, ioctl_struct)
250#endif 262#endif
251 263
252#define DM_IOCTL 0xfd 264#define DM_IOCTL 0xfd
@@ -270,11 +282,12 @@ typedef char ioctl_struct[308];
270#define DM_LIST_VERSIONS _IOWR(DM_IOCTL, DM_LIST_VERSIONS_CMD, struct dm_ioctl) 282#define DM_LIST_VERSIONS _IOWR(DM_IOCTL, DM_LIST_VERSIONS_CMD, struct dm_ioctl)
271 283
272#define DM_TARGET_MSG _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, struct dm_ioctl) 284#define DM_TARGET_MSG _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, struct dm_ioctl)
285#define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
273 286
274#define DM_VERSION_MAJOR 4 287#define DM_VERSION_MAJOR 4
275#define DM_VERSION_MINOR 5 288#define DM_VERSION_MINOR 6
276#define DM_VERSION_PATCHLEVEL 0 289#define DM_VERSION_PATCHLEVEL 0
277#define DM_VERSION_EXTRA "-ioctl (2005-10-04)" 290#define DM_VERSION_EXTRA "-ioctl (2006-02-17)"
278 291
279/* Status bits */ 292/* Status bits */
280#define DM_READONLY_FLAG (1 << 0) /* In/Out */ 293#define DM_READONLY_FLAG (1 << 0) /* In/Out */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 9d9674946956..680d913350e7 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -410,6 +410,9 @@ struct block_device {
410 struct list_head bd_inodes; 410 struct list_head bd_inodes;
411 void * bd_holder; 411 void * bd_holder;
412 int bd_holders; 412 int bd_holders;
413#ifdef CONFIG_SYSFS
414 struct list_head bd_holder_list;
415#endif
413 struct block_device * bd_contains; 416 struct block_device * bd_contains;
414 unsigned bd_block_size; 417 unsigned bd_block_size;
415 struct hd_struct * bd_part; 418 struct hd_struct * bd_part;
@@ -1399,6 +1402,13 @@ extern int blkdev_get(struct block_device *, mode_t, unsigned);
1399extern int blkdev_put(struct block_device *); 1402extern int blkdev_put(struct block_device *);
1400extern int bd_claim(struct block_device *, void *); 1403extern int bd_claim(struct block_device *, void *);
1401extern void bd_release(struct block_device *); 1404extern void bd_release(struct block_device *);
1405#ifdef CONFIG_SYSFS
1406extern int bd_claim_by_disk(struct block_device *, void *, struct gendisk *);
1407extern void bd_release_from_disk(struct block_device *, struct gendisk *);
1408#else
1409#define bd_claim_by_disk(bdev, holder, disk) bd_claim(bdev, holder)
1410#define bd_release_from_disk(bdev, disk) bd_release(bdev)
1411#endif
1402 1412
1403/* fs/char_dev.c */ 1413/* fs/char_dev.c */
1404extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *); 1414extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *);
diff --git a/include/linux/futex.h b/include/linux/futex.h
index 10f96c31971e..966a5b3da439 100644
--- a/include/linux/futex.h
+++ b/include/linux/futex.h
@@ -1,6 +1,8 @@
1#ifndef _LINUX_FUTEX_H 1#ifndef _LINUX_FUTEX_H
2#define _LINUX_FUTEX_H 2#define _LINUX_FUTEX_H
3 3
4#include <linux/sched.h>
5
4/* Second argument to futex syscall */ 6/* Second argument to futex syscall */
5 7
6 8
@@ -11,10 +13,97 @@
11#define FUTEX_CMP_REQUEUE 4 13#define FUTEX_CMP_REQUEUE 4
12#define FUTEX_WAKE_OP 5 14#define FUTEX_WAKE_OP 5
13 15
16/*
17 * Support for robust futexes: the kernel cleans up held futexes at
18 * thread exit time.
19 */
20
21/*
22 * Per-lock list entry - embedded in user-space locks, somewhere close
23 * to the futex field. (Note: user-space uses a double-linked list to
24 * achieve O(1) list add and remove, but the kernel only needs to know
25 * about the forward link)
26 *
27 * NOTE: this structure is part of the syscall ABI, and must not be
28 * changed.
29 */
30struct robust_list {
31 struct robust_list __user *next;
32};
33
34/*
35 * Per-thread list head:
36 *
37 * NOTE: this structure is part of the syscall ABI, and must only be
38 * changed if the change is first communicated with the glibc folks.
39 * (When an incompatible change is done, we'll increase the structure
40 * size, which glibc will detect)
41 */
42struct robust_list_head {
43 /*
44 * The head of the list. Points back to itself if empty:
45 */
46 struct robust_list list;
47
48 /*
49 * This relative offset is set by user-space, it gives the kernel
50 * the relative position of the futex field to examine. This way
51 * we keep userspace flexible, to freely shape its data-structure,
52 * without hardcoding any particular offset into the kernel:
53 */
54 long futex_offset;
55
56 /*
57 * The death of the thread may race with userspace setting
58 * up a lock's links. So to handle this race, userspace first
59 * sets this field to the address of the to-be-taken lock,
60 * then does the lock acquire, and then adds itself to the
61 * list, and then clears this field. Hence the kernel will
62 * always have full knowledge of all locks that the thread
63 * _might_ have taken. We check the owner TID in any case,
64 * so only truly owned locks will be handled.
65 */
66 struct robust_list __user *list_op_pending;
67};
68
69/*
70 * Are there any waiters for this robust futex:
71 */
72#define FUTEX_WAITERS 0x80000000
73
74/*
75 * The kernel signals via this bit that a thread holding a futex
76 * has exited without unlocking the futex. The kernel also does
77 * a FUTEX_WAKE on such futexes, after setting the bit, to wake
78 * up any possible waiters:
79 */
80#define FUTEX_OWNER_DIED 0x40000000
81
82/*
83 * The rest of the robust-futex field is for the TID:
84 */
85#define FUTEX_TID_MASK 0x3fffffff
86
87/*
88 * This limit protects against a deliberately circular list.
89 * (Not worth introducing an rlimit for it)
90 */
91#define ROBUST_LIST_LIMIT 2048
92
14long do_futex(unsigned long uaddr, int op, int val, 93long do_futex(unsigned long uaddr, int op, int val,
15 unsigned long timeout, unsigned long uaddr2, int val2, 94 unsigned long timeout, unsigned long uaddr2, int val2,
16 int val3); 95 int val3);
17 96
97extern int handle_futex_death(u32 __user *uaddr, struct task_struct *curr);
98
99#ifdef CONFIG_FUTEX
100extern void exit_robust_list(struct task_struct *curr);
101#else
102static inline void exit_robust_list(struct task_struct *curr)
103{
104}
105#endif
106
18#define FUTEX_OP_SET 0 /* *(int *)UADDR2 = OPARG; */ 107#define FUTEX_OP_SET 0 /* *(int *)UADDR2 = OPARG; */
19#define FUTEX_OP_ADD 1 /* *(int *)UADDR2 += OPARG; */ 108#define FUTEX_OP_ADD 1 /* *(int *)UADDR2 += OPARG; */
20#define FUTEX_OP_OR 2 /* *(int *)UADDR2 |= OPARG; */ 109#define FUTEX_OP_OR 2 /* *(int *)UADDR2 |= OPARG; */
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index fd647fde5ec1..3c1b0294a742 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -78,6 +78,7 @@ struct hd_struct {
78 sector_t start_sect; 78 sector_t start_sect;
79 sector_t nr_sects; 79 sector_t nr_sects;
80 struct kobject kobj; 80 struct kobject kobj;
81 struct kobject *holder_dir;
81 unsigned ios[2], sectors[2]; /* READs and WRITEs */ 82 unsigned ios[2], sectors[2]; /* READs and WRITEs */
82 int policy, partno; 83 int policy, partno;
83}; 84};
@@ -89,12 +90,12 @@ struct hd_struct {
89#define GENHD_FL_SUPPRESS_PARTITION_INFO 32 90#define GENHD_FL_SUPPRESS_PARTITION_INFO 32
90 91
91struct disk_stats { 92struct disk_stats {
92 unsigned sectors[2]; /* READs and WRITEs */ 93 unsigned long sectors[2]; /* READs and WRITEs */
93 unsigned ios[2]; 94 unsigned long ios[2];
94 unsigned merges[2]; 95 unsigned long merges[2];
95 unsigned ticks[2]; 96 unsigned long ticks[2];
96 unsigned io_ticks; 97 unsigned long io_ticks;
97 unsigned time_in_queue; 98 unsigned long time_in_queue;
98}; 99};
99 100
100struct gendisk { 101struct gendisk {
@@ -114,6 +115,8 @@ struct gendisk {
114 int number; /* more of the same */ 115 int number; /* more of the same */
115 struct device *driverfs_dev; 116 struct device *driverfs_dev;
116 struct kobject kobj; 117 struct kobject kobj;
118 struct kobject *holder_dir;
119 struct kobject *slave_dir;
117 120
118 struct timer_rand_state *random; 121 struct timer_rand_state *random;
119 int policy; 122 int policy;
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
index 679b46a6a565..c8b81f419fd8 100644
--- a/include/linux/i2c-id.h
+++ b/include/linux/i2c-id.h
@@ -108,6 +108,10 @@
108#define I2C_DRIVERID_UPD64083 78 /* upd64083 video processor */ 108#define I2C_DRIVERID_UPD64083 78 /* upd64083 video processor */
109#define I2C_DRIVERID_UPD64031A 79 /* upd64031a video processor */ 109#define I2C_DRIVERID_UPD64031A 79 /* upd64031a video processor */
110#define I2C_DRIVERID_SAA717X 80 /* saa717x video encoder */ 110#define I2C_DRIVERID_SAA717X 80 /* saa717x video encoder */
111#define I2C_DRIVERID_DS1672 81 /* Dallas/Maxim DS1672 RTC */
112#define I2C_DRIVERID_X1205 82 /* Xicor/Intersil X1205 RTC */
113#define I2C_DRIVERID_PCF8563 83 /* Philips PCF8563 RTC */
114#define I2C_DRIVERID_RS5C372 84 /* Ricoh RS5C372 RTC */
111 115
112#define I2C_DRIVERID_I2CDEV 900 116#define I2C_DRIVERID_I2CDEV 900
113#define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */ 117#define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 03d6cfaa5b8a..a3720f973ea5 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -87,7 +87,7 @@ extern int cond_resched(void);
87 (__x < 0) ? -__x : __x; \ 87 (__x < 0) ? -__x : __x; \
88 }) 88 })
89 89
90extern struct notifier_block *panic_notifier_list; 90extern struct atomic_notifier_head panic_notifier_list;
91extern long (*panic_blink)(long time); 91extern long (*panic_blink)(long time);
92NORET_TYPE void panic(const char * fmt, ...) 92NORET_TYPE void panic(const char * fmt, ...)
93 __attribute__ ((NORET_AND format (printf, 1, 2))); 93 __attribute__ ((NORET_AND format (printf, 1, 2)));
diff --git a/include/linux/m48t86.h b/include/linux/m48t86.h
new file mode 100644
index 000000000000..9065199319d0
--- /dev/null
+++ b/include/linux/m48t86.h
@@ -0,0 +1,16 @@
1/*
2 * ST M48T86 / Dallas DS12887 RTC driver
3 * Copyright (c) 2006 Tower Technologies
4 *
5 * Author: Alessandro Zummo <a.zummo@towertech.it>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10*/
11
12struct m48t86_ops
13{
14 void (*writeb)(unsigned char value, unsigned long addr);
15 unsigned char (*readb)(unsigned long addr);
16};
diff --git a/include/linux/memory.h b/include/linux/memory.h
index e251dc43d0f5..8f04143ca363 100644
--- a/include/linux/memory.h
+++ b/include/linux/memory.h
@@ -77,7 +77,6 @@ extern int remove_memory_block(unsigned long, struct mem_section *, int);
77 77
78#define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT) 78#define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT)
79 79
80struct notifier_block;
81 80
82#endif /* CONFIG_MEMORY_HOTPLUG */ 81#endif /* CONFIG_MEMORY_HOTPLUG */
83 82
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index ebfc238cc243..b5c21122c299 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -13,6 +13,7 @@
13#include <linux/numa.h> 13#include <linux/numa.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/seqlock.h> 15#include <linux/seqlock.h>
16#include <linux/nodemask.h>
16#include <asm/atomic.h> 17#include <asm/atomic.h>
17 18
18/* Free memory management - zoned buddy allocator. */ 19/* Free memory management - zoned buddy allocator. */
@@ -225,7 +226,6 @@ struct zone {
225 * Discontig memory support fields. 226 * Discontig memory support fields.
226 */ 227 */
227 struct pglist_data *zone_pgdat; 228 struct pglist_data *zone_pgdat;
228 struct page *zone_mem_map;
229 /* zone_start_pfn == zone_start_paddr >> PAGE_SHIFT */ 229 /* zone_start_pfn == zone_start_paddr >> PAGE_SHIFT */
230 unsigned long zone_start_pfn; 230 unsigned long zone_start_pfn;
231 231
@@ -307,7 +307,6 @@ typedef struct pglist_data {
307 unsigned long node_spanned_pages; /* total size of physical page 307 unsigned long node_spanned_pages; /* total size of physical page
308 range, including holes */ 308 range, including holes */
309 int node_id; 309 int node_id;
310 struct pglist_data *pgdat_next;
311 wait_queue_head_t kswapd_wait; 310 wait_queue_head_t kswapd_wait;
312 struct task_struct *kswapd; 311 struct task_struct *kswapd;
313 int kswapd_max_order; 312 int kswapd_max_order;
@@ -324,8 +323,6 @@ typedef struct pglist_data {
324 323
325#include <linux/memory_hotplug.h> 324#include <linux/memory_hotplug.h>
326 325
327extern struct pglist_data *pgdat_list;
328
329void __get_zone_counts(unsigned long *active, unsigned long *inactive, 326void __get_zone_counts(unsigned long *active, unsigned long *inactive,
330 unsigned long *free, struct pglist_data *pgdat); 327 unsigned long *free, struct pglist_data *pgdat);
331void get_zone_counts(unsigned long *active, unsigned long *inactive, 328void get_zone_counts(unsigned long *active, unsigned long *inactive,
@@ -350,57 +347,6 @@ unsigned long __init node_memmap_size_bytes(int, unsigned long, unsigned long);
350 */ 347 */
351#define zone_idx(zone) ((zone) - (zone)->zone_pgdat->node_zones) 348#define zone_idx(zone) ((zone) - (zone)->zone_pgdat->node_zones)
352 349
353/**
354 * for_each_pgdat - helper macro to iterate over all nodes
355 * @pgdat - pointer to a pg_data_t variable
356 *
357 * Meant to help with common loops of the form
358 * pgdat = pgdat_list;
359 * while(pgdat) {
360 * ...
361 * pgdat = pgdat->pgdat_next;
362 * }
363 */
364#define for_each_pgdat(pgdat) \
365 for (pgdat = pgdat_list; pgdat; pgdat = pgdat->pgdat_next)
366
367/*
368 * next_zone - helper magic for for_each_zone()
369 * Thanks to William Lee Irwin III for this piece of ingenuity.
370 */
371static inline struct zone *next_zone(struct zone *zone)
372{
373 pg_data_t *pgdat = zone->zone_pgdat;
374
375 if (zone < pgdat->node_zones + MAX_NR_ZONES - 1)
376 zone++;
377 else if (pgdat->pgdat_next) {
378 pgdat = pgdat->pgdat_next;
379 zone = pgdat->node_zones;
380 } else
381 zone = NULL;
382
383 return zone;
384}
385
386/**
387 * for_each_zone - helper macro to iterate over all memory zones
388 * @zone - pointer to struct zone variable
389 *
390 * The user only needs to declare the zone variable, for_each_zone
391 * fills it in. This basically means for_each_zone() is an
392 * easier to read version of this piece of code:
393 *
394 * for (pgdat = pgdat_list; pgdat; pgdat = pgdat->node_next)
395 * for (i = 0; i < MAX_NR_ZONES; ++i) {
396 * struct zone * z = pgdat->node_zones + i;
397 * ...
398 * }
399 * }
400 */
401#define for_each_zone(zone) \
402 for (zone = pgdat_list->node_zones; zone; zone = next_zone(zone))
403
404static inline int populated_zone(struct zone *zone) 350static inline int populated_zone(struct zone *zone)
405{ 351{
406 return (!!zone->present_pages); 352 return (!!zone->present_pages);
@@ -472,6 +418,30 @@ extern struct pglist_data contig_page_data;
472 418
473#endif /* !CONFIG_NEED_MULTIPLE_NODES */ 419#endif /* !CONFIG_NEED_MULTIPLE_NODES */
474 420
421extern struct pglist_data *first_online_pgdat(void);
422extern struct pglist_data *next_online_pgdat(struct pglist_data *pgdat);
423extern struct zone *next_zone(struct zone *zone);
424
425/**
426 * for_each_pgdat - helper macro to iterate over all nodes
427 * @pgdat - pointer to a pg_data_t variable
428 */
429#define for_each_online_pgdat(pgdat) \
430 for (pgdat = first_online_pgdat(); \
431 pgdat; \
432 pgdat = next_online_pgdat(pgdat))
433/**
434 * for_each_zone - helper macro to iterate over all memory zones
435 * @zone - pointer to struct zone variable
436 *
437 * The user only needs to declare the zone variable, for_each_zone
438 * fills it in.
439 */
440#define for_each_zone(zone) \
441 for (zone = (first_online_pgdat())->node_zones; \
442 zone; \
443 zone = next_zone(zone))
444
475#ifdef CONFIG_SPARSEMEM 445#ifdef CONFIG_SPARSEMEM
476#include <asm/sparsemem.h> 446#include <asm/sparsemem.h>
477#endif 447#endif
@@ -602,17 +572,6 @@ static inline struct mem_section *__pfn_to_section(unsigned long pfn)
602 return __nr_to_section(pfn_to_section_nr(pfn)); 572 return __nr_to_section(pfn_to_section_nr(pfn));
603} 573}
604 574
605#define pfn_to_page(pfn) \
606({ \
607 unsigned long __pfn = (pfn); \
608 __section_mem_map_addr(__pfn_to_section(__pfn)) + __pfn; \
609})
610#define page_to_pfn(page) \
611({ \
612 page - __section_mem_map_addr(__nr_to_section( \
613 page_to_section(page))); \
614})
615
616static inline int pfn_valid(unsigned long pfn) 575static inline int pfn_valid(unsigned long pfn)
617{ 576{
618 if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS) 577 if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS)
diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h
index f32d75c4f4cf..d54d7b278e96 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack.h
@@ -308,29 +308,30 @@ DECLARE_PER_CPU(struct ip_conntrack_ecache, ip_conntrack_ecache);
308 308
309#define CONNTRACK_ECACHE(x) (__get_cpu_var(ip_conntrack_ecache).x) 309#define CONNTRACK_ECACHE(x) (__get_cpu_var(ip_conntrack_ecache).x)
310 310
311extern struct notifier_block *ip_conntrack_chain; 311extern struct atomic_notifier_head ip_conntrack_chain;
312extern struct notifier_block *ip_conntrack_expect_chain; 312extern struct atomic_notifier_head ip_conntrack_expect_chain;
313 313
314static inline int ip_conntrack_register_notifier(struct notifier_block *nb) 314static inline int ip_conntrack_register_notifier(struct notifier_block *nb)
315{ 315{
316 return notifier_chain_register(&ip_conntrack_chain, nb); 316 return atomic_notifier_chain_register(&ip_conntrack_chain, nb);
317} 317}
318 318
319static inline int ip_conntrack_unregister_notifier(struct notifier_block *nb) 319static inline int ip_conntrack_unregister_notifier(struct notifier_block *nb)
320{ 320{
321 return notifier_chain_unregister(&ip_conntrack_chain, nb); 321 return atomic_notifier_chain_unregister(&ip_conntrack_chain, nb);
322} 322}
323 323
324static inline int 324static inline int
325ip_conntrack_expect_register_notifier(struct notifier_block *nb) 325ip_conntrack_expect_register_notifier(struct notifier_block *nb)
326{ 326{
327 return notifier_chain_register(&ip_conntrack_expect_chain, nb); 327 return atomic_notifier_chain_register(&ip_conntrack_expect_chain, nb);
328} 328}
329 329
330static inline int 330static inline int
331ip_conntrack_expect_unregister_notifier(struct notifier_block *nb) 331ip_conntrack_expect_unregister_notifier(struct notifier_block *nb)
332{ 332{
333 return notifier_chain_unregister(&ip_conntrack_expect_chain, nb); 333 return atomic_notifier_chain_unregister(&ip_conntrack_expect_chain,
334 nb);
334} 335}
335 336
336extern void ip_ct_deliver_cached_events(const struct ip_conntrack *ct); 337extern void ip_ct_deliver_cached_events(const struct ip_conntrack *ct);
@@ -355,14 +356,14 @@ static inline void ip_conntrack_event(enum ip_conntrack_events event,
355 struct ip_conntrack *ct) 356 struct ip_conntrack *ct)
356{ 357{
357 if (is_confirmed(ct) && !is_dying(ct)) 358 if (is_confirmed(ct) && !is_dying(ct))
358 notifier_call_chain(&ip_conntrack_chain, event, ct); 359 atomic_notifier_call_chain(&ip_conntrack_chain, event, ct);
359} 360}
360 361
361static inline void 362static inline void
362ip_conntrack_expect_event(enum ip_conntrack_expect_events event, 363ip_conntrack_expect_event(enum ip_conntrack_expect_events event,
363 struct ip_conntrack_expect *exp) 364 struct ip_conntrack_expect *exp)
364{ 365{
365 notifier_call_chain(&ip_conntrack_expect_chain, event, exp); 366 atomic_notifier_call_chain(&ip_conntrack_expect_chain, event, exp);
366} 367}
367#else /* CONFIG_IP_NF_CONNTRACK_EVENTS */ 368#else /* CONFIG_IP_NF_CONNTRACK_EVENTS */
368static inline void ip_conntrack_event_cache(enum ip_conntrack_events event, 369static inline void ip_conntrack_event_cache(enum ip_conntrack_events event,
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
index 6bad4766d3d9..d2a8abb5011a 100644
--- a/include/linux/nfsd/export.h
+++ b/include/linux/nfsd/export.h
@@ -67,7 +67,8 @@ struct svc_expkey {
67 int ek_fsidtype; 67 int ek_fsidtype;
68 u32 ek_fsid[3]; 68 u32 ek_fsid[3];
69 69
70 struct svc_export * ek_export; 70 struct vfsmount * ek_mnt;
71 struct dentry * ek_dentry;
71}; 72};
72 73
73#define EX_SECURE(exp) (!((exp)->ex_flags & NFSEXP_INSECURE_PORT)) 74#define EX_SECURE(exp) (!((exp)->ex_flags & NFSEXP_INSECURE_PORT))
@@ -85,9 +86,6 @@ void nfsd_export_shutdown(void);
85void nfsd_export_flush(void); 86void nfsd_export_flush(void);
86void exp_readlock(void); 87void exp_readlock(void);
87void exp_readunlock(void); 88void exp_readunlock(void);
88struct svc_expkey * exp_find_key(struct auth_domain *clp,
89 int fsid_type, u32 *fsidv,
90 struct cache_req *reqp);
91struct svc_export * exp_get_by_name(struct auth_domain *clp, 89struct svc_export * exp_get_by_name(struct auth_domain *clp,
92 struct vfsmount *mnt, 90 struct vfsmount *mnt,
93 struct dentry *dentry, 91 struct dentry *dentry,
@@ -101,35 +99,20 @@ int exp_rootfh(struct auth_domain *,
101int exp_pseudoroot(struct auth_domain *, struct svc_fh *fhp, struct cache_req *creq); 99int exp_pseudoroot(struct auth_domain *, struct svc_fh *fhp, struct cache_req *creq);
102int nfserrno(int errno); 100int nfserrno(int errno);
103 101
104extern void expkey_put(struct cache_head *item, struct cache_detail *cd); 102extern struct cache_detail svc_export_cache;
105extern void svc_export_put(struct cache_head *item, struct cache_detail *cd);
106extern struct cache_detail svc_export_cache, svc_expkey_cache;
107 103
108static inline void exp_put(struct svc_export *exp) 104static inline void exp_put(struct svc_export *exp)
109{ 105{
110 svc_export_put(&exp->h, &svc_export_cache); 106 cache_put(&exp->h, &svc_export_cache);
111} 107}
112 108
113static inline void exp_get(struct svc_export *exp) 109static inline void exp_get(struct svc_export *exp)
114{ 110{
115 cache_get(&exp->h); 111 cache_get(&exp->h);
116} 112}
117static inline struct svc_export * 113extern struct svc_export *
118exp_find(struct auth_domain *clp, int fsid_type, u32 *fsidv, 114exp_find(struct auth_domain *clp, int fsid_type, u32 *fsidv,
119 struct cache_req *reqp) 115 struct cache_req *reqp);
120{
121 struct svc_expkey *ek = exp_find_key(clp, fsid_type, fsidv, reqp);
122 if (ek && !IS_ERR(ek)) {
123 struct svc_export *exp = ek->ek_export;
124 int err;
125 exp_get(exp);
126 expkey_put(&ek->h, &svc_expkey_cache);
127 if ((err = cache_check(&svc_export_cache, &exp->h, reqp)))
128 exp = ERR_PTR(err);
129 return exp;
130 } else
131 return ERR_PTR(PTR_ERR(ek));
132}
133 116
134#endif /* __KERNEL__ */ 117#endif /* __KERNEL__ */
135 118
diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h
index b959a4525cbd..1a9ef3e627d1 100644
--- a/include/linux/nodemask.h
+++ b/include/linux/nodemask.h
@@ -350,11 +350,15 @@ extern nodemask_t node_possible_map;
350#define num_possible_nodes() nodes_weight(node_possible_map) 350#define num_possible_nodes() nodes_weight(node_possible_map)
351#define node_online(node) node_isset((node), node_online_map) 351#define node_online(node) node_isset((node), node_online_map)
352#define node_possible(node) node_isset((node), node_possible_map) 352#define node_possible(node) node_isset((node), node_possible_map)
353#define first_online_node first_node(node_online_map)
354#define next_online_node(nid) next_node((nid), node_online_map)
353#else 355#else
354#define num_online_nodes() 1 356#define num_online_nodes() 1
355#define num_possible_nodes() 1 357#define num_possible_nodes() 1
356#define node_online(node) ((node) == 0) 358#define node_online(node) ((node) == 0)
357#define node_possible(node) ((node) == 0) 359#define node_possible(node) ((node) == 0)
360#define first_online_node 0
361#define next_online_node(nid) (MAX_NUMNODES)
358#endif 362#endif
359 363
360#define any_online_node(mask) \ 364#define any_online_node(mask) \
diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index 5937dd6053c3..51dbab9710c7 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -10,25 +10,107 @@
10#ifndef _LINUX_NOTIFIER_H 10#ifndef _LINUX_NOTIFIER_H
11#define _LINUX_NOTIFIER_H 11#define _LINUX_NOTIFIER_H
12#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/mutex.h>
14#include <linux/rwsem.h>
13 15
14struct notifier_block 16/*
15{ 17 * Notifier chains are of three types:
16 int (*notifier_call)(struct notifier_block *self, unsigned long, void *); 18 *
19 * Atomic notifier chains: Chain callbacks run in interrupt/atomic
20 * context. Callouts are not allowed to block.
21 * Blocking notifier chains: Chain callbacks run in process context.
22 * Callouts are allowed to block.
23 * Raw notifier chains: There are no restrictions on callbacks,
24 * registration, or unregistration. All locking and protection
25 * must be provided by the caller.
26 *
27 * atomic_notifier_chain_register() may be called from an atomic context,
28 * but blocking_notifier_chain_register() must be called from a process
29 * context. Ditto for the corresponding _unregister() routines.
30 *
31 * atomic_notifier_chain_unregister() and blocking_notifier_chain_unregister()
32 * _must not_ be called from within the call chain.
33 */
34
35struct notifier_block {
36 int (*notifier_call)(struct notifier_block *, unsigned long, void *);
17 struct notifier_block *next; 37 struct notifier_block *next;
18 int priority; 38 int priority;
19}; 39};
20 40
41struct atomic_notifier_head {
42 spinlock_t lock;
43 struct notifier_block *head;
44};
45
46struct blocking_notifier_head {
47 struct rw_semaphore rwsem;
48 struct notifier_block *head;
49};
50
51struct raw_notifier_head {
52 struct notifier_block *head;
53};
54
55#define ATOMIC_INIT_NOTIFIER_HEAD(name) do { \
56 spin_lock_init(&(name)->lock); \
57 (name)->head = NULL; \
58 } while (0)
59#define BLOCKING_INIT_NOTIFIER_HEAD(name) do { \
60 init_rwsem(&(name)->rwsem); \
61 (name)->head = NULL; \
62 } while (0)
63#define RAW_INIT_NOTIFIER_HEAD(name) do { \
64 (name)->head = NULL; \
65 } while (0)
66
67#define ATOMIC_NOTIFIER_INIT(name) { \
68 .lock = SPIN_LOCK_UNLOCKED, \
69 .head = NULL }
70#define BLOCKING_NOTIFIER_INIT(name) { \
71 .rwsem = __RWSEM_INITIALIZER((name).rwsem), \
72 .head = NULL }
73#define RAW_NOTIFIER_INIT(name) { \
74 .head = NULL }
75
76#define ATOMIC_NOTIFIER_HEAD(name) \
77 struct atomic_notifier_head name = \
78 ATOMIC_NOTIFIER_INIT(name)
79#define BLOCKING_NOTIFIER_HEAD(name) \
80 struct blocking_notifier_head name = \
81 BLOCKING_NOTIFIER_INIT(name)
82#define RAW_NOTIFIER_HEAD(name) \
83 struct raw_notifier_head name = \
84 RAW_NOTIFIER_INIT(name)
21 85
22#ifdef __KERNEL__ 86#ifdef __KERNEL__
23 87
24extern int notifier_chain_register(struct notifier_block **list, struct notifier_block *n); 88extern int atomic_notifier_chain_register(struct atomic_notifier_head *,
25extern int notifier_chain_unregister(struct notifier_block **nl, struct notifier_block *n); 89 struct notifier_block *);
26extern int notifier_call_chain(struct notifier_block **n, unsigned long val, void *v); 90extern int blocking_notifier_chain_register(struct blocking_notifier_head *,
91 struct notifier_block *);
92extern int raw_notifier_chain_register(struct raw_notifier_head *,
93 struct notifier_block *);
94
95extern int atomic_notifier_chain_unregister(struct atomic_notifier_head *,
96 struct notifier_block *);
97extern int blocking_notifier_chain_unregister(struct blocking_notifier_head *,
98 struct notifier_block *);
99extern int raw_notifier_chain_unregister(struct raw_notifier_head *,
100 struct notifier_block *);
101
102extern int atomic_notifier_call_chain(struct atomic_notifier_head *,
103 unsigned long val, void *v);
104extern int blocking_notifier_call_chain(struct blocking_notifier_head *,
105 unsigned long val, void *v);
106extern int raw_notifier_call_chain(struct raw_notifier_head *,
107 unsigned long val, void *v);
27 108
28#define NOTIFY_DONE 0x0000 /* Don't care */ 109#define NOTIFY_DONE 0x0000 /* Don't care */
29#define NOTIFY_OK 0x0001 /* Suits me */ 110#define NOTIFY_OK 0x0001 /* Suits me */
30#define NOTIFY_STOP_MASK 0x8000 /* Don't call further */ 111#define NOTIFY_STOP_MASK 0x8000 /* Don't call further */
31#define NOTIFY_BAD (NOTIFY_STOP_MASK|0x0002) /* Bad/Veto action */ 112#define NOTIFY_BAD (NOTIFY_STOP_MASK|0x0002)
113 /* Bad/Veto action */
32/* 114/*
33 * Clean way to return from the notifier and stop further calls. 115 * Clean way to return from the notifier and stop further calls.
34 */ 116 */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 6f080ae59286..02f6cf20b141 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1052,6 +1052,7 @@
1052#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT2 0x00f2 1052#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT2 0x00f2
1053#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6200_ALT1 0x00f3 1053#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6200_ALT1 0x00f3
1054#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_GT 0x00f9 1054#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_GT 0x00f9
1055#define PCIE_DEVICE_ID_NVIDIA_QUADRO_NVS280 0x00fd
1055#define PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR 0x0100 1056#define PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR 0x0100
1056#define PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR 0x0101 1057#define PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR 0x0101
1057#define PCI_DEVICE_ID_NVIDIA_QUADRO 0x0103 1058#define PCI_DEVICE_ID_NVIDIA_QUADRO 0x0103
diff --git a/include/linux/pfn.h b/include/linux/pfn.h
new file mode 100644
index 000000000000..bb01f8b92b56
--- /dev/null
+++ b/include/linux/pfn.h
@@ -0,0 +1,9 @@
1#ifndef _LINUX_PFN_H_
2#define _LINUX_PFN_H_
3
4#define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
5#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
6#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
7#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
8
9#endif
diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h
index b6e0bcad84e1..66b44e5e0d6e 100644
--- a/include/linux/raid/md.h
+++ b/include/linux/raid/md.h
@@ -92,7 +92,10 @@ extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
92extern void md_super_wait(mddev_t *mddev); 92extern void md_super_wait(mddev_t *mddev);
93extern int sync_page_io(struct block_device *bdev, sector_t sector, int size, 93extern int sync_page_io(struct block_device *bdev, sector_t sector, int size,
94 struct page *page, int rw); 94 struct page *page, int rw);
95extern void md_do_sync(mddev_t *mddev);
96extern void md_new_event(mddev_t *mddev);
95 97
98extern void md_update_sb(mddev_t * mddev);
96 99
97#define MD_BUG(x...) { printk("md: bug in file %s, line %d\n", __FILE__, __LINE__); md_print_devices(); } 100#define MD_BUG(x...) { printk("md: bug in file %s, line %d\n", __FILE__, __LINE__); md_print_devices(); }
98 101
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
index 617b9506c760..e2df61f5b09a 100644
--- a/include/linux/raid/md_k.h
+++ b/include/linux/raid/md_k.h
@@ -132,6 +132,14 @@ struct mddev_s
132 132
133 char uuid[16]; 133 char uuid[16];
134 134
135 /* If the array is being reshaped, we need to record the
136 * new shape and an indication of where we are up to.
137 * This is written to the superblock.
138 * If reshape_position is MaxSector, then no reshape is happening (yet).
139 */
140 sector_t reshape_position;
141 int delta_disks, new_level, new_layout, new_chunk;
142
135 struct mdk_thread_s *thread; /* management thread */ 143 struct mdk_thread_s *thread; /* management thread */
136 struct mdk_thread_s *sync_thread; /* doing resync or reconstruct */ 144 struct mdk_thread_s *sync_thread; /* doing resync or reconstruct */
137 sector_t curr_resync; /* blocks scheduled */ 145 sector_t curr_resync; /* blocks scheduled */
@@ -143,6 +151,10 @@ struct mddev_s
143 sector_t resync_mismatches; /* count of sectors where 151 sector_t resync_mismatches; /* count of sectors where
144 * parity/replica mismatch found 152 * parity/replica mismatch found
145 */ 153 */
154
155 /* allow user-space to request suspension of IO to regions of the array */
156 sector_t suspend_lo;
157 sector_t suspend_hi;
146 /* if zero, use the system-wide default */ 158 /* if zero, use the system-wide default */
147 int sync_speed_min; 159 int sync_speed_min;
148 int sync_speed_max; 160 int sync_speed_max;
@@ -157,6 +169,9 @@ struct mddev_s
157 * DONE: thread is done and is waiting to be reaped 169 * DONE: thread is done and is waiting to be reaped
158 * REQUEST: user-space has requested a sync (used with SYNC) 170 * REQUEST: user-space has requested a sync (used with SYNC)
159 * CHECK: user-space request for for check-only, no repair 171 * CHECK: user-space request for for check-only, no repair
172 * RESHAPE: A reshape is happening
173 *
174 * If neither SYNC or RESHAPE are set, then it is a recovery.
160 */ 175 */
161#define MD_RECOVERY_RUNNING 0 176#define MD_RECOVERY_RUNNING 0
162#define MD_RECOVERY_SYNC 1 177#define MD_RECOVERY_SYNC 1
@@ -166,10 +181,11 @@ struct mddev_s
166#define MD_RECOVERY_NEEDED 5 181#define MD_RECOVERY_NEEDED 5
167#define MD_RECOVERY_REQUESTED 6 182#define MD_RECOVERY_REQUESTED 6
168#define MD_RECOVERY_CHECK 7 183#define MD_RECOVERY_CHECK 7
184#define MD_RECOVERY_RESHAPE 8
169 unsigned long recovery; 185 unsigned long recovery;
170 186
171 int in_sync; /* know to not need resync */ 187 int in_sync; /* know to not need resync */
172 struct semaphore reconfig_sem; 188 struct mutex reconfig_mutex;
173 atomic_t active; 189 atomic_t active;
174 190
175 int changed; /* true if we might need to reread partition info */ 191 int changed; /* true if we might need to reread partition info */
@@ -249,7 +265,8 @@ struct mdk_personality
249 int (*spare_active) (mddev_t *mddev); 265 int (*spare_active) (mddev_t *mddev);
250 sector_t (*sync_request)(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster); 266 sector_t (*sync_request)(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster);
251 int (*resize) (mddev_t *mddev, sector_t sectors); 267 int (*resize) (mddev_t *mddev, sector_t sectors);
252 int (*reshape) (mddev_t *mddev, int raid_disks); 268 int (*check_reshape) (mddev_t *mddev);
269 int (*start_reshape) (mddev_t *mddev);
253 int (*reconfig) (mddev_t *mddev, int layout, int chunk_size); 270 int (*reconfig) (mddev_t *mddev, int layout, int chunk_size);
254 /* quiesce moves between quiescence states 271 /* quiesce moves between quiescence states
255 * 0 - fully active 272 * 0 - fully active
diff --git a/include/linux/raid/md_p.h b/include/linux/raid/md_p.h
index c100fa5d4bfa..774e1acfb8c4 100644
--- a/include/linux/raid/md_p.h
+++ b/include/linux/raid/md_p.h
@@ -102,6 +102,18 @@ typedef struct mdp_device_descriptor_s {
102#define MD_SB_ERRORS 1 102#define MD_SB_ERRORS 1
103 103
104#define MD_SB_BITMAP_PRESENT 8 /* bitmap may be present nearby */ 104#define MD_SB_BITMAP_PRESENT 8 /* bitmap may be present nearby */
105
106/*
107 * Notes:
108 * - if an array is being reshaped (restriped) in order to change the
109 * the number of active devices in the array, 'raid_disks' will be
110 * the larger of the old and new numbers. 'delta_disks' will
111 * be the "new - old". So if +ve, raid_disks is the new value, and
112 * "raid_disks-delta_disks" is the old. If -ve, raid_disks is the
113 * old value and "raid_disks+delta_disks" is the new (smaller) value.
114 */
115
116
105typedef struct mdp_superblock_s { 117typedef struct mdp_superblock_s {
106 /* 118 /*
107 * Constant generic information 119 * Constant generic information
@@ -146,7 +158,13 @@ typedef struct mdp_superblock_s {
146 __u32 cp_events_hi; /* 10 high-order of checkpoint update count */ 158 __u32 cp_events_hi; /* 10 high-order of checkpoint update count */
147#endif 159#endif
148 __u32 recovery_cp; /* 11 recovery checkpoint sector count */ 160 __u32 recovery_cp; /* 11 recovery checkpoint sector count */
149 __u32 gstate_sreserved[MD_SB_GENERIC_STATE_WORDS - 12]; 161 /* There are only valid for minor_version > 90 */
162 __u64 reshape_position; /* 12,13 next address in array-space for reshape */
163 __u32 new_level; /* 14 new level we are reshaping to */
164 __u32 delta_disks; /* 15 change in number of raid_disks */
165 __u32 new_layout; /* 16 new layout */
166 __u32 new_chunk; /* 17 new chunk size (bytes) */
167 __u32 gstate_sreserved[MD_SB_GENERIC_STATE_WORDS - 18];
150 168
151 /* 169 /*
152 * Personality information 170 * Personality information
@@ -207,7 +225,14 @@ struct mdp_superblock_1 {
207 * NOTE: signed, so bitmap can be before superblock 225 * NOTE: signed, so bitmap can be before superblock
208 * only meaningful of feature_map[0] is set. 226 * only meaningful of feature_map[0] is set.
209 */ 227 */
210 __u8 pad1[128-100]; /* set to 0 when written */ 228
229 /* These are only valid with feature bit '4' */
230 __u64 reshape_position; /* next address in array-space for reshape */
231 __u32 new_level; /* new level we are reshaping to */
232 __u32 delta_disks; /* change in number of raid_disks */
233 __u32 new_layout; /* new layout */
234 __u32 new_chunk; /* new chunk size (bytes) */
235 __u8 pad1[128-124]; /* set to 0 when written */
211 236
212 /* constant this-device information - 64 bytes */ 237 /* constant this-device information - 64 bytes */
213 __u64 data_offset; /* sector start of data, often 0 */ 238 __u64 data_offset; /* sector start of data, often 0 */
@@ -240,8 +265,9 @@ struct mdp_superblock_1 {
240 265
241/* feature_map bits */ 266/* feature_map bits */
242#define MD_FEATURE_BITMAP_OFFSET 1 267#define MD_FEATURE_BITMAP_OFFSET 1
268#define MD_FEATURE_RESHAPE_ACTIVE 4
243 269
244#define MD_FEATURE_ALL 1 270#define MD_FEATURE_ALL 5
245 271
246#endif 272#endif
247 273
diff --git a/include/linux/raid/raid5.h b/include/linux/raid/raid5.h
index 394da8207b34..914af667044f 100644
--- a/include/linux/raid/raid5.h
+++ b/include/linux/raid/raid5.h
@@ -135,6 +135,7 @@ struct stripe_head {
135 atomic_t count; /* nr of active thread/requests */ 135 atomic_t count; /* nr of active thread/requests */
136 spinlock_t lock; 136 spinlock_t lock;
137 int bm_seq; /* sequence number for bitmap flushes */ 137 int bm_seq; /* sequence number for bitmap flushes */
138 int disks; /* disks in stripe */
138 struct r5dev { 139 struct r5dev {
139 struct bio req; 140 struct bio req;
140 struct bio_vec vec; 141 struct bio_vec vec;
@@ -156,6 +157,7 @@ struct stripe_head {
156#define R5_ReadError 8 /* seen a read error here recently */ 157#define R5_ReadError 8 /* seen a read error here recently */
157#define R5_ReWrite 9 /* have tried to over-write the readerror */ 158#define R5_ReWrite 9 /* have tried to over-write the readerror */
158 159
160#define R5_Expanded 10 /* This block now has post-expand data */
159/* 161/*
160 * Write method 162 * Write method
161 */ 163 */
@@ -174,7 +176,9 @@ struct stripe_head {
174#define STRIPE_DELAYED 6 176#define STRIPE_DELAYED 6
175#define STRIPE_DEGRADED 7 177#define STRIPE_DEGRADED 7
176#define STRIPE_BIT_DELAY 8 178#define STRIPE_BIT_DELAY 8
177 179#define STRIPE_EXPANDING 9
180#define STRIPE_EXPAND_SOURCE 10
181#define STRIPE_EXPAND_READY 11
178/* 182/*
179 * Plugging: 183 * Plugging:
180 * 184 *
@@ -211,12 +215,24 @@ struct raid5_private_data {
211 int raid_disks, working_disks, failed_disks; 215 int raid_disks, working_disks, failed_disks;
212 int max_nr_stripes; 216 int max_nr_stripes;
213 217
218 /* used during an expand */
219 sector_t expand_progress; /* MaxSector when no expand happening */
220 sector_t expand_lo; /* from here up to expand_progress it out-of-bounds
221 * as we haven't flushed the metadata yet
222 */
223 int previous_raid_disks;
224
214 struct list_head handle_list; /* stripes needing handling */ 225 struct list_head handle_list; /* stripes needing handling */
215 struct list_head delayed_list; /* stripes that have plugged requests */ 226 struct list_head delayed_list; /* stripes that have plugged requests */
216 struct list_head bitmap_list; /* stripes delaying awaiting bitmap update */ 227 struct list_head bitmap_list; /* stripes delaying awaiting bitmap update */
217 atomic_t preread_active_stripes; /* stripes with scheduled io */ 228 atomic_t preread_active_stripes; /* stripes with scheduled io */
218 229
219 char cache_name[20]; 230 atomic_t reshape_stripes; /* stripes with pending writes for reshape */
231 /* unfortunately we need two cache names as we temporarily have
232 * two caches.
233 */
234 int active_name;
235 char cache_name[2][20];
220 kmem_cache_t *slab_cache; /* for allocating stripes */ 236 kmem_cache_t *slab_cache; /* for allocating stripes */
221 237
222 int seq_flush, seq_write; 238 int seq_flush, seq_write;
@@ -238,9 +254,10 @@ struct raid5_private_data {
238 wait_queue_head_t wait_for_overlap; 254 wait_queue_head_t wait_for_overlap;
239 int inactive_blocked; /* release of inactive stripes blocked, 255 int inactive_blocked; /* release of inactive stripes blocked,
240 * waiting for 25% to be free 256 * waiting for 25% to be free
241 */ 257 */
258 int pool_size; /* number of disks in stripeheads in pool */
242 spinlock_t device_lock; 259 spinlock_t device_lock;
243 struct disk_info disks[0]; 260 struct disk_info *disks;
244}; 261};
245 262
246typedef struct raid5_private_data raid5_conf_t; 263typedef struct raid5_private_data raid5_conf_t;
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index b739ac1f7ca0..ab61cd1199f2 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -91,10 +91,102 @@ struct rtc_pll_info {
91#define RTC_PLL_GET _IOR('p', 0x11, struct rtc_pll_info) /* Get PLL correction */ 91#define RTC_PLL_GET _IOR('p', 0x11, struct rtc_pll_info) /* Get PLL correction */
92#define RTC_PLL_SET _IOW('p', 0x12, struct rtc_pll_info) /* Set PLL correction */ 92#define RTC_PLL_SET _IOW('p', 0x12, struct rtc_pll_info) /* Set PLL correction */
93 93
94/* interrupt flags */
95#define RTC_IRQF 0x80 /* any of the following is active */
96#define RTC_PF 0x40
97#define RTC_AF 0x20
98#define RTC_UF 0x10
99
94#ifdef __KERNEL__ 100#ifdef __KERNEL__
95 101
96#include <linux/interrupt.h> 102#include <linux/interrupt.h>
97 103
104extern int rtc_month_days(unsigned int month, unsigned int year);
105extern int rtc_valid_tm(struct rtc_time *tm);
106extern int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time);
107extern void rtc_time_to_tm(unsigned long time, struct rtc_time *tm);
108
109#include <linux/device.h>
110#include <linux/seq_file.h>
111#include <linux/cdev.h>
112#include <linux/poll.h>
113#include <linux/mutex.h>
114
115extern struct class *rtc_class;
116
117struct rtc_class_ops {
118 int (*open)(struct device *);
119 void (*release)(struct device *);
120 int (*ioctl)(struct device *, unsigned int, unsigned long);
121 int (*read_time)(struct device *, struct rtc_time *);
122 int (*set_time)(struct device *, struct rtc_time *);
123 int (*read_alarm)(struct device *, struct rtc_wkalrm *);
124 int (*set_alarm)(struct device *, struct rtc_wkalrm *);
125 int (*proc)(struct device *, struct seq_file *);
126 int (*set_mmss)(struct device *, unsigned long secs);
127 int (*irq_set_state)(struct device *, int enabled);
128 int (*irq_set_freq)(struct device *, int freq);
129 int (*read_callback)(struct device *, int data);
130};
131
132#define RTC_DEVICE_NAME_SIZE 20
133struct rtc_task;
134
135struct rtc_device
136{
137 struct class_device class_dev;
138 struct module *owner;
139
140 int id;
141 char name[RTC_DEVICE_NAME_SIZE];
142
143 struct rtc_class_ops *ops;
144 struct mutex ops_lock;
145
146 struct class_device *rtc_dev;
147 struct cdev char_dev;
148 struct mutex char_lock;
149
150 unsigned long irq_data;
151 spinlock_t irq_lock;
152 wait_queue_head_t irq_queue;
153 struct fasync_struct *async_queue;
154
155 struct rtc_task *irq_task;
156 spinlock_t irq_task_lock;
157 int irq_freq;
158};
159#define to_rtc_device(d) container_of(d, struct rtc_device, class_dev)
160
161extern struct rtc_device *rtc_device_register(const char *name,
162 struct device *dev,
163 struct rtc_class_ops *ops,
164 struct module *owner);
165extern void rtc_device_unregister(struct rtc_device *rdev);
166extern int rtc_interface_register(struct class_interface *intf);
167
168extern int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm);
169extern int rtc_set_time(struct class_device *class_dev, struct rtc_time *tm);
170extern int rtc_set_mmss(struct class_device *class_dev, unsigned long secs);
171extern int rtc_read_alarm(struct class_device *class_dev,
172 struct rtc_wkalrm *alrm);
173extern int rtc_set_alarm(struct class_device *class_dev,
174 struct rtc_wkalrm *alrm);
175extern void rtc_update_irq(struct class_device *class_dev,
176 unsigned long num, unsigned long events);
177
178extern struct class_device *rtc_class_open(char *name);
179extern void rtc_class_close(struct class_device *class_dev);
180
181extern int rtc_irq_register(struct class_device *class_dev,
182 struct rtc_task *task);
183extern void rtc_irq_unregister(struct class_device *class_dev,
184 struct rtc_task *task);
185extern int rtc_irq_set_state(struct class_device *class_dev,
186 struct rtc_task *task, int enabled);
187extern int rtc_irq_set_freq(struct class_device *class_dev,
188 struct rtc_task *task, int freq);
189
98typedef struct rtc_task { 190typedef struct rtc_task {
99 void (*func)(void *private_data); 191 void (*func)(void *private_data);
100 void *private_data; 192 void *private_data;
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 036d14d2bf90..20b4f0372e44 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -35,6 +35,7 @@
35#include <linux/topology.h> 35#include <linux/topology.h>
36#include <linux/seccomp.h> 36#include <linux/seccomp.h>
37#include <linux/rcupdate.h> 37#include <linux/rcupdate.h>
38#include <linux/futex.h>
38 39
39#include <linux/auxvec.h> /* For AT_VECTOR_SIZE */ 40#include <linux/auxvec.h> /* For AT_VECTOR_SIZE */
40 41
@@ -872,6 +873,11 @@ struct task_struct {
872 int cpuset_mems_generation; 873 int cpuset_mems_generation;
873 int cpuset_mem_spread_rotor; 874 int cpuset_mem_spread_rotor;
874#endif 875#endif
876 struct robust_list_head __user *robust_list;
877#ifdef CONFIG_COMPAT
878 struct compat_robust_list_head __user *compat_robust_list;
879#endif
880
875 atomic_t fs_excl; /* holding fs exclusive resources */ 881 atomic_t fs_excl; /* holding fs exclusive resources */
876 struct rcu_head rcu; 882 struct rcu_head rcu;
877}; 883};
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h
index c4e3ea7cf154..b5612c958cce 100644
--- a/include/linux/sunrpc/cache.h
+++ b/include/linux/sunrpc/cache.h
@@ -50,7 +50,7 @@ struct cache_head {
50 time_t last_refresh; /* If CACHE_PENDING, this is when upcall 50 time_t last_refresh; /* If CACHE_PENDING, this is when upcall
51 * was sent, else this is when update was received 51 * was sent, else this is when update was received
52 */ 52 */
53 atomic_t refcnt; 53 struct kref ref;
54 unsigned long flags; 54 unsigned long flags;
55}; 55};
56#define CACHE_VALID 0 /* Entry contains valid data */ 56#define CACHE_VALID 0 /* Entry contains valid data */
@@ -68,8 +68,7 @@ struct cache_detail {
68 atomic_t inuse; /* active user-space update or lookup */ 68 atomic_t inuse; /* active user-space update or lookup */
69 69
70 char *name; 70 char *name;
71 void (*cache_put)(struct cache_head *, 71 void (*cache_put)(struct kref *);
72 struct cache_detail*);
73 72
74 void (*cache_request)(struct cache_detail *cd, 73 void (*cache_request)(struct cache_detail *cd,
75 struct cache_head *h, 74 struct cache_head *h,
@@ -81,6 +80,11 @@ struct cache_detail {
81 struct cache_detail *cd, 80 struct cache_detail *cd,
82 struct cache_head *h); 81 struct cache_head *h);
83 82
83 struct cache_head * (*alloc)(void);
84 int (*match)(struct cache_head *orig, struct cache_head *new);
85 void (*init)(struct cache_head *orig, struct cache_head *new);
86 void (*update)(struct cache_head *orig, struct cache_head *new);
87
84 /* fields below this comment are for internal use 88 /* fields below this comment are for internal use
85 * and should not be touched by cache owners 89 * and should not be touched by cache owners
86 */ 90 */
@@ -123,126 +127,14 @@ struct cache_deferred_req {
123 int too_many); 127 int too_many);
124}; 128};
125 129
126/*
127 * just like a template in C++, this macro does cache lookup
128 * for us.
129 * The function is passed some sort of HANDLE from which a cache_detail
130 * structure can be determined (via SETUP, DETAIL), a template
131 * cache entry (type RTN*), and a "set" flag. Using the HASHFN and the
132 * TEST, the function will try to find a matching cache entry in the cache.
133 * If "set" == 0 :
134 * If an entry is found, it is returned
135 * If no entry is found, a new non-VALID entry is created.
136 * If "set" == 1 and INPLACE == 0 :
137 * If no entry is found a new one is inserted with data from "template"
138 * If a non-CACHE_VALID entry is found, it is updated from template using UPDATE
139 * If a CACHE_VALID entry is found, a new entry is swapped in with data
140 * from "template"
141 * If set == 1, and INPLACE == 1 :
142 * As above, except that if a CACHE_VALID entry is found, we UPDATE in place
143 * instead of swapping in a new entry.
144 *
145 * If the passed handle has the CACHE_NEGATIVE flag set, then UPDATE is not
146 * run but insteead CACHE_NEGATIVE is set in any new item.
147 130
148 * In any case, the new entry is returned with a reference count. 131extern struct cache_head *
149 * 132sunrpc_cache_lookup(struct cache_detail *detail,
150 * 133 struct cache_head *key, int hash);
151 * RTN is a struct type for a cache entry 134extern struct cache_head *
152 * MEMBER is the member of the cache which is cache_head, which must be first 135sunrpc_cache_update(struct cache_detail *detail,
153 * FNAME is the name for the function 136 struct cache_head *new, struct cache_head *old, int hash);
154 * ARGS are arguments to function and must contain RTN *item, int set. May
155 * also contain something to be usedby SETUP or DETAIL to find cache_detail.
156 * SETUP locates the cache detail and makes it available as...
157 * DETAIL identifies the cache detail, possibly set up by SETUP
158 * HASHFN returns a hash value of the cache entry "item"
159 * TEST tests if "tmp" matches "item"
160 * INIT copies key information from "item" to "new"
161 * UPDATE copies content information from "item" to "tmp"
162 * INPLACE is true if updates can happen inplace rather than allocating a new structure
163 *
164 * WARNING: any substantial changes to this must be reflected in
165 * net/sunrpc/svcauth.c(auth_domain_lookup)
166 * which is a similar routine that is open-coded.
167 */
168#define DefineCacheLookup(RTN,MEMBER,FNAME,ARGS,SETUP,DETAIL,HASHFN,TEST,INIT,UPDATE,INPLACE) \
169RTN *FNAME ARGS \
170{ \
171 RTN *tmp, *new=NULL; \
172 struct cache_head **hp, **head; \
173 SETUP; \
174 head = &(DETAIL)->hash_table[HASHFN]; \
175 retry: \
176 if (set||new) write_lock(&(DETAIL)->hash_lock); \
177 else read_lock(&(DETAIL)->hash_lock); \
178 for(hp=head; *hp != NULL; hp = &tmp->MEMBER.next) { \
179 tmp = container_of(*hp, RTN, MEMBER); \
180 if (TEST) { /* found a match */ \
181 \
182 if (set && !INPLACE && test_bit(CACHE_VALID, &tmp->MEMBER.flags) && !new) \
183 break; \
184 \
185 if (new) \
186 {INIT;} \
187 if (set) { \
188 if (!INPLACE && test_bit(CACHE_VALID, &tmp->MEMBER.flags))\
189 { /* need to swap in new */ \
190 RTN *t2; \
191 \
192 new->MEMBER.next = tmp->MEMBER.next; \
193 *hp = &new->MEMBER; \
194 tmp->MEMBER.next = NULL; \
195 t2 = tmp; tmp = new; new = t2; \
196 } \
197 if (test_bit(CACHE_NEGATIVE, &item->MEMBER.flags)) \
198 set_bit(CACHE_NEGATIVE, &tmp->MEMBER.flags); \
199 else { \
200 UPDATE; \
201 clear_bit(CACHE_NEGATIVE, &tmp->MEMBER.flags); \
202 } \
203 } \
204 cache_get(&tmp->MEMBER); \
205 if (set||new) write_unlock(&(DETAIL)->hash_lock); \
206 else read_unlock(&(DETAIL)->hash_lock); \
207 if (set) \
208 cache_fresh(DETAIL, &tmp->MEMBER, item->MEMBER.expiry_time); \
209 if (set && !INPLACE && new) cache_fresh(DETAIL, &new->MEMBER, 0); \
210 if (new) (DETAIL)->cache_put(&new->MEMBER, DETAIL); \
211 return tmp; \
212 } \
213 } \
214 /* Didn't find anything */ \
215 if (new) { \
216 INIT; \
217 new->MEMBER.next = *head; \
218 *head = &new->MEMBER; \
219 (DETAIL)->entries ++; \
220 cache_get(&new->MEMBER); \
221 if (set) { \
222 tmp = new; \
223 if (test_bit(CACHE_NEGATIVE, &item->MEMBER.flags)) \
224 set_bit(CACHE_NEGATIVE, &tmp->MEMBER.flags); \
225 else {UPDATE;} \
226 } \
227 } \
228 if (set||new) write_unlock(&(DETAIL)->hash_lock); \
229 else read_unlock(&(DETAIL)->hash_lock); \
230 if (new && set) \
231 cache_fresh(DETAIL, &new->MEMBER, item->MEMBER.expiry_time); \
232 if (new) \
233 return new; \
234 new = kmalloc(sizeof(*new), GFP_KERNEL); \
235 if (new) { \
236 cache_init(&new->MEMBER); \
237 goto retry; \
238 } \
239 return NULL; \
240}
241 137
242#define DefineSimpleCacheLookup(STRUCT,INPLACE) \
243 DefineCacheLookup(struct STRUCT, h, STRUCT##_lookup, (struct STRUCT *item, int set), /*no setup */, \
244 & STRUCT##_cache, STRUCT##_hash(item), STRUCT##_match(item, tmp),\
245 STRUCT##_init(new, item), STRUCT##_update(tmp, item),INPLACE)
246 138
247#define cache_for_each(pos, detail, index, member) \ 139#define cache_for_each(pos, detail, index, member) \
248 for (({read_lock(&(detail)->hash_lock); index = (detail)->hash_size;}) ; \ 140 for (({read_lock(&(detail)->hash_lock); index = (detail)->hash_size;}) ; \
@@ -258,22 +150,19 @@ extern void cache_clean_deferred(void *owner);
258 150
259static inline struct cache_head *cache_get(struct cache_head *h) 151static inline struct cache_head *cache_get(struct cache_head *h)
260{ 152{
261 atomic_inc(&h->refcnt); 153 kref_get(&h->ref);
262 return h; 154 return h;
263} 155}
264 156
265 157
266static inline int cache_put(struct cache_head *h, struct cache_detail *cd) 158static inline void cache_put(struct cache_head *h, struct cache_detail *cd)
267{ 159{
268 if (atomic_read(&h->refcnt) <= 2 && 160 if (atomic_read(&h->ref.refcount) <= 2 &&
269 h->expiry_time < cd->nextcheck) 161 h->expiry_time < cd->nextcheck)
270 cd->nextcheck = h->expiry_time; 162 cd->nextcheck = h->expiry_time;
271 return atomic_dec_and_test(&h->refcnt); 163 kref_put(&h->ref, cd->cache_put);
272} 164}
273 165
274extern void cache_init(struct cache_head *h);
275extern void cache_fresh(struct cache_detail *detail,
276 struct cache_head *head, time_t expiry);
277extern int cache_check(struct cache_detail *detail, 166extern int cache_check(struct cache_detail *detail,
278 struct cache_head *h, struct cache_req *rqstp); 167 struct cache_head *h, struct cache_req *rqstp);
279extern void cache_flush(void); 168extern void cache_flush(void);
diff --git a/include/linux/sunrpc/svcauth.h b/include/linux/sunrpc/svcauth.h
index c119ce7cbd22..2fe2087edd66 100644
--- a/include/linux/sunrpc/svcauth.h
+++ b/include/linux/sunrpc/svcauth.h
@@ -45,9 +45,10 @@ struct svc_rqst; /* forward decl */
45 * of ip addresses to the given client. 45 * of ip addresses to the given client.
46 */ 46 */
47struct auth_domain { 47struct auth_domain {
48 struct cache_head h; 48 struct kref ref;
49 struct hlist_node hash;
49 char *name; 50 char *name;
50 int flavour; 51 struct auth_ops *flavour;
51}; 52};
52 53
53/* 54/*
@@ -86,6 +87,9 @@ struct auth_domain {
86 * 87 *
87 * domain_release() 88 * domain_release()
88 * This call releases a domain. 89 * This call releases a domain.
90 * set_client()
91 * Givens a pending request (struct svc_rqst), finds and assigns
92 * an appropriate 'auth_domain' as the client.
89 */ 93 */
90struct auth_ops { 94struct auth_ops {
91 char * name; 95 char * name;
@@ -117,7 +121,7 @@ extern void svc_auth_unregister(rpc_authflavor_t flavor);
117extern struct auth_domain *unix_domain_find(char *name); 121extern struct auth_domain *unix_domain_find(char *name);
118extern void auth_domain_put(struct auth_domain *item); 122extern void auth_domain_put(struct auth_domain *item);
119extern int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom); 123extern int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom);
120extern struct auth_domain *auth_domain_lookup(struct auth_domain *item, int set); 124extern struct auth_domain *auth_domain_lookup(char *name, struct auth_domain *new);
121extern struct auth_domain *auth_domain_find(char *name); 125extern struct auth_domain *auth_domain_find(char *name);
122extern struct auth_domain *auth_unix_lookup(struct in_addr addr); 126extern struct auth_domain *auth_unix_lookup(struct in_addr addr);
123extern int auth_unix_forget_old(struct auth_domain *dom); 127extern int auth_unix_forget_old(struct auth_domain *dom);
@@ -160,8 +164,6 @@ static inline unsigned long hash_mem(char *buf, int length, int bits)
160 return hash >> (BITS_PER_LONG - bits); 164 return hash >> (BITS_PER_LONG - bits);
161} 165}
162 166
163extern struct cache_detail auth_domain_cache, ip_map_cache;
164
165#endif /* __KERNEL__ */ 167#endif /* __KERNEL__ */
166 168
167#endif /* _LINUX_SUNRPC_SVCAUTH_H_ */ 169#endif /* _LINUX_SUNRPC_SVCAUTH_H_ */
diff --git a/include/linux/threads.h b/include/linux/threads.h
index b59738ac6197..e646bcdf2614 100644
--- a/include/linux/threads.h
+++ b/include/linux/threads.h
@@ -28,7 +28,8 @@
28#define PID_MAX_DEFAULT (CONFIG_BASE_SMALL ? 0x1000 : 0x8000) 28#define PID_MAX_DEFAULT (CONFIG_BASE_SMALL ? 0x1000 : 0x8000)
29 29
30/* 30/*
31 * A maximum of 4 million PIDs should be enough for a while: 31 * A maximum of 4 million PIDs should be enough for a while.
32 * [NOTE: PID/TIDs are limited to 2^29 ~= 500+ million, see futex.h.]
32 */ 33 */
33#define PID_MAX_LIMIT (CONFIG_BASE_SMALL ? PAGE_SIZE * 8 : \ 34#define PID_MAX_LIMIT (CONFIG_BASE_SMALL ? PAGE_SIZE * 8 : \
34 (sizeof(long) > 4 ? 4 * 1024 * 1024 : PID_MAX_DEFAULT)) 35 (sizeof(long) > 4 ? 4 * 1024 * 1024 : PID_MAX_DEFAULT))
diff --git a/include/linux/topology.h b/include/linux/topology.h
index e8eb0040ce3a..a305ae2e44b6 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -164,6 +164,15 @@
164 .nr_balance_failed = 0, \ 164 .nr_balance_failed = 0, \
165} 165}
166 166
167#ifdef CONFIG_SCHED_MC
168#ifndef SD_MC_INIT
169/* for now its same as SD_CPU_INIT.
170 * TBD: Tune Domain parameters!
171 */
172#define SD_MC_INIT SD_CPU_INIT
173#endif
174#endif
175
167#ifdef CONFIG_NUMA 176#ifdef CONFIG_NUMA
168#ifndef SD_NODE_INIT 177#ifndef SD_NODE_INIT
169#error Please define an appropriate SD_NODE_INIT in include/asm/topology.h!!! 178#error Please define an appropriate SD_NODE_INIT in include/asm/topology.h!!!
diff --git a/include/linux/x1205.h b/include/linux/x1205.h
deleted file mode 100644
index 64fd3af894a5..000000000000
--- a/include/linux/x1205.h
+++ /dev/null
@@ -1,31 +0,0 @@
1/*
2 * x1205.h - defines for drivers/i2c/chips/x1205.c
3 * Copyright 2004 Karen Spearel
4 * Copyright 2005 Alessandro Zummo
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#ifndef __LINUX_X1205_H__
13#define __LINUX_X1205_H__
14
15/* commands */
16
17#define X1205_CMD_GETDATETIME 0
18#define X1205_CMD_SETTIME 1
19#define X1205_CMD_SETDATETIME 2
20#define X1205_CMD_GETALARM 3
21#define X1205_CMD_SETALARM 4
22#define X1205_CMD_GETDTRIM 5
23#define X1205_CMD_SETDTRIM 6
24#define X1205_CMD_GETATRIM 7
25#define X1205_CMD_SETATRIM 8
26
27extern int x1205_do_command(unsigned int cmd, void *arg);
28extern int x1205_direct_attach(int adapter_id,
29 struct i2c_client_address_data *address_data);
30
31#endif /* __LINUX_X1205_H__ */
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index b6f0905a4ee2..916013ca4a5c 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -300,29 +300,30 @@ DECLARE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache);
300 300
301#define CONNTRACK_ECACHE(x) (__get_cpu_var(nf_conntrack_ecache).x) 301#define CONNTRACK_ECACHE(x) (__get_cpu_var(nf_conntrack_ecache).x)
302 302
303extern struct notifier_block *nf_conntrack_chain; 303extern struct atomic_notifier_head nf_conntrack_chain;
304extern struct notifier_block *nf_conntrack_expect_chain; 304extern struct atomic_notifier_head nf_conntrack_expect_chain;
305 305
306static inline int nf_conntrack_register_notifier(struct notifier_block *nb) 306static inline int nf_conntrack_register_notifier(struct notifier_block *nb)
307{ 307{
308 return notifier_chain_register(&nf_conntrack_chain, nb); 308 return atomic_notifier_chain_register(&nf_conntrack_chain, nb);
309} 309}
310 310
311static inline int nf_conntrack_unregister_notifier(struct notifier_block *nb) 311static inline int nf_conntrack_unregister_notifier(struct notifier_block *nb)
312{ 312{
313 return notifier_chain_unregister(&nf_conntrack_chain, nb); 313 return atomic_notifier_chain_unregister(&nf_conntrack_chain, nb);
314} 314}
315 315
316static inline int 316static inline int
317nf_conntrack_expect_register_notifier(struct notifier_block *nb) 317nf_conntrack_expect_register_notifier(struct notifier_block *nb)
318{ 318{
319 return notifier_chain_register(&nf_conntrack_expect_chain, nb); 319 return atomic_notifier_chain_register(&nf_conntrack_expect_chain, nb);
320} 320}
321 321
322static inline int 322static inline int
323nf_conntrack_expect_unregister_notifier(struct notifier_block *nb) 323nf_conntrack_expect_unregister_notifier(struct notifier_block *nb)
324{ 324{
325 return notifier_chain_unregister(&nf_conntrack_expect_chain, nb); 325 return atomic_notifier_chain_unregister(&nf_conntrack_expect_chain,
326 nb);
326} 327}
327 328
328extern void nf_ct_deliver_cached_events(const struct nf_conn *ct); 329extern void nf_ct_deliver_cached_events(const struct nf_conn *ct);
@@ -347,14 +348,14 @@ static inline void nf_conntrack_event(enum ip_conntrack_events event,
347 struct nf_conn *ct) 348 struct nf_conn *ct)
348{ 349{
349 if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) 350 if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct))
350 notifier_call_chain(&nf_conntrack_chain, event, ct); 351 atomic_notifier_call_chain(&nf_conntrack_chain, event, ct);
351} 352}
352 353
353static inline void 354static inline void
354nf_conntrack_expect_event(enum ip_conntrack_expect_events event, 355nf_conntrack_expect_event(enum ip_conntrack_expect_events event,
355 struct nf_conntrack_expect *exp) 356 struct nf_conntrack_expect *exp)
356{ 357{
357 notifier_call_chain(&nf_conntrack_expect_chain, event, exp); 358 atomic_notifier_call_chain(&nf_conntrack_expect_chain, event, exp);
358} 359}
359#else /* CONFIG_NF_CONNTRACK_EVENTS */ 360#else /* CONFIG_NF_CONNTRACK_EVENTS */
360static inline void nf_conntrack_event_cache(enum ip_conntrack_events event, 361static inline void nf_conntrack_event_cache(enum ip_conntrack_events event,
diff --git a/kernel/Makefile b/kernel/Makefile
index ff1c11dc12cf..58908f9d156a 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -12,6 +12,9 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \
12 12
13obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o 13obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o
14obj-$(CONFIG_FUTEX) += futex.o 14obj-$(CONFIG_FUTEX) += futex.o
15ifeq ($(CONFIG_COMPAT),y)
16obj-$(CONFIG_FUTEX) += futex_compat.o
17endif
15obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o 18obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
16obj-$(CONFIG_SMP) += cpu.o spinlock.o 19obj-$(CONFIG_SMP) += cpu.o spinlock.o
17obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o 20obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o
diff --git a/kernel/compat.c b/kernel/compat.c
index b9bdd1271f44..c1601a84f8d8 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -17,7 +17,6 @@
17#include <linux/time.h> 17#include <linux/time.h>
18#include <linux/signal.h> 18#include <linux/signal.h>
19#include <linux/sched.h> /* for MAX_SCHEDULE_TIMEOUT */ 19#include <linux/sched.h> /* for MAX_SCHEDULE_TIMEOUT */
20#include <linux/futex.h> /* for FUTEX_WAIT */
21#include <linux/syscalls.h> 20#include <linux/syscalls.h>
22#include <linux/unistd.h> 21#include <linux/unistd.h>
23#include <linux/security.h> 22#include <linux/security.h>
@@ -239,28 +238,6 @@ asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t __user *set,
239 return ret; 238 return ret;
240} 239}
241 240
242#ifdef CONFIG_FUTEX
243asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, int val,
244 struct compat_timespec __user *utime, u32 __user *uaddr2,
245 int val3)
246{
247 struct timespec t;
248 unsigned long timeout = MAX_SCHEDULE_TIMEOUT;
249 int val2 = 0;
250
251 if ((op == FUTEX_WAIT) && utime) {
252 if (get_compat_timespec(&t, utime))
253 return -EFAULT;
254 timeout = timespec_to_jiffies(&t) + 1;
255 }
256 if (op >= FUTEX_REQUEUE)
257 val2 = (int) (unsigned long) utime;
258
259 return do_futex((unsigned long)uaddr, op, val, timeout,
260 (unsigned long)uaddr2, val2, val3);
261}
262#endif
263
264asmlinkage long compat_sys_setrlimit(unsigned int resource, 241asmlinkage long compat_sys_setrlimit(unsigned int resource,
265 struct compat_rlimit __user *rlim) 242 struct compat_rlimit __user *rlim)
266{ 243{
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 8be22bd80933..fe2b8d0bfe4c 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -18,7 +18,7 @@
18/* This protects CPUs going up and down... */ 18/* This protects CPUs going up and down... */
19static DECLARE_MUTEX(cpucontrol); 19static DECLARE_MUTEX(cpucontrol);
20 20
21static struct notifier_block *cpu_chain; 21static BLOCKING_NOTIFIER_HEAD(cpu_chain);
22 22
23#ifdef CONFIG_HOTPLUG_CPU 23#ifdef CONFIG_HOTPLUG_CPU
24static struct task_struct *lock_cpu_hotplug_owner; 24static struct task_struct *lock_cpu_hotplug_owner;
@@ -71,21 +71,13 @@ EXPORT_SYMBOL_GPL(lock_cpu_hotplug_interruptible);
71/* Need to know about CPUs going up/down? */ 71/* Need to know about CPUs going up/down? */
72int register_cpu_notifier(struct notifier_block *nb) 72int register_cpu_notifier(struct notifier_block *nb)
73{ 73{
74 int ret; 74 return blocking_notifier_chain_register(&cpu_chain, nb);
75
76 if ((ret = lock_cpu_hotplug_interruptible()) != 0)
77 return ret;
78 ret = notifier_chain_register(&cpu_chain, nb);
79 unlock_cpu_hotplug();
80 return ret;
81} 75}
82EXPORT_SYMBOL(register_cpu_notifier); 76EXPORT_SYMBOL(register_cpu_notifier);
83 77
84void unregister_cpu_notifier(struct notifier_block *nb) 78void unregister_cpu_notifier(struct notifier_block *nb)
85{ 79{
86 lock_cpu_hotplug(); 80 blocking_notifier_chain_unregister(&cpu_chain, nb);
87 notifier_chain_unregister(&cpu_chain, nb);
88 unlock_cpu_hotplug();
89} 81}
90EXPORT_SYMBOL(unregister_cpu_notifier); 82EXPORT_SYMBOL(unregister_cpu_notifier);
91 83
@@ -141,7 +133,7 @@ int cpu_down(unsigned int cpu)
141 goto out; 133 goto out;
142 } 134 }
143 135
144 err = notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE, 136 err = blocking_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE,
145 (void *)(long)cpu); 137 (void *)(long)cpu);
146 if (err == NOTIFY_BAD) { 138 if (err == NOTIFY_BAD) {
147 printk("%s: attempt to take down CPU %u failed\n", 139 printk("%s: attempt to take down CPU %u failed\n",
@@ -159,7 +151,7 @@ int cpu_down(unsigned int cpu)
159 p = __stop_machine_run(take_cpu_down, NULL, cpu); 151 p = __stop_machine_run(take_cpu_down, NULL, cpu);
160 if (IS_ERR(p)) { 152 if (IS_ERR(p)) {
161 /* CPU didn't die: tell everyone. Can't complain. */ 153 /* CPU didn't die: tell everyone. Can't complain. */
162 if (notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED, 154 if (blocking_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED,
163 (void *)(long)cpu) == NOTIFY_BAD) 155 (void *)(long)cpu) == NOTIFY_BAD)
164 BUG(); 156 BUG();
165 157
@@ -182,8 +174,8 @@ int cpu_down(unsigned int cpu)
182 put_cpu(); 174 put_cpu();
183 175
184 /* CPU is completely dead: tell everyone. Too late to complain. */ 176 /* CPU is completely dead: tell everyone. Too late to complain. */
185 if (notifier_call_chain(&cpu_chain, CPU_DEAD, (void *)(long)cpu) 177 if (blocking_notifier_call_chain(&cpu_chain, CPU_DEAD,
186 == NOTIFY_BAD) 178 (void *)(long)cpu) == NOTIFY_BAD)
187 BUG(); 179 BUG();
188 180
189 check_for_tasks(cpu); 181 check_for_tasks(cpu);
@@ -211,7 +203,7 @@ int __devinit cpu_up(unsigned int cpu)
211 goto out; 203 goto out;
212 } 204 }
213 205
214 ret = notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu); 206 ret = blocking_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu);
215 if (ret == NOTIFY_BAD) { 207 if (ret == NOTIFY_BAD) {
216 printk("%s: attempt to bring up CPU %u failed\n", 208 printk("%s: attempt to bring up CPU %u failed\n",
217 __FUNCTION__, cpu); 209 __FUNCTION__, cpu);
@@ -226,11 +218,12 @@ int __devinit cpu_up(unsigned int cpu)
226 BUG_ON(!cpu_online(cpu)); 218 BUG_ON(!cpu_online(cpu));
227 219
228 /* Now call notifier in preparation. */ 220 /* Now call notifier in preparation. */
229 notifier_call_chain(&cpu_chain, CPU_ONLINE, hcpu); 221 blocking_notifier_call_chain(&cpu_chain, CPU_ONLINE, hcpu);
230 222
231out_notify: 223out_notify:
232 if (ret != 0) 224 if (ret != 0)
233 notifier_call_chain(&cpu_chain, CPU_UP_CANCELED, hcpu); 225 blocking_notifier_call_chain(&cpu_chain,
226 CPU_UP_CANCELED, hcpu);
234out: 227out:
235 unlock_cpu_hotplug(); 228 unlock_cpu_hotplug();
236 return ret; 229 return ret;
diff --git a/kernel/exit.c b/kernel/exit.c
index 8037405e136e..a8c7efc7a681 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -31,6 +31,8 @@
31#include <linux/signal.h> 31#include <linux/signal.h>
32#include <linux/cn_proc.h> 32#include <linux/cn_proc.h>
33#include <linux/mutex.h> 33#include <linux/mutex.h>
34#include <linux/futex.h>
35#include <linux/compat.h>
34 36
35#include <asm/uaccess.h> 37#include <asm/uaccess.h>
36#include <asm/unistd.h> 38#include <asm/unistd.h>
@@ -852,6 +854,12 @@ fastcall NORET_TYPE void do_exit(long code)
852 exit_itimers(tsk->signal); 854 exit_itimers(tsk->signal);
853 acct_process(code); 855 acct_process(code);
854 } 856 }
857 if (unlikely(tsk->robust_list))
858 exit_robust_list(tsk);
859#ifdef CONFIG_COMPAT
860 if (unlikely(tsk->compat_robust_list))
861 compat_exit_robust_list(tsk);
862#endif
855 exit_mm(tsk); 863 exit_mm(tsk);
856 864
857 exit_sem(tsk); 865 exit_sem(tsk);
diff --git a/kernel/fork.c b/kernel/fork.c
index e0a2b449dea6..c49bd193b058 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1061,7 +1061,10 @@ static task_t *copy_process(unsigned long clone_flags,
1061 * Clear TID on mm_release()? 1061 * Clear TID on mm_release()?
1062 */ 1062 */
1063 p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? child_tidptr: NULL; 1063 p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? child_tidptr: NULL;
1064 1064 p->robust_list = NULL;
1065#ifdef CONFIG_COMPAT
1066 p->compat_robust_list = NULL;
1067#endif
1065 /* 1068 /*
1066 * sigaltstack should be cleared when sharing the same VM 1069 * sigaltstack should be cleared when sharing the same VM
1067 */ 1070 */
diff --git a/kernel/futex.c b/kernel/futex.c
index 5efa2f978032..9c9b2b6b22dd 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -8,6 +8,10 @@
8 * Removed page pinning, fix privately mapped COW pages and other cleanups 8 * Removed page pinning, fix privately mapped COW pages and other cleanups
9 * (C) Copyright 2003, 2004 Jamie Lokier 9 * (C) Copyright 2003, 2004 Jamie Lokier
10 * 10 *
11 * Robust futex support started by Ingo Molnar
12 * (C) Copyright 2006 Red Hat Inc, All Rights Reserved
13 * Thanks to Thomas Gleixner for suggestions, analysis and fixes.
14 *
11 * Thanks to Ben LaHaise for yelling "hashed waitqueues" loudly 15 * Thanks to Ben LaHaise for yelling "hashed waitqueues" loudly
12 * enough at me, Linus for the original (flawed) idea, Matthew 16 * enough at me, Linus for the original (flawed) idea, Matthew
13 * Kirkwood for proof-of-concept implementation. 17 * Kirkwood for proof-of-concept implementation.
@@ -829,6 +833,172 @@ error:
829 goto out; 833 goto out;
830} 834}
831 835
836/*
837 * Support for robust futexes: the kernel cleans up held futexes at
838 * thread exit time.
839 *
840 * Implementation: user-space maintains a per-thread list of locks it
841 * is holding. Upon do_exit(), the kernel carefully walks this list,
842 * and marks all locks that are owned by this thread with the
843 * FUTEX_OWNER_DEAD bit, and wakes up a waiter (if any). The list is
844 * always manipulated with the lock held, so the list is private and
845 * per-thread. Userspace also maintains a per-thread 'list_op_pending'
846 * field, to allow the kernel to clean up if the thread dies after
847 * acquiring the lock, but just before it could have added itself to
848 * the list. There can only be one such pending lock.
849 */
850
851/**
852 * sys_set_robust_list - set the robust-futex list head of a task
853 * @head: pointer to the list-head
854 * @len: length of the list-head, as userspace expects
855 */
856asmlinkage long
857sys_set_robust_list(struct robust_list_head __user *head,
858 size_t len)
859{
860 /*
861 * The kernel knows only one size for now:
862 */
863 if (unlikely(len != sizeof(*head)))
864 return -EINVAL;
865
866 current->robust_list = head;
867
868 return 0;
869}
870
871/**
872 * sys_get_robust_list - get the robust-futex list head of a task
873 * @pid: pid of the process [zero for current task]
874 * @head_ptr: pointer to a list-head pointer, the kernel fills it in
875 * @len_ptr: pointer to a length field, the kernel fills in the header size
876 */
877asmlinkage long
878sys_get_robust_list(int pid, struct robust_list_head __user **head_ptr,
879 size_t __user *len_ptr)
880{
881 struct robust_list_head *head;
882 unsigned long ret;
883
884 if (!pid)
885 head = current->robust_list;
886 else {
887 struct task_struct *p;
888
889 ret = -ESRCH;
890 read_lock(&tasklist_lock);
891 p = find_task_by_pid(pid);
892 if (!p)
893 goto err_unlock;
894 ret = -EPERM;
895 if ((current->euid != p->euid) && (current->euid != p->uid) &&
896 !capable(CAP_SYS_PTRACE))
897 goto err_unlock;
898 head = p->robust_list;
899 read_unlock(&tasklist_lock);
900 }
901
902 if (put_user(sizeof(*head), len_ptr))
903 return -EFAULT;
904 return put_user(head, head_ptr);
905
906err_unlock:
907 read_unlock(&tasklist_lock);
908
909 return ret;
910}
911
912/*
913 * Process a futex-list entry, check whether it's owned by the
914 * dying task, and do notification if so:
915 */
916int handle_futex_death(u32 __user *uaddr, struct task_struct *curr)
917{
918 u32 uval;
919
920retry:
921 if (get_user(uval, uaddr))
922 return -1;
923
924 if ((uval & FUTEX_TID_MASK) == curr->pid) {
925 /*
926 * Ok, this dying thread is truly holding a futex
927 * of interest. Set the OWNER_DIED bit atomically
928 * via cmpxchg, and if the value had FUTEX_WAITERS
929 * set, wake up a waiter (if any). (We have to do a
930 * futex_wake() even if OWNER_DIED is already set -
931 * to handle the rare but possible case of recursive
932 * thread-death.) The rest of the cleanup is done in
933 * userspace.
934 */
935 if (futex_atomic_cmpxchg_inatomic(uaddr, uval,
936 uval | FUTEX_OWNER_DIED) != uval)
937 goto retry;
938
939 if (uval & FUTEX_WAITERS)
940 futex_wake((unsigned long)uaddr, 1);
941 }
942 return 0;
943}
944
945/*
946 * Walk curr->robust_list (very carefully, it's a userspace list!)
947 * and mark any locks found there dead, and notify any waiters.
948 *
949 * We silently return on any sign of list-walking problem.
950 */
951void exit_robust_list(struct task_struct *curr)
952{
953 struct robust_list_head __user *head = curr->robust_list;
954 struct robust_list __user *entry, *pending;
955 unsigned int limit = ROBUST_LIST_LIMIT;
956 unsigned long futex_offset;
957
958 /*
959 * Fetch the list head (which was registered earlier, via
960 * sys_set_robust_list()):
961 */
962 if (get_user(entry, &head->list.next))
963 return;
964 /*
965 * Fetch the relative futex offset:
966 */
967 if (get_user(futex_offset, &head->futex_offset))
968 return;
969 /*
970 * Fetch any possibly pending lock-add first, and handle it
971 * if it exists:
972 */
973 if (get_user(pending, &head->list_op_pending))
974 return;
975 if (pending)
976 handle_futex_death((void *)pending + futex_offset, curr);
977
978 while (entry != &head->list) {
979 /*
980 * A pending lock might already be on the list, so
981 * dont process it twice:
982 */
983 if (entry != pending)
984 if (handle_futex_death((void *)entry + futex_offset,
985 curr))
986 return;
987 /*
988 * Fetch the next entry in the list:
989 */
990 if (get_user(entry, &entry->next))
991 return;
992 /*
993 * Avoid excessively long or circular lists:
994 */
995 if (!--limit)
996 break;
997
998 cond_resched();
999 }
1000}
1001
832long do_futex(unsigned long uaddr, int op, int val, unsigned long timeout, 1002long do_futex(unsigned long uaddr, int op, int val, unsigned long timeout,
833 unsigned long uaddr2, int val2, int val3) 1003 unsigned long uaddr2, int val2, int val3)
834{ 1004{
diff --git a/kernel/futex_compat.c b/kernel/futex_compat.c
new file mode 100644
index 000000000000..9c077cf9aa84
--- /dev/null
+++ b/kernel/futex_compat.c
@@ -0,0 +1,141 @@
1/*
2 * linux/kernel/futex_compat.c
3 *
4 * Futex compatibililty routines.
5 *
6 * Copyright 2006, Red Hat, Inc., Ingo Molnar
7 */
8
9#include <linux/linkage.h>
10#include <linux/compat.h>
11#include <linux/futex.h>
12
13#include <asm/uaccess.h>
14
15/*
16 * Walk curr->robust_list (very carefully, it's a userspace list!)
17 * and mark any locks found there dead, and notify any waiters.
18 *
19 * We silently return on any sign of list-walking problem.
20 */
21void compat_exit_robust_list(struct task_struct *curr)
22{
23 struct compat_robust_list_head __user *head = curr->compat_robust_list;
24 struct robust_list __user *entry, *pending;
25 compat_uptr_t uentry, upending;
26 unsigned int limit = ROBUST_LIST_LIMIT;
27 compat_long_t futex_offset;
28
29 /*
30 * Fetch the list head (which was registered earlier, via
31 * sys_set_robust_list()):
32 */
33 if (get_user(uentry, &head->list.next))
34 return;
35 entry = compat_ptr(uentry);
36 /*
37 * Fetch the relative futex offset:
38 */
39 if (get_user(futex_offset, &head->futex_offset))
40 return;
41 /*
42 * Fetch any possibly pending lock-add first, and handle it
43 * if it exists:
44 */
45 if (get_user(upending, &head->list_op_pending))
46 return;
47 pending = compat_ptr(upending);
48 if (upending)
49 handle_futex_death((void *)pending + futex_offset, curr);
50
51 while (compat_ptr(uentry) != &head->list) {
52 /*
53 * A pending lock might already be on the list, so
54 * dont process it twice:
55 */
56 if (entry != pending)
57 if (handle_futex_death((void *)entry + futex_offset,
58 curr))
59 return;
60
61 /*
62 * Fetch the next entry in the list:
63 */
64 if (get_user(uentry, (compat_uptr_t *)&entry->next))
65 return;
66 entry = compat_ptr(uentry);
67 /*
68 * Avoid excessively long or circular lists:
69 */
70 if (!--limit)
71 break;
72
73 cond_resched();
74 }
75}
76
77asmlinkage long
78compat_sys_set_robust_list(struct compat_robust_list_head __user *head,
79 compat_size_t len)
80{
81 if (unlikely(len != sizeof(*head)))
82 return -EINVAL;
83
84 current->compat_robust_list = head;
85
86 return 0;
87}
88
89asmlinkage long
90compat_sys_get_robust_list(int pid, compat_uptr_t *head_ptr,
91 compat_size_t __user *len_ptr)
92{
93 struct compat_robust_list_head *head;
94 unsigned long ret;
95
96 if (!pid)
97 head = current->compat_robust_list;
98 else {
99 struct task_struct *p;
100
101 ret = -ESRCH;
102 read_lock(&tasklist_lock);
103 p = find_task_by_pid(pid);
104 if (!p)
105 goto err_unlock;
106 ret = -EPERM;
107 if ((current->euid != p->euid) && (current->euid != p->uid) &&
108 !capable(CAP_SYS_PTRACE))
109 goto err_unlock;
110 head = p->compat_robust_list;
111 read_unlock(&tasklist_lock);
112 }
113
114 if (put_user(sizeof(*head), len_ptr))
115 return -EFAULT;
116 return put_user(ptr_to_compat(head), head_ptr);
117
118err_unlock:
119 read_unlock(&tasklist_lock);
120
121 return ret;
122}
123
124asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val,
125 struct compat_timespec __user *utime, u32 __user *uaddr2,
126 u32 val3)
127{
128 struct timespec t;
129 unsigned long timeout = MAX_SCHEDULE_TIMEOUT;
130 int val2 = 0;
131
132 if ((op == FUTEX_WAIT) && utime) {
133 if (get_compat_timespec(&t, utime))
134 return -EFAULT;
135 timeout = timespec_to_jiffies(&t) + 1;
136 }
137 if (op >= FUTEX_REQUEUE)
138 val2 = (int) (unsigned long) utime;
139
140 return do_futex(uaddr, op, val, timeout, uaddr2, val2, val3);
141}
diff --git a/kernel/module.c b/kernel/module.c
index ddfe45ac2fd1..4fafd58038a0 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -64,26 +64,17 @@ static DEFINE_SPINLOCK(modlist_lock);
64static DEFINE_MUTEX(module_mutex); 64static DEFINE_MUTEX(module_mutex);
65static LIST_HEAD(modules); 65static LIST_HEAD(modules);
66 66
67static DEFINE_MUTEX(notify_mutex); 67static BLOCKING_NOTIFIER_HEAD(module_notify_list);
68static struct notifier_block * module_notify_list;
69 68
70int register_module_notifier(struct notifier_block * nb) 69int register_module_notifier(struct notifier_block * nb)
71{ 70{
72 int err; 71 return blocking_notifier_chain_register(&module_notify_list, nb);
73 mutex_lock(&notify_mutex);
74 err = notifier_chain_register(&module_notify_list, nb);
75 mutex_unlock(&notify_mutex);
76 return err;
77} 72}
78EXPORT_SYMBOL(register_module_notifier); 73EXPORT_SYMBOL(register_module_notifier);
79 74
80int unregister_module_notifier(struct notifier_block * nb) 75int unregister_module_notifier(struct notifier_block * nb)
81{ 76{
82 int err; 77 return blocking_notifier_chain_unregister(&module_notify_list, nb);
83 mutex_lock(&notify_mutex);
84 err = notifier_chain_unregister(&module_notify_list, nb);
85 mutex_unlock(&notify_mutex);
86 return err;
87} 78}
88EXPORT_SYMBOL(unregister_module_notifier); 79EXPORT_SYMBOL(unregister_module_notifier);
89 80
@@ -1816,9 +1807,8 @@ sys_init_module(void __user *umod,
1816 /* Drop lock so they can recurse */ 1807 /* Drop lock so they can recurse */
1817 mutex_unlock(&module_mutex); 1808 mutex_unlock(&module_mutex);
1818 1809
1819 mutex_lock(&notify_mutex); 1810 blocking_notifier_call_chain(&module_notify_list,
1820 notifier_call_chain(&module_notify_list, MODULE_STATE_COMING, mod); 1811 MODULE_STATE_COMING, mod);
1821 mutex_unlock(&notify_mutex);
1822 1812
1823 /* Start the module */ 1813 /* Start the module */
1824 if (mod->init != NULL) 1814 if (mod->init != NULL)
diff --git a/kernel/panic.c b/kernel/panic.c
index acd95adddb93..f895c7c01d5b 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -29,7 +29,7 @@ static DEFINE_SPINLOCK(pause_on_oops_lock);
29int panic_timeout; 29int panic_timeout;
30EXPORT_SYMBOL(panic_timeout); 30EXPORT_SYMBOL(panic_timeout);
31 31
32struct notifier_block *panic_notifier_list; 32ATOMIC_NOTIFIER_HEAD(panic_notifier_list);
33 33
34EXPORT_SYMBOL(panic_notifier_list); 34EXPORT_SYMBOL(panic_notifier_list);
35 35
@@ -97,7 +97,7 @@ NORET_TYPE void panic(const char * fmt, ...)
97 smp_send_stop(); 97 smp_send_stop();
98#endif 98#endif
99 99
100 notifier_call_chain(&panic_notifier_list, 0, buf); 100 atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
101 101
102 if (!panic_blink) 102 if (!panic_blink)
103 panic_blink = no_blink; 103 panic_blink = no_blink;
diff --git a/kernel/profile.c b/kernel/profile.c
index ad81f799a9b4..5a730fdb1a2c 100644
--- a/kernel/profile.c
+++ b/kernel/profile.c
@@ -87,72 +87,52 @@ void __init profile_init(void)
87 87
88#ifdef CONFIG_PROFILING 88#ifdef CONFIG_PROFILING
89 89
90static DECLARE_RWSEM(profile_rwsem); 90static BLOCKING_NOTIFIER_HEAD(task_exit_notifier);
91static DEFINE_RWLOCK(handoff_lock); 91static ATOMIC_NOTIFIER_HEAD(task_free_notifier);
92static struct notifier_block * task_exit_notifier; 92static BLOCKING_NOTIFIER_HEAD(munmap_notifier);
93static struct notifier_block * task_free_notifier;
94static struct notifier_block * munmap_notifier;
95 93
96void profile_task_exit(struct task_struct * task) 94void profile_task_exit(struct task_struct * task)
97{ 95{
98 down_read(&profile_rwsem); 96 blocking_notifier_call_chain(&task_exit_notifier, 0, task);
99 notifier_call_chain(&task_exit_notifier, 0, task);
100 up_read(&profile_rwsem);
101} 97}
102 98
103int profile_handoff_task(struct task_struct * task) 99int profile_handoff_task(struct task_struct * task)
104{ 100{
105 int ret; 101 int ret;
106 read_lock(&handoff_lock); 102 ret = atomic_notifier_call_chain(&task_free_notifier, 0, task);
107 ret = notifier_call_chain(&task_free_notifier, 0, task);
108 read_unlock(&handoff_lock);
109 return (ret == NOTIFY_OK) ? 1 : 0; 103 return (ret == NOTIFY_OK) ? 1 : 0;
110} 104}
111 105
112void profile_munmap(unsigned long addr) 106void profile_munmap(unsigned long addr)
113{ 107{
114 down_read(&profile_rwsem); 108 blocking_notifier_call_chain(&munmap_notifier, 0, (void *)addr);
115 notifier_call_chain(&munmap_notifier, 0, (void *)addr);
116 up_read(&profile_rwsem);
117} 109}
118 110
119int task_handoff_register(struct notifier_block * n) 111int task_handoff_register(struct notifier_block * n)
120{ 112{
121 int err = -EINVAL; 113 return atomic_notifier_chain_register(&task_free_notifier, n);
122
123 write_lock(&handoff_lock);
124 err = notifier_chain_register(&task_free_notifier, n);
125 write_unlock(&handoff_lock);
126 return err;
127} 114}
128 115
129int task_handoff_unregister(struct notifier_block * n) 116int task_handoff_unregister(struct notifier_block * n)
130{ 117{
131 int err = -EINVAL; 118 return atomic_notifier_chain_unregister(&task_free_notifier, n);
132
133 write_lock(&handoff_lock);
134 err = notifier_chain_unregister(&task_free_notifier, n);
135 write_unlock(&handoff_lock);
136 return err;
137} 119}
138 120
139int profile_event_register(enum profile_type type, struct notifier_block * n) 121int profile_event_register(enum profile_type type, struct notifier_block * n)
140{ 122{
141 int err = -EINVAL; 123 int err = -EINVAL;
142 124
143 down_write(&profile_rwsem);
144
145 switch (type) { 125 switch (type) {
146 case PROFILE_TASK_EXIT: 126 case PROFILE_TASK_EXIT:
147 err = notifier_chain_register(&task_exit_notifier, n); 127 err = blocking_notifier_chain_register(
128 &task_exit_notifier, n);
148 break; 129 break;
149 case PROFILE_MUNMAP: 130 case PROFILE_MUNMAP:
150 err = notifier_chain_register(&munmap_notifier, n); 131 err = blocking_notifier_chain_register(
132 &munmap_notifier, n);
151 break; 133 break;
152 } 134 }
153 135
154 up_write(&profile_rwsem);
155
156 return err; 136 return err;
157} 137}
158 138
@@ -161,18 +141,17 @@ int profile_event_unregister(enum profile_type type, struct notifier_block * n)
161{ 141{
162 int err = -EINVAL; 142 int err = -EINVAL;
163 143
164 down_write(&profile_rwsem);
165
166 switch (type) { 144 switch (type) {
167 case PROFILE_TASK_EXIT: 145 case PROFILE_TASK_EXIT:
168 err = notifier_chain_unregister(&task_exit_notifier, n); 146 err = blocking_notifier_chain_unregister(
147 &task_exit_notifier, n);
169 break; 148 break;
170 case PROFILE_MUNMAP: 149 case PROFILE_MUNMAP:
171 err = notifier_chain_unregister(&munmap_notifier, n); 150 err = blocking_notifier_chain_unregister(
151 &munmap_notifier, n);
172 break; 152 break;
173 } 153 }
174 154
175 up_write(&profile_rwsem);
176 return err; 155 return err;
177} 156}
178 157
diff --git a/kernel/sched.c b/kernel/sched.c
index 78acdefeccca..7854ee516b92 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -145,7 +145,8 @@
145 (v1) * (v2_max) / (v1_max) 145 (v1) * (v2_max) / (v1_max)
146 146
147#define DELTA(p) \ 147#define DELTA(p) \
148 (SCALE(TASK_NICE(p), 40, MAX_BONUS) + INTERACTIVE_DELTA) 148 (SCALE(TASK_NICE(p) + 20, 40, MAX_BONUS) - 20 * MAX_BONUS / 40 + \
149 INTERACTIVE_DELTA)
149 150
150#define TASK_INTERACTIVE(p) \ 151#define TASK_INTERACTIVE(p) \
151 ((p)->prio <= (p)->static_prio - DELTA(p)) 152 ((p)->prio <= (p)->static_prio - DELTA(p))
@@ -2878,13 +2879,11 @@ asmlinkage void __sched schedule(void)
2878 * schedule() atomically, we ignore that path for now. 2879 * schedule() atomically, we ignore that path for now.
2879 * Otherwise, whine if we are scheduling when we should not be. 2880 * Otherwise, whine if we are scheduling when we should not be.
2880 */ 2881 */
2881 if (likely(!current->exit_state)) { 2882 if (unlikely(in_atomic() && !current->exit_state)) {
2882 if (unlikely(in_atomic())) { 2883 printk(KERN_ERR "BUG: scheduling while atomic: "
2883 printk(KERN_ERR "BUG: scheduling while atomic: " 2884 "%s/0x%08x/%d\n",
2884 "%s/0x%08x/%d\n", 2885 current->comm, preempt_count(), current->pid);
2885 current->comm, preempt_count(), current->pid); 2886 dump_stack();
2886 dump_stack();
2887 }
2888 } 2887 }
2889 profile_hit(SCHED_PROFILING, __builtin_return_address(0)); 2888 profile_hit(SCHED_PROFILING, __builtin_return_address(0));
2890 2889
@@ -5575,11 +5574,31 @@ static int cpu_to_cpu_group(int cpu)
5575} 5574}
5576#endif 5575#endif
5577 5576
5577#ifdef CONFIG_SCHED_MC
5578static DEFINE_PER_CPU(struct sched_domain, core_domains);
5579static struct sched_group sched_group_core[NR_CPUS];
5580#endif
5581
5582#if defined(CONFIG_SCHED_MC) && defined(CONFIG_SCHED_SMT)
5583static int cpu_to_core_group(int cpu)
5584{
5585 return first_cpu(cpu_sibling_map[cpu]);
5586}
5587#elif defined(CONFIG_SCHED_MC)
5588static int cpu_to_core_group(int cpu)
5589{
5590 return cpu;
5591}
5592#endif
5593
5578static DEFINE_PER_CPU(struct sched_domain, phys_domains); 5594static DEFINE_PER_CPU(struct sched_domain, phys_domains);
5579static struct sched_group sched_group_phys[NR_CPUS]; 5595static struct sched_group sched_group_phys[NR_CPUS];
5580static int cpu_to_phys_group(int cpu) 5596static int cpu_to_phys_group(int cpu)
5581{ 5597{
5582#ifdef CONFIG_SCHED_SMT 5598#if defined(CONFIG_SCHED_MC)
5599 cpumask_t mask = cpu_coregroup_map(cpu);
5600 return first_cpu(mask);
5601#elif defined(CONFIG_SCHED_SMT)
5583 return first_cpu(cpu_sibling_map[cpu]); 5602 return first_cpu(cpu_sibling_map[cpu]);
5584#else 5603#else
5585 return cpu; 5604 return cpu;
@@ -5602,6 +5621,32 @@ static int cpu_to_allnodes_group(int cpu)
5602{ 5621{
5603 return cpu_to_node(cpu); 5622 return cpu_to_node(cpu);
5604} 5623}
5624static void init_numa_sched_groups_power(struct sched_group *group_head)
5625{
5626 struct sched_group *sg = group_head;
5627 int j;
5628
5629 if (!sg)
5630 return;
5631next_sg:
5632 for_each_cpu_mask(j, sg->cpumask) {
5633 struct sched_domain *sd;
5634
5635 sd = &per_cpu(phys_domains, j);
5636 if (j != first_cpu(sd->groups->cpumask)) {
5637 /*
5638 * Only add "power" once for each
5639 * physical package.
5640 */
5641 continue;
5642 }
5643
5644 sg->cpu_power += sd->groups->cpu_power;
5645 }
5646 sg = sg->next;
5647 if (sg != group_head)
5648 goto next_sg;
5649}
5605#endif 5650#endif
5606 5651
5607/* 5652/*
@@ -5677,6 +5722,17 @@ void build_sched_domains(const cpumask_t *cpu_map)
5677 sd->parent = p; 5722 sd->parent = p;
5678 sd->groups = &sched_group_phys[group]; 5723 sd->groups = &sched_group_phys[group];
5679 5724
5725#ifdef CONFIG_SCHED_MC
5726 p = sd;
5727 sd = &per_cpu(core_domains, i);
5728 group = cpu_to_core_group(i);
5729 *sd = SD_MC_INIT;
5730 sd->span = cpu_coregroup_map(i);
5731 cpus_and(sd->span, sd->span, *cpu_map);
5732 sd->parent = p;
5733 sd->groups = &sched_group_core[group];
5734#endif
5735
5680#ifdef CONFIG_SCHED_SMT 5736#ifdef CONFIG_SCHED_SMT
5681 p = sd; 5737 p = sd;
5682 sd = &per_cpu(cpu_domains, i); 5738 sd = &per_cpu(cpu_domains, i);
@@ -5702,6 +5758,19 @@ void build_sched_domains(const cpumask_t *cpu_map)
5702 } 5758 }
5703#endif 5759#endif
5704 5760
5761#ifdef CONFIG_SCHED_MC
5762 /* Set up multi-core groups */
5763 for_each_cpu_mask(i, *cpu_map) {
5764 cpumask_t this_core_map = cpu_coregroup_map(i);
5765 cpus_and(this_core_map, this_core_map, *cpu_map);
5766 if (i != first_cpu(this_core_map))
5767 continue;
5768 init_sched_build_groups(sched_group_core, this_core_map,
5769 &cpu_to_core_group);
5770 }
5771#endif
5772
5773
5705 /* Set up physical groups */ 5774 /* Set up physical groups */
5706 for (i = 0; i < MAX_NUMNODES; i++) { 5775 for (i = 0; i < MAX_NUMNODES; i++) {
5707 cpumask_t nodemask = node_to_cpumask(i); 5776 cpumask_t nodemask = node_to_cpumask(i);
@@ -5798,51 +5867,38 @@ void build_sched_domains(const cpumask_t *cpu_map)
5798 power = SCHED_LOAD_SCALE; 5867 power = SCHED_LOAD_SCALE;
5799 sd->groups->cpu_power = power; 5868 sd->groups->cpu_power = power;
5800#endif 5869#endif
5870#ifdef CONFIG_SCHED_MC
5871 sd = &per_cpu(core_domains, i);
5872 power = SCHED_LOAD_SCALE + (cpus_weight(sd->groups->cpumask)-1)
5873 * SCHED_LOAD_SCALE / 10;
5874 sd->groups->cpu_power = power;
5801 5875
5802 sd = &per_cpu(phys_domains, i); 5876 sd = &per_cpu(phys_domains, i);
5877
5878 /*
5879 * This has to be < 2 * SCHED_LOAD_SCALE
5880 * Lets keep it SCHED_LOAD_SCALE, so that
5881 * while calculating NUMA group's cpu_power
5882 * we can simply do
5883 * numa_group->cpu_power += phys_group->cpu_power;
5884 *
5885 * See "only add power once for each physical pkg"
5886 * comment below
5887 */
5888 sd->groups->cpu_power = SCHED_LOAD_SCALE;
5889#else
5890 sd = &per_cpu(phys_domains, i);
5803 power = SCHED_LOAD_SCALE + SCHED_LOAD_SCALE * 5891 power = SCHED_LOAD_SCALE + SCHED_LOAD_SCALE *
5804 (cpus_weight(sd->groups->cpumask)-1) / 10; 5892 (cpus_weight(sd->groups->cpumask)-1) / 10;
5805 sd->groups->cpu_power = power; 5893 sd->groups->cpu_power = power;
5806
5807#ifdef CONFIG_NUMA
5808 sd = &per_cpu(allnodes_domains, i);
5809 if (sd->groups) {
5810 power = SCHED_LOAD_SCALE + SCHED_LOAD_SCALE *
5811 (cpus_weight(sd->groups->cpumask)-1) / 10;
5812 sd->groups->cpu_power = power;
5813 }
5814#endif 5894#endif
5815 } 5895 }
5816 5896
5817#ifdef CONFIG_NUMA 5897#ifdef CONFIG_NUMA
5818 for (i = 0; i < MAX_NUMNODES; i++) { 5898 for (i = 0; i < MAX_NUMNODES; i++)
5819 struct sched_group *sg = sched_group_nodes[i]; 5899 init_numa_sched_groups_power(sched_group_nodes[i]);
5820 int j;
5821
5822 if (sg == NULL)
5823 continue;
5824next_sg:
5825 for_each_cpu_mask(j, sg->cpumask) {
5826 struct sched_domain *sd;
5827 int power;
5828
5829 sd = &per_cpu(phys_domains, j);
5830 if (j != first_cpu(sd->groups->cpumask)) {
5831 /*
5832 * Only add "power" once for each
5833 * physical package.
5834 */
5835 continue;
5836 }
5837 power = SCHED_LOAD_SCALE + SCHED_LOAD_SCALE *
5838 (cpus_weight(sd->groups->cpumask)-1) / 10;
5839 5900
5840 sg->cpu_power += power; 5901 init_numa_sched_groups_power(sched_group_allnodes);
5841 }
5842 sg = sg->next;
5843 if (sg != sched_group_nodes[i])
5844 goto next_sg;
5845 }
5846#endif 5902#endif
5847 5903
5848 /* Attach the domains */ 5904 /* Attach the domains */
@@ -5850,6 +5906,8 @@ next_sg:
5850 struct sched_domain *sd; 5906 struct sched_domain *sd;
5851#ifdef CONFIG_SCHED_SMT 5907#ifdef CONFIG_SCHED_SMT
5852 sd = &per_cpu(cpu_domains, i); 5908 sd = &per_cpu(cpu_domains, i);
5909#elif defined(CONFIG_SCHED_MC)
5910 sd = &per_cpu(core_domains, i);
5853#else 5911#else
5854 sd = &per_cpu(phys_domains, i); 5912 sd = &per_cpu(phys_domains, i);
5855#endif 5913#endif
diff --git a/kernel/softlockup.c b/kernel/softlockup.c
index d9b3d5847ed8..ced91e1ff564 100644
--- a/kernel/softlockup.c
+++ b/kernel/softlockup.c
@@ -152,5 +152,5 @@ __init void spawn_softlockup_task(void)
152 cpu_callback(&cpu_nfb, CPU_ONLINE, cpu); 152 cpu_callback(&cpu_nfb, CPU_ONLINE, cpu);
153 register_cpu_notifier(&cpu_nfb); 153 register_cpu_notifier(&cpu_nfb);
154 154
155 notifier_chain_register(&panic_notifier_list, &panic_block); 155 atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
156} 156}
diff --git a/kernel/sys.c b/kernel/sys.c
index 38bc73ede2ba..c93d37f71aef 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -95,99 +95,304 @@ int cad_pid = 1;
95 * and the like. 95 * and the like.
96 */ 96 */
97 97
98static struct notifier_block *reboot_notifier_list; 98static BLOCKING_NOTIFIER_HEAD(reboot_notifier_list);
99static DEFINE_RWLOCK(notifier_lock); 99
100/*
101 * Notifier chain core routines. The exported routines below
102 * are layered on top of these, with appropriate locking added.
103 */
104
105static int notifier_chain_register(struct notifier_block **nl,
106 struct notifier_block *n)
107{
108 while ((*nl) != NULL) {
109 if (n->priority > (*nl)->priority)
110 break;
111 nl = &((*nl)->next);
112 }
113 n->next = *nl;
114 rcu_assign_pointer(*nl, n);
115 return 0;
116}
117
118static int notifier_chain_unregister(struct notifier_block **nl,
119 struct notifier_block *n)
120{
121 while ((*nl) != NULL) {
122 if ((*nl) == n) {
123 rcu_assign_pointer(*nl, n->next);
124 return 0;
125 }
126 nl = &((*nl)->next);
127 }
128 return -ENOENT;
129}
130
131static int __kprobes notifier_call_chain(struct notifier_block **nl,
132 unsigned long val, void *v)
133{
134 int ret = NOTIFY_DONE;
135 struct notifier_block *nb;
136
137 nb = rcu_dereference(*nl);
138 while (nb) {
139 ret = nb->notifier_call(nb, val, v);
140 if ((ret & NOTIFY_STOP_MASK) == NOTIFY_STOP_MASK)
141 break;
142 nb = rcu_dereference(nb->next);
143 }
144 return ret;
145}
146
147/*
148 * Atomic notifier chain routines. Registration and unregistration
149 * use a mutex, and call_chain is synchronized by RCU (no locks).
150 */
100 151
101/** 152/**
102 * notifier_chain_register - Add notifier to a notifier chain 153 * atomic_notifier_chain_register - Add notifier to an atomic notifier chain
103 * @list: Pointer to root list pointer 154 * @nh: Pointer to head of the atomic notifier chain
104 * @n: New entry in notifier chain 155 * @n: New entry in notifier chain
105 * 156 *
106 * Adds a notifier to a notifier chain. 157 * Adds a notifier to an atomic notifier chain.
107 * 158 *
108 * Currently always returns zero. 159 * Currently always returns zero.
109 */ 160 */
161
162int atomic_notifier_chain_register(struct atomic_notifier_head *nh,
163 struct notifier_block *n)
164{
165 unsigned long flags;
166 int ret;
167
168 spin_lock_irqsave(&nh->lock, flags);
169 ret = notifier_chain_register(&nh->head, n);
170 spin_unlock_irqrestore(&nh->lock, flags);
171 return ret;
172}
173
174EXPORT_SYMBOL_GPL(atomic_notifier_chain_register);
175
176/**
177 * atomic_notifier_chain_unregister - Remove notifier from an atomic notifier chain
178 * @nh: Pointer to head of the atomic notifier chain
179 * @n: Entry to remove from notifier chain
180 *
181 * Removes a notifier from an atomic notifier chain.
182 *
183 * Returns zero on success or %-ENOENT on failure.
184 */
185int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh,
186 struct notifier_block *n)
187{
188 unsigned long flags;
189 int ret;
190
191 spin_lock_irqsave(&nh->lock, flags);
192 ret = notifier_chain_unregister(&nh->head, n);
193 spin_unlock_irqrestore(&nh->lock, flags);
194 synchronize_rcu();
195 return ret;
196}
197
198EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister);
199
200/**
201 * atomic_notifier_call_chain - Call functions in an atomic notifier chain
202 * @nh: Pointer to head of the atomic notifier chain
203 * @val: Value passed unmodified to notifier function
204 * @v: Pointer passed unmodified to notifier function
205 *
206 * Calls each function in a notifier chain in turn. The functions
207 * run in an atomic context, so they must not block.
208 * This routine uses RCU to synchronize with changes to the chain.
209 *
210 * If the return value of the notifier can be and'ed
211 * with %NOTIFY_STOP_MASK then atomic_notifier_call_chain
212 * will return immediately, with the return value of
213 * the notifier function which halted execution.
214 * Otherwise the return value is the return value
215 * of the last notifier function called.
216 */
110 217
111int notifier_chain_register(struct notifier_block **list, struct notifier_block *n) 218int atomic_notifier_call_chain(struct atomic_notifier_head *nh,
219 unsigned long val, void *v)
112{ 220{
113 write_lock(&notifier_lock); 221 int ret;
114 while(*list) 222
115 { 223 rcu_read_lock();
116 if(n->priority > (*list)->priority) 224 ret = notifier_call_chain(&nh->head, val, v);
117 break; 225 rcu_read_unlock();
118 list= &((*list)->next); 226 return ret;
119 }
120 n->next = *list;
121 *list=n;
122 write_unlock(&notifier_lock);
123 return 0;
124} 227}
125 228
126EXPORT_SYMBOL(notifier_chain_register); 229EXPORT_SYMBOL_GPL(atomic_notifier_call_chain);
230
231/*
232 * Blocking notifier chain routines. All access to the chain is
233 * synchronized by an rwsem.
234 */
127 235
128/** 236/**
129 * notifier_chain_unregister - Remove notifier from a notifier chain 237 * blocking_notifier_chain_register - Add notifier to a blocking notifier chain
130 * @nl: Pointer to root list pointer 238 * @nh: Pointer to head of the blocking notifier chain
131 * @n: New entry in notifier chain 239 * @n: New entry in notifier chain
132 * 240 *
133 * Removes a notifier from a notifier chain. 241 * Adds a notifier to a blocking notifier chain.
242 * Must be called in process context.
134 * 243 *
135 * Returns zero on success, or %-ENOENT on failure. 244 * Currently always returns zero.
136 */ 245 */
137 246
138int notifier_chain_unregister(struct notifier_block **nl, struct notifier_block *n) 247int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
248 struct notifier_block *n)
139{ 249{
140 write_lock(&notifier_lock); 250 int ret;
141 while((*nl)!=NULL) 251
142 { 252 /*
143 if((*nl)==n) 253 * This code gets used during boot-up, when task switching is
144 { 254 * not yet working and interrupts must remain disabled. At
145 *nl=n->next; 255 * such times we must not call down_write().
146 write_unlock(&notifier_lock); 256 */
147 return 0; 257 if (unlikely(system_state == SYSTEM_BOOTING))
148 } 258 return notifier_chain_register(&nh->head, n);
149 nl=&((*nl)->next); 259
150 } 260 down_write(&nh->rwsem);
151 write_unlock(&notifier_lock); 261 ret = notifier_chain_register(&nh->head, n);
152 return -ENOENT; 262 up_write(&nh->rwsem);
263 return ret;
153} 264}
154 265
155EXPORT_SYMBOL(notifier_chain_unregister); 266EXPORT_SYMBOL_GPL(blocking_notifier_chain_register);
156 267
157/** 268/**
158 * notifier_call_chain - Call functions in a notifier chain 269 * blocking_notifier_chain_unregister - Remove notifier from a blocking notifier chain
159 * @n: Pointer to root pointer of notifier chain 270 * @nh: Pointer to head of the blocking notifier chain
271 * @n: Entry to remove from notifier chain
272 *
273 * Removes a notifier from a blocking notifier chain.
274 * Must be called from process context.
275 *
276 * Returns zero on success or %-ENOENT on failure.
277 */
278int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh,
279 struct notifier_block *n)
280{
281 int ret;
282
283 /*
284 * This code gets used during boot-up, when task switching is
285 * not yet working and interrupts must remain disabled. At
286 * such times we must not call down_write().
287 */
288 if (unlikely(system_state == SYSTEM_BOOTING))
289 return notifier_chain_unregister(&nh->head, n);
290
291 down_write(&nh->rwsem);
292 ret = notifier_chain_unregister(&nh->head, n);
293 up_write(&nh->rwsem);
294 return ret;
295}
296
297EXPORT_SYMBOL_GPL(blocking_notifier_chain_unregister);
298
299/**
300 * blocking_notifier_call_chain - Call functions in a blocking notifier chain
301 * @nh: Pointer to head of the blocking notifier chain
160 * @val: Value passed unmodified to notifier function 302 * @val: Value passed unmodified to notifier function
161 * @v: Pointer passed unmodified to notifier function 303 * @v: Pointer passed unmodified to notifier function
162 * 304 *
163 * Calls each function in a notifier chain in turn. 305 * Calls each function in a notifier chain in turn. The functions
306 * run in a process context, so they are allowed to block.
164 * 307 *
165 * If the return value of the notifier can be and'd 308 * If the return value of the notifier can be and'ed
166 * with %NOTIFY_STOP_MASK, then notifier_call_chain 309 * with %NOTIFY_STOP_MASK then blocking_notifier_call_chain
167 * will return immediately, with the return value of 310 * will return immediately, with the return value of
168 * the notifier function which halted execution. 311 * the notifier function which halted execution.
169 * Otherwise, the return value is the return value 312 * Otherwise the return value is the return value
170 * of the last notifier function called. 313 * of the last notifier function called.
171 */ 314 */
172 315
173int __kprobes notifier_call_chain(struct notifier_block **n, unsigned long val, void *v) 316int blocking_notifier_call_chain(struct blocking_notifier_head *nh,
317 unsigned long val, void *v)
174{ 318{
175 int ret=NOTIFY_DONE; 319 int ret;
176 struct notifier_block *nb = *n;
177 320
178 while(nb) 321 down_read(&nh->rwsem);
179 { 322 ret = notifier_call_chain(&nh->head, val, v);
180 ret=nb->notifier_call(nb,val,v); 323 up_read(&nh->rwsem);
181 if(ret&NOTIFY_STOP_MASK)
182 {
183 return ret;
184 }
185 nb=nb->next;
186 }
187 return ret; 324 return ret;
188} 325}
189 326
190EXPORT_SYMBOL(notifier_call_chain); 327EXPORT_SYMBOL_GPL(blocking_notifier_call_chain);
328
329/*
330 * Raw notifier chain routines. There is no protection;
331 * the caller must provide it. Use at your own risk!
332 */
333
334/**
335 * raw_notifier_chain_register - Add notifier to a raw notifier chain
336 * @nh: Pointer to head of the raw notifier chain
337 * @n: New entry in notifier chain
338 *
339 * Adds a notifier to a raw notifier chain.
340 * All locking must be provided by the caller.
341 *
342 * Currently always returns zero.
343 */
344
345int raw_notifier_chain_register(struct raw_notifier_head *nh,
346 struct notifier_block *n)
347{
348 return notifier_chain_register(&nh->head, n);
349}
350
351EXPORT_SYMBOL_GPL(raw_notifier_chain_register);
352
353/**
354 * raw_notifier_chain_unregister - Remove notifier from a raw notifier chain
355 * @nh: Pointer to head of the raw notifier chain
356 * @n: Entry to remove from notifier chain
357 *
358 * Removes a notifier from a raw notifier chain.
359 * All locking must be provided by the caller.
360 *
361 * Returns zero on success or %-ENOENT on failure.
362 */
363int raw_notifier_chain_unregister(struct raw_notifier_head *nh,
364 struct notifier_block *n)
365{
366 return notifier_chain_unregister(&nh->head, n);
367}
368
369EXPORT_SYMBOL_GPL(raw_notifier_chain_unregister);
370
371/**
372 * raw_notifier_call_chain - Call functions in a raw notifier chain
373 * @nh: Pointer to head of the raw notifier chain
374 * @val: Value passed unmodified to notifier function
375 * @v: Pointer passed unmodified to notifier function
376 *
377 * Calls each function in a notifier chain in turn. The functions
378 * run in an undefined context.
379 * All locking must be provided by the caller.
380 *
381 * If the return value of the notifier can be and'ed
382 * with %NOTIFY_STOP_MASK then raw_notifier_call_chain
383 * will return immediately, with the return value of
384 * the notifier function which halted execution.
385 * Otherwise the return value is the return value
386 * of the last notifier function called.
387 */
388
389int raw_notifier_call_chain(struct raw_notifier_head *nh,
390 unsigned long val, void *v)
391{
392 return notifier_call_chain(&nh->head, val, v);
393}
394
395EXPORT_SYMBOL_GPL(raw_notifier_call_chain);
191 396
192/** 397/**
193 * register_reboot_notifier - Register function to be called at reboot time 398 * register_reboot_notifier - Register function to be called at reboot time
@@ -196,13 +401,13 @@ EXPORT_SYMBOL(notifier_call_chain);
196 * Registers a function with the list of functions 401 * Registers a function with the list of functions
197 * to be called at reboot time. 402 * to be called at reboot time.
198 * 403 *
199 * Currently always returns zero, as notifier_chain_register 404 * Currently always returns zero, as blocking_notifier_chain_register
200 * always returns zero. 405 * always returns zero.
201 */ 406 */
202 407
203int register_reboot_notifier(struct notifier_block * nb) 408int register_reboot_notifier(struct notifier_block * nb)
204{ 409{
205 return notifier_chain_register(&reboot_notifier_list, nb); 410 return blocking_notifier_chain_register(&reboot_notifier_list, nb);
206} 411}
207 412
208EXPORT_SYMBOL(register_reboot_notifier); 413EXPORT_SYMBOL(register_reboot_notifier);
@@ -219,7 +424,7 @@ EXPORT_SYMBOL(register_reboot_notifier);
219 424
220int unregister_reboot_notifier(struct notifier_block * nb) 425int unregister_reboot_notifier(struct notifier_block * nb)
221{ 426{
222 return notifier_chain_unregister(&reboot_notifier_list, nb); 427 return blocking_notifier_chain_unregister(&reboot_notifier_list, nb);
223} 428}
224 429
225EXPORT_SYMBOL(unregister_reboot_notifier); 430EXPORT_SYMBOL(unregister_reboot_notifier);
@@ -380,7 +585,7 @@ EXPORT_SYMBOL_GPL(emergency_restart);
380 585
381void kernel_restart_prepare(char *cmd) 586void kernel_restart_prepare(char *cmd)
382{ 587{
383 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); 588 blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd);
384 system_state = SYSTEM_RESTART; 589 system_state = SYSTEM_RESTART;
385 device_shutdown(); 590 device_shutdown();
386} 591}
@@ -430,7 +635,7 @@ EXPORT_SYMBOL_GPL(kernel_kexec);
430 635
431void kernel_shutdown_prepare(enum system_states state) 636void kernel_shutdown_prepare(enum system_states state)
432{ 637{
433 notifier_call_chain(&reboot_notifier_list, 638 blocking_notifier_call_chain(&reboot_notifier_list,
434 (state == SYSTEM_HALT)?SYS_HALT:SYS_POWER_OFF, NULL); 639 (state == SYSTEM_HALT)?SYS_HALT:SYS_POWER_OFF, NULL);
435 system_state = state; 640 system_state = state;
436 device_shutdown(); 641 device_shutdown();
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 1067090db6b1..d82864c4a617 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -42,6 +42,10 @@ cond_syscall(sys_recvmsg);
42cond_syscall(sys_socketcall); 42cond_syscall(sys_socketcall);
43cond_syscall(sys_futex); 43cond_syscall(sys_futex);
44cond_syscall(compat_sys_futex); 44cond_syscall(compat_sys_futex);
45cond_syscall(sys_set_robust_list);
46cond_syscall(compat_sys_set_robust_list);
47cond_syscall(sys_get_robust_list);
48cond_syscall(compat_sys_get_robust_list);
45cond_syscall(sys_epoll_create); 49cond_syscall(sys_epoll_create);
46cond_syscall(sys_epoll_ctl); 50cond_syscall(sys_epoll_ctl);
47cond_syscall(sys_epoll_wait); 51cond_syscall(sys_epoll_wait);
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 7e70ab13e191..6e8a60f67c7a 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -172,7 +172,7 @@ config DEBUG_IOREMAP
172 172
173config DEBUG_FS 173config DEBUG_FS
174 bool "Debug Filesystem" 174 bool "Debug Filesystem"
175 depends on DEBUG_KERNEL && SYSFS 175 depends on SYSFS
176 help 176 help
177 debugfs is a virtual file system that kernel developers use to put 177 debugfs is a virtual file system that kernel developers use to put
178 debugging files into. Enable this option to be able to read and 178 debugging files into. Enable this option to be able to read and
diff --git a/mm/Makefile b/mm/Makefile
index f10c753dce6d..0b8f73f2ed16 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -10,7 +10,7 @@ mmu-$(CONFIG_MMU) := fremap.o highmem.o madvise.o memory.o mincore.o \
10obj-y := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \ 10obj-y := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \
11 page_alloc.o page-writeback.o pdflush.o \ 11 page_alloc.o page-writeback.o pdflush.o \
12 readahead.o swap.o truncate.o vmscan.o \ 12 readahead.o swap.o truncate.o vmscan.o \
13 prio_tree.o util.o $(mmu-y) 13 prio_tree.o util.o mmzone.o $(mmu-y)
14 14
15obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o thrash.o 15obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o thrash.o
16obj-$(CONFIG_HUGETLBFS) += hugetlb.o 16obj-$(CONFIG_HUGETLBFS) += hugetlb.o
diff --git a/mm/bootmem.c b/mm/bootmem.c
index b55bd39fc5dd..d3e3bd2ffcea 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -33,6 +33,7 @@ EXPORT_SYMBOL(max_pfn); /* This is exported so
33 * dma_get_required_mask(), which uses 33 * dma_get_required_mask(), which uses
34 * it, can be an inline function */ 34 * it, can be an inline function */
35 35
36static LIST_HEAD(bdata_list);
36#ifdef CONFIG_CRASH_DUMP 37#ifdef CONFIG_CRASH_DUMP
37/* 38/*
38 * If we have booted due to a crash, max_pfn will be a very low value. We need 39 * If we have booted due to a crash, max_pfn will be a very low value. We need
@@ -52,6 +53,27 @@ unsigned long __init bootmem_bootmap_pages (unsigned long pages)
52 53
53 return mapsize; 54 return mapsize;
54} 55}
56/*
57 * link bdata in order
58 */
59static void link_bootmem(bootmem_data_t *bdata)
60{
61 bootmem_data_t *ent;
62 if (list_empty(&bdata_list)) {
63 list_add(&bdata->list, &bdata_list);
64 return;
65 }
66 /* insert in order */
67 list_for_each_entry(ent, &bdata_list, list) {
68 if (bdata->node_boot_start < ent->node_boot_start) {
69 list_add_tail(&bdata->list, &ent->list);
70 return;
71 }
72 }
73 list_add_tail(&bdata->list, &bdata_list);
74 return;
75}
76
55 77
56/* 78/*
57 * Called once to set up the allocator itself. 79 * Called once to set up the allocator itself.
@@ -62,13 +84,11 @@ static unsigned long __init init_bootmem_core (pg_data_t *pgdat,
62 bootmem_data_t *bdata = pgdat->bdata; 84 bootmem_data_t *bdata = pgdat->bdata;
63 unsigned long mapsize = ((end - start)+7)/8; 85 unsigned long mapsize = ((end - start)+7)/8;
64 86
65 pgdat->pgdat_next = pgdat_list;
66 pgdat_list = pgdat;
67
68 mapsize = ALIGN(mapsize, sizeof(long)); 87 mapsize = ALIGN(mapsize, sizeof(long));
69 bdata->node_bootmem_map = phys_to_virt(mapstart << PAGE_SHIFT); 88 bdata->node_bootmem_map = phys_to_virt(mapstart << PAGE_SHIFT);
70 bdata->node_boot_start = (start << PAGE_SHIFT); 89 bdata->node_boot_start = (start << PAGE_SHIFT);
71 bdata->node_low_pfn = end; 90 bdata->node_low_pfn = end;
91 link_bootmem(bdata);
72 92
73 /* 93 /*
74 * Initially all pages are reserved - setup_arch() has to 94 * Initially all pages are reserved - setup_arch() has to
@@ -383,12 +403,11 @@ unsigned long __init free_all_bootmem (void)
383 403
384void * __init __alloc_bootmem(unsigned long size, unsigned long align, unsigned long goal) 404void * __init __alloc_bootmem(unsigned long size, unsigned long align, unsigned long goal)
385{ 405{
386 pg_data_t *pgdat = pgdat_list; 406 bootmem_data_t *bdata;
387 void *ptr; 407 void *ptr;
388 408
389 for_each_pgdat(pgdat) 409 list_for_each_entry(bdata, &bdata_list, list)
390 if ((ptr = __alloc_bootmem_core(pgdat->bdata, size, 410 if ((ptr = __alloc_bootmem_core(bdata, size, align, goal, 0)))
391 align, goal, 0)))
392 return(ptr); 411 return(ptr);
393 412
394 /* 413 /*
@@ -416,11 +435,11 @@ void * __init __alloc_bootmem_node(pg_data_t *pgdat, unsigned long size, unsigne
416 435
417void * __init __alloc_bootmem_low(unsigned long size, unsigned long align, unsigned long goal) 436void * __init __alloc_bootmem_low(unsigned long size, unsigned long align, unsigned long goal)
418{ 437{
419 pg_data_t *pgdat = pgdat_list; 438 bootmem_data_t *bdata;
420 void *ptr; 439 void *ptr;
421 440
422 for_each_pgdat(pgdat) 441 list_for_each_entry(bdata, &bdata_list, list)
423 if ((ptr = __alloc_bootmem_core(pgdat->bdata, size, 442 if ((ptr = __alloc_bootmem_core(bdata, size,
424 align, goal, LOW32LIMIT))) 443 align, goal, LOW32LIMIT)))
425 return(ptr); 444 return(ptr);
426 445
diff --git a/mm/mmzone.c b/mm/mmzone.c
new file mode 100644
index 000000000000..b022370e612e
--- /dev/null
+++ b/mm/mmzone.c
@@ -0,0 +1,50 @@
1/*
2 * linux/mm/mmzone.c
3 *
4 * management codes for pgdats and zones.
5 */
6
7
8#include <linux/config.h>
9#include <linux/stddef.h>
10#include <linux/mmzone.h>
11#include <linux/module.h>
12
13struct pglist_data *first_online_pgdat(void)
14{
15 return NODE_DATA(first_online_node);
16}
17
18EXPORT_SYMBOL(first_online_pgdat);
19
20struct pglist_data *next_online_pgdat(struct pglist_data *pgdat)
21{
22 int nid = next_online_node(pgdat->node_id);
23
24 if (nid == MAX_NUMNODES)
25 return NULL;
26 return NODE_DATA(nid);
27}
28EXPORT_SYMBOL(next_online_pgdat);
29
30
31/*
32 * next_zone - helper magic for for_each_zone()
33 */
34struct zone *next_zone(struct zone *zone)
35{
36 pg_data_t *pgdat = zone->zone_pgdat;
37
38 if (zone < pgdat->node_zones + MAX_NR_ZONES - 1)
39 zone++;
40 else {
41 pgdat = next_online_pgdat(pgdat);
42 if (pgdat)
43 zone = pgdat->node_zones;
44 else
45 zone = NULL;
46 }
47 return zone;
48}
49EXPORT_SYMBOL(next_zone);
50
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 338a02bb004d..dc523a1f270d 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -49,7 +49,6 @@ nodemask_t node_online_map __read_mostly = { { [0] = 1UL } };
49EXPORT_SYMBOL(node_online_map); 49EXPORT_SYMBOL(node_online_map);
50nodemask_t node_possible_map __read_mostly = NODE_MASK_ALL; 50nodemask_t node_possible_map __read_mostly = NODE_MASK_ALL;
51EXPORT_SYMBOL(node_possible_map); 51EXPORT_SYMBOL(node_possible_map);
52struct pglist_data *pgdat_list __read_mostly;
53unsigned long totalram_pages __read_mostly; 52unsigned long totalram_pages __read_mostly;
54unsigned long totalhigh_pages __read_mostly; 53unsigned long totalhigh_pages __read_mostly;
55long nr_swap_pages; 54long nr_swap_pages;
@@ -1201,7 +1200,7 @@ unsigned int nr_free_highpages (void)
1201 pg_data_t *pgdat; 1200 pg_data_t *pgdat;
1202 unsigned int pages = 0; 1201 unsigned int pages = 0;
1203 1202
1204 for_each_pgdat(pgdat) 1203 for_each_online_pgdat(pgdat)
1205 pages += pgdat->node_zones[ZONE_HIGHMEM].free_pages; 1204 pages += pgdat->node_zones[ZONE_HIGHMEM].free_pages;
1206 1205
1207 return pages; 1206 return pages;
@@ -1343,7 +1342,7 @@ void get_zone_counts(unsigned long *active,
1343 *active = 0; 1342 *active = 0;
1344 *inactive = 0; 1343 *inactive = 0;
1345 *free = 0; 1344 *free = 0;
1346 for_each_pgdat(pgdat) { 1345 for_each_online_pgdat(pgdat) {
1347 unsigned long l, m, n; 1346 unsigned long l, m, n;
1348 __get_zone_counts(&l, &m, &n, pgdat); 1347 __get_zone_counts(&l, &m, &n, pgdat);
1349 *active += l; 1348 *active += l;
@@ -2042,7 +2041,6 @@ static __meminit void init_currently_empty_zone(struct zone *zone,
2042 zone_wait_table_init(zone, size); 2041 zone_wait_table_init(zone, size);
2043 pgdat->nr_zones = zone_idx(zone) + 1; 2042 pgdat->nr_zones = zone_idx(zone) + 1;
2044 2043
2045 zone->zone_mem_map = pfn_to_page(zone_start_pfn);
2046 zone->zone_start_pfn = zone_start_pfn; 2044 zone->zone_start_pfn = zone_start_pfn;
2047 2045
2048 memmap_init(size, pgdat->node_id, zone_idx(zone), zone_start_pfn); 2046 memmap_init(size, pgdat->node_id, zone_idx(zone), zone_start_pfn);
@@ -2170,8 +2168,9 @@ static void *frag_start(struct seq_file *m, loff_t *pos)
2170{ 2168{
2171 pg_data_t *pgdat; 2169 pg_data_t *pgdat;
2172 loff_t node = *pos; 2170 loff_t node = *pos;
2173 2171 for (pgdat = first_online_pgdat();
2174 for (pgdat = pgdat_list; pgdat && node; pgdat = pgdat->pgdat_next) 2172 pgdat && node;
2173 pgdat = next_online_pgdat(pgdat))
2175 --node; 2174 --node;
2176 2175
2177 return pgdat; 2176 return pgdat;
@@ -2182,7 +2181,7 @@ static void *frag_next(struct seq_file *m, void *arg, loff_t *pos)
2182 pg_data_t *pgdat = (pg_data_t *)arg; 2181 pg_data_t *pgdat = (pg_data_t *)arg;
2183 2182
2184 (*pos)++; 2183 (*pos)++;
2185 return pgdat->pgdat_next; 2184 return next_online_pgdat(pgdat);
2186} 2185}
2187 2186
2188static void frag_stop(struct seq_file *m, void *arg) 2187static void frag_stop(struct seq_file *m, void *arg)
@@ -2483,7 +2482,7 @@ static void setup_per_zone_lowmem_reserve(void)
2483 struct pglist_data *pgdat; 2482 struct pglist_data *pgdat;
2484 int j, idx; 2483 int j, idx;
2485 2484
2486 for_each_pgdat(pgdat) { 2485 for_each_online_pgdat(pgdat) {
2487 for (j = 0; j < MAX_NR_ZONES; j++) { 2486 for (j = 0; j < MAX_NR_ZONES; j++) {
2488 struct zone *zone = pgdat->node_zones + j; 2487 struct zone *zone = pgdat->node_zones + j;
2489 unsigned long present_pages = zone->present_pages; 2488 unsigned long present_pages = zone->present_pages;
@@ -2745,3 +2744,44 @@ void *__init alloc_large_system_hash(const char *tablename,
2745 2744
2746 return table; 2745 return table;
2747} 2746}
2747
2748#ifdef CONFIG_OUT_OF_LINE_PFN_TO_PAGE
2749/*
2750 * pfn <-> page translation. out-of-line version.
2751 * (see asm-generic/memory_model.h)
2752 */
2753#if defined(CONFIG_FLATMEM)
2754struct page *pfn_to_page(unsigned long pfn)
2755{
2756 return mem_map + (pfn - ARCH_PFN_OFFSET);
2757}
2758unsigned long page_to_pfn(struct page *page)
2759{
2760 return (page - mem_map) + ARCH_PFN_OFFSET;
2761}
2762#elif defined(CONFIG_DISCONTIGMEM)
2763struct page *pfn_to_page(unsigned long pfn)
2764{
2765 int nid = arch_pfn_to_nid(pfn);
2766 return NODE_DATA(nid)->node_mem_map + arch_local_page_offset(pfn,nid);
2767}
2768unsigned long page_to_pfn(struct page *page)
2769{
2770 struct pglist_data *pgdat = NODE_DATA(page_to_nid(page));
2771 return (page - pgdat->node_mem_map) + pgdat->node_start_pfn;
2772}
2773#elif defined(CONFIG_SPARSEMEM)
2774struct page *pfn_to_page(unsigned long pfn)
2775{
2776 return __section_mem_map_addr(__pfn_to_section(pfn)) + pfn;
2777}
2778
2779unsigned long page_to_pfn(struct page *page)
2780{
2781 long section_id = page_to_section(page);
2782 return page - __section_mem_map_addr(__nr_to_section(section_id));
2783}
2784#endif /* CONFIG_FLATMEM/DISCONTIGMME/SPARSEMEM */
2785EXPORT_SYMBOL(pfn_to_page);
2786EXPORT_SYMBOL(page_to_pfn);
2787#endif /* CONFIG_OUT_OF_LINE_PFN_TO_PAGE */
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 78865c849f8f..acdf001d6941 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1305,7 +1305,7 @@ unsigned long shrink_all_memory(unsigned long nr_pages)
1305 1305
1306 current->reclaim_state = &reclaim_state; 1306 current->reclaim_state = &reclaim_state;
1307repeat: 1307repeat:
1308 for_each_pgdat(pgdat) { 1308 for_each_online_pgdat(pgdat) {
1309 unsigned long freed; 1309 unsigned long freed;
1310 1310
1311 freed = balance_pgdat(pgdat, nr_to_free, 0); 1311 freed = balance_pgdat(pgdat, nr_to_free, 0);
@@ -1335,7 +1335,7 @@ static int __devinit cpu_callback(struct notifier_block *nfb,
1335 cpumask_t mask; 1335 cpumask_t mask;
1336 1336
1337 if (action == CPU_ONLINE) { 1337 if (action == CPU_ONLINE) {
1338 for_each_pgdat(pgdat) { 1338 for_each_online_pgdat(pgdat) {
1339 mask = node_to_cpumask(pgdat->node_id); 1339 mask = node_to_cpumask(pgdat->node_id);
1340 if (any_online_cpu(mask) != NR_CPUS) 1340 if (any_online_cpu(mask) != NR_CPUS)
1341 /* One of our CPUs online: restore mask */ 1341 /* One of our CPUs online: restore mask */
@@ -1351,7 +1351,7 @@ static int __init kswapd_init(void)
1351 pg_data_t *pgdat; 1351 pg_data_t *pgdat;
1352 1352
1353 swap_setup(); 1353 swap_setup();
1354 for_each_pgdat(pgdat) { 1354 for_each_online_pgdat(pgdat) {
1355 pid_t pid; 1355 pid_t pid;
1356 1356
1357 pid = kernel_thread(kswapd, pgdat, CLONE_KERNEL); 1357 pid = kernel_thread(kswapd, pgdat, CLONE_KERNEL);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 9106354c781e..a49a6975092d 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -73,23 +73,23 @@ DEFINE_RWLOCK(hci_cb_list_lock);
73struct hci_proto *hci_proto[HCI_MAX_PROTO]; 73struct hci_proto *hci_proto[HCI_MAX_PROTO];
74 74
75/* HCI notifiers list */ 75/* HCI notifiers list */
76static struct notifier_block *hci_notifier; 76static ATOMIC_NOTIFIER_HEAD(hci_notifier);
77 77
78/* ---- HCI notifications ---- */ 78/* ---- HCI notifications ---- */
79 79
80int hci_register_notifier(struct notifier_block *nb) 80int hci_register_notifier(struct notifier_block *nb)
81{ 81{
82 return notifier_chain_register(&hci_notifier, nb); 82 return atomic_notifier_chain_register(&hci_notifier, nb);
83} 83}
84 84
85int hci_unregister_notifier(struct notifier_block *nb) 85int hci_unregister_notifier(struct notifier_block *nb)
86{ 86{
87 return notifier_chain_unregister(&hci_notifier, nb); 87 return atomic_notifier_chain_unregister(&hci_notifier, nb);
88} 88}
89 89
90static void hci_notify(struct hci_dev *hdev, int event) 90static void hci_notify(struct hci_dev *hdev, int event)
91{ 91{
92 notifier_call_chain(&hci_notifier, event, hdev); 92 atomic_notifier_call_chain(&hci_notifier, event, hdev);
93} 93}
94 94
95/* ---- HCI requests ---- */ 95/* ---- HCI requests ---- */
diff --git a/net/core/dev.c b/net/core/dev.c
index 8e1dc3051222..a3ab11f34153 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -193,7 +193,7 @@ static inline struct hlist_head *dev_index_hash(int ifindex)
193 * Our notifier list 193 * Our notifier list
194 */ 194 */
195 195
196static struct notifier_block *netdev_chain; 196static BLOCKING_NOTIFIER_HEAD(netdev_chain);
197 197
198/* 198/*
199 * Device drivers call our routines to queue packets here. We empty the 199 * Device drivers call our routines to queue packets here. We empty the
@@ -736,7 +736,8 @@ int dev_change_name(struct net_device *dev, char *newname)
736 if (!err) { 736 if (!err) {
737 hlist_del(&dev->name_hlist); 737 hlist_del(&dev->name_hlist);
738 hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name)); 738 hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name));
739 notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev); 739 blocking_notifier_call_chain(&netdev_chain,
740 NETDEV_CHANGENAME, dev);
740 } 741 }
741 742
742 return err; 743 return err;
@@ -750,7 +751,7 @@ int dev_change_name(struct net_device *dev, char *newname)
750 */ 751 */
751void netdev_features_change(struct net_device *dev) 752void netdev_features_change(struct net_device *dev)
752{ 753{
753 notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev); 754 blocking_notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev);
754} 755}
755EXPORT_SYMBOL(netdev_features_change); 756EXPORT_SYMBOL(netdev_features_change);
756 757
@@ -765,7 +766,8 @@ EXPORT_SYMBOL(netdev_features_change);
765void netdev_state_change(struct net_device *dev) 766void netdev_state_change(struct net_device *dev)
766{ 767{
767 if (dev->flags & IFF_UP) { 768 if (dev->flags & IFF_UP) {
768 notifier_call_chain(&netdev_chain, NETDEV_CHANGE, dev); 769 blocking_notifier_call_chain(&netdev_chain,
770 NETDEV_CHANGE, dev);
769 rtmsg_ifinfo(RTM_NEWLINK, dev, 0); 771 rtmsg_ifinfo(RTM_NEWLINK, dev, 0);
770 } 772 }
771} 773}
@@ -862,7 +864,7 @@ int dev_open(struct net_device *dev)
862 /* 864 /*
863 * ... and announce new interface. 865 * ... and announce new interface.
864 */ 866 */
865 notifier_call_chain(&netdev_chain, NETDEV_UP, dev); 867 blocking_notifier_call_chain(&netdev_chain, NETDEV_UP, dev);
866 } 868 }
867 return ret; 869 return ret;
868} 870}
@@ -885,7 +887,7 @@ int dev_close(struct net_device *dev)
885 * Tell people we are going down, so that they can 887 * Tell people we are going down, so that they can
886 * prepare to death, when device is still operating. 888 * prepare to death, when device is still operating.
887 */ 889 */
888 notifier_call_chain(&netdev_chain, NETDEV_GOING_DOWN, dev); 890 blocking_notifier_call_chain(&netdev_chain, NETDEV_GOING_DOWN, dev);
889 891
890 dev_deactivate(dev); 892 dev_deactivate(dev);
891 893
@@ -922,7 +924,7 @@ int dev_close(struct net_device *dev)
922 /* 924 /*
923 * Tell people we are down 925 * Tell people we are down
924 */ 926 */
925 notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev); 927 blocking_notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev);
926 928
927 return 0; 929 return 0;
928} 930}
@@ -953,7 +955,7 @@ int register_netdevice_notifier(struct notifier_block *nb)
953 int err; 955 int err;
954 956
955 rtnl_lock(); 957 rtnl_lock();
956 err = notifier_chain_register(&netdev_chain, nb); 958 err = blocking_notifier_chain_register(&netdev_chain, nb);
957 if (!err) { 959 if (!err) {
958 for (dev = dev_base; dev; dev = dev->next) { 960 for (dev = dev_base; dev; dev = dev->next) {
959 nb->notifier_call(nb, NETDEV_REGISTER, dev); 961 nb->notifier_call(nb, NETDEV_REGISTER, dev);
@@ -981,7 +983,7 @@ int unregister_netdevice_notifier(struct notifier_block *nb)
981 int err; 983 int err;
982 984
983 rtnl_lock(); 985 rtnl_lock();
984 err = notifier_chain_unregister(&netdev_chain, nb); 986 err = blocking_notifier_chain_unregister(&netdev_chain, nb);
985 rtnl_unlock(); 987 rtnl_unlock();
986 return err; 988 return err;
987} 989}
@@ -992,12 +994,12 @@ int unregister_netdevice_notifier(struct notifier_block *nb)
992 * @v: pointer passed unmodified to notifier function 994 * @v: pointer passed unmodified to notifier function
993 * 995 *
994 * Call all network notifier blocks. Parameters and return value 996 * Call all network notifier blocks. Parameters and return value
995 * are as for notifier_call_chain(). 997 * are as for blocking_notifier_call_chain().
996 */ 998 */
997 999
998int call_netdevice_notifiers(unsigned long val, void *v) 1000int call_netdevice_notifiers(unsigned long val, void *v)
999{ 1001{
1000 return notifier_call_chain(&netdev_chain, val, v); 1002 return blocking_notifier_call_chain(&netdev_chain, val, v);
1001} 1003}
1002 1004
1003/* When > 0 there are consumers of rx skb time stamps */ 1005/* When > 0 there are consumers of rx skb time stamps */
@@ -2242,7 +2244,8 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
2242 if (dev->flags & IFF_UP && 2244 if (dev->flags & IFF_UP &&
2243 ((old_flags ^ dev->flags) &~ (IFF_UP | IFF_PROMISC | IFF_ALLMULTI | 2245 ((old_flags ^ dev->flags) &~ (IFF_UP | IFF_PROMISC | IFF_ALLMULTI |
2244 IFF_VOLATILE))) 2246 IFF_VOLATILE)))
2245 notifier_call_chain(&netdev_chain, NETDEV_CHANGE, dev); 2247 blocking_notifier_call_chain(&netdev_chain,
2248 NETDEV_CHANGE, dev);
2246 2249
2247 if ((flags ^ dev->gflags) & IFF_PROMISC) { 2250 if ((flags ^ dev->gflags) & IFF_PROMISC) {
2248 int inc = (flags & IFF_PROMISC) ? +1 : -1; 2251 int inc = (flags & IFF_PROMISC) ? +1 : -1;
@@ -2286,8 +2289,8 @@ int dev_set_mtu(struct net_device *dev, int new_mtu)
2286 else 2289 else
2287 dev->mtu = new_mtu; 2290 dev->mtu = new_mtu;
2288 if (!err && dev->flags & IFF_UP) 2291 if (!err && dev->flags & IFF_UP)
2289 notifier_call_chain(&netdev_chain, 2292 blocking_notifier_call_chain(&netdev_chain,
2290 NETDEV_CHANGEMTU, dev); 2293 NETDEV_CHANGEMTU, dev);
2291 return err; 2294 return err;
2292} 2295}
2293 2296
@@ -2303,7 +2306,8 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa)
2303 return -ENODEV; 2306 return -ENODEV;
2304 err = dev->set_mac_address(dev, sa); 2307 err = dev->set_mac_address(dev, sa);
2305 if (!err) 2308 if (!err)
2306 notifier_call_chain(&netdev_chain, NETDEV_CHANGEADDR, dev); 2309 blocking_notifier_call_chain(&netdev_chain,
2310 NETDEV_CHANGEADDR, dev);
2307 return err; 2311 return err;
2308} 2312}
2309 2313
@@ -2359,7 +2363,7 @@ static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd)
2359 return -EINVAL; 2363 return -EINVAL;
2360 memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data, 2364 memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data,
2361 min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len)); 2365 min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));
2362 notifier_call_chain(&netdev_chain, 2366 blocking_notifier_call_chain(&netdev_chain,
2363 NETDEV_CHANGEADDR, dev); 2367 NETDEV_CHANGEADDR, dev);
2364 return 0; 2368 return 0;
2365 2369
@@ -2813,7 +2817,7 @@ int register_netdevice(struct net_device *dev)
2813 write_unlock_bh(&dev_base_lock); 2817 write_unlock_bh(&dev_base_lock);
2814 2818
2815 /* Notify protocols, that a new device appeared. */ 2819 /* Notify protocols, that a new device appeared. */
2816 notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev); 2820 blocking_notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev);
2817 2821
2818 /* Finish registration after unlock */ 2822 /* Finish registration after unlock */
2819 net_set_todo(dev); 2823 net_set_todo(dev);
@@ -2892,7 +2896,7 @@ static void netdev_wait_allrefs(struct net_device *dev)
2892 rtnl_lock(); 2896 rtnl_lock();
2893 2897
2894 /* Rebroadcast unregister notification */ 2898 /* Rebroadcast unregister notification */
2895 notifier_call_chain(&netdev_chain, 2899 blocking_notifier_call_chain(&netdev_chain,
2896 NETDEV_UNREGISTER, dev); 2900 NETDEV_UNREGISTER, dev);
2897 2901
2898 if (test_bit(__LINK_STATE_LINKWATCH_PENDING, 2902 if (test_bit(__LINK_STATE_LINKWATCH_PENDING,
@@ -3148,7 +3152,7 @@ int unregister_netdevice(struct net_device *dev)
3148 /* Notify protocols, that we are about to destroy 3152 /* Notify protocols, that we are about to destroy
3149 this device. They should clean all the things. 3153 this device. They should clean all the things.
3150 */ 3154 */
3151 notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev); 3155 blocking_notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev);
3152 3156
3153 /* 3157 /*
3154 * Flush the multicast chain 3158 * Flush the multicast chain
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index cc7b9d9255ef..d2ae9893ca17 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -68,7 +68,7 @@ __le16 decnet_address = 0;
68 68
69static DEFINE_RWLOCK(dndev_lock); 69static DEFINE_RWLOCK(dndev_lock);
70static struct net_device *decnet_default_device; 70static struct net_device *decnet_default_device;
71static struct notifier_block *dnaddr_chain; 71static BLOCKING_NOTIFIER_HEAD(dnaddr_chain);
72 72
73static struct dn_dev *dn_dev_create(struct net_device *dev, int *err); 73static struct dn_dev *dn_dev_create(struct net_device *dev, int *err);
74static void dn_dev_delete(struct net_device *dev); 74static void dn_dev_delete(struct net_device *dev);
@@ -446,7 +446,7 @@ static void dn_dev_del_ifa(struct dn_dev *dn_db, struct dn_ifaddr **ifap, int de
446 } 446 }
447 447
448 rtmsg_ifa(RTM_DELADDR, ifa1); 448 rtmsg_ifa(RTM_DELADDR, ifa1);
449 notifier_call_chain(&dnaddr_chain, NETDEV_DOWN, ifa1); 449 blocking_notifier_call_chain(&dnaddr_chain, NETDEV_DOWN, ifa1);
450 if (destroy) { 450 if (destroy) {
451 dn_dev_free_ifa(ifa1); 451 dn_dev_free_ifa(ifa1);
452 452
@@ -481,7 +481,7 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa)
481 dn_db->ifa_list = ifa; 481 dn_db->ifa_list = ifa;
482 482
483 rtmsg_ifa(RTM_NEWADDR, ifa); 483 rtmsg_ifa(RTM_NEWADDR, ifa);
484 notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa); 484 blocking_notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa);
485 485
486 return 0; 486 return 0;
487} 487}
@@ -1285,12 +1285,12 @@ void dn_dev_devices_on(void)
1285 1285
1286int register_dnaddr_notifier(struct notifier_block *nb) 1286int register_dnaddr_notifier(struct notifier_block *nb)
1287{ 1287{
1288 return notifier_chain_register(&dnaddr_chain, nb); 1288 return blocking_notifier_chain_register(&dnaddr_chain, nb);
1289} 1289}
1290 1290
1291int unregister_dnaddr_notifier(struct notifier_block *nb) 1291int unregister_dnaddr_notifier(struct notifier_block *nb)
1292{ 1292{
1293 return notifier_chain_unregister(&dnaddr_chain, nb); 1293 return blocking_notifier_chain_unregister(&dnaddr_chain, nb);
1294} 1294}
1295 1295
1296#ifdef CONFIG_PROC_FS 1296#ifdef CONFIG_PROC_FS
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 44fdf1413e2c..81c2f7885292 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -81,7 +81,7 @@ static struct ipv4_devconf ipv4_devconf_dflt = {
81 81
82static void rtmsg_ifa(int event, struct in_ifaddr *); 82static void rtmsg_ifa(int event, struct in_ifaddr *);
83 83
84static struct notifier_block *inetaddr_chain; 84static BLOCKING_NOTIFIER_HEAD(inetaddr_chain);
85static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, 85static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
86 int destroy); 86 int destroy);
87#ifdef CONFIG_SYSCTL 87#ifdef CONFIG_SYSCTL
@@ -267,7 +267,8 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
267 *ifap1 = ifa->ifa_next; 267 *ifap1 = ifa->ifa_next;
268 268
269 rtmsg_ifa(RTM_DELADDR, ifa); 269 rtmsg_ifa(RTM_DELADDR, ifa);
270 notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa); 270 blocking_notifier_call_chain(&inetaddr_chain,
271 NETDEV_DOWN, ifa);
271 inet_free_ifa(ifa); 272 inet_free_ifa(ifa);
272 } else { 273 } else {
273 promote = ifa; 274 promote = ifa;
@@ -291,7 +292,7 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
291 So that, this order is correct. 292 So that, this order is correct.
292 */ 293 */
293 rtmsg_ifa(RTM_DELADDR, ifa1); 294 rtmsg_ifa(RTM_DELADDR, ifa1);
294 notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1); 295 blocking_notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1);
295 296
296 if (promote) { 297 if (promote) {
297 298
@@ -303,7 +304,8 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
303 304
304 promote->ifa_flags &= ~IFA_F_SECONDARY; 305 promote->ifa_flags &= ~IFA_F_SECONDARY;
305 rtmsg_ifa(RTM_NEWADDR, promote); 306 rtmsg_ifa(RTM_NEWADDR, promote);
306 notifier_call_chain(&inetaddr_chain, NETDEV_UP, promote); 307 blocking_notifier_call_chain(&inetaddr_chain,
308 NETDEV_UP, promote);
307 for (ifa = promote->ifa_next; ifa; ifa = ifa->ifa_next) { 309 for (ifa = promote->ifa_next; ifa; ifa = ifa->ifa_next) {
308 if (ifa1->ifa_mask != ifa->ifa_mask || 310 if (ifa1->ifa_mask != ifa->ifa_mask ||
309 !inet_ifa_match(ifa1->ifa_address, ifa)) 311 !inet_ifa_match(ifa1->ifa_address, ifa))
@@ -366,7 +368,7 @@ static int inet_insert_ifa(struct in_ifaddr *ifa)
366 Notifier will trigger FIB update, so that 368 Notifier will trigger FIB update, so that
367 listeners of netlink will know about new ifaddr */ 369 listeners of netlink will know about new ifaddr */
368 rtmsg_ifa(RTM_NEWADDR, ifa); 370 rtmsg_ifa(RTM_NEWADDR, ifa);
369 notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa); 371 blocking_notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa);
370 372
371 return 0; 373 return 0;
372} 374}
@@ -938,12 +940,12 @@ u32 inet_confirm_addr(const struct net_device *dev, u32 dst, u32 local, int scop
938 940
939int register_inetaddr_notifier(struct notifier_block *nb) 941int register_inetaddr_notifier(struct notifier_block *nb)
940{ 942{
941 return notifier_chain_register(&inetaddr_chain, nb); 943 return blocking_notifier_chain_register(&inetaddr_chain, nb);
942} 944}
943 945
944int unregister_inetaddr_notifier(struct notifier_block *nb) 946int unregister_inetaddr_notifier(struct notifier_block *nb)
945{ 947{
946 return notifier_chain_unregister(&inetaddr_chain, nb); 948 return blocking_notifier_chain_unregister(&inetaddr_chain, nb);
947} 949}
948 950
949/* Rename ifa_labels for a device name change. Make some effort to preserve existing 951/* Rename ifa_labels for a device name change. Make some effort to preserve existing
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index 9e34034729a6..ceaabc18202b 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -80,8 +80,8 @@ static int ip_conntrack_vmalloc;
80static unsigned int ip_conntrack_next_id; 80static unsigned int ip_conntrack_next_id;
81static unsigned int ip_conntrack_expect_next_id; 81static unsigned int ip_conntrack_expect_next_id;
82#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS 82#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
83struct notifier_block *ip_conntrack_chain; 83ATOMIC_NOTIFIER_HEAD(ip_conntrack_chain);
84struct notifier_block *ip_conntrack_expect_chain; 84ATOMIC_NOTIFIER_HEAD(ip_conntrack_expect_chain);
85 85
86DEFINE_PER_CPU(struct ip_conntrack_ecache, ip_conntrack_ecache); 86DEFINE_PER_CPU(struct ip_conntrack_ecache, ip_conntrack_ecache);
87 87
@@ -92,7 +92,7 @@ __ip_ct_deliver_cached_events(struct ip_conntrack_ecache *ecache)
92{ 92{
93 DEBUGP("ecache: delivering events for %p\n", ecache->ct); 93 DEBUGP("ecache: delivering events for %p\n", ecache->ct);
94 if (is_confirmed(ecache->ct) && !is_dying(ecache->ct) && ecache->events) 94 if (is_confirmed(ecache->ct) && !is_dying(ecache->ct) && ecache->events)
95 notifier_call_chain(&ip_conntrack_chain, ecache->events, 95 atomic_notifier_call_chain(&ip_conntrack_chain, ecache->events,
96 ecache->ct); 96 ecache->ct);
97 ecache->events = 0; 97 ecache->events = 0;
98 ip_conntrack_put(ecache->ct); 98 ip_conntrack_put(ecache->ct);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 01c62a0d3742..445006ee4522 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -143,7 +143,7 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev,
143 struct prefix_info *pinfo); 143 struct prefix_info *pinfo);
144static int ipv6_chk_same_addr(const struct in6_addr *addr, struct net_device *dev); 144static int ipv6_chk_same_addr(const struct in6_addr *addr, struct net_device *dev);
145 145
146static struct notifier_block *inet6addr_chain; 146static ATOMIC_NOTIFIER_HEAD(inet6addr_chain);
147 147
148struct ipv6_devconf ipv6_devconf = { 148struct ipv6_devconf ipv6_devconf = {
149 .forwarding = 0, 149 .forwarding = 0,
@@ -593,7 +593,7 @@ out2:
593 read_unlock_bh(&addrconf_lock); 593 read_unlock_bh(&addrconf_lock);
594 594
595 if (likely(err == 0)) 595 if (likely(err == 0))
596 notifier_call_chain(&inet6addr_chain, NETDEV_UP, ifa); 596 atomic_notifier_call_chain(&inet6addr_chain, NETDEV_UP, ifa);
597 else { 597 else {
598 kfree(ifa); 598 kfree(ifa);
599 ifa = ERR_PTR(err); 599 ifa = ERR_PTR(err);
@@ -688,7 +688,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
688 688
689 ipv6_ifa_notify(RTM_DELADDR, ifp); 689 ipv6_ifa_notify(RTM_DELADDR, ifp);
690 690
691 notifier_call_chain(&inet6addr_chain,NETDEV_DOWN,ifp); 691 atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifp);
692 692
693 addrconf_del_timer(ifp); 693 addrconf_del_timer(ifp);
694 694
@@ -3767,12 +3767,12 @@ static void addrconf_sysctl_unregister(struct ipv6_devconf *p)
3767 3767
3768int register_inet6addr_notifier(struct notifier_block *nb) 3768int register_inet6addr_notifier(struct notifier_block *nb)
3769{ 3769{
3770 return notifier_chain_register(&inet6addr_chain, nb); 3770 return atomic_notifier_chain_register(&inet6addr_chain, nb);
3771} 3771}
3772 3772
3773int unregister_inet6addr_notifier(struct notifier_block *nb) 3773int unregister_inet6addr_notifier(struct notifier_block *nb)
3774{ 3774{
3775 return notifier_chain_unregister(&inet6addr_chain,nb); 3775 return atomic_notifier_chain_unregister(&inet6addr_chain,nb);
3776} 3776}
3777 3777
3778/* 3778/*
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 0ae281d9bfc3..56389c83557c 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -90,8 +90,8 @@ static int nf_conntrack_vmalloc;
90static unsigned int nf_conntrack_next_id; 90static unsigned int nf_conntrack_next_id;
91static unsigned int nf_conntrack_expect_next_id; 91static unsigned int nf_conntrack_expect_next_id;
92#ifdef CONFIG_NF_CONNTRACK_EVENTS 92#ifdef CONFIG_NF_CONNTRACK_EVENTS
93struct notifier_block *nf_conntrack_chain; 93ATOMIC_NOTIFIER_HEAD(nf_conntrack_chain);
94struct notifier_block *nf_conntrack_expect_chain; 94ATOMIC_NOTIFIER_HEAD(nf_conntrack_expect_chain);
95 95
96DEFINE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache); 96DEFINE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache);
97 97
@@ -103,7 +103,7 @@ __nf_ct_deliver_cached_events(struct nf_conntrack_ecache *ecache)
103 DEBUGP("ecache: delivering events for %p\n", ecache->ct); 103 DEBUGP("ecache: delivering events for %p\n", ecache->ct);
104 if (nf_ct_is_confirmed(ecache->ct) && !nf_ct_is_dying(ecache->ct) 104 if (nf_ct_is_confirmed(ecache->ct) && !nf_ct_is_dying(ecache->ct)
105 && ecache->events) 105 && ecache->events)
106 notifier_call_chain(&nf_conntrack_chain, ecache->events, 106 atomic_notifier_call_chain(&nf_conntrack_chain, ecache->events,
107 ecache->ct); 107 ecache->ct);
108 108
109 ecache->events = 0; 109 ecache->events = 0;
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index d00a9034cb5f..2a233ffcf618 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -123,7 +123,7 @@ static void netlink_destroy_callback(struct netlink_callback *cb);
123static DEFINE_RWLOCK(nl_table_lock); 123static DEFINE_RWLOCK(nl_table_lock);
124static atomic_t nl_table_users = ATOMIC_INIT(0); 124static atomic_t nl_table_users = ATOMIC_INIT(0);
125 125
126static struct notifier_block *netlink_chain; 126static ATOMIC_NOTIFIER_HEAD(netlink_chain);
127 127
128static u32 netlink_group_mask(u32 group) 128static u32 netlink_group_mask(u32 group)
129{ 129{
@@ -469,7 +469,8 @@ static int netlink_release(struct socket *sock)
469 .protocol = sk->sk_protocol, 469 .protocol = sk->sk_protocol,
470 .pid = nlk->pid, 470 .pid = nlk->pid,
471 }; 471 };
472 notifier_call_chain(&netlink_chain, NETLINK_URELEASE, &n); 472 atomic_notifier_call_chain(&netlink_chain,
473 NETLINK_URELEASE, &n);
473 } 474 }
474 475
475 if (nlk->module) 476 if (nlk->module)
@@ -1695,12 +1696,12 @@ static struct file_operations netlink_seq_fops = {
1695 1696
1696int netlink_register_notifier(struct notifier_block *nb) 1697int netlink_register_notifier(struct notifier_block *nb)
1697{ 1698{
1698 return notifier_chain_register(&netlink_chain, nb); 1699 return atomic_notifier_chain_register(&netlink_chain, nb);
1699} 1700}
1700 1701
1701int netlink_unregister_notifier(struct notifier_block *nb) 1702int netlink_unregister_notifier(struct notifier_block *nb)
1702{ 1703{
1703 return notifier_chain_unregister(&netlink_chain, nb); 1704 return atomic_notifier_chain_unregister(&netlink_chain, nb);
1704} 1705}
1705 1706
1706static const struct proto_ops netlink_ops = { 1707static const struct proto_ops netlink_ops = {
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 23632d84d8d7..4d7eb9e704da 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -78,7 +78,8 @@ struct rsi {
78 78
79static struct cache_head *rsi_table[RSI_HASHMAX]; 79static struct cache_head *rsi_table[RSI_HASHMAX];
80static struct cache_detail rsi_cache; 80static struct cache_detail rsi_cache;
81static struct rsi *rsi_lookup(struct rsi *item, int set); 81static struct rsi *rsi_update(struct rsi *new, struct rsi *old);
82static struct rsi *rsi_lookup(struct rsi *item);
82 83
83static void rsi_free(struct rsi *rsii) 84static void rsi_free(struct rsi *rsii)
84{ 85{
@@ -88,13 +89,11 @@ static void rsi_free(struct rsi *rsii)
88 kfree(rsii->out_token.data); 89 kfree(rsii->out_token.data);
89} 90}
90 91
91static void rsi_put(struct cache_head *item, struct cache_detail *cd) 92static void rsi_put(struct kref *ref)
92{ 93{
93 struct rsi *rsii = container_of(item, struct rsi, h); 94 struct rsi *rsii = container_of(ref, struct rsi, h.ref);
94 if (cache_put(item, cd)) { 95 rsi_free(rsii);
95 rsi_free(rsii); 96 kfree(rsii);
96 kfree(rsii);
97 }
98} 97}
99 98
100static inline int rsi_hash(struct rsi *item) 99static inline int rsi_hash(struct rsi *item)
@@ -103,8 +102,10 @@ static inline int rsi_hash(struct rsi *item)
103 ^ hash_mem(item->in_token.data, item->in_token.len, RSI_HASHBITS); 102 ^ hash_mem(item->in_token.data, item->in_token.len, RSI_HASHBITS);
104} 103}
105 104
106static inline int rsi_match(struct rsi *item, struct rsi *tmp) 105static int rsi_match(struct cache_head *a, struct cache_head *b)
107{ 106{
107 struct rsi *item = container_of(a, struct rsi, h);
108 struct rsi *tmp = container_of(b, struct rsi, h);
108 return netobj_equal(&item->in_handle, &tmp->in_handle) 109 return netobj_equal(&item->in_handle, &tmp->in_handle)
109 && netobj_equal(&item->in_token, &tmp->in_token); 110 && netobj_equal(&item->in_token, &tmp->in_token);
110} 111}
@@ -125,8 +126,11 @@ static inline int dup_netobj(struct xdr_netobj *dst, struct xdr_netobj *src)
125 return dup_to_netobj(dst, src->data, src->len); 126 return dup_to_netobj(dst, src->data, src->len);
126} 127}
127 128
128static inline void rsi_init(struct rsi *new, struct rsi *item) 129static void rsi_init(struct cache_head *cnew, struct cache_head *citem)
129{ 130{
131 struct rsi *new = container_of(cnew, struct rsi, h);
132 struct rsi *item = container_of(citem, struct rsi, h);
133
130 new->out_handle.data = NULL; 134 new->out_handle.data = NULL;
131 new->out_handle.len = 0; 135 new->out_handle.len = 0;
132 new->out_token.data = NULL; 136 new->out_token.data = NULL;
@@ -141,8 +145,11 @@ static inline void rsi_init(struct rsi *new, struct rsi *item)
141 item->in_token.data = NULL; 145 item->in_token.data = NULL;
142} 146}
143 147
144static inline void rsi_update(struct rsi *new, struct rsi *item) 148static void update_rsi(struct cache_head *cnew, struct cache_head *citem)
145{ 149{
150 struct rsi *new = container_of(cnew, struct rsi, h);
151 struct rsi *item = container_of(citem, struct rsi, h);
152
146 BUG_ON(new->out_handle.data || new->out_token.data); 153 BUG_ON(new->out_handle.data || new->out_token.data);
147 new->out_handle.len = item->out_handle.len; 154 new->out_handle.len = item->out_handle.len;
148 item->out_handle.len = 0; 155 item->out_handle.len = 0;
@@ -157,6 +164,15 @@ static inline void rsi_update(struct rsi *new, struct rsi *item)
157 new->minor_status = item->minor_status; 164 new->minor_status = item->minor_status;
158} 165}
159 166
167static struct cache_head *rsi_alloc(void)
168{
169 struct rsi *rsii = kmalloc(sizeof(*rsii), GFP_KERNEL);
170 if (rsii)
171 return &rsii->h;
172 else
173 return NULL;
174}
175
160static void rsi_request(struct cache_detail *cd, 176static void rsi_request(struct cache_detail *cd,
161 struct cache_head *h, 177 struct cache_head *h,
162 char **bpp, int *blen) 178 char **bpp, int *blen)
@@ -198,6 +214,10 @@ static int rsi_parse(struct cache_detail *cd,
198 if (dup_to_netobj(&rsii.in_token, buf, len)) 214 if (dup_to_netobj(&rsii.in_token, buf, len))
199 goto out; 215 goto out;
200 216
217 rsip = rsi_lookup(&rsii);
218 if (!rsip)
219 goto out;
220
201 rsii.h.flags = 0; 221 rsii.h.flags = 0;
202 /* expiry */ 222 /* expiry */
203 expiry = get_expiry(&mesg); 223 expiry = get_expiry(&mesg);
@@ -240,12 +260,14 @@ static int rsi_parse(struct cache_detail *cd,
240 goto out; 260 goto out;
241 } 261 }
242 rsii.h.expiry_time = expiry; 262 rsii.h.expiry_time = expiry;
243 rsip = rsi_lookup(&rsii, 1); 263 rsip = rsi_update(&rsii, rsip);
244 status = 0; 264 status = 0;
245out: 265out:
246 rsi_free(&rsii); 266 rsi_free(&rsii);
247 if (rsip) 267 if (rsip)
248 rsi_put(&rsip->h, &rsi_cache); 268 cache_put(&rsip->h, &rsi_cache);
269 else
270 status = -ENOMEM;
249 return status; 271 return status;
250} 272}
251 273
@@ -257,9 +279,37 @@ static struct cache_detail rsi_cache = {
257 .cache_put = rsi_put, 279 .cache_put = rsi_put,
258 .cache_request = rsi_request, 280 .cache_request = rsi_request,
259 .cache_parse = rsi_parse, 281 .cache_parse = rsi_parse,
282 .match = rsi_match,
283 .init = rsi_init,
284 .update = update_rsi,
285 .alloc = rsi_alloc,
260}; 286};
261 287
262static DefineSimpleCacheLookup(rsi, 0) 288static struct rsi *rsi_lookup(struct rsi *item)
289{
290 struct cache_head *ch;
291 int hash = rsi_hash(item);
292
293 ch = sunrpc_cache_lookup(&rsi_cache, &item->h, hash);
294 if (ch)
295 return container_of(ch, struct rsi, h);
296 else
297 return NULL;
298}
299
300static struct rsi *rsi_update(struct rsi *new, struct rsi *old)
301{
302 struct cache_head *ch;
303 int hash = rsi_hash(new);
304
305 ch = sunrpc_cache_update(&rsi_cache, &new->h,
306 &old->h, hash);
307 if (ch)
308 return container_of(ch, struct rsi, h);
309 else
310 return NULL;
311}
312
263 313
264/* 314/*
265 * The rpcsec_context cache is used to store a context that is 315 * The rpcsec_context cache is used to store a context that is
@@ -293,7 +343,8 @@ struct rsc {
293 343
294static struct cache_head *rsc_table[RSC_HASHMAX]; 344static struct cache_head *rsc_table[RSC_HASHMAX];
295static struct cache_detail rsc_cache; 345static struct cache_detail rsc_cache;
296static struct rsc *rsc_lookup(struct rsc *item, int set); 346static struct rsc *rsc_update(struct rsc *new, struct rsc *old);
347static struct rsc *rsc_lookup(struct rsc *item);
297 348
298static void rsc_free(struct rsc *rsci) 349static void rsc_free(struct rsc *rsci)
299{ 350{
@@ -304,14 +355,12 @@ static void rsc_free(struct rsc *rsci)
304 put_group_info(rsci->cred.cr_group_info); 355 put_group_info(rsci->cred.cr_group_info);
305} 356}
306 357
307static void rsc_put(struct cache_head *item, struct cache_detail *cd) 358static void rsc_put(struct kref *ref)
308{ 359{
309 struct rsc *rsci = container_of(item, struct rsc, h); 360 struct rsc *rsci = container_of(ref, struct rsc, h.ref);
310 361
311 if (cache_put(item, cd)) { 362 rsc_free(rsci);
312 rsc_free(rsci); 363 kfree(rsci);
313 kfree(rsci);
314 }
315} 364}
316 365
317static inline int 366static inline int
@@ -320,15 +369,21 @@ rsc_hash(struct rsc *rsci)
320 return hash_mem(rsci->handle.data, rsci->handle.len, RSC_HASHBITS); 369 return hash_mem(rsci->handle.data, rsci->handle.len, RSC_HASHBITS);
321} 370}
322 371
323static inline int 372static int
324rsc_match(struct rsc *new, struct rsc *tmp) 373rsc_match(struct cache_head *a, struct cache_head *b)
325{ 374{
375 struct rsc *new = container_of(a, struct rsc, h);
376 struct rsc *tmp = container_of(b, struct rsc, h);
377
326 return netobj_equal(&new->handle, &tmp->handle); 378 return netobj_equal(&new->handle, &tmp->handle);
327} 379}
328 380
329static inline void 381static void
330rsc_init(struct rsc *new, struct rsc *tmp) 382rsc_init(struct cache_head *cnew, struct cache_head *ctmp)
331{ 383{
384 struct rsc *new = container_of(cnew, struct rsc, h);
385 struct rsc *tmp = container_of(ctmp, struct rsc, h);
386
332 new->handle.len = tmp->handle.len; 387 new->handle.len = tmp->handle.len;
333 tmp->handle.len = 0; 388 tmp->handle.len = 0;
334 new->handle.data = tmp->handle.data; 389 new->handle.data = tmp->handle.data;
@@ -337,9 +392,12 @@ rsc_init(struct rsc *new, struct rsc *tmp)
337 new->cred.cr_group_info = NULL; 392 new->cred.cr_group_info = NULL;
338} 393}
339 394
340static inline void 395static void
341rsc_update(struct rsc *new, struct rsc *tmp) 396update_rsc(struct cache_head *cnew, struct cache_head *ctmp)
342{ 397{
398 struct rsc *new = container_of(cnew, struct rsc, h);
399 struct rsc *tmp = container_of(ctmp, struct rsc, h);
400
343 new->mechctx = tmp->mechctx; 401 new->mechctx = tmp->mechctx;
344 tmp->mechctx = NULL; 402 tmp->mechctx = NULL;
345 memset(&new->seqdata, 0, sizeof(new->seqdata)); 403 memset(&new->seqdata, 0, sizeof(new->seqdata));
@@ -348,6 +406,16 @@ rsc_update(struct rsc *new, struct rsc *tmp)
348 tmp->cred.cr_group_info = NULL; 406 tmp->cred.cr_group_info = NULL;
349} 407}
350 408
409static struct cache_head *
410rsc_alloc(void)
411{
412 struct rsc *rsci = kmalloc(sizeof(*rsci), GFP_KERNEL);
413 if (rsci)
414 return &rsci->h;
415 else
416 return NULL;
417}
418
351static int rsc_parse(struct cache_detail *cd, 419static int rsc_parse(struct cache_detail *cd,
352 char *mesg, int mlen) 420 char *mesg, int mlen)
353{ 421{
@@ -373,6 +441,10 @@ static int rsc_parse(struct cache_detail *cd,
373 if (expiry == 0) 441 if (expiry == 0)
374 goto out; 442 goto out;
375 443
444 rscp = rsc_lookup(&rsci);
445 if (!rscp)
446 goto out;
447
376 /* uid, or NEGATIVE */ 448 /* uid, or NEGATIVE */
377 rv = get_int(&mesg, &rsci.cred.cr_uid); 449 rv = get_int(&mesg, &rsci.cred.cr_uid);
378 if (rv == -EINVAL) 450 if (rv == -EINVAL)
@@ -428,12 +500,14 @@ static int rsc_parse(struct cache_detail *cd,
428 gss_mech_put(gm); 500 gss_mech_put(gm);
429 } 501 }
430 rsci.h.expiry_time = expiry; 502 rsci.h.expiry_time = expiry;
431 rscp = rsc_lookup(&rsci, 1); 503 rscp = rsc_update(&rsci, rscp);
432 status = 0; 504 status = 0;
433out: 505out:
434 rsc_free(&rsci); 506 rsc_free(&rsci);
435 if (rscp) 507 if (rscp)
436 rsc_put(&rscp->h, &rsc_cache); 508 cache_put(&rscp->h, &rsc_cache);
509 else
510 status = -ENOMEM;
437 return status; 511 return status;
438} 512}
439 513
@@ -444,9 +518,37 @@ static struct cache_detail rsc_cache = {
444 .name = "auth.rpcsec.context", 518 .name = "auth.rpcsec.context",
445 .cache_put = rsc_put, 519 .cache_put = rsc_put,
446 .cache_parse = rsc_parse, 520 .cache_parse = rsc_parse,
521 .match = rsc_match,
522 .init = rsc_init,
523 .update = update_rsc,
524 .alloc = rsc_alloc,
447}; 525};
448 526
449static DefineSimpleCacheLookup(rsc, 0); 527static struct rsc *rsc_lookup(struct rsc *item)
528{
529 struct cache_head *ch;
530 int hash = rsc_hash(item);
531
532 ch = sunrpc_cache_lookup(&rsc_cache, &item->h, hash);
533 if (ch)
534 return container_of(ch, struct rsc, h);
535 else
536 return NULL;
537}
538
539static struct rsc *rsc_update(struct rsc *new, struct rsc *old)
540{
541 struct cache_head *ch;
542 int hash = rsc_hash(new);
543
544 ch = sunrpc_cache_update(&rsc_cache, &new->h,
545 &old->h, hash);
546 if (ch)
547 return container_of(ch, struct rsc, h);
548 else
549 return NULL;
550}
551
450 552
451static struct rsc * 553static struct rsc *
452gss_svc_searchbyctx(struct xdr_netobj *handle) 554gss_svc_searchbyctx(struct xdr_netobj *handle)
@@ -457,7 +559,7 @@ gss_svc_searchbyctx(struct xdr_netobj *handle)
457 memset(&rsci, 0, sizeof(rsci)); 559 memset(&rsci, 0, sizeof(rsci));
458 if (dup_to_netobj(&rsci.handle, handle->data, handle->len)) 560 if (dup_to_netobj(&rsci.handle, handle->data, handle->len))
459 return NULL; 561 return NULL;
460 found = rsc_lookup(&rsci, 0); 562 found = rsc_lookup(&rsci);
461 rsc_free(&rsci); 563 rsc_free(&rsci);
462 if (!found) 564 if (!found)
463 return NULL; 565 return NULL;
@@ -645,6 +747,8 @@ find_gss_auth_domain(struct gss_ctx *ctx, u32 svc)
645 return auth_domain_find(name); 747 return auth_domain_find(name);
646} 748}
647 749
750static struct auth_ops svcauthops_gss;
751
648int 752int
649svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name) 753svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name)
650{ 754{
@@ -655,20 +759,18 @@ svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name)
655 new = kmalloc(sizeof(*new), GFP_KERNEL); 759 new = kmalloc(sizeof(*new), GFP_KERNEL);
656 if (!new) 760 if (!new)
657 goto out; 761 goto out;
658 cache_init(&new->h.h); 762 kref_init(&new->h.ref);
659 new->h.name = kmalloc(strlen(name) + 1, GFP_KERNEL); 763 new->h.name = kmalloc(strlen(name) + 1, GFP_KERNEL);
660 if (!new->h.name) 764 if (!new->h.name)
661 goto out_free_dom; 765 goto out_free_dom;
662 strcpy(new->h.name, name); 766 strcpy(new->h.name, name);
663 new->h.flavour = RPC_AUTH_GSS; 767 new->h.flavour = &svcauthops_gss;
664 new->pseudoflavor = pseudoflavor; 768 new->pseudoflavor = pseudoflavor;
665 new->h.h.expiry_time = NEVER;
666 769
667 test = auth_domain_lookup(&new->h, 1); 770 test = auth_domain_lookup(name, &new->h);
668 if (test == &new->h) { 771 if (test != &new->h) { /* XXX Duplicate registration? */
669 BUG_ON(atomic_dec_and_test(&new->h.h.refcnt));
670 } else { /* XXX Duplicate registration? */
671 auth_domain_put(&new->h); 772 auth_domain_put(&new->h);
773 /* dangling ref-count... */
672 goto out; 774 goto out;
673 } 775 }
674 return 0; 776 return 0;
@@ -895,7 +997,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, u32 *authp)
895 goto drop; 997 goto drop;
896 } 998 }
897 999
898 rsip = rsi_lookup(&rsikey, 0); 1000 rsip = rsi_lookup(&rsikey);
899 rsi_free(&rsikey); 1001 rsi_free(&rsikey);
900 if (!rsip) { 1002 if (!rsip) {
901 goto drop; 1003 goto drop;
@@ -970,7 +1072,7 @@ drop:
970 ret = SVC_DROP; 1072 ret = SVC_DROP;
971out: 1073out:
972 if (rsci) 1074 if (rsci)
973 rsc_put(&rsci->h, &rsc_cache); 1075 cache_put(&rsci->h, &rsc_cache);
974 return ret; 1076 return ret;
975} 1077}
976 1078
@@ -1062,7 +1164,7 @@ out_err:
1062 put_group_info(rqstp->rq_cred.cr_group_info); 1164 put_group_info(rqstp->rq_cred.cr_group_info);
1063 rqstp->rq_cred.cr_group_info = NULL; 1165 rqstp->rq_cred.cr_group_info = NULL;
1064 if (gsd->rsci) 1166 if (gsd->rsci)
1065 rsc_put(&gsd->rsci->h, &rsc_cache); 1167 cache_put(&gsd->rsci->h, &rsc_cache);
1066 gsd->rsci = NULL; 1168 gsd->rsci = NULL;
1067 1169
1068 return stat; 1170 return stat;
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 0acccfeeb284..3ac4193a78ed 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -37,16 +37,138 @@
37static void cache_defer_req(struct cache_req *req, struct cache_head *item); 37static void cache_defer_req(struct cache_req *req, struct cache_head *item);
38static void cache_revisit_request(struct cache_head *item); 38static void cache_revisit_request(struct cache_head *item);
39 39
40void cache_init(struct cache_head *h) 40static void cache_init(struct cache_head *h)
41{ 41{
42 time_t now = get_seconds(); 42 time_t now = get_seconds();
43 h->next = NULL; 43 h->next = NULL;
44 h->flags = 0; 44 h->flags = 0;
45 atomic_set(&h->refcnt, 1); 45 kref_init(&h->ref);
46 h->expiry_time = now + CACHE_NEW_EXPIRY; 46 h->expiry_time = now + CACHE_NEW_EXPIRY;
47 h->last_refresh = now; 47 h->last_refresh = now;
48} 48}
49 49
50struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail,
51 struct cache_head *key, int hash)
52{
53 struct cache_head **head, **hp;
54 struct cache_head *new = NULL;
55
56 head = &detail->hash_table[hash];
57
58 read_lock(&detail->hash_lock);
59
60 for (hp=head; *hp != NULL ; hp = &(*hp)->next) {
61 struct cache_head *tmp = *hp;
62 if (detail->match(tmp, key)) {
63 cache_get(tmp);
64 read_unlock(&detail->hash_lock);
65 return tmp;
66 }
67 }
68 read_unlock(&detail->hash_lock);
69 /* Didn't find anything, insert an empty entry */
70
71 new = detail->alloc();
72 if (!new)
73 return NULL;
74 cache_init(new);
75
76 write_lock(&detail->hash_lock);
77
78 /* check if entry appeared while we slept */
79 for (hp=head; *hp != NULL ; hp = &(*hp)->next) {
80 struct cache_head *tmp = *hp;
81 if (detail->match(tmp, key)) {
82 cache_get(tmp);
83 write_unlock(&detail->hash_lock);
84 cache_put(new, detail);
85 return tmp;
86 }
87 }
88 detail->init(new, key);
89 new->next = *head;
90 *head = new;
91 detail->entries++;
92 cache_get(new);
93 write_unlock(&detail->hash_lock);
94
95 return new;
96}
97EXPORT_SYMBOL(sunrpc_cache_lookup);
98
99
100static void queue_loose(struct cache_detail *detail, struct cache_head *ch);
101
102static int cache_fresh_locked(struct cache_head *head, time_t expiry)
103{
104 head->expiry_time = expiry;
105 head->last_refresh = get_seconds();
106 return !test_and_set_bit(CACHE_VALID, &head->flags);
107}
108
109static void cache_fresh_unlocked(struct cache_head *head,
110 struct cache_detail *detail, int new)
111{
112 if (new)
113 cache_revisit_request(head);
114 if (test_and_clear_bit(CACHE_PENDING, &head->flags)) {
115 cache_revisit_request(head);
116 queue_loose(detail, head);
117 }
118}
119
120struct cache_head *sunrpc_cache_update(struct cache_detail *detail,
121 struct cache_head *new, struct cache_head *old, int hash)
122{
123 /* The 'old' entry is to be replaced by 'new'.
124 * If 'old' is not VALID, we update it directly,
125 * otherwise we need to replace it
126 */
127 struct cache_head **head;
128 struct cache_head *tmp;
129 int is_new;
130
131 if (!test_bit(CACHE_VALID, &old->flags)) {
132 write_lock(&detail->hash_lock);
133 if (!test_bit(CACHE_VALID, &old->flags)) {
134 if (test_bit(CACHE_NEGATIVE, &new->flags))
135 set_bit(CACHE_NEGATIVE, &old->flags);
136 else
137 detail->update(old, new);
138 is_new = cache_fresh_locked(old, new->expiry_time);
139 write_unlock(&detail->hash_lock);
140 cache_fresh_unlocked(old, detail, is_new);
141 return old;
142 }
143 write_unlock(&detail->hash_lock);
144 }
145 /* We need to insert a new entry */
146 tmp = detail->alloc();
147 if (!tmp) {
148 cache_put(old, detail);
149 return NULL;
150 }
151 cache_init(tmp);
152 detail->init(tmp, old);
153 head = &detail->hash_table[hash];
154
155 write_lock(&detail->hash_lock);
156 if (test_bit(CACHE_NEGATIVE, &new->flags))
157 set_bit(CACHE_NEGATIVE, &tmp->flags);
158 else
159 detail->update(tmp, new);
160 tmp->next = *head;
161 *head = tmp;
162 cache_get(tmp);
163 is_new = cache_fresh_locked(tmp, new->expiry_time);
164 cache_fresh_locked(old, 0);
165 write_unlock(&detail->hash_lock);
166 cache_fresh_unlocked(tmp, detail, is_new);
167 cache_fresh_unlocked(old, detail, 0);
168 cache_put(old, detail);
169 return tmp;
170}
171EXPORT_SYMBOL(sunrpc_cache_update);
50 172
51static int cache_make_upcall(struct cache_detail *detail, struct cache_head *h); 173static int cache_make_upcall(struct cache_detail *detail, struct cache_head *h);
52/* 174/*
@@ -94,7 +216,8 @@ int cache_check(struct cache_detail *detail,
94 clear_bit(CACHE_PENDING, &h->flags); 216 clear_bit(CACHE_PENDING, &h->flags);
95 if (rv == -EAGAIN) { 217 if (rv == -EAGAIN) {
96 set_bit(CACHE_NEGATIVE, &h->flags); 218 set_bit(CACHE_NEGATIVE, &h->flags);
97 cache_fresh(detail, h, get_seconds()+CACHE_NEW_EXPIRY); 219 cache_fresh_unlocked(h, detail,
220 cache_fresh_locked(h, get_seconds()+CACHE_NEW_EXPIRY));
98 rv = -ENOENT; 221 rv = -ENOENT;
99 } 222 }
100 break; 223 break;
@@ -110,25 +233,11 @@ int cache_check(struct cache_detail *detail,
110 if (rv == -EAGAIN) 233 if (rv == -EAGAIN)
111 cache_defer_req(rqstp, h); 234 cache_defer_req(rqstp, h);
112 235
113 if (rv && h) 236 if (rv)
114 detail->cache_put(h, detail); 237 cache_put(h, detail);
115 return rv; 238 return rv;
116} 239}
117 240
118static void queue_loose(struct cache_detail *detail, struct cache_head *ch);
119
120void cache_fresh(struct cache_detail *detail,
121 struct cache_head *head, time_t expiry)
122{
123
124 head->expiry_time = expiry;
125 head->last_refresh = get_seconds();
126 if (!test_and_set_bit(CACHE_VALID, &head->flags))
127 cache_revisit_request(head);
128 if (test_and_clear_bit(CACHE_PENDING, &head->flags))
129 queue_loose(detail, head);
130}
131
132/* 241/*
133 * caches need to be periodically cleaned. 242 * caches need to be periodically cleaned.
134 * For this we maintain a list of cache_detail and 243 * For this we maintain a list of cache_detail and
@@ -322,7 +431,7 @@ static int cache_clean(void)
322 if (test_and_clear_bit(CACHE_PENDING, &ch->flags)) 431 if (test_and_clear_bit(CACHE_PENDING, &ch->flags))
323 queue_loose(current_detail, ch); 432 queue_loose(current_detail, ch);
324 433
325 if (atomic_read(&ch->refcnt) == 1) 434 if (atomic_read(&ch->ref.refcount) == 1)
326 break; 435 break;
327 } 436 }
328 if (ch) { 437 if (ch) {
@@ -337,7 +446,7 @@ static int cache_clean(void)
337 current_index ++; 446 current_index ++;
338 spin_unlock(&cache_list_lock); 447 spin_unlock(&cache_list_lock);
339 if (ch) 448 if (ch)
340 d->cache_put(ch, d); 449 cache_put(ch, d);
341 } else 450 } else
342 spin_unlock(&cache_list_lock); 451 spin_unlock(&cache_list_lock);
343 452
@@ -453,7 +562,7 @@ static void cache_defer_req(struct cache_req *req, struct cache_head *item)
453 /* there was one too many */ 562 /* there was one too many */
454 dreq->revisit(dreq, 1); 563 dreq->revisit(dreq, 1);
455 } 564 }
456 if (test_bit(CACHE_VALID, &item->flags)) { 565 if (!test_bit(CACHE_PENDING, &item->flags)) {
457 /* must have just been validated... */ 566 /* must have just been validated... */
458 cache_revisit_request(item); 567 cache_revisit_request(item);
459 } 568 }
@@ -614,7 +723,7 @@ cache_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
614 !test_bit(CACHE_PENDING, &rq->item->flags)) { 723 !test_bit(CACHE_PENDING, &rq->item->flags)) {
615 list_del(&rq->q.list); 724 list_del(&rq->q.list);
616 spin_unlock(&queue_lock); 725 spin_unlock(&queue_lock);
617 cd->cache_put(rq->item, cd); 726 cache_put(rq->item, cd);
618 kfree(rq->buf); 727 kfree(rq->buf);
619 kfree(rq); 728 kfree(rq);
620 } else 729 } else
@@ -794,10 +903,10 @@ static void queue_loose(struct cache_detail *detail, struct cache_head *ch)
794 if (cr->item != ch) 903 if (cr->item != ch)
795 continue; 904 continue;
796 if (cr->readers != 0) 905 if (cr->readers != 0)
797 break; 906 continue;
798 list_del(&cr->q.list); 907 list_del(&cr->q.list);
799 spin_unlock(&queue_lock); 908 spin_unlock(&queue_lock);
800 detail->cache_put(cr->item, detail); 909 cache_put(cr->item, detail);
801 kfree(cr->buf); 910 kfree(cr->buf);
802 kfree(cr); 911 kfree(cr);
803 return; 912 return;
@@ -1082,8 +1191,8 @@ static int c_show(struct seq_file *m, void *p)
1082 return cd->cache_show(m, cd, NULL); 1191 return cd->cache_show(m, cd, NULL);
1083 1192
1084 ifdebug(CACHE) 1193 ifdebug(CACHE)
1085 seq_printf(m, "# expiry=%ld refcnt=%d\n", 1194 seq_printf(m, "# expiry=%ld refcnt=%d flags=%lx\n",
1086 cp->expiry_time, atomic_read(&cp->refcnt)); 1195 cp->expiry_time, atomic_read(&cp->ref.refcount), cp->flags);
1087 cache_get(cp); 1196 cache_get(cp);
1088 if (cache_check(cd, cp, NULL)) 1197 if (cache_check(cd, cp, NULL))
1089 /* cache_check does a cache_put on failure */ 1198 /* cache_check does a cache_put on failure */
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index 9f7373203592..769114f0f886 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -105,8 +105,6 @@ EXPORT_SYMBOL(auth_unix_lookup);
105EXPORT_SYMBOL(cache_check); 105EXPORT_SYMBOL(cache_check);
106EXPORT_SYMBOL(cache_flush); 106EXPORT_SYMBOL(cache_flush);
107EXPORT_SYMBOL(cache_purge); 107EXPORT_SYMBOL(cache_purge);
108EXPORT_SYMBOL(cache_fresh);
109EXPORT_SYMBOL(cache_init);
110EXPORT_SYMBOL(cache_register); 108EXPORT_SYMBOL(cache_register);
111EXPORT_SYMBOL(cache_unregister); 109EXPORT_SYMBOL(cache_unregister);
112EXPORT_SYMBOL(qword_add); 110EXPORT_SYMBOL(qword_add);
@@ -142,6 +140,7 @@ EXPORT_SYMBOL(nlm_debug);
142 140
143extern int register_rpc_pipefs(void); 141extern int register_rpc_pipefs(void);
144extern void unregister_rpc_pipefs(void); 142extern void unregister_rpc_pipefs(void);
143extern struct cache_detail ip_map_cache;
145 144
146static int __init 145static int __init
147init_sunrpc(void) 146init_sunrpc(void)
@@ -158,7 +157,6 @@ init_sunrpc(void)
158#ifdef CONFIG_PROC_FS 157#ifdef CONFIG_PROC_FS
159 rpc_proc_init(); 158 rpc_proc_init();
160#endif 159#endif
161 cache_register(&auth_domain_cache);
162 cache_register(&ip_map_cache); 160 cache_register(&ip_map_cache);
163out: 161out:
164 return err; 162 return err;
@@ -169,8 +167,6 @@ cleanup_sunrpc(void)
169{ 167{
170 unregister_rpc_pipefs(); 168 unregister_rpc_pipefs();
171 rpc_destroy_mempool(); 169 rpc_destroy_mempool();
172 if (cache_unregister(&auth_domain_cache))
173 printk(KERN_ERR "sunrpc: failed to unregister auth_domain cache\n");
174 if (cache_unregister(&ip_map_cache)) 170 if (cache_unregister(&ip_map_cache))
175 printk(KERN_ERR "sunrpc: failed to unregister ip_map cache\n"); 171 printk(KERN_ERR "sunrpc: failed to unregister ip_map cache\n");
176#ifdef RPC_DEBUG 172#ifdef RPC_DEBUG
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c
index dda4f0c63511..5b28c6176806 100644
--- a/net/sunrpc/svcauth.c
+++ b/net/sunrpc/svcauth.c
@@ -106,112 +106,56 @@ svc_auth_unregister(rpc_authflavor_t flavor)
106EXPORT_SYMBOL(svc_auth_unregister); 106EXPORT_SYMBOL(svc_auth_unregister);
107 107
108/************************************************** 108/**************************************************
109 * cache for domain name to auth_domain 109 * 'auth_domains' are stored in a hash table indexed by name.
110 * Entries are only added by flavours which will normally 110 * When the last reference to an 'auth_domain' is dropped,
111 * have a structure that 'inherits' from auth_domain. 111 * the object is unhashed and freed.
112 * e.g. when an IP -> domainname is given to auth_unix, 112 * If auth_domain_lookup fails to find an entry, it will return
113 * and the domain name doesn't exist, it will create a 113 * it's second argument 'new'. If this is non-null, it will
114 * auth_unix_domain and add it to this hash table. 114 * have been atomically linked into the table.
115 * If it finds the name does exist, but isn't AUTH_UNIX,
116 * it will complain.
117 */ 115 */
118 116
119/*
120 * Auth auth_domain cache is somewhat different to other caches,
121 * largely because the entries are possibly of different types:
122 * each auth flavour has it's own type.
123 * One consequence of this that DefineCacheLookup cannot
124 * allocate a new structure as it cannot know the size.
125 * Notice that the "INIT" code fragment is quite different
126 * from other caches. When auth_domain_lookup might be
127 * creating a new domain, the new domain is passed in
128 * complete and it is used as-is rather than being copied into
129 * another structure.
130 */
131#define DN_HASHBITS 6 117#define DN_HASHBITS 6
132#define DN_HASHMAX (1<<DN_HASHBITS) 118#define DN_HASHMAX (1<<DN_HASHBITS)
133#define DN_HASHMASK (DN_HASHMAX-1) 119#define DN_HASHMASK (DN_HASHMAX-1)
134 120
135static struct cache_head *auth_domain_table[DN_HASHMAX]; 121static struct hlist_head auth_domain_table[DN_HASHMAX];
136 122static spinlock_t auth_domain_lock = SPIN_LOCK_UNLOCKED;
137static void auth_domain_drop(struct cache_head *item, struct cache_detail *cd)
138{
139 struct auth_domain *dom = container_of(item, struct auth_domain, h);
140 if (cache_put(item,cd))
141 authtab[dom->flavour]->domain_release(dom);
142}
143
144
145struct cache_detail auth_domain_cache = {
146 .owner = THIS_MODULE,
147 .hash_size = DN_HASHMAX,
148 .hash_table = auth_domain_table,
149 .name = "auth.domain",
150 .cache_put = auth_domain_drop,
151};
152 123
153void auth_domain_put(struct auth_domain *dom) 124void auth_domain_put(struct auth_domain *dom)
154{ 125{
155 auth_domain_drop(&dom->h, &auth_domain_cache); 126 if (atomic_dec_and_lock(&dom->ref.refcount, &auth_domain_lock)) {
156} 127 hlist_del(&dom->hash);
157 128 dom->flavour->domain_release(dom);
158static inline int auth_domain_hash(struct auth_domain *item) 129 }
159{
160 return hash_str(item->name, DN_HASHBITS);
161}
162static inline int auth_domain_match(struct auth_domain *tmp, struct auth_domain *item)
163{
164 return strcmp(tmp->name, item->name) == 0;
165} 130}
166 131
167struct auth_domain * 132struct auth_domain *
168auth_domain_lookup(struct auth_domain *item, int set) 133auth_domain_lookup(char *name, struct auth_domain *new)
169{ 134{
170 struct auth_domain *tmp = NULL; 135 struct auth_domain *hp;
171 struct cache_head **hp, **head; 136 struct hlist_head *head;
172 head = &auth_domain_cache.hash_table[auth_domain_hash(item)]; 137 struct hlist_node *np;
173 138
174 if (set) 139 head = &auth_domain_table[hash_str(name, DN_HASHBITS)];
175 write_lock(&auth_domain_cache.hash_lock); 140
176 else 141 spin_lock(&auth_domain_lock);
177 read_lock(&auth_domain_cache.hash_lock); 142
178 for (hp=head; *hp != NULL; hp = &tmp->h.next) { 143 hlist_for_each_entry(hp, np, head, hash) {
179 tmp = container_of(*hp, struct auth_domain, h); 144 if (strcmp(hp->name, name)==0) {
180 if (!auth_domain_match(tmp, item)) 145 kref_get(&hp->ref);
181 continue; 146 spin_unlock(&auth_domain_lock);
182 if (!set) { 147 return hp;
183 cache_get(&tmp->h);
184 goto out_noset;
185 } 148 }
186 *hp = tmp->h.next;
187 tmp->h.next = NULL;
188 auth_domain_drop(&tmp->h, &auth_domain_cache);
189 goto out_set;
190 } 149 }
191 /* Didn't find anything */ 150 if (new) {
192 if (!set) 151 hlist_add_head(&new->hash, head);
193 goto out_nada; 152 kref_get(&new->ref);
194 auth_domain_cache.entries++; 153 }
195out_set: 154 spin_unlock(&auth_domain_lock);
196 item->h.next = *head; 155 return new;
197 *head = &item->h;
198 cache_get(&item->h);
199 write_unlock(&auth_domain_cache.hash_lock);
200 cache_fresh(&auth_domain_cache, &item->h, item->h.expiry_time);
201 cache_get(&item->h);
202 return item;
203out_nada:
204 tmp = NULL;
205out_noset:
206 read_unlock(&auth_domain_cache.hash_lock);
207 return tmp;
208} 156}
209 157
210struct auth_domain *auth_domain_find(char *name) 158struct auth_domain *auth_domain_find(char *name)
211{ 159{
212 struct auth_domain *rv, ad; 160 return auth_domain_lookup(name, NULL);
213
214 ad.name = name;
215 rv = auth_domain_lookup(&ad, 0);
216 return rv;
217} 161}
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 3e6c694bbad1..7e5707e2d6b6 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -27,41 +27,35 @@ struct unix_domain {
27 /* other stuff later */ 27 /* other stuff later */
28}; 28};
29 29
30extern struct auth_ops svcauth_unix;
31
30struct auth_domain *unix_domain_find(char *name) 32struct auth_domain *unix_domain_find(char *name)
31{ 33{
32 struct auth_domain *rv, ud; 34 struct auth_domain *rv;
33 struct unix_domain *new; 35 struct unix_domain *new = NULL;
34 36
35 ud.name = name; 37 rv = auth_domain_lookup(name, NULL);
36 38 while(1) {
37 rv = auth_domain_lookup(&ud, 0); 39 if (rv) {
38 40 if (new && rv != &new->h)
39 foundit: 41 auth_domain_put(&new->h);
40 if (rv && rv->flavour != RPC_AUTH_UNIX) { 42
41 auth_domain_put(rv); 43 if (rv->flavour != &svcauth_unix) {
42 return NULL; 44 auth_domain_put(rv);
43 } 45 return NULL;
44 if (rv) 46 }
45 return rv; 47 return rv;
46 48 }
47 new = kmalloc(sizeof(*new), GFP_KERNEL); 49
48 if (new == NULL) 50 new = kmalloc(sizeof(*new), GFP_KERNEL);
49 return NULL; 51 if (new == NULL)
50 cache_init(&new->h.h); 52 return NULL;
51 new->h.name = kstrdup(name, GFP_KERNEL); 53 kref_init(&new->h.ref);
52 new->h.flavour = RPC_AUTH_UNIX; 54 new->h.name = kstrdup(name, GFP_KERNEL);
53 new->addr_changes = 0; 55 new->h.flavour = &svcauth_unix;
54 new->h.h.expiry_time = NEVER; 56 new->addr_changes = 0;
55 57 rv = auth_domain_lookup(name, &new->h);
56 rv = auth_domain_lookup(&new->h, 2);
57 if (rv == &new->h) {
58 if (atomic_dec_and_test(&new->h.h.refcnt)) BUG();
59 } else {
60 auth_domain_put(&new->h);
61 goto foundit;
62 } 58 }
63
64 return rv;
65} 59}
66 60
67static void svcauth_unix_domain_release(struct auth_domain *dom) 61static void svcauth_unix_domain_release(struct auth_domain *dom)
@@ -90,15 +84,15 @@ struct ip_map {
90}; 84};
91static struct cache_head *ip_table[IP_HASHMAX]; 85static struct cache_head *ip_table[IP_HASHMAX];
92 86
93static void ip_map_put(struct cache_head *item, struct cache_detail *cd) 87static void ip_map_put(struct kref *kref)
94{ 88{
89 struct cache_head *item = container_of(kref, struct cache_head, ref);
95 struct ip_map *im = container_of(item, struct ip_map,h); 90 struct ip_map *im = container_of(item, struct ip_map,h);
96 if (cache_put(item, cd)) { 91
97 if (test_bit(CACHE_VALID, &item->flags) && 92 if (test_bit(CACHE_VALID, &item->flags) &&
98 !test_bit(CACHE_NEGATIVE, &item->flags)) 93 !test_bit(CACHE_NEGATIVE, &item->flags))
99 auth_domain_put(&im->m_client->h); 94 auth_domain_put(&im->m_client->h);
100 kfree(im); 95 kfree(im);
101 }
102} 96}
103 97
104#if IP_HASHBITS == 8 98#if IP_HASHBITS == 8
@@ -112,28 +106,38 @@ static inline int hash_ip(unsigned long ip)
112 return (hash ^ (hash>>8)) & 0xff; 106 return (hash ^ (hash>>8)) & 0xff;
113} 107}
114#endif 108#endif
115 109static int ip_map_match(struct cache_head *corig, struct cache_head *cnew)
116static inline int ip_map_hash(struct ip_map *item)
117{
118 return hash_str(item->m_class, IP_HASHBITS) ^
119 hash_ip((unsigned long)item->m_addr.s_addr);
120}
121static inline int ip_map_match(struct ip_map *item, struct ip_map *tmp)
122{ 110{
123 return strcmp(tmp->m_class, item->m_class) == 0 111 struct ip_map *orig = container_of(corig, struct ip_map, h);
124 && tmp->m_addr.s_addr == item->m_addr.s_addr; 112 struct ip_map *new = container_of(cnew, struct ip_map, h);
113 return strcmp(orig->m_class, new->m_class) == 0
114 && orig->m_addr.s_addr == new->m_addr.s_addr;
125} 115}
126static inline void ip_map_init(struct ip_map *new, struct ip_map *item) 116static void ip_map_init(struct cache_head *cnew, struct cache_head *citem)
127{ 117{
118 struct ip_map *new = container_of(cnew, struct ip_map, h);
119 struct ip_map *item = container_of(citem, struct ip_map, h);
120
128 strcpy(new->m_class, item->m_class); 121 strcpy(new->m_class, item->m_class);
129 new->m_addr.s_addr = item->m_addr.s_addr; 122 new->m_addr.s_addr = item->m_addr.s_addr;
130} 123}
131static inline void ip_map_update(struct ip_map *new, struct ip_map *item) 124static void update(struct cache_head *cnew, struct cache_head *citem)
132{ 125{
133 cache_get(&item->m_client->h.h); 126 struct ip_map *new = container_of(cnew, struct ip_map, h);
127 struct ip_map *item = container_of(citem, struct ip_map, h);
128
129 kref_get(&item->m_client->h.ref);
134 new->m_client = item->m_client; 130 new->m_client = item->m_client;
135 new->m_add_change = item->m_add_change; 131 new->m_add_change = item->m_add_change;
136} 132}
133static struct cache_head *ip_map_alloc(void)
134{
135 struct ip_map *i = kmalloc(sizeof(*i), GFP_KERNEL);
136 if (i)
137 return &i->h;
138 else
139 return NULL;
140}
137 141
138static void ip_map_request(struct cache_detail *cd, 142static void ip_map_request(struct cache_detail *cd,
139 struct cache_head *h, 143 struct cache_head *h,
@@ -154,7 +158,8 @@ static void ip_map_request(struct cache_detail *cd,
154 (*bpp)[-1] = '\n'; 158 (*bpp)[-1] = '\n';
155} 159}
156 160
157static struct ip_map *ip_map_lookup(struct ip_map *, int); 161static struct ip_map *ip_map_lookup(char *class, struct in_addr addr);
162static int ip_map_update(struct ip_map *ipm, struct unix_domain *udom, time_t expiry);
158 163
159static int ip_map_parse(struct cache_detail *cd, 164static int ip_map_parse(struct cache_detail *cd,
160 char *mesg, int mlen) 165 char *mesg, int mlen)
@@ -166,7 +171,11 @@ static int ip_map_parse(struct cache_detail *cd,
166 int len; 171 int len;
167 int b1,b2,b3,b4; 172 int b1,b2,b3,b4;
168 char c; 173 char c;
169 struct ip_map ipm, *ipmp; 174 char class[8];
175 struct in_addr addr;
176 int err;
177
178 struct ip_map *ipmp;
170 struct auth_domain *dom; 179 struct auth_domain *dom;
171 time_t expiry; 180 time_t expiry;
172 181
@@ -175,7 +184,7 @@ static int ip_map_parse(struct cache_detail *cd,
175 mesg[mlen-1] = 0; 184 mesg[mlen-1] = 0;
176 185
177 /* class */ 186 /* class */
178 len = qword_get(&mesg, ipm.m_class, sizeof(ipm.m_class)); 187 len = qword_get(&mesg, class, sizeof(class));
179 if (len <= 0) return -EINVAL; 188 if (len <= 0) return -EINVAL;
180 189
181 /* ip address */ 190 /* ip address */
@@ -200,25 +209,22 @@ static int ip_map_parse(struct cache_detail *cd,
200 } else 209 } else
201 dom = NULL; 210 dom = NULL;
202 211
203 ipm.m_addr.s_addr = 212 addr.s_addr =
204 htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4); 213 htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4);
205 ipm.h.flags = 0; 214
206 if (dom) { 215 ipmp = ip_map_lookup(class,addr);
207 ipm.m_client = container_of(dom, struct unix_domain, h); 216 if (ipmp) {
208 ipm.m_add_change = ipm.m_client->addr_changes; 217 err = ip_map_update(ipmp,
218 container_of(dom, struct unix_domain, h),
219 expiry);
209 } else 220 } else
210 set_bit(CACHE_NEGATIVE, &ipm.h.flags); 221 err = -ENOMEM;
211 ipm.h.expiry_time = expiry;
212 222
213 ipmp = ip_map_lookup(&ipm, 1);
214 if (ipmp)
215 ip_map_put(&ipmp->h, &ip_map_cache);
216 if (dom) 223 if (dom)
217 auth_domain_put(dom); 224 auth_domain_put(dom);
218 if (!ipmp) 225
219 return -ENOMEM;
220 cache_flush(); 226 cache_flush();
221 return 0; 227 return err;
222} 228}
223 229
224static int ip_map_show(struct seq_file *m, 230static int ip_map_show(struct seq_file *m,
@@ -262,32 +268,70 @@ struct cache_detail ip_map_cache = {
262 .cache_request = ip_map_request, 268 .cache_request = ip_map_request,
263 .cache_parse = ip_map_parse, 269 .cache_parse = ip_map_parse,
264 .cache_show = ip_map_show, 270 .cache_show = ip_map_show,
271 .match = ip_map_match,
272 .init = ip_map_init,
273 .update = update,
274 .alloc = ip_map_alloc,
265}; 275};
266 276
267static DefineSimpleCacheLookup(ip_map, 0) 277static struct ip_map *ip_map_lookup(char *class, struct in_addr addr)
278{
279 struct ip_map ip;
280 struct cache_head *ch;
281
282 strcpy(ip.m_class, class);
283 ip.m_addr = addr;
284 ch = sunrpc_cache_lookup(&ip_map_cache, &ip.h,
285 hash_str(class, IP_HASHBITS) ^
286 hash_ip((unsigned long)addr.s_addr));
287
288 if (ch)
289 return container_of(ch, struct ip_map, h);
290 else
291 return NULL;
292}
268 293
294static int ip_map_update(struct ip_map *ipm, struct unix_domain *udom, time_t expiry)
295{
296 struct ip_map ip;
297 struct cache_head *ch;
298
299 ip.m_client = udom;
300 ip.h.flags = 0;
301 if (!udom)
302 set_bit(CACHE_NEGATIVE, &ip.h.flags);
303 else {
304 ip.m_add_change = udom->addr_changes;
305 /* if this is from the legacy set_client system call,
306 * we need m_add_change to be one higher
307 */
308 if (expiry == NEVER)
309 ip.m_add_change++;
310 }
311 ip.h.expiry_time = expiry;
312 ch = sunrpc_cache_update(&ip_map_cache,
313 &ip.h, &ipm->h,
314 hash_str(ipm->m_class, IP_HASHBITS) ^
315 hash_ip((unsigned long)ipm->m_addr.s_addr));
316 if (!ch)
317 return -ENOMEM;
318 cache_put(ch, &ip_map_cache);
319 return 0;
320}
269 321
270int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom) 322int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom)
271{ 323{
272 struct unix_domain *udom; 324 struct unix_domain *udom;
273 struct ip_map ip, *ipmp; 325 struct ip_map *ipmp;
274 326
275 if (dom->flavour != RPC_AUTH_UNIX) 327 if (dom->flavour != &svcauth_unix)
276 return -EINVAL; 328 return -EINVAL;
277 udom = container_of(dom, struct unix_domain, h); 329 udom = container_of(dom, struct unix_domain, h);
278 strcpy(ip.m_class, "nfsd"); 330 ipmp = ip_map_lookup("nfsd", addr);
279 ip.m_addr = addr;
280 ip.m_client = udom;
281 ip.m_add_change = udom->addr_changes+1;
282 ip.h.flags = 0;
283 ip.h.expiry_time = NEVER;
284
285 ipmp = ip_map_lookup(&ip, 1);
286 331
287 if (ipmp) { 332 if (ipmp)
288 ip_map_put(&ipmp->h, &ip_map_cache); 333 return ip_map_update(ipmp, udom, NEVER);
289 return 0; 334 else
290 } else
291 return -ENOMEM; 335 return -ENOMEM;
292} 336}
293 337
@@ -295,7 +339,7 @@ int auth_unix_forget_old(struct auth_domain *dom)
295{ 339{
296 struct unix_domain *udom; 340 struct unix_domain *udom;
297 341
298 if (dom->flavour != RPC_AUTH_UNIX) 342 if (dom->flavour != &svcauth_unix)
299 return -EINVAL; 343 return -EINVAL;
300 udom = container_of(dom, struct unix_domain, h); 344 udom = container_of(dom, struct unix_domain, h);
301 udom->addr_changes++; 345 udom->addr_changes++;
@@ -310,7 +354,7 @@ struct auth_domain *auth_unix_lookup(struct in_addr addr)
310 strcpy(key.m_class, "nfsd"); 354 strcpy(key.m_class, "nfsd");
311 key.m_addr = addr; 355 key.m_addr = addr;
312 356
313 ipm = ip_map_lookup(&key, 0); 357 ipm = ip_map_lookup("nfsd", addr);
314 358
315 if (!ipm) 359 if (!ipm)
316 return NULL; 360 return NULL;
@@ -323,31 +367,28 @@ struct auth_domain *auth_unix_lookup(struct in_addr addr)
323 rv = NULL; 367 rv = NULL;
324 } else { 368 } else {
325 rv = &ipm->m_client->h; 369 rv = &ipm->m_client->h;
326 cache_get(&rv->h); 370 kref_get(&rv->ref);
327 } 371 }
328 ip_map_put(&ipm->h, &ip_map_cache); 372 cache_put(&ipm->h, &ip_map_cache);
329 return rv; 373 return rv;
330} 374}
331 375
332void svcauth_unix_purge(void) 376void svcauth_unix_purge(void)
333{ 377{
334 cache_purge(&ip_map_cache); 378 cache_purge(&ip_map_cache);
335 cache_purge(&auth_domain_cache);
336} 379}
337 380
338static int 381static int
339svcauth_unix_set_client(struct svc_rqst *rqstp) 382svcauth_unix_set_client(struct svc_rqst *rqstp)
340{ 383{
341 struct ip_map key, *ipm; 384 struct ip_map *ipm;
342 385
343 rqstp->rq_client = NULL; 386 rqstp->rq_client = NULL;
344 if (rqstp->rq_proc == 0) 387 if (rqstp->rq_proc == 0)
345 return SVC_OK; 388 return SVC_OK;
346 389
347 strcpy(key.m_class, rqstp->rq_server->sv_program->pg_class); 390 ipm = ip_map_lookup(rqstp->rq_server->sv_program->pg_class,
348 key.m_addr = rqstp->rq_addr.sin_addr; 391 rqstp->rq_addr.sin_addr);
349
350 ipm = ip_map_lookup(&key, 0);
351 392
352 if (ipm == NULL) 393 if (ipm == NULL)
353 return SVC_DENIED; 394 return SVC_DENIED;
@@ -361,8 +402,8 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
361 return SVC_DENIED; 402 return SVC_DENIED;
362 case 0: 403 case 0:
363 rqstp->rq_client = &ipm->m_client->h; 404 rqstp->rq_client = &ipm->m_client->h;
364 cache_get(&rqstp->rq_client->h); 405 kref_get(&rqstp->rq_client->ref);
365 ip_map_put(&ipm->h, &ip_map_cache); 406 cache_put(&ipm->h, &ip_map_cache);
366 break; 407 break;
367 } 408 }
368 return SVC_OK; 409 return SVC_OK;
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c
index 9d10d79e27af..9ea3059a7064 100644
--- a/sound/drivers/mpu401/mpu401.c
+++ b/sound/drivers/mpu401/mpu401.c
@@ -59,7 +59,8 @@ module_param_array(irq, int, NULL, 0444);
59MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device."); 59MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device.");
60 60
61static struct platform_device *platform_devices[SNDRV_CARDS]; 61static struct platform_device *platform_devices[SNDRV_CARDS];
62static int pnp_registered = 0; 62static int pnp_registered;
63static unsigned int snd_mpu401_devices;
63 64
64static int snd_mpu401_create(int dev, struct snd_card **rcard) 65static int snd_mpu401_create(int dev, struct snd_card **rcard)
65{ 66{
@@ -197,6 +198,7 @@ static int __devinit snd_mpu401_pnp_probe(struct pnp_dev *pnp_dev,
197 } 198 }
198 snd_card_set_dev(card, &pnp_dev->dev); 199 snd_card_set_dev(card, &pnp_dev->dev);
199 pnp_set_drvdata(pnp_dev, card); 200 pnp_set_drvdata(pnp_dev, card);
201 snd_mpu401_devices++;
200 ++dev; 202 ++dev;
201 return 0; 203 return 0;
202 } 204 }
@@ -234,12 +236,11 @@ static void __init_or_module snd_mpu401_unregister_all(void)
234 236
235static int __init alsa_card_mpu401_init(void) 237static int __init alsa_card_mpu401_init(void)
236{ 238{
237 int i, err, devices; 239 int i, err;
238 240
239 if ((err = platform_driver_register(&snd_mpu401_driver)) < 0) 241 if ((err = platform_driver_register(&snd_mpu401_driver)) < 0)
240 return err; 242 return err;
241 243
242 devices = 0;
243 for (i = 0; i < SNDRV_CARDS; i++) { 244 for (i = 0; i < SNDRV_CARDS; i++) {
244 struct platform_device *device; 245 struct platform_device *device;
245 if (! enable[i]) 246 if (! enable[i])
@@ -255,14 +256,13 @@ static int __init alsa_card_mpu401_init(void)
255 goto errout; 256 goto errout;
256 } 257 }
257 platform_devices[i] = device; 258 platform_devices[i] = device;
258 devices++; 259 snd_mpu401_devices++;
259 } 260 }
260 if ((err = pnp_register_driver(&snd_mpu401_pnp_driver)) >= 0) { 261 err = pnp_register_driver(&snd_mpu401_pnp_driver);
262 if (!err)
261 pnp_registered = 1; 263 pnp_registered = 1;
262 devices += err;
263 }
264 264
265 if (!devices) { 265 if (!snd_mpu401_devices) {
266#ifdef MODULE 266#ifdef MODULE
267 printk(KERN_ERR "MPU-401 device not found or device busy\n"); 267 printk(KERN_ERR "MPU-401 device not found or device busy\n");
268#endif 268#endif
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c
index 7051f7798ed7..31f299aed281 100644
--- a/sound/isa/ad1816a/ad1816a.c
+++ b/sound/isa/ad1816a/ad1816a.c
@@ -262,6 +262,8 @@ static int __devinit snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard
262 return 0; 262 return 0;
263} 263}
264 264
265static unsigned int __devinitdata ad1816a_devices;
266
265static int __devinit snd_ad1816a_pnp_detect(struct pnp_card_link *card, 267static int __devinit snd_ad1816a_pnp_detect(struct pnp_card_link *card,
266 const struct pnp_card_device_id *id) 268 const struct pnp_card_device_id *id)
267{ 269{
@@ -275,6 +277,7 @@ static int __devinit snd_ad1816a_pnp_detect(struct pnp_card_link *card,
275 if (res < 0) 277 if (res < 0)
276 return res; 278 return res;
277 dev++; 279 dev++;
280 ad1816a_devices++;
278 return 0; 281 return 0;
279 } 282 }
280 return -ENODEV; 283 return -ENODEV;
@@ -297,10 +300,13 @@ static struct pnp_card_driver ad1816a_pnpc_driver = {
297 300
298static int __init alsa_card_ad1816a_init(void) 301static int __init alsa_card_ad1816a_init(void)
299{ 302{
300 int cards; 303 int err;
304
305 err = pnp_register_card_driver(&ad1816a_pnpc_driver);
306 if (err)
307 return err;
301 308
302 cards = pnp_register_card_driver(&ad1816a_pnpc_driver); 309 if (!ad1816a_devices) {
303 if (cards <= 0) {
304 pnp_unregister_card_driver(&ad1816a_pnpc_driver); 310 pnp_unregister_card_driver(&ad1816a_pnpc_driver);
305#ifdef MODULE 311#ifdef MODULE
306 printk(KERN_ERR "no AD1816A based soundcards found.\n"); 312 printk(KERN_ERR "no AD1816A based soundcards found.\n");
diff --git a/sound/isa/als100.c b/sound/isa/als100.c
index 9b77c17b3f66..a52bd8a14c9b 100644
--- a/sound/isa/als100.c
+++ b/sound/isa/als100.c
@@ -199,7 +199,7 @@ static int __devinit snd_card_als100_pnp(int dev, struct snd_card_als100 *acard,
199 return 0; 199 return 0;
200} 200}
201 201
202static int __init snd_card_als100_probe(int dev, 202static int __devinit snd_card_als100_probe(int dev,
203 struct pnp_card_link *pcard, 203 struct pnp_card_link *pcard,
204 const struct pnp_card_device_id *pid) 204 const struct pnp_card_device_id *pid)
205{ 205{
@@ -281,6 +281,8 @@ static int __init snd_card_als100_probe(int dev,
281 return 0; 281 return 0;
282} 282}
283 283
284static unsigned int __devinitdata als100_devices;
285
284static int __devinit snd_als100_pnp_detect(struct pnp_card_link *card, 286static int __devinit snd_als100_pnp_detect(struct pnp_card_link *card,
285 const struct pnp_card_device_id *id) 287 const struct pnp_card_device_id *id)
286{ 288{
@@ -294,6 +296,7 @@ static int __devinit snd_als100_pnp_detect(struct pnp_card_link *card,
294 if (res < 0) 296 if (res < 0)
295 return res; 297 return res;
296 dev++; 298 dev++;
299 als100_devices++;
297 return 0; 300 return 0;
298 } 301 }
299 return -ENODEV; 302 return -ENODEV;
@@ -345,10 +348,13 @@ static struct pnp_card_driver als100_pnpc_driver = {
345 348
346static int __init alsa_card_als100_init(void) 349static int __init alsa_card_als100_init(void)
347{ 350{
348 int cards; 351 int err;
352
353 err = pnp_register_card_driver(&als100_pnpc_driver);
354 if (err)
355 return err;
349 356
350 cards = pnp_register_card_driver(&als100_pnpc_driver); 357 if (!als100_devices) {
351 if (cards <= 0) {
352 pnp_unregister_card_driver(&als100_pnpc_driver); 358 pnp_unregister_card_driver(&als100_pnpc_driver);
353#ifdef MODULE 359#ifdef MODULE
354 snd_printk(KERN_ERR "no ALS100 based soundcards found\n"); 360 snd_printk(KERN_ERR "no ALS100 based soundcards found\n");
diff --git a/sound/isa/azt2320.c b/sound/isa/azt2320.c
index a530691bf4f7..15e59283aac6 100644
--- a/sound/isa/azt2320.c
+++ b/sound/isa/azt2320.c
@@ -310,6 +310,8 @@ static int __devinit snd_card_azt2320_probe(int dev,
310 return 0; 310 return 0;
311} 311}
312 312
313static unsigned int __devinitdata azt2320_devices;
314
313static int __devinit snd_azt2320_pnp_detect(struct pnp_card_link *card, 315static int __devinit snd_azt2320_pnp_detect(struct pnp_card_link *card,
314 const struct pnp_card_device_id *id) 316 const struct pnp_card_device_id *id)
315{ 317{
@@ -323,6 +325,7 @@ static int __devinit snd_azt2320_pnp_detect(struct pnp_card_link *card,
323 if (res < 0) 325 if (res < 0)
324 return res; 326 return res;
325 dev++; 327 dev++;
328 azt2320_devices++;
326 return 0; 329 return 0;
327 } 330 }
328 return -ENODEV; 331 return -ENODEV;
@@ -372,10 +375,13 @@ static struct pnp_card_driver azt2320_pnpc_driver = {
372 375
373static int __init alsa_card_azt2320_init(void) 376static int __init alsa_card_azt2320_init(void)
374{ 377{
375 int cards; 378 int err;
379
380 err = pnp_register_card_driver(&azt2320_pnpc_driver);
381 if (err)
382 return err;
376 383
377 cards = pnp_register_card_driver(&azt2320_pnpc_driver); 384 if (!azt2320_devices) {
378 if (cards <= 0) {
379 pnp_unregister_card_driver(&azt2320_pnpc_driver); 385 pnp_unregister_card_driver(&azt2320_pnpc_driver);
380#ifdef MODULE 386#ifdef MODULE
381 snd_printk(KERN_ERR "no AZT2320 based soundcards found\n"); 387 snd_printk(KERN_ERR "no AZT2320 based soundcards found\n");
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index fd9bb2575de8..fa63048a8b9d 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -175,7 +175,7 @@ MODULE_DEVICE_TABLE(pnp_card, snd_cmi8330_pnpids);
175#endif 175#endif
176 176
177 177
178static struct ad1848_mix_elem snd_cmi8330_controls[] __initdata = { 178static struct ad1848_mix_elem snd_cmi8330_controls[] __devinitdata = {
179AD1848_DOUBLE("Master Playback Volume", 0, CMI8330_MASTVOL, CMI8330_MASTVOL, 4, 0, 15, 0), 179AD1848_DOUBLE("Master Playback Volume", 0, CMI8330_MASTVOL, CMI8330_MASTVOL, 4, 0, 15, 0),
180AD1848_SINGLE("Loud Playback Switch", 0, CMI8330_MUTEMUX, 6, 1, 1), 180AD1848_SINGLE("Loud Playback Switch", 0, CMI8330_MUTEMUX, 6, 1, 1),
181AD1848_DOUBLE("PCM Playback Switch", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1), 181AD1848_DOUBLE("PCM Playback Switch", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1),
@@ -204,7 +204,7 @@ AD1848_SINGLE(SNDRV_CTL_NAME_IEC958("Input ",PLAYBACK,SWITCH), 0, CMI8330_MUTEMU
204}; 204};
205 205
206#ifdef ENABLE_SB_MIXER 206#ifdef ENABLE_SB_MIXER
207static struct sbmix_elem cmi8330_sb_mixers[] __initdata = { 207static struct sbmix_elem cmi8330_sb_mixers[] __devinitdata = {
208SB_DOUBLE("SB Master Playback Volume", SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV + 1), 3, 3, 31), 208SB_DOUBLE("SB Master Playback Volume", SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV + 1), 3, 3, 31),
209SB_DOUBLE("Tone Control - Bass", SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4, 4, 15), 209SB_DOUBLE("Tone Control - Bass", SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4, 4, 15),
210SB_DOUBLE("Tone Control - Treble", SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV + 1), 4, 4, 15), 210SB_DOUBLE("Tone Control - Treble", SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV + 1), 4, 4, 15),
@@ -222,7 +222,7 @@ SB_DOUBLE("SB Playback Volume", SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6
222SB_SINGLE("SB Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1), 222SB_SINGLE("SB Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1),
223}; 223};
224 224
225static unsigned char cmi8330_sb_init_values[][2] __initdata = { 225static unsigned char cmi8330_sb_init_values[][2] __devinitdata = {
226 { SB_DSP4_MASTER_DEV + 0, 0 }, 226 { SB_DSP4_MASTER_DEV + 0, 0 },
227 { SB_DSP4_MASTER_DEV + 1, 0 }, 227 { SB_DSP4_MASTER_DEV + 1, 0 },
228 { SB_DSP4_PCM_DEV + 0, 0 }, 228 { SB_DSP4_PCM_DEV + 0, 0 },
@@ -545,7 +545,7 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
545 return snd_card_register(card); 545 return snd_card_register(card);
546} 546}
547 547
548static int __init snd_cmi8330_nonpnp_probe(struct platform_device *pdev) 548static int __devinit snd_cmi8330_nonpnp_probe(struct platform_device *pdev)
549{ 549{
550 struct snd_card *card; 550 struct snd_card *card;
551 int err; 551 int err;
@@ -607,6 +607,8 @@ static struct platform_driver snd_cmi8330_driver = {
607 607
608 608
609#ifdef CONFIG_PNP 609#ifdef CONFIG_PNP
610static unsigned int __devinitdata cmi8330_pnp_devices;
611
610static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard, 612static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard,
611 const struct pnp_card_device_id *pid) 613 const struct pnp_card_device_id *pid)
612{ 614{
@@ -636,6 +638,7 @@ static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard,
636 } 638 }
637 pnp_set_card_drvdata(pcard, card); 639 pnp_set_card_drvdata(pcard, card);
638 dev++; 640 dev++;
641 cmi8330_pnp_devices++;
639 return 0; 642 return 0;
640} 643}
641 644
@@ -706,9 +709,9 @@ static int __init alsa_card_cmi8330_init(void)
706 709
707#ifdef CONFIG_PNP 710#ifdef CONFIG_PNP
708 err = pnp_register_card_driver(&cmi8330_pnpc_driver); 711 err = pnp_register_card_driver(&cmi8330_pnpc_driver);
709 if (err >= 0) { 712 if (!err) {
710 pnp_registered = 1; 713 pnp_registered = 1;
711 cards += err; 714 cards += cmi8330_pnp_devices;
712 } 715 }
713#endif 716#endif
714 717
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index 4060918e0327..382bb17ef49f 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -133,6 +133,7 @@ static int pnpc_registered;
133static int pnp_registered; 133static int pnp_registered;
134#endif 134#endif
135#endif /* CONFIG_PNP */ 135#endif /* CONFIG_PNP */
136static unsigned int snd_cs423x_devices;
136 137
137struct snd_card_cs4236 { 138struct snd_card_cs4236 {
138 struct snd_cs4231 *chip; 139 struct snd_cs4231 *chip;
@@ -564,7 +565,7 @@ static int __init snd_cs423x_nonpnp_probe(struct platform_device *pdev)
564 snd_card_free(card); 565 snd_card_free(card);
565 return err; 566 return err;
566 } 567 }
567 568
568 platform_set_drvdata(pdev, card); 569 platform_set_drvdata(pdev, card);
569 return 0; 570 return 0;
570} 571}
@@ -650,6 +651,7 @@ static int __devinit snd_cs4232_pnpbios_detect(struct pnp_dev *pdev,
650 } 651 }
651 pnp_set_drvdata(pdev, card); 652 pnp_set_drvdata(pdev, card);
652 dev++; 653 dev++;
654 snd_cs423x_devices++;
653 return 0; 655 return 0;
654} 656}
655 657
@@ -713,6 +715,7 @@ static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard,
713 } 715 }
714 pnp_set_card_drvdata(pcard, card); 716 pnp_set_card_drvdata(pcard, card);
715 dev++; 717 dev++;
718 snd_cs423x_devices++;
716 return 0; 719 return 0;
717} 720}
718 721
@@ -721,7 +724,7 @@ static void __devexit snd_cs423x_pnpc_remove(struct pnp_card_link * pcard)
721 snd_card_free(pnp_get_card_drvdata(pcard)); 724 snd_card_free(pnp_get_card_drvdata(pcard));
722 pnp_set_card_drvdata(pcard, NULL); 725 pnp_set_card_drvdata(pcard, NULL);
723} 726}
724 727
725#ifdef CONFIG_PM 728#ifdef CONFIG_PM
726static int snd_cs423x_pnpc_suspend(struct pnp_card_link *pcard, pm_message_t state) 729static int snd_cs423x_pnpc_suspend(struct pnp_card_link *pcard, pm_message_t state)
727{ 730{
@@ -766,7 +769,7 @@ static void __init_or_module snd_cs423x_unregister_all(void)
766 769
767static int __init alsa_card_cs423x_init(void) 770static int __init alsa_card_cs423x_init(void)
768{ 771{
769 int i, err, cards = 0; 772 int i, err;
770 773
771 if ((err = platform_driver_register(&cs423x_nonpnp_driver)) < 0) 774 if ((err = platform_driver_register(&cs423x_nonpnp_driver)) < 0)
772 return err; 775 return err;
@@ -782,24 +785,20 @@ static int __init alsa_card_cs423x_init(void)
782 goto errout; 785 goto errout;
783 } 786 }
784 platform_devices[i] = device; 787 platform_devices[i] = device;
785 cards++; 788 snd_cs423x_devices++;
786 } 789 }
787#ifdef CONFIG_PNP 790#ifdef CONFIG_PNP
788#ifdef CS4232 791#ifdef CS4232
789 i = pnp_register_driver(&cs4232_pnp_driver); 792 err = pnp_register_driver(&cs4232_pnp_driver);
790 if (i >= 0) { 793 if (!err)
791 pnp_registered = 1; 794 pnp_registered = 1;
792 cards += i;
793 }
794#endif 795#endif
795 i = pnp_register_card_driver(&cs423x_pnpc_driver); 796 err = pnp_register_card_driver(&cs423x_pnpc_driver);
796 if (i >= 0) { 797 if (!err)
797 pnpc_registered = 1; 798 pnpc_registered = 1;
798 cards += i;
799 }
800#endif /* CONFIG_PNP */ 799#endif /* CONFIG_PNP */
801 800
802 if (!cards) { 801 if (!snd_cs423x_devices) {
803#ifdef MODULE 802#ifdef MODULE
804 printk(KERN_ERR IDENT " soundcard not found or device busy\n"); 803 printk(KERN_ERR IDENT " soundcard not found or device busy\n");
805#endif 804#endif
diff --git a/sound/isa/dt019x.c b/sound/isa/dt019x.c
index 50e7bc5ef561..0acb4e5da47f 100644
--- a/sound/isa/dt019x.c
+++ b/sound/isa/dt019x.c
@@ -272,6 +272,8 @@ static int __devinit snd_card_dt019x_probe(int dev, struct pnp_card_link *pcard,
272 return 0; 272 return 0;
273} 273}
274 274
275static unsigned int __devinitdata dt019x_devices;
276
275static int __devinit snd_dt019x_pnp_probe(struct pnp_card_link *card, 277static int __devinit snd_dt019x_pnp_probe(struct pnp_card_link *card,
276 const struct pnp_card_device_id *pid) 278 const struct pnp_card_device_id *pid)
277{ 279{
@@ -285,6 +287,7 @@ static int __devinit snd_dt019x_pnp_probe(struct pnp_card_link *card,
285 if (res < 0) 287 if (res < 0)
286 return res; 288 return res;
287 dev++; 289 dev++;
290 dt019x_devices++;
288 return 0; 291 return 0;
289 } 292 }
290 return -ENODEV; 293 return -ENODEV;
@@ -336,10 +339,13 @@ static struct pnp_card_driver dt019x_pnpc_driver = {
336 339
337static int __init alsa_card_dt019x_init(void) 340static int __init alsa_card_dt019x_init(void)
338{ 341{
339 int cards = 0; 342 int err;
343
344 err = pnp_register_card_driver(&dt019x_pnpc_driver);
345 if (err)
346 return err;
340 347
341 cards = pnp_register_card_driver(&dt019x_pnpc_driver); 348 if (!dt019x_devices) {
342 if (cards <= 0) {
343 pnp_unregister_card_driver(&dt019x_pnpc_driver); 349 pnp_unregister_card_driver(&dt019x_pnpc_driver);
344#ifdef MODULE 350#ifdef MODULE
345 snd_printk(KERN_ERR "no DT-019X / ALS-007 based soundcards found\n"); 351 snd_printk(KERN_ERR "no DT-019X / ALS-007 based soundcards found\n");
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index 721955d26194..9fbc185b4cc2 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -2204,7 +2204,7 @@ static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev)
2204 return snd_card_register(card); 2204 return snd_card_register(card);
2205} 2205}
2206 2206
2207static int __init snd_es18xx_nonpnp_probe1(int dev, struct platform_device *devptr) 2207static int __devinit snd_es18xx_nonpnp_probe1(int dev, struct platform_device *devptr)
2208{ 2208{
2209 struct snd_card *card; 2209 struct snd_card *card;
2210 int err; 2210 int err;
@@ -2221,7 +2221,7 @@ static int __init snd_es18xx_nonpnp_probe1(int dev, struct platform_device *devp
2221 return 0; 2221 return 0;
2222} 2222}
2223 2223
2224static int __init snd_es18xx_nonpnp_probe(struct platform_device *pdev) 2224static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev)
2225{ 2225{
2226 int dev = pdev->id; 2226 int dev = pdev->id;
2227 int err; 2227 int err;
@@ -2297,6 +2297,8 @@ static struct platform_driver snd_es18xx_nonpnp_driver = {
2297 2297
2298 2298
2299#ifdef CONFIG_PNP 2299#ifdef CONFIG_PNP
2300static unsigned int __devinitdata es18xx_pnp_devices;
2301
2300static int __devinit snd_audiodrive_pnp_detect(struct pnp_card_link *pcard, 2302static int __devinit snd_audiodrive_pnp_detect(struct pnp_card_link *pcard,
2301 const struct pnp_card_device_id *pid) 2303 const struct pnp_card_device_id *pid)
2302{ 2304{
@@ -2327,6 +2329,7 @@ static int __devinit snd_audiodrive_pnp_detect(struct pnp_card_link *pcard,
2327 2329
2328 pnp_set_card_drvdata(pcard, card); 2330 pnp_set_card_drvdata(pcard, card);
2329 dev++; 2331 dev++;
2332 es18xx_pnp_devices++;
2330 return 0; 2333 return 0;
2331} 2334}
2332 2335
@@ -2397,10 +2400,10 @@ static int __init alsa_card_es18xx_init(void)
2397 } 2400 }
2398 2401
2399#ifdef CONFIG_PNP 2402#ifdef CONFIG_PNP
2400 i = pnp_register_card_driver(&es18xx_pnpc_driver); 2403 err = pnp_register_card_driver(&es18xx_pnpc_driver);
2401 if (i >= 0) { 2404 if (!err) {
2402 pnp_registered = 1; 2405 pnp_registered = 1;
2403 cards += i; 2406 cards += es18xx_pnp_devices;
2404 } 2407 }
2405#endif 2408#endif
2406 2409
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index 2cacd0fa6871..de71b7a99c83 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -791,7 +791,7 @@ static int __devinit snd_interwave_probe(struct snd_card *card, int dev)
791 return 0; 791 return 0;
792} 792}
793 793
794static int __init snd_interwave_nonpnp_probe1(int dev, struct platform_device *devptr) 794static int __devinit snd_interwave_nonpnp_probe1(int dev, struct platform_device *devptr)
795{ 795{
796 struct snd_card *card; 796 struct snd_card *card;
797 int err; 797 int err;
@@ -809,7 +809,7 @@ static int __init snd_interwave_nonpnp_probe1(int dev, struct platform_device *d
809 return 0; 809 return 0;
810} 810}
811 811
812static int __init snd_interwave_nonpnp_probe(struct platform_device *pdev) 812static int __devinit snd_interwave_nonpnp_probe(struct platform_device *pdev)
813{ 813{
814 int dev = pdev->id; 814 int dev = pdev->id;
815 int err; 815 int err;
@@ -867,6 +867,7 @@ static struct platform_driver snd_interwave_driver = {
867}; 867};
868 868
869#ifdef CONFIG_PNP 869#ifdef CONFIG_PNP
870static unsigned int __devinitdata interwave_pnp_devices;
870 871
871static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard, 872static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard,
872 const struct pnp_card_device_id *pid) 873 const struct pnp_card_device_id *pid)
@@ -897,6 +898,7 @@ static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard,
897 } 898 }
898 pnp_set_card_drvdata(pcard, card); 899 pnp_set_card_drvdata(pcard, card);
899 dev++; 900 dev++;
901 interwave_pnp_devices++;
900 return 0; 902 return 0;
901} 903}
902 904
@@ -954,10 +956,10 @@ static int __init alsa_card_interwave_init(void)
954 } 956 }
955 957
956 /* ISA PnP cards */ 958 /* ISA PnP cards */
957 i = pnp_register_card_driver(&interwave_pnpc_driver); 959 err = pnp_register_card_driver(&interwave_pnpc_driver);
958 if (i >= 0) { 960 if (!err) {
959 pnp_registered = 1; 961 pnp_registered = 1;
960 cards += i; 962 cards += interwave_pnp_devices;;
961 } 963 }
962 964
963 if (!cards) { 965 if (!cards) {
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index 56fcd8a946a4..c906e205d7d5 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -95,6 +95,7 @@ static struct platform_device *platform_devices[SNDRV_CARDS];
95static int pnp_registered; 95static int pnp_registered;
96static int pnpc_registered; 96static int pnpc_registered;
97#endif 97#endif
98static unsigned int snd_opl3sa2_devices;
98 99
99/* control ports */ 100/* control ports */
100#define OPL3SA2_PM_CTRL 0x01 101#define OPL3SA2_PM_CTRL 0x01
@@ -760,6 +761,7 @@ static int __devinit snd_opl3sa2_pnp_detect(struct pnp_dev *pdev,
760 } 761 }
761 pnp_set_drvdata(pdev, card); 762 pnp_set_drvdata(pdev, card);
762 dev++; 763 dev++;
764 snd_opl3sa2_devices++;
763 return 0; 765 return 0;
764} 766}
765 767
@@ -826,6 +828,7 @@ static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *pcard,
826 } 828 }
827 pnp_set_card_drvdata(pcard, card); 829 pnp_set_card_drvdata(pcard, card);
828 dev++; 830 dev++;
831 snd_opl3sa2_devices++;
829 return 0; 832 return 0;
830} 833}
831 834
@@ -944,7 +947,7 @@ static void __init_or_module snd_opl3sa2_unregister_all(void)
944 947
945static int __init alsa_card_opl3sa2_init(void) 948static int __init alsa_card_opl3sa2_init(void)
946{ 949{
947 int i, err, cards = 0; 950 int i, err;
948 951
949 if ((err = platform_driver_register(&snd_opl3sa2_nonpnp_driver)) < 0) 952 if ((err = platform_driver_register(&snd_opl3sa2_nonpnp_driver)) < 0)
950 return err; 953 return err;
@@ -964,23 +967,19 @@ static int __init alsa_card_opl3sa2_init(void)
964 goto errout; 967 goto errout;
965 } 968 }
966 platform_devices[i] = device; 969 platform_devices[i] = device;
967 cards++; 970 snd_opl3sa2_devices++;
968 } 971 }
969 972
970#ifdef CONFIG_PNP 973#ifdef CONFIG_PNP
971 err = pnp_register_driver(&opl3sa2_pnp_driver); 974 err = pnp_register_driver(&opl3sa2_pnp_driver);
972 if (err >= 0) { 975 if (!err)
973 pnp_registered = 1; 976 pnp_registered = 1;
974 cards += err;
975 }
976 err = pnp_register_card_driver(&opl3sa2_pnpc_driver); 977 err = pnp_register_card_driver(&opl3sa2_pnpc_driver);
977 if (err >= 0) { 978 if (!err)
978 pnpc_registered = 1; 979 pnpc_registered = 1;
979 cards += err;
980 }
981#endif 980#endif
982 981
983 if (!cards) { 982 if (!snd_opl3sa2_devices) {
984#ifdef MODULE 983#ifdef MODULE
985 snd_printk(KERN_ERR "Yamaha OPL3-SA soundcard not found or device busy\n"); 984 snd_printk(KERN_ERR "Yamaha OPL3-SA soundcard not found or device busy\n");
986#endif 985#endif
diff --git a/sound/isa/sb/es968.c b/sound/isa/sb/es968.c
index 9da80bfa3027..d4d65b84265a 100644
--- a/sound/isa/sb/es968.c
+++ b/sound/isa/sb/es968.c
@@ -124,7 +124,7 @@ static int __devinit snd_card_es968_pnp(int dev, struct snd_card_es968 *acard,
124 return 0; 124 return 0;
125} 125}
126 126
127static int __init snd_card_es968_probe(int dev, 127static int __devinit snd_card_es968_probe(int dev,
128 struct pnp_card_link *pcard, 128 struct pnp_card_link *pcard,
129 const struct pnp_card_device_id *pid) 129 const struct pnp_card_device_id *pid)
130{ 130{
@@ -182,6 +182,8 @@ static int __init snd_card_es968_probe(int dev,
182 return 0; 182 return 0;
183} 183}
184 184
185static unsigned int __devinitdata es968_devices;
186
185static int __devinit snd_es968_pnp_detect(struct pnp_card_link *card, 187static int __devinit snd_es968_pnp_detect(struct pnp_card_link *card,
186 const struct pnp_card_device_id *id) 188 const struct pnp_card_device_id *id)
187{ 189{
@@ -195,6 +197,7 @@ static int __devinit snd_es968_pnp_detect(struct pnp_card_link *card,
195 if (res < 0) 197 if (res < 0)
196 return res; 198 return res;
197 dev++; 199 dev++;
200 es968_devices++;
198 return 0; 201 return 0;
199 } 202 }
200 return -ENODEV; 203 return -ENODEV;
@@ -246,8 +249,11 @@ static struct pnp_card_driver es968_pnpc_driver = {
246 249
247static int __init alsa_card_es968_init(void) 250static int __init alsa_card_es968_init(void)
248{ 251{
249 int cards = pnp_register_card_driver(&es968_pnpc_driver); 252 int err = pnp_register_card_driver(&es968_pnpc_driver);
250 if (cards <= 0) { 253 if (err)
254 return err;
255
256 if (!es968_devices) {
251 pnp_unregister_card_driver(&es968_pnpc_driver); 257 pnp_unregister_card_driver(&es968_pnpc_driver);
252#ifdef MODULE 258#ifdef MODULE
253 snd_printk(KERN_ERR "no ES968 based soundcards found\n"); 259 snd_printk(KERN_ERR "no ES968 based soundcards found\n");
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index 5737ab76160c..21ea65925a9e 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -369,7 +369,7 @@ static struct snd_card *snd_sb16_card_new(int dev)
369 return card; 369 return card;
370} 370}
371 371
372static int __init snd_sb16_probe(struct snd_card *card, int dev) 372static int __devinit snd_sb16_probe(struct snd_card *card, int dev)
373{ 373{
374 int xirq, xdma8, xdma16; 374 int xirq, xdma8, xdma16;
375 struct snd_sb *chip; 375 struct snd_sb *chip;
@@ -518,7 +518,7 @@ static int snd_sb16_resume(struct snd_card *card)
518} 518}
519#endif 519#endif
520 520
521static int __init snd_sb16_nonpnp_probe1(int dev, struct platform_device *devptr) 521static int __devinit snd_sb16_nonpnp_probe1(int dev, struct platform_device *devptr)
522{ 522{
523 struct snd_card_sb16 *acard; 523 struct snd_card_sb16 *acard;
524 struct snd_card *card; 524 struct snd_card *card;
@@ -548,7 +548,7 @@ static int __init snd_sb16_nonpnp_probe1(int dev, struct platform_device *devptr
548} 548}
549 549
550 550
551static int __init snd_sb16_nonpnp_probe(struct platform_device *pdev) 551static int __devinit snd_sb16_nonpnp_probe(struct platform_device *pdev)
552{ 552{
553 int dev = pdev->id; 553 int dev = pdev->id;
554 int err; 554 int err;
@@ -629,6 +629,7 @@ static struct platform_driver snd_sb16_nonpnp_driver = {
629 629
630 630
631#ifdef CONFIG_PNP 631#ifdef CONFIG_PNP
632static unsigned int __devinitdata sb16_pnp_devices;
632 633
633static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard, 634static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard,
634 const struct pnp_card_device_id *pid) 635 const struct pnp_card_device_id *pid)
@@ -651,6 +652,7 @@ static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard,
651 } 652 }
652 pnp_set_card_drvdata(pcard, card); 653 pnp_set_card_drvdata(pcard, card);
653 dev++; 654 dev++;
655 sb16_pnp_devices++;
654 return 0; 656 return 0;
655 } 657 }
656 658
@@ -727,10 +729,10 @@ static int __init alsa_card_sb16_init(void)
727 } 729 }
728#ifdef CONFIG_PNP 730#ifdef CONFIG_PNP
729 /* PnP cards at last */ 731 /* PnP cards at last */
730 i = pnp_register_card_driver(&sb16_pnpc_driver); 732 err = pnp_register_card_driver(&sb16_pnpc_driver);
731 if (i >= 0) { 733 if (!err) {
732 pnp_registered = 1; 734 pnp_registered = 1;
733 cards += i; 735 cards += sb16_pnp_devices;
734 } 736 }
735#endif 737#endif
736 738
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index 29bba8cc3ef3..48e5552d3444 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -1255,7 +1255,7 @@ static int __devinit create_sscape(int dev, struct snd_card **rcardp)
1255} 1255}
1256 1256
1257 1257
1258static int __init snd_sscape_probe(struct platform_device *pdev) 1258static int __devinit snd_sscape_probe(struct platform_device *pdev)
1259{ 1259{
1260 int dev = pdev->id; 1260 int dev = pdev->id;
1261 struct snd_card *card; 1261 struct snd_card *card;
@@ -1469,7 +1469,7 @@ static int __init sscape_init(void)
1469 if (ret < 0) 1469 if (ret < 0)
1470 return ret; 1470 return ret;
1471#ifdef CONFIG_PNP 1471#ifdef CONFIG_PNP
1472 if (pnp_register_card_driver(&sscape_pnpc_driver) >= 0) 1472 if (pnp_register_card_driver(&sscape_pnpc_driver) == 0)
1473 pnp_registered = 1; 1473 pnp_registered = 1;
1474#endif 1474#endif
1475 return 0; 1475 return 0;
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index c0115bf9065e..2f13cd5d4dcb 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -589,7 +589,7 @@ snd_wavefront_probe (struct snd_card *card, int dev)
589 return snd_card_register(card); 589 return snd_card_register(card);
590} 590}
591 591
592static int __init snd_wavefront_nonpnp_probe(struct platform_device *pdev) 592static int __devinit snd_wavefront_nonpnp_probe(struct platform_device *pdev)
593{ 593{
594 int dev = pdev->id; 594 int dev = pdev->id;
595 struct snd_card *card; 595 struct snd_card *card;
@@ -637,6 +637,7 @@ static struct platform_driver snd_wavefront_driver = {
637 637
638 638
639#ifdef CONFIG_PNP 639#ifdef CONFIG_PNP
640static unsigned int __devinitdata wavefront_pnp_devices;
640 641
641static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard, 642static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard,
642 const struct pnp_card_device_id *pid) 643 const struct pnp_card_device_id *pid)
@@ -670,6 +671,7 @@ static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard,
670 671
671 pnp_set_card_drvdata(pcard, card); 672 pnp_set_card_drvdata(pcard, card);
672 dev++; 673 dev++;
674 wavefront_pnp_devices++;
673 return 0; 675 return 0;
674} 676}
675 677
@@ -729,10 +731,10 @@ static int __init alsa_card_wavefront_init(void)
729 } 731 }
730 732
731#ifdef CONFIG_PNP 733#ifdef CONFIG_PNP
732 i = pnp_register_card_driver(&wavefront_pnpc_driver); 734 err = pnp_register_card_driver(&wavefront_pnpc_driver);
733 if (i >= 0) { 735 if (!err) {
734 pnp_registered = 1; 736 pnp_registered = 1;
735 cards += i; 737 cards += wavefront_pnp_devices;
736 } 738 }
737#endif 739#endif
738 740
diff --git a/sound/oss/cs4232.c b/sound/oss/cs4232.c
index 7c59e2d4003a..c7f86f09c28d 100644
--- a/sound/oss/cs4232.c
+++ b/sound/oss/cs4232.c
@@ -360,6 +360,8 @@ static int __initdata synthio = -1;
360static int __initdata synthirq = -1; 360static int __initdata synthirq = -1;
361static int __initdata isapnp = 1; 361static int __initdata isapnp = 1;
362 362
363static unsigned int cs4232_devices;
364
363MODULE_DESCRIPTION("CS4232 based soundcard driver"); 365MODULE_DESCRIPTION("CS4232 based soundcard driver");
364MODULE_AUTHOR("Hannu Savolainen, Paul Barton-Davis"); 366MODULE_AUTHOR("Hannu Savolainen, Paul Barton-Davis");
365MODULE_LICENSE("GPL"); 367MODULE_LICENSE("GPL");
@@ -421,6 +423,7 @@ static int cs4232_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev
421 return -ENODEV; 423 return -ENODEV;
422 } 424 }
423 pnp_set_drvdata(dev,isapnpcfg); 425 pnp_set_drvdata(dev,isapnpcfg);
426 cs4232_devices++;
424 return 0; 427 return 0;
425} 428}
426 429
@@ -455,10 +458,11 @@ static int __init init_cs4232(void)
455#endif 458#endif
456 cfg.irq = -1; 459 cfg.irq = -1;
457 460
458 if (isapnp && 461 if (isapnp) {
459 (pnp_register_driver(&cs4232_driver) > 0) 462 pnp_register_driver(&cs4232_driver);
460 ) 463 if (cs4232_devices)
461 return 0; 464 return 0;
465 }
462 466
463 if(io==-1||irq==-1||dma==-1) 467 if(io==-1||irq==-1||dma==-1)
464 { 468 {
@@ -503,7 +507,8 @@ static int __init setup_cs4232(char *str)
503 int ints[7]; 507 int ints[7];
504 508
505 /* If we have isapnp cards, no need for options */ 509 /* If we have isapnp cards, no need for options */
506 if (pnp_register_driver(&cs4232_driver) > 0) 510 pnp_register_driver(&cs4232_driver);
511 if (cs4232_devices)
507 return 1; 512 return 1;
508 513
509 str = get_options(str, ARRAY_SIZE(ints), ints); 514 str = get_options(str, ARRAY_SIZE(ints), ints);
diff --git a/sound/oss/sb_card.c b/sound/oss/sb_card.c
index 680b82e15298..d38e88abc8fa 100644
--- a/sound/oss/sb_card.c
+++ b/sound/oss/sb_card.c
@@ -52,6 +52,7 @@ static int __initdata sm_games = 0; /* Logitech soundman games? */
52static struct sb_card_config *legacy = NULL; 52static struct sb_card_config *legacy = NULL;
53 53
54#ifdef CONFIG_PNP 54#ifdef CONFIG_PNP
55static int pnp_registered;
55static int __initdata pnp = 1; 56static int __initdata pnp = 1;
56/* 57/*
57static int __initdata uart401 = 0; 58static int __initdata uart401 = 0;
@@ -133,7 +134,7 @@ static void sb_unload(struct sb_card_config *scc)
133} 134}
134 135
135/* Register legacy card with OSS subsystem */ 136/* Register legacy card with OSS subsystem */
136static int sb_init_legacy(void) 137static int __init sb_init_legacy(void)
137{ 138{
138 struct sb_module_options sbmo = {0}; 139 struct sb_module_options sbmo = {0};
139 140
@@ -234,6 +235,8 @@ static void sb_dev2cfg(struct pnp_dev *dev, struct sb_card_config *scc)
234 } 235 }
235} 236}
236 237
238static unsigned int sb_pnp_devices;
239
237/* Probe callback function for the PnP API */ 240/* Probe callback function for the PnP API */
238static int sb_pnp_probe(struct pnp_card_link *card, const struct pnp_card_device_id *card_id) 241static int sb_pnp_probe(struct pnp_card_link *card, const struct pnp_card_device_id *card_id)
239{ 242{
@@ -264,6 +267,7 @@ static int sb_pnp_probe(struct pnp_card_link *card, const struct pnp_card_device
264 scc->conf.dma, scc->conf.dma2); 267 scc->conf.dma, scc->conf.dma2);
265 268
266 pnp_set_card_drvdata(card, scc); 269 pnp_set_card_drvdata(card, scc);
270 sb_pnp_devices++;
267 271
268 return sb_register_oss(scc, &sbmo); 272 return sb_register_oss(scc, &sbmo);
269} 273}
@@ -289,6 +293,14 @@ static struct pnp_card_driver sb_pnp_driver = {
289MODULE_DEVICE_TABLE(pnp_card, sb_pnp_card_table); 293MODULE_DEVICE_TABLE(pnp_card, sb_pnp_card_table);
290#endif /* CONFIG_PNP */ 294#endif /* CONFIG_PNP */
291 295
296static void __init_or_module sb_unregister_all(void)
297{
298#ifdef CONFIG_PNP
299 if (pnp_registered)
300 pnp_unregister_card_driver(&sb_pnp_driver);
301#endif
302}
303
292static int __init sb_init(void) 304static int __init sb_init(void)
293{ 305{
294 int lres = 0; 306 int lres = 0;
@@ -307,17 +319,18 @@ static int __init sb_init(void)
307 319
308#ifdef CONFIG_PNP 320#ifdef CONFIG_PNP
309 if(pnp) { 321 if(pnp) {
310 pres = pnp_register_card_driver(&sb_pnp_driver); 322 int err = pnp_register_card_driver(&sb_pnp_driver);
323 if (!err)
324 pnp_registered = 1;
325 pres = sb_pnp_devices;
311 } 326 }
312#endif 327#endif
313 printk(KERN_INFO "sb: Init: Done\n"); 328 printk(KERN_INFO "sb: Init: Done\n");
314 329
315 /* If either PnP or Legacy registered a card then return 330 /* If either PnP or Legacy registered a card then return
316 * success */ 331 * success */
317 if (pres <= 0 && lres <= 0) { 332 if (pres == 0 && lres <= 0) {
318#ifdef CONFIG_PNP 333 sb_unregister_all();
319 pnp_unregister_card_driver(&sb_pnp_driver);
320#endif
321 return -ENODEV; 334 return -ENODEV;
322 } 335 }
323 return 0; 336 return 0;
@@ -333,9 +346,7 @@ static void __exit sb_exit(void)
333 sb_unload(legacy); 346 sb_unload(legacy);
334 } 347 }
335 348
336#ifdef CONFIG_PNP 349 sb_unregister_all();
337 pnp_unregister_card_driver(&sb_pnp_driver);
338#endif
339 350
340 if (smw_free) { 351 if (smw_free) {
341 vfree(smw_free); 352 vfree(smw_free);